Files
yudao-dev/src/views/home/rawSheetYieldComponents/operatingLineBarSale.vue
‘937886381’ 20ef2b9763 修改
2025-12-30 19:36:05 +08:00

208 lines
5.8 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: 400px;"></div>
</template>
<script>
import * as echarts from 'echarts';
export default {
components: {},
data() {
return {
myChart: null, // 存储图表实例
resizeHandler: null, // 存储resize事件处理函数
// 核心:基地名称与序号的映射表(固定顺序)
baseNameToIndexMap: {
'宜兴': 7,
'漳州': 8,
'自贡': 3,
'桐城': 2,
'洛阳': 9,
'合肥': 5,
'宿迁': 6,
'秦皇岛': 10
}
};
},
props: {
chartData: {
type: Object,
default: () => ({}),
}
},
mounted() {
this.$nextTick(() => {
this.initChart(); // 初始化图表(只执行一次)
this.updateChart(); // 更新图表数据
});
},
watch: {
chartData: {
handler() {
console.log(this.chartData, 'chartData');
this.updateChart(); // 仅更新数据,不重新创建实例
},
deep: true,
immediate: true
}
},
beforeDestroy() {
// 组件销毁时清理资源
this.destroyChart();
},
methods: {
// 初始化图表只在mounted中执行一次
initChart() {
const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
console.error('图表容器未找到!');
return;
}
// 只创建一次图表实例
this.myChart = echarts.init(chartDom);
// 绑定点击事件(只绑定一次,永久生效)
this.myChart.on('click', (params) => {
// 提取点击的基地名称
const itemName = params.name;
// 根据映射表获取对应的序号未匹配到则返回0或其他默认值
const baseIndex = this.baseNameToIndexMap[itemName] || 0;
// 兼容不同图表类型的value柱状图value是数值折线图是[横坐标, 纵坐标]
// const itemValue = Array.isArray(params.value) ? params.value[1] : params.value;
// const seriesName = params.seriesName;
console.log(`你点击了【${itemName}】(序号:${baseIndex})`);
// 路由跳转时携带序号(或名称+序号)
this.$router.push({
path: 'rawSheetYieldBase',
query: { // 使用query传递参数推荐也可使用params
// baseName: itemName,
factory: baseIndex
}
// 若仍需用base作为参数
// base: itemName,
// params: { baseIndex: baseIndex }
});
});
// 定义resize处理函数命名函数方便移除
this.resizeHandler = () => {
this.myChart && this.myChart.resize();
};
// 绑定resize事件只绑定一次
window.addEventListener('resize', this.resizeHandler);
},
// 更新图表数据(数据变化时执行)
updateChart() {
if (!this.myChart) {
return; // 实例未初始化则返回
}
const { allPlaceNames, series } = this.chartData || {};
const xData = allPlaceNames || [];
const chartSeries = series || [];
const option = {
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'cross',
label: {
backgroundColor: '#6a7985'
}
}
},
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],
// 可选X轴标签显示“序号+名称”如“1 宜兴”)
// formatter: (value) => {
// const index = this.baseNameToIndexMap[value] || '';
// return index ? `${index} ${value}` : value;
// }
},
data: xData
}
],
yAxis: [
{
type: 'value',
name: '万元',
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'right'
},
scale: true,
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: { show: true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }
},
{
type: 'value',
nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
align: 'left'
},
axisTick: { show: false },
axisLabel: {
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12,
formatter: '{value}%'
},
splitLine: { show: false },
axisLine: { show: true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4
}
],
series: chartSeries
};
// 只更新配置,不重新创建实例
this.myChart.setOption(option, true); // 第二个参数true表示清空原有配置避免数据残留
},
// 销毁图表资源
destroyChart() {
// 移除resize事件
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}
};
</script>