Files
yudao-dev/src/views/home/components/heatBarChart.vue

166 lines
4.1 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: 216px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
components: {},
data() {
return {
myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
};
},
props: {
lineData: {
type: Object,
default: () => ({}),
}
},
mounted() {
this.$nextTick(() => {
this.updateChart();
});
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
// 新增:监听 chartData 变化
watch: {
// 深度监听数据变化,仅更新图表配置(不销毁实例)
lineData: {
handler() {
this.updateChart();
},
deep: true,
immediate: true // 初始化时立即执行
}
},
methods: {
updateChart() {
const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
console.error('图表容器未找到!');
return;
}
if (this.myChart) {
this.myChart.dispose();
}
this.myChart = echarts.init(chartDom);
const entries = Object.entries(this.lineData);
entries.sort((item1, item2) => item2[1] - item1[1]);
const sortedObj = Object.fromEntries(entries);
let xData = Object.keys(sortedObj);
let yData = Object.values(sortedObj);
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
},
},
grid: {
top: 30,
bottom: 30,
right: 20,
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:xData
}
],
yAxis: [
// 左侧Y轴营业收入、成本单位万元
{
type: 'value',
name: 'kcal/kg',
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'right'
},
splitNumber: 4,
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
},
],
series: [
{
name: '实际',
type: 'bar',
yAxisIndex: 0,
barWidth: 40,
label: {
show: true,
position: 'top'
},
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: yData
}
]
};
option && this.myChart.setOption(option);
}
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>