Files
yudao-dev/src/views/home/costComponents/costBaseBarChart.vue

199 lines
5.3 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 500px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
components: {},
data() {
return {
myChart: null, // 保存图表实例,方便更新
resizeHandler: null // 窗口resize事件处理器
};
},
props: {
yName: {
type: String,
default: () => '元/㎡'
},
chartData: {
type: Object,
default: () => { }
},
},
watch: {
chartData: {
handler() {
this.updateChart(); // 数据变化时更新图表
},
deep: true,
immediate: true
}
},
mounted() {
this.$nextTick(() => {
this.initChart();
});
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
methods: {
initChart() {
const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
console.error('图表容器未找到!');
return;
}
this.myChart = echarts.init(chartDom);
this.updateChart(); // 初始化图表数据
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
},
updateChart() {
if (!this.myChart || !this.chartData.rawData || !this.chartData.timeArray) {
return; // 图表未初始化或数据不完整时不更新
}
// 从rawData中提取目标和实际数据
const targetData = this.chartData.rawData.map(item => item.target); // 目标数据数组
const actualData = this.chartData.rawData.map(item => item.value); // 实际数据数组
const xAxisData = this.chartData.timeArray; // 横坐标时间数组
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
formatter: (params) => {
let html = `${params[0].axisValue}<br/>`;
params.forEach(item => {
html += `${item.marker} ${item.seriesName}: ${item.value}${this.yName}<br/>`;
});
return html;
}
},
grid: {
top: 30,
bottom: 30,
right: 70,
left: 60,
},
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: xAxisData // 使用timeArray作为横坐标
}
],
yAxis: [
{
type: 'value',
name: this.yName,
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'right'
},
// min: 0,
// max: (value) => value.max > 0 ? Math.ceil(value.max * 1.1) : 100, // 留10%余量
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: 3
}
],
series: [
// 目标数据柱状图
{
name: '预算',
type: 'bar',
yAxisIndex: 0,
barWidth: 24,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(130, 204, 255, 1)' },
{ offset: 1, color: 'rgba(75, 157, 255, 1)' }
]
},
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
data: targetData // 目标数据数组
},
// 实际数据柱状图
{
name: '实际',
type: 'bar',
yAxisIndex: 0,
barWidth: 24,
itemStyle: {
color: {
type: 'linear',
x: 0,
y: 0,
x2: 0,
y2: 1,
colorStops: [
{ offset: 0, color: 'rgba(174, 239, 224, 1)' },
{ offset: 1, color: 'rgba(118, 218, 190, 1)' }
]
},
borderRadius: [4, 4, 0, 0],
borderWidth: 0
},
data: actualData // 实际数据数组
}
]
};
this.myChart.setOption(option);
}
},
};
</script>