修改
This commit is contained in:
@@ -19,30 +19,74 @@ import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
name: 'Container',
|
||||
props: ["chartData",'dateData'],
|
||||
components: {},
|
||||
data() {
|
||||
return {};
|
||||
return {
|
||||
myChart: null, // 存储 echarts 实例
|
||||
};
|
||||
},
|
||||
// 关键:监听 chartData 变化
|
||||
watch: {
|
||||
chartData: {
|
||||
handler(newData) {
|
||||
this.updateChart(newData);
|
||||
},
|
||||
immediate: true, // 组件初始化时立即执行一次
|
||||
deep: true, // 深度监听对象内部变化
|
||||
}
|
||||
},
|
||||
computed: {},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initData();
|
||||
this.initChart();
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
// 优先使用 ref 获取 DOM,避免 id 冲突
|
||||
// 初始化图表实例
|
||||
initChart() {
|
||||
const chartDom = this.$refs.cockpitEffChip;
|
||||
if (!chartDom) {
|
||||
console.error('图表容器未找到!');
|
||||
return;
|
||||
}
|
||||
const myChart = echarts.init(chartDom);
|
||||
this.myChart = echarts.init(chartDom);
|
||||
|
||||
// 初始化时调用一次更新
|
||||
this.updateChart(this.chartData);
|
||||
|
||||
// 监听窗口缩放
|
||||
window.addEventListener('resize', () => {
|
||||
this.myChart?.resize();
|
||||
});
|
||||
},
|
||||
|
||||
// 核心:根据数据更新图表
|
||||
updateChart(data) {
|
||||
if (!this.myChart) {
|
||||
// 如果实例还未初始化,则等待 initChart 完成后再更新
|
||||
setTimeout(() => this.updateChart(data), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
// 1. 处理数据,如果 data 无效则清空图表
|
||||
if (!data || typeof data !== 'object' || (!data.real && !data.target)) {
|
||||
this.myChart.setOption({
|
||||
xAxis: { data: [] },
|
||||
series: [{ data: [] }, { data: [] }]
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 提取 X 轴数据(从 real 或 target 中取键名)
|
||||
const xAxisData = data.real ? Object.keys(data.real) : Object.keys(data.target);
|
||||
console.log('xAxisData', xAxisData);
|
||||
|
||||
// 3. 提取 "实际" 和 "目标" 系列的数据
|
||||
const realData = data.real ? Object.values(data.real) : [];
|
||||
const targetData = data.target ? Object.values(data.target) : [];
|
||||
|
||||
// 4. 准备 echarts 的 option 配置
|
||||
const option = {
|
||||
// color: ['#80FFA5', '#00DDFF', '#37A2FF', '#FF0087', '#FFBF00'],
|
||||
// title: {
|
||||
// text: 'Gradient Stacked Area Chart'
|
||||
// },
|
||||
tooltip: {
|
||||
trigger: 'axis',
|
||||
axisPointer: {
|
||||
@@ -55,60 +99,56 @@ export default {
|
||||
grid: {
|
||||
top: 20,
|
||||
bottom: 20,
|
||||
// top: 10,
|
||||
// bottom: 20,
|
||||
right: 25,
|
||||
},
|
||||
// legend: {
|
||||
// data: ['Line 1', 'Line 2', 'Line 3', 'Line 4', 'Line 5']
|
||||
// },
|
||||
// toolbox: {
|
||||
// feature: {
|
||||
// saveAsImage: {}
|
||||
// }
|
||||
// },
|
||||
xAxis: [
|
||||
{
|
||||
type: 'category',
|
||||
boundaryGap: false,
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLine: {
|
||||
show: true,
|
||||
onZero: false,
|
||||
lineStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.15)'
|
||||
}
|
||||
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
|
||||
},
|
||||
axisLabel: {
|
||||
color: 'rgba(0, 0, 0, 0.45)',
|
||||
fontSize: 12,
|
||||
interval: 0,
|
||||
width: 38,
|
||||
overflow: 'break'
|
||||
// 这里可以根据需要调整标签的显示方式
|
||||
formatter: (value) => {
|
||||
const dateParts = value.split('-'); // ["2025", "07", "01"]
|
||||
if (dateParts.length < 2) return value; // 处理异常格式
|
||||
|
||||
switch (this.dateData.mode) {
|
||||
case 1: // 日模式,显示“月-日”
|
||||
// 确保有日的部分
|
||||
return dateParts.length >= 3
|
||||
? `${dateParts[1]}月${dateParts[2]}日`
|
||||
: `${dateParts[1]}月`; // fallback
|
||||
case 2: // 月模式,显示“月”
|
||||
return `${dateParts[1]}月`;
|
||||
case 3: // 年模式,显示“年”
|
||||
return `${dateParts[0]}年`;
|
||||
default: // 默认月模式
|
||||
return `${dateParts[1]}月`;
|
||||
}
|
||||
}
|
||||
},
|
||||
data: ['6月', '7月', '8月', '9月', '10月', '11月']
|
||||
data: xAxisData // 使用提取出的 X 轴数据
|
||||
}
|
||||
],
|
||||
yAxis: {
|
||||
type: 'value',
|
||||
// name: '单位/片',
|
||||
nameTextStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.45)',
|
||||
fontSize: 14,
|
||||
align: 'left'
|
||||
},
|
||||
min: function (value) {
|
||||
return 0
|
||||
},
|
||||
max: function (value) {
|
||||
return Math.ceil(value.max)
|
||||
},
|
||||
min: 0,
|
||||
// max: function (value) { return Math.ceil(value.max * 1.1); }, // 增加一点余量
|
||||
scale: true,
|
||||
axisTick: {
|
||||
show: false
|
||||
},
|
||||
axisTick: { show: false },
|
||||
axisLabel: {
|
||||
color: 'rgba(0, 0, 0, 0.45)',
|
||||
fontSize: 12
|
||||
@@ -116,101 +156,88 @@ export default {
|
||||
splitLine: {
|
||||
lineStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.15)',
|
||||
// type: 'dashed'
|
||||
}
|
||||
},
|
||||
axisLine: {
|
||||
show: true,
|
||||
lineStyle: {
|
||||
color: 'rgba(0, 0, 0, 0.15)'
|
||||
}
|
||||
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
|
||||
}
|
||||
},
|
||||
series: [
|
||||
{
|
||||
name: '实际',
|
||||
type: 'line',
|
||||
stack: 'Total',
|
||||
symbol: 'circle', // 点的形状(circle为圆形)
|
||||
// stack: 'Total', // 趋势图通常不需要堆叠
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
lineStyle: {
|
||||
color: 'rgba(255, 132, 0, .5)',
|
||||
color: 'rgba(255, 132, 0, 1)', // 加深颜色
|
||||
width: 2,
|
||||
},
|
||||
itemStyle: {
|
||||
color: 'rgba(255, 132, 0, .5)',
|
||||
borderColor: 'rgba(255, 132, 0, .5)', // 数据点边框色(白色)
|
||||
borderWidth: 2, // 数据点边框宽度
|
||||
color: 'rgba(255, 132, 0, 1)',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2,
|
||||
},
|
||||
areaStyle: {
|
||||
opacity: 0.5,
|
||||
opacity: 0.3,
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(255, 132, 0, .4)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(18, 255, 245, 0)',
|
||||
},
|
||||
{ offset: 0, color: 'rgba(255, 132, 0, .5)' },
|
||||
{ offset: 1, color: 'rgba(255, 132, 0, 0)' },
|
||||
]),
|
||||
},
|
||||
// emphasis: { focus: 'series' },
|
||||
data: [140, 232, 101, 264, 90, 340, 250]
|
||||
data: realData // 使用提取出的 "实际" 数据
|
||||
},
|
||||
{
|
||||
name: '目标',
|
||||
type: 'line',
|
||||
stack: 'Total',
|
||||
symbol: 'circle', // 点的形状(circle为圆形)
|
||||
// stack: 'Total',
|
||||
symbol: 'circle',
|
||||
symbolSize: 8,
|
||||
lineStyle: {
|
||||
color: 'rgba(98, 213, 180, .5)',
|
||||
color: 'rgba(98, 213, 180, 1)', // 加深颜色
|
||||
width: 2,
|
||||
type: 'dashed' // 目标线使用虚线
|
||||
},
|
||||
itemStyle: {
|
||||
color: 'rgba(98, 213, 180, .5)',
|
||||
borderColor: 'rgba(98, 213, 180, .5)', // 数据点边框色(白色)
|
||||
borderWidth: 2, // 数据点边框宽度
|
||||
color: 'rgba(98, 213, 180, 1)',
|
||||
borderColor: '#fff',
|
||||
borderWidth: 2,
|
||||
},
|
||||
areaStyle: {
|
||||
opacity: 0.5,
|
||||
opacity: 0.3,
|
||||
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
|
||||
{
|
||||
offset: 0,
|
||||
color: 'rgba(98, 213, 180,.4)',
|
||||
},
|
||||
{
|
||||
offset: 1,
|
||||
color: 'rgba(18, 255, 245, 0)',
|
||||
},
|
||||
{ offset: 0, color: 'rgba(98, 213, 180, .5)' },
|
||||
{ offset: 1, color: 'rgba(98, 213, 180, 0)' },
|
||||
]),
|
||||
},
|
||||
// emphasis: { focus: 'series' },
|
||||
data: [120, 282, 111, 234, 220, 340, 310]
|
||||
data: targetData // 使用提取出的 "目标" 数据
|
||||
},
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
|
||||
// 监听窗口缩放
|
||||
window.addEventListener('resize', () => {
|
||||
myChart.resize();
|
||||
});
|
||||
|
||||
// 组件销毁时清理
|
||||
this.$once('hook:destroyed', () => {
|
||||
window.removeEventListener('resize', () => {
|
||||
myChart.resize();
|
||||
});
|
||||
myChart.dispose();
|
||||
});
|
||||
// 5. 应用配置项更新图表
|
||||
this.myChart.setOption(option, true);
|
||||
}
|
||||
},
|
||||
beforeDestroy() {
|
||||
// 组件销毁时清理
|
||||
window.removeEventListener('resize', () => {
|
||||
this.myChart?.resize();
|
||||
});
|
||||
this.myChart?.dispose();
|
||||
}
|
||||
};
|
||||
</script>
|
||||
<style lang="scss" scoped>
|
||||
/* (你的样式代码保持不变) */
|
||||
.legend {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: -5px;
|
||||
display: flex;
|
||||
/* 使用 flex 布局让两个图例项并排且对齐 */
|
||||
gap: 20px;
|
||||
}
|
||||
|
||||
.legend-item-line {
|
||||
@@ -220,25 +247,27 @@ export default {
|
||||
color: rgba(0, 0, 0, 0.8);
|
||||
text-align: left;
|
||||
font-style: normal;
|
||||
margin-right: 20px;
|
||||
/* 增加两个图例项之间的间距 */
|
||||
position: relative;
|
||||
padding-left: 8px;
|
||||
/* 给文字左侧增加内边距 */
|
||||
padding-left: 20px;
|
||||
/* 为圆点和线条留出空间 */
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.line {
|
||||
position: absolute;
|
||||
left: 5px;
|
||||
/* 调整线条位置 */
|
||||
top: 10px;
|
||||
left: 6px;
|
||||
/* 线条从圆点右侧开始 */
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
display: inline-block;
|
||||
width: 12px;
|
||||
width: 16px;
|
||||
/* 线条长度 */
|
||||
height: 2px;
|
||||
margin-right: 4px;
|
||||
}
|
||||
|
||||
.target {
|
||||
background: rgba(91, 230, 190, 1);
|
||||
background: rgba(98, 213, 180, 1);
|
||||
}
|
||||
|
||||
.real {
|
||||
@@ -251,23 +280,18 @@ export default {
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
border-radius: 50%;
|
||||
margin-right: 10px;
|
||||
/* 关键:增加图例圆点和文字之间的间距 */
|
||||
margin-bottom: 2px;
|
||||
margin-right: 8px;
|
||||
background-color: rgba(255, 132, 0, 1);
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
}
|
||||
|
||||
.legend-item-line:nth-child(1) {
|
||||
&::before {
|
||||
content: "";
|
||||
display: inline-block;
|
||||
width: 6px;
|
||||
height: 6px;
|
||||
margin-right: 10px;
|
||||
/* 关键:增加图例圆点和文字之间的间距 */
|
||||
margin-bottom: 2px;
|
||||
background-color: rgba(91, 230, 190, 1);
|
||||
background-color: rgba(98, 213, 180, 1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
Reference in New Issue
Block a user