This commit is contained in:
‘937886381’
2025-11-12 16:56:14 +08:00
commit 1ea62af1d6
1135 changed files with 109385 additions and 0 deletions

View File

@@ -0,0 +1,236 @@
<template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 400px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
name: 'operatingLineBar',
props: {
echartData: {
type: Object,
// 确保默认值中 flag 是数组,避免 undefined
default: () => ({
locations: [],
target: [],
value: [],
proportion: [],
flag: [] // 强制初始化为空数组
})
}
},
data() {
return {
myChart: null
};
},
watch: {
echartData: {
handler() {
this.initData();
},
deep: true,
immediate: true // 首次绑定就执行 handler
}
},
mounted() {
this.$nextTick(() => {
this.initData();
});
},
methods: {
initData() {
const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
console.error('图表容器未找到!');
return;
}
if (!this.myChart) {
this.myChart = echarts.init(chartDom);
}
// 解构时给 flag 加默认值,防止 undefined
const {
locations = [],
target = [],
value = [],
proportion = [],
flag = []
} = this.echartData;
console.log('this.echartData', this.echartData);
// 确保 flag 数组长度与 value 一致(补全缺失的 flag 值为 0
const safeFlag = [...flag];
while (safeFlag.length < value.length) {
safeFlag.push(0); // 缺失的 flag 默认为 0达标
}
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
formatter: (params) => {
if (!params.length) return '';
const currentIndex = params[0].dataIndex;
// 使用处理后的 safeFlag避免越界
const currentFlag = safeFlag[currentIndex] || 0;
const statusText = currentFlag === 0 ? '达标' : '不达标';
let html = `${params[0].axisValue}${statusText}<br/>`;
params.forEach(item => {
const unit = item.seriesName === '完成率' ? '%' : '万元';
html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
});
return html;
}
},
grid: {
top: 30,
bottom: 30,
right: 70,
left: 40,
},
xAxis: [
{
type: 'category',
boundaryGap: true,
axisTick: { show: false },
axisLine: {
show: true,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
},
axisLabel: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
interval: 0,
padding: [5, 0, 0, 0]
},
data: locations
}
],
yAxis: [
{
type: 'value',
name: '万元',
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'right'
},
min: 0,
max: (val) => val.max > 0 ? Math.ceil(val.max * 1.1) : 10,
scale: false,
axisTick: { show: false },
axisLabel: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
formatter: '{value}'
},
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4
},
{
type: 'value',
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'left'
},
min: 0,
max: 100,
axisTick: { show: false },
axisLabel: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
formatter: '{value}%'
},
splitLine: { show: false },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4
}
],
series: [
{
name: '完成率',
type: 'line',
yAxisIndex: 1,
lineStyle: {
color: 'rgba(40, 138, 255, .5)',
width: 2
},
itemStyle: {
color: 'rgba(40, 138, 255, 1)',
borderColor: 'rgba(40, 138, 255, 1)',
borderWidth: 2,
radius: 4
},
areaStyle: {
opacity: 0.2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{ offset: 0, color: 'rgba(40, 138, 255, .9)' },
{ offset: 1, color: 'rgba(255, 132, 0, 0)' }
])
},
data: proportion,
symbol: 'circle',
symbolSize: 6
},
{
name: '目标',
type: 'bar',
yAxisIndex: 0,
barWidth: 14,
itemStyle: {
color: 'rgba(40, 137, 255, 1)',
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
data: target
},
{
name: '实际',
type: 'bar',
yAxisIndex: 0,
barWidth: 14,
itemStyle: {
// 使用处理后的 safeFlag 避免 undefined
color: (params) => {
const dataIndex = params.dataIndex;
const currentFlag = safeFlag[dataIndex] || 0; // 双重保险,防止越界
return currentFlag === 0
? 'rgba(118, 218, 190, 1)'
: 'rgba(249, 164, 74, 1)';
},
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
data: value
}
]
};
this.myChart.setOption(option);
// 窗口缩放适配
window.addEventListener('resize', () => {
this.myChart && this.myChart.resize();
});
// 组件销毁清理
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => {
this.myChart && this.myChart.resize();
});
this.myChart && this.myChart.dispose();
});
}
},
};
</script>