处理监听图表的函数,确保及时移除&生产环境不打印log

This commit is contained in:
2026-04-22 11:07:10 +08:00
parent 845e5a8af3
commit cfcb4f5068
117 changed files with 6781 additions and 5767 deletions

View File

@@ -1,4 +1,5 @@
# 生产环境配置 # 生产环境配置
NODE_ENV = production
ENV = 'production' ENV = 'production'
# 页面标题 # 页面标题

View File

@@ -1,8 +1,16 @@
const plugins = [];
// 生产环境移除 console.log/debug/info保留 error/warn
if (process.env.NODE_ENV === 'production') {
plugins.push(['transform-remove-console', { exclude: ['error', 'warn'] }]);
}
module.exports = { module.exports = {
presets: [ presets: [
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
'@vue/cli-plugin-babel/preset' '@vue/cli-plugin-babel/preset'
], ],
plugins: plugins,
'env': { 'env': {
'development': { 'development': {
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().

View File

@@ -50,6 +50,7 @@
"code-brick-zj": "^1.1.1", "code-brick-zj": "^1.1.1",
"core-js": "^3.26.0", "core-js": "^3.26.0",
"crypto-js": "^4.0.0", "crypto-js": "^4.0.0",
"diagram-js": "^15.12.0",
"echarts": "5.4.0", "echarts": "5.4.0",
"element-ui": "2.15.14", "element-ui": "2.15.14",
"file-saver": "2.0.5", "file-saver": "2.0.5",
@@ -65,6 +66,7 @@
"screenfull": "5.0.2", "screenfull": "5.0.2",
"sortablejs": "1.10.2", "sortablejs": "1.10.2",
"throttle-debounce": "2.1.0", "throttle-debounce": "2.1.0",
"video.js": "^8.23.7",
"vue": "2.7.14", "vue": "2.7.14",
"vue-count-to": "1.0.13", "vue-count-to": "1.0.13",
"vue-cropper": "0.5.8", "vue-cropper": "0.5.8",
@@ -83,6 +85,7 @@
"@vue/compiler-sfc": "^3.0.1", "@vue/compiler-sfc": "^3.0.1",
"@vue/eslint-config-prettier": "^5.0.0", "@vue/eslint-config-prettier": "^5.0.0",
"babel-eslint": "10.1.0", "babel-eslint": "10.1.0",
"babel-plugin-transform-remove-console": "^6.9.4",
"bpmn-js": "8.9.0", "bpmn-js": "8.9.0",
"bpmn-js-properties-panel": "0.46.0", "bpmn-js-properties-panel": "0.46.0",
"chalk": "4.1.0", "chalk": "4.1.0",

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -158,18 +158,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -147,18 +147,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -1,124 +1,131 @@
<template> <template>
<div ref="cockpitEffChip" id="coreLineChart" style="height: 184px; width: 100%;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="height: 184px; width: 100%;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
name: 'Container', name: 'Container',
components: {}, components: {},
// 接收父组件传递的 series 数据 // 接收父组件传递的 series 数据
props: { props: {
chartSeries: { chartSeries: {
type: Object, type: Object,
default: () => {{}} // 默认空数组,避免报错 default: () => {{}} // 默认空数组,避免报错
}, },
xAxisData: { xAxisData: {
type: Array, type: Array,
default: () => [] // 默认空数组,避免报错 default: () => [] // 默认空数组,避免报错
}, },
dateData: { dateData: {
type: Object, type: Object,
default: () => {} // 默认空数组,避免报错 default: () => {} // 默认空数组,避免报错
}, },
}, },
data() { data() {
return { return {
myChart: null // 存储图表实例,方便后续操作 myChart: null, // 存储图表实例,方便后续操作
}; resizeHandler: null // 窗口resize事件处理器
}, };
mounted() { },
this.$nextTick(() => { mounted() {
this.initData(); this.$nextTick(() => {
}); this.initData();
}, });
watch: { // 注册窗口resize事件使用稳定的引用以便后续移除
// 监听 series 数据变化,实时更新图表 this.resizeHandler = () => {
chartSeries: { if (this.myChart) {
handler() { this.myChart.resize();
this.updateChart(); }
}, };
deep: true // 深度监听数组内元素变化 window.addEventListener('resize', this.resizeHandler);
} },
}, watch: {
methods: { // 监听 series 数据变化,实时更新图表
initData() { chartSeries: {
const chartDom = this.$refs.cockpitEffChip; handler() {
if (!chartDom) { this.updateChart();
console.error('图表容器未找到!'); },
return; deep: true // 深度监听数组内元素变化
} }
this.myChart = echarts.init(chartDom); },
this.updateChart(); // 初始化时渲染图表 methods: {
initData() {
// 监听窗口缩放 const chartDom = this.$refs.cockpitEffChip;
window.addEventListener('resize', () => { if (!chartDom) {
this.myChart && this.myChart.resize(); console.error('图表容器未找到!');
}); return;
}
// 组件销毁时清理 this.myChart = echarts.init(chartDom);
this.$once('hook:destroyed', () => { this.updateChart(); // 初始化时渲染图表
window.removeEventListener('resize', () => { },
this.myChart && this.myChart.resize(); // 单独提取更新图表的方法,方便复用
}); updateChart() {
this.myChart && this.myChart.dispose(); if (!this.myChart) return;
});
}, const option = {
// 单独提取更新图表的方法,方便复用 tooltip: {
updateChart() { trigger: 'axis',
if (!this.myChart) return; axisPointer: {
type: 'cross',
const option = { label: { backgroundColor: '#6a7985' }
tooltip: { }
trigger: 'axis', },
axisPointer: { grid: { top: 35, bottom: 3, right: 15, left: 18, containLabel: true},
type: 'cross', xAxis: [
label: { backgroundColor: '#6a7985' } {
} type: 'category',
}, boundaryGap: false,
grid: { top: 35, bottom: 3, right: 15, left: 18, containLabel: true}, axisTick: { show: false },
xAxis: [ axisLine: {
{ show: true,
type: 'category', onZero: false,
boundaryGap: false, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
axisTick: { show: false }, },
axisLine: { axisLabel: {
show: true, color: 'rgba(0, 0, 0, 0.45)',
onZero: false, fontSize: 12,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } interval: 0,
}, // width: 38,
axisLabel: { overflow: 'break',
color: 'rgba(0, 0, 0, 0.45)', formatter: (value) => {
fontSize: 12, const dateParts = value.split('-'); // ["2025", "07", "01"]
interval: 0, if (dateParts.length < 2) return value;
// width: 38,
overflow: 'break', // 去掉月份前面的0然后加上"月"
formatter: (value) => { const month = dateParts[1].replace(/^0+/, '');
const dateParts = value.split('-'); // ["2025", "07", "01"] return `${month}`;
if (dateParts.length < 2) return value; }
},
// 去掉月份前面的0然后加上"月" data: this.xAxisData
const month = dateParts[1].replace(/^0+/, ''); }
return `${month}`; ],
} yAxis: {
}, name: this.chartSeries.unit,
data: this.xAxisData nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'right' },
} axisTick: { show: false },
], axisLabel: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 12 },
yAxis: { splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
name: this.chartSeries.unit, axisLine: { show: true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }
nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'right' }, },
axisTick: { show: false }, series: this.chartSeries.series // 使用父组件传递的 series 数据
axisLabel: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 12 }, };
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: { show: true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } } this.myChart.setOption(option, true); // 第二个参数 true 表示替换现有配置
}, }
series: this.chartSeries.series // 使用父组件传递的 series 数据 },
}; beforeDestroy() {
// 移除窗口resize事件监听器
this.myChart.setOption(option, true); // 第二个参数 true 表示替换现有配置 if (this.resizeHandler) {
} window.removeEventListener('resize', this.resizeHandler);
} this.resizeHandler = null;
}; }
</script> // 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -1,401 +1,412 @@
<template> <template>
<div style="flex: 1"> <div style="flex: 1">
<!-- 传入点击切换的状态到Container组件 --> <!-- 传入点击切换的状态到Container组件 -->
<Container name="财务重点指标" nameTwo="费用重点指标" icon="cockpitItemIcon" size="topBasic" @switchTab="handleTabSwitch" @tabChange='tabChange'> <Container name="财务重点指标" nameTwo="费用重点指标" icon="cockpitItemIcon" size="topBasic" @switchTab="handleTabSwitch" @tabChange='tabChange'>
<div class="bottom-left-content" style="display: flex;gap: 0px;padding: 14px 16px;flex-direction: column;"> <div class="bottom-left-content" style="display: flex;gap: 0px;padding: 14px 16px;flex-direction: column;">
<!-- 根据activeTab状态切换显示采购/存货内容 --> <!-- 根据activeTab状态切换显示采购/存货内容 -->
<template v-if="activeTab === 'purchase'"> <template v-if="activeTab === 'purchase'">
<!-- 财务重点指标应的内容 --> <!-- 财务重点指标应的内容 -->
<coreBottomLeftItem :dateData="dateData" :finance="financeData"></coreBottomLeftItem> <coreBottomLeftItem :dateData="dateData" :finance="financeData"></coreBottomLeftItem>
<div class="bottom" <div class="bottom"
style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);"> style="display: flex; width: 100%;margin-top: 8px;background-color: rgba(249, 252, 255, 1);">
<coreBottomBar :dateData="dateData" :line="finance.line"></coreBottomBar> <coreBottomBar :dateData="dateData" :line="finance.line"></coreBottomBar>
</div> </div>
</template> </template>
<template v-else-if="activeTab === 'inventory'"> <template v-else-if="activeTab === 'inventory'">
<!-- 费用重点指标对应的内容 --> <!-- 费用重点指标对应的内容 -->
<costItem :dateData="dateData" :cost="costData" :currentTap='currentTap'></costItem> <costItem :dateData="dateData" :cost="costData" :currentTap='currentTap'></costItem>
<div class="bottom" <div class="bottom"
style="display: flex; width: 100%;margin-top: 4px;background-color: rgba(249, 252, 255, 1);"> style="display: flex; width: 100%;margin-top: 4px;background-color: rgba(249, 252, 255, 1);">
<CostsBottomBar :line="cost.line" :dateData="dateData"> <CostsBottomBar :line="cost.line" :dateData="dateData">
</CostsBottomBar> </CostsBottomBar>
</div> </div>
</template> </template>
</div> </div>
</Container> </Container>
</div> </div>
</template> </template>
<script> <script>
import Container from './financeCostsContainer.vue' import Container from './financeCostsContainer.vue'
import * as echarts from 'echarts' import * as echarts from 'echarts'
import coreBottomLeftItem from './purchase-Item.vue' import coreBottomLeftItem from './purchase-Item.vue'
import coreBottomBar from './financeCostsBottomBar.vue' import coreBottomBar from './financeCostsBottomBar.vue'
import costItem from './cost-Item.vue' import costItem from './cost-Item.vue'
import CostsBottomBar from './CostsBottomBar.vue' import CostsBottomBar from './CostsBottomBar.vue'
export default { export default {
name: 'ProductionStatus', name: 'ProductionStatus',
components: { Container, coreBottomLeftItem, coreBottomBar, costItem, CostsBottomBar }, components: { Container, coreBottomLeftItem, coreBottomBar, costItem, CostsBottomBar },
props: { props: {
finance: { finance: {
type: Object, type: Object,
default: () => {} default: () => {}
}, },
cost: { cost: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
}, },
dateData: { dateData: {
type: Object, type: Object,
default: () => ({}) default: () => ({})
} }
}, },
data() { data() {
return { return {
activeTab: 'purchase', // 激活的标签purchase=采购inventory=存货 activeTab: 'purchase', // 激活的标签purchase=采购inventory=存货
showChart: true, // 控制图表是否显示 showChart: true, // 控制图表是否显示
chart: null, // 图表实例 chart: null, // 图表实例
financeData:{}, financeData:{},
costData:{}, costData:{},
currentTap: 'month' currentTap: 'month',
} resizeHandler: null // 窗口resize事件处理器
}, }
watch: { },
// 切换标签时更新图表 watch: {
activeTab(newVal) { // 切换标签时更新图表
this.$nextTick(() => this.updateChart()) activeTab(newVal) {
}, this.$nextTick(() => this.updateChart())
productionOverviewVo: { },
handler() { productionOverviewVo: {
this.updateChart() handler() {
}, this.updateChart()
deep: true },
}, deep: true
finance: { },
handler() { finance: {
if(this.currentTap === 'month') { handler() {
this.financeData = this.finance.mon if(this.currentTap === 'month') {
}else{ this.financeData = this.finance.mon
this.financeData = this.finance.total }else{
} this.financeData = this.finance.total
}, }
deep: true },
}, deep: true
cost: { },
handler() { cost: {
if(this.currentTap === 'month') { handler() {
this.costData = this.cost.mon if(this.currentTap === 'month') {
}else{ this.costData = this.cost.mon
this.costData = this.cost.total }else{
} this.costData = this.cost.total
}, }
deep: true },
} deep: true
}
},
mounted() { },
// 初始化图表 mounted() {
this.$nextTick(() => this.updateChart()) // 初始化图表
}, this.$nextTick(() => this.updateChart())
beforeDestroy() { // 注册窗口resize事件使用稳定的引用以便后续移除
// 销毁图表,避免内存泄漏 this.resizeHandler = () => {
if (this.chart) { if (this.chart) {
this.chart.dispose() this.chart.resize()
this.chart = null }
} }
}, window.addEventListener('resize', this.resizeHandler)
methods: { },
tabChange(val) { beforeDestroy() {
if(val === 'month') { // 移除窗口resize事件监听器
this.currentTap = 'month' if (this.resizeHandler) {
this.financeData = this.finance.mon window.removeEventListener('resize', this.resizeHandler)
this.costData = this.cost.mon this.resizeHandler = null
}else{ }
this.currentTap = 'total' // 销毁图表,避免内存泄漏
this.financeData = this.finance.total if (this.chart) {
this.costData = this.cost.total this.chart.dispose()
} this.chart = null
}, }
// 处理标题点击切换标签 },
handleTabSwitch(tabType) { methods: {
this.activeTab = tabType // tabType由Container组件传递'purchase'或'inventory' tabChange(val) {
this.showChart = true // 切换时默认显示图表(可根据需求调整) if(val === 'month') {
}, this.currentTap = 'month'
// 更新图表内容 this.financeData = this.finance.mon
updateChart() { this.costData = this.cost.mon
const chartDom = document.getElementById('productionStatusChart') }else{
if (!chartDom) return this.currentTap = 'total'
this.financeData = this.finance.total
// 销毁已有图表实例 this.costData = this.cost.total
if (this.chart) this.chart.dispose() }
this.chart = echarts.init(chartDom) },
// 处理标题点击切换标签
// 根据当前激活的标签,设置对应图表数据(示例:可根据实际需求修改) handleTabSwitch(tabType) {
const data = this.activeTab === 'purchase' this.activeTab = tabType // tabType由Container组件传递'purchase'或'inventory'
? [ this.showChart = true // 切换时默认显示图表(可根据需求调整)
this.productionOverviewVo.purchaseInput || 0, },
this.productionOverviewVo.purchaseOutput || 0, // 更新图表内容
this.productionOverviewVo.purchaseNg || 0, updateChart() {
0, 0, 0, 0 // 补充默认值,避免图表报错 const chartDom = document.getElementById('productionStatusChart')
] if (!chartDom) return
: [
this.productionOverviewVo.inventoryInput || 0, // 销毁已有图表实例
this.productionOverviewVo.inventoryOutput || 0, if (this.chart) this.chart.dispose()
this.productionOverviewVo.inventoryNg || 0, this.chart = echarts.init(chartDom)
0, 0, 0, 0
] // 根据当前激活的标签,设置对应图表数据(示例:可根据实际需求修改)
const data = this.activeTab === 'purchase'
const option = { ? [
type: 'bar', this.productionOverviewVo.purchaseInput || 0,
grid: { left: 51, right: 40, top: 50, bottom: 45 }, this.productionOverviewVo.purchaseOutput || 0,
tooltip: { this.productionOverviewVo.purchaseNg || 0,
trigger: 'axis', 0, 0, 0, 0 // 补充默认值,避免图表报错
axisPointer: { type: 'shadow' }, ]
className: 'production-status-chart-tooltip' : [
}, this.productionOverviewVo.inventoryInput || 0,
xAxis: { this.productionOverviewVo.inventoryOutput || 0,
type: 'category', this.productionOverviewVo.inventoryNg || 0,
offset: 8, 0, 0, 0, 0
data: this.activeTab === 'purchase' ]
? ['采购投入', '采购产出', '采购待判', '低价值', '报废', '在制', '实验片']
: ['存货投入', '存货产出', '存货待判', '低价值', '报废', '在制', '实验片'], const option = {
axisTick: { show: false }, type: 'bar',
axisLine: { show: true, onZero: false, lineStyle: { color: '#00E8FF' } }, grid: { left: 51, right: 40, top: 50, bottom: 45 },
axisLabel: { tooltip: {
color: 'rgba(255,255,255,0.7)', trigger: 'axis',
fontSize: 12, axisPointer: { type: 'shadow' },
interval: 0, className: 'production-status-chart-tooltip'
width: 38, },
overflow: 'break' xAxis: {
} type: 'category',
}, offset: 8,
yAxis: { data: this.activeTab === 'purchase'
type: 'value', ? ['采购投入', '采购产出', '采购待判', '低价值', '报废', '在制', '实验片']
name: '单位/片', : ['存货投入', '存货产出', '存货待判', '低价值', '报废', '在制', '实验片'],
nameTextStyle: { color: 'rgba(255,255,255,0.7)', fontSize: 14, align: 'left' }, axisTick: { show: false },
min: 0, axisLine: { show: true, onZero: false, lineStyle: { color: '#00E8FF' } },
max: (value) => Math.ceil(value.max), axisLabel: {
color: 'rgba(255,255,255,0.7)',
axisTick: { show: false }, fontSize: 12,
axisLabel: { color: 'rgba(255,255,255,0.7)', fontSize: 12 }, interval: 0,
splitLine: { lineStyle: { color: 'RGBA(24, 88, 100, 0.6)', type: 'dashed' } }, width: 38,
axisLine: { show: true, lineStyle: { color: '#00E8FF' } } overflow: 'break'
}, }
series: [ },
{ yAxis: {
type: 'pictorialBar', type: 'value',
label: { show: true, position: 'top', distance: -3, color: '#89CDFF', fontSize: 11 }, name: '单位/片',
symbolSize: [20, 8], nameTextStyle: { color: 'rgba(255,255,255,0.7)', fontSize: 14, align: 'left' },
symbolOffset: [0, 5], min: 0,
z: 20, max: (value) => Math.ceil(value.max),
itemStyle: {
borderColor: '#3588C7', axisTick: { show: false },
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ axisLabel: { color: 'rgba(255,255,255,0.7)', fontSize: 12 },
{ offset: 0, color: 'RGBA(22, 89, 98, 1)' }, splitLine: { lineStyle: { color: 'RGBA(24, 88, 100, 0.6)', type: 'dashed' } },
{ offset: 1, color: '#3588C7' } axisLine: { show: true, lineStyle: { color: '#00E8FF' } }
]) },
}, series: [
data: data {
}, type: 'pictorialBar',
{ label: { show: true, position: 'top', distance: -3, color: '#89CDFF', fontSize: 11 },
type: 'bar', symbolSize: [20, 8],
barWidth: 20, symbolOffset: [0, 5],
itemStyle: { z: 20,
borderWidth: 1, itemStyle: {
borderColor: '#3588C7', borderColor: '#3588C7',
opacity: 0.8, color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
color: { { offset: 0, color: 'RGBA(22, 89, 98, 1)' },
x: 0, y: 0, x2: 0, y2: 1, { offset: 1, color: '#3588C7' }
type: 'linear', ])
global: false, },
colorStops: [ data: data
{ offset: 0, color: 'rgba(73,178,255,0)' }, },
{ offset: 0.5, color: 'rgba(0, 232, 255, .5)' }, {
{ offset: 1, color: 'rgba(0, 232, 255, 1)' } type: 'bar',
] barWidth: 20,
} itemStyle: {
}, borderWidth: 1,
tooltip: { show: false }, borderColor: '#3588C7',
data: data opacity: 0.8,
}, color: {
{ x: 0, y: 0, x2: 0, y2: 1,
type: 'pictorialBar', type: 'linear',
symbolSize: [20, 8], global: false,
symbolOffset: [0, -4], colorStops: [
z: 12, { offset: 0, color: 'rgba(73,178,255,0)' },
symbolPosition: 'end', { offset: 0.5, color: 'rgba(0, 232, 255, .5)' },
itemStyle: { { offset: 1, color: 'rgba(0, 232, 255, 1)' }
borderColor: 'rgba(0, 232, 255, 1)', ]
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ }
{ offset: 0, color: 'RGBA(22, 89, 98, 1)' }, },
{ offset: 1, color: '#3588C7' } tooltip: { show: false },
]) data: data
}, },
tooltip: { show: false }, {
data: data type: 'pictorialBar',
} symbolSize: [20, 8],
] symbolOffset: [0, -4],
} z: 12,
symbolPosition: 'end',
this.chart.setOption(option) itemStyle: {
// 监听窗口 resize自适应图表 borderColor: 'rgba(0, 232, 255, 1)',
window.addEventListener('resize', this.chart.resize) color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
} { offset: 0, color: 'RGBA(22, 89, 98, 1)' },
} { offset: 1, color: '#3588C7' }
} ])
</script> },
tooltip: { show: false },
<style lang='scss' scoped> data: data
/* 原有样式保留,新增内容容器样式 */ }
.bottom-left-content { ]
width: 100%; }
height: 100%;
overflow: hidden; this.chart.setOption(option)
} }
}
/* 其他原有样式... */ }
.scroll-container { </script>
max-height: 210px;
overflow-y: auto; <style lang='scss' scoped>
overflow-x: hidden; /* 原有样式保留,新增内容容器样式 */
padding: 10px 0; .bottom-left-content {
width: 100%;
&::-webkit-scrollbar { height: 100%;
display: none; overflow: hidden;
} }
scrollbar-width: none; /* 其他原有样式... */
-ms-overflow-style: none; .scroll-container {
} max-height: 210px;
overflow-y: auto;
.proBarInfo { overflow-x: hidden;
display: flex; padding: 10px 0;
flex-direction: column;
padding: 8px 27px; &::-webkit-scrollbar {
margin-bottom: 10px; display: none;
} }
.proBarInfoEqInfo { scrollbar-width: none;
display: flex; -ms-overflow-style: none;
justify-content: space-between; }
align-items: center;
} .proBarInfo {
display: flex;
.slot { flex-direction: column;
width: 21px; padding: 8px 27px;
height: 23px; margin-bottom: 10px;
background: rgba(0, 106, 205, 0.22); }
backdrop-filter: blur(1.5px);
font-family: PingFangSC, PingFang SC; .proBarInfoEqInfo {
font-weight: 400; display: flex;
font-size: 16px; justify-content: space-between;
color: #68B5FF; align-items: center;
line-height: 23px; }
text-align: center;
font-style: normal; .slot {
} width: 21px;
height: 23px;
.eq-name { background: rgba(0, 106, 205, 0.22);
margin-left: 8px; backdrop-filter: blur(1.5px);
font-family: PingFangSC, PingFang SC; font-family: PingFangSC, PingFang SC;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 16px;
color: #FFFFFF; color: #68B5FF;
line-height: 18px; line-height: 23px;
letter-spacing: 1px; text-align: center;
text-align: left; font-style: normal;
font-style: normal; }
}
.eq-name {
.eqStatus { margin-left: 8px;
font-family: PingFangSC, PingFang SC; font-family: PingFangSC, PingFang SC;
font-weight: 400; font-weight: 400;
font-size: 16px; font-size: 16px;
color: #FFFFFF; color: #FFFFFF;
line-height: 18px; line-height: 18px;
text-align: right; letter-spacing: 1px;
font-style: normal; text-align: left;
} font-style: normal;
}
.splitLine {
width: 1px; .eqStatus {
height: 14px; font-family: PingFangSC, PingFang SC;
border: 1px solid #ADADAD; font-weight: 400;
margin: 0 8px; font-size: 16px;
} color: #FFFFFF;
line-height: 18px;
.yield { text-align: right;
height: 18px; font-style: normal;
font-family: PingFangSC, PingFang SC; }
font-weight: 400;
font-size: 16px; .splitLine {
color: #00FFFF; width: 1px;
line-height: 18px; height: 14px;
text-align: right; border: 1px solid #ADADAD;
font-style: normal; margin: 0 8px;
} }
.proBarInfoEqInfoLeft { .yield {
display: flex; height: 18px;
align-items: center; font-family: PingFangSC, PingFang SC;
} font-weight: 400;
font-size: 16px;
.proBarInfoEqInfoRight { color: #00FFFF;
display: flex; line-height: 18px;
align-items: center; text-align: right;
} font-style: normal;
}
.proBarWrapper {
position: relative; .proBarInfoEqInfoLeft {
height: 10px; display: flex;
margin-top: 6px; align-items: center;
border-radius: 5px; }
overflow: hidden;
} .proBarInfoEqInfoRight {
display: flex;
.proBarLine { align-items: center;
width: 100%; }
height: 100%;
background: linear-gradient(65deg, rgba(82, 82, 82, 0) 0%, #ACACAC 100%); .proBarWrapper {
opacity: 0.2; position: relative;
} height: 10px;
margin-top: 6px;
.proBarLineTop { border-radius: 5px;
position: absolute; overflow: hidden;
top: 0; }
left: 0;
height: 100%; .proBarLine {
background: linear-gradient(65deg, rgba(53, 223, 247, 0) 0%, rgba(54, 220, 246, 0.92) 92%, #36F6E5 100%, #37ACF5 100%); width: 100%;
border-radius: 5px; height: 100%;
transition: width 0.3s ease; background: linear-gradient(65deg, rgba(82, 82, 82, 0) 0%, #ACACAC 100%);
} opacity: 0.2;
}
.chartImgBottom {
position: absolute; .proBarLineTop {
bottom: 45px; position: absolute;
left: 58px; top: 0;
} left: 0;
height: 100%;
.line { background: linear-gradient(65deg, rgba(53, 223, 247, 0) 0%, rgba(54, 220, 246, 0.92) 92%, #36F6E5 100%, #37ACF5 100%);
display: inline-block; border-radius: 5px;
position: absolute; transition: width 0.3s ease;
left: 57px; }
bottom: 42px;
width: 1px; .chartImgBottom {
height: 20px; position: absolute;
background-color: #00E8FF; bottom: 45px;
} left: 58px;
</style> }
<style> .line {
.production-status-chart-tooltip { display: inline-block;
background: #0a2b4f77 !important; position: absolute;
border: none !important; left: 57px;
backdrop-filter: blur(12px); bottom: 42px;
} width: 1px;
height: 20px;
.production-status-chart-tooltip * { background-color: #00E8FF;
color: #fff !important; }
} </style>
</style>
<style>
.production-status-chart-tooltip {
background: #0a2b4f77 !important;
border: none !important;
backdrop-filter: blur(12px);
}
.production-status-chart-tooltip * {
color: #fff !important;
}
</style>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -21,6 +22,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -139,19 +147,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -1,176 +1,184 @@
<template> <template>
<div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChipBottom; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChipBottom;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
formatter: (params) => { tooltip: {
let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
params.forEach(item => { axisPointer: {
const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
); backgroundColor: '#6a7985'
html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
}); },
return html; formatter: (params) => {
} let html = `${params[0].axisValue}<br/>`;
}, params.forEach(item => {
grid: { const unit = item.seriesName === '完成率' ? '%' : (
top: 30, ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, );
right: 20, html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, });
}, return html;
xAxis: [ }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
splitNumber: 4, },
name: '万元', data: xData
nameTextStyle: { }
color: 'rgba(0, 0, 0, 0.45)', ],
fontSize: 12, yAxis: [
align: 'right' // 左侧Y轴营业收入、成本单位万元
}, {
// min: 0, type: 'value',
// max: (value) => Math.ceil((value.max || 0) * 1.1), splitNumber: 4,
name: '万元',
axisTick: { show: false }, nameTextStyle: {
axisLabel: { color: 'rgba(0, 0, 0, 0.45)',
color: 'rgba(0, 0, 0, 0.45)', fontSize: 12,
fontSize: 12, align: 'right'
formatter: '{value}' },
}, // min: 0,
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: (value) => Math.ceil((value.max || 0) * 1.1),
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
{ fontSize: 12,
type: 'value', formatter: '{value}'
nameTextStyle: { },
color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
align: 'left' splitNumber: 4
}, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, {
scale:true, type: 'value',
splitNumber: 4, nameTextStyle: {
axisTick: { show: false }, color: 'rgba(0, 0, 0, 0.45)',
axisLabel: { fontSize: 12,
color: 'rgba(0, 0, 0, 0.45)', align: 'left'
fontSize: 12, },
formatter: '{value}%' // min: 0,
}, // max: 100,
splitLine: { show: false }, scale:true,
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
} axisLabel: {
], color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series fontSize: 12,
}; formatter: '{value}%'
},
option && this.myChart.setOption(option); splitLine: { show: false },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 splitNumber: 4
window.addEventListener('resize', () => { }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -1,172 +1,180 @@
<template> <template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChip; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
// formatter: (params) => { tooltip: {
// let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
// params.forEach(item => { axisPointer: {
// const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
// ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
// ); backgroundColor: '#6a7985'
// html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
// }); },
// return html; // formatter: (params) => {
// } // let html = `${params[0].axisValue}<br/>`;
}, // params.forEach(item => {
grid: { // const unit = item.seriesName === '完成率' ? '%' : (
top: 30, // ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, // );
right: 20, // html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, // });
}, // return html;
xAxis: [ // }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
name: '万元', },
nameTextStyle: { data: xData
color: 'rgba(0, 0, 0, 0.45)', }
fontSize: 12, ],
align: 'right' yAxis: [
}, // 左侧Y轴营业收入、成本单位万元
{
splitNumber: 4, type: 'value',
axisTick: { show: false }, name: '万元',
axisLabel: { nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)', color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12, fontSize: 12,
formatter: '{value}' align: 'right'
}, },
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
// { fontSize: 12,
// type: 'value', formatter: '{value}'
// nameTextStyle: { },
// color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// align: 'left' splitNumber: 4
// }, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, // {
// axisTick: { show: false }, // type: 'value',
// axisLabel: { // nameTextStyle: {
// color: 'rgba(0, 0, 0, 0.45)', // color: 'rgba(0, 0, 0, 0.45)',
// fontSize: 12, // fontSize: 12,
// formatter: '{value}%' // align: 'left'
// }, // },
// splitLine: { show: false }, // min: 0,
// axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: 100,
// splitNumber: 4 // axisTick: { show: false },
// } // axisLabel: {
], // color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series // fontSize: 12,
}; // formatter: '{value}%'
// },
option && this.myChart.setOption(option); // splitLine: { show: false },
// axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 // splitNumber: 4
window.addEventListener('resize', () => { // }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -152,19 +160,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -24,7 +24,10 @@ export default {
}, },
}, },
data() { data() {
return {}; return {
myChart: null,
resizeHandler: null
};
}, },
computed: {}, computed: {},
watch: { watch: {
@@ -41,6 +44,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initChart(); // 只负责初始化图表实例 this.initChart(); // 只负责初始化图表实例
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
methods: { methods: {
initData() { initData() {
@@ -266,21 +276,20 @@ export default {
] ]
}; };
option && myChart.setOption(option); option && this.myChart.setOption(option);
// 窗口缩放监听
window.addEventListener('resize', () => {
myChart.resize();
});
// 组件销毁清理
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => {
myChart.resize();
});
myChart.dispose();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -1,286 +1,294 @@
<template> <template>
<div style="position: relative;"> <div style="position: relative;">
<div class="legend"> <div class="legend">
<span class="legend-item-line"> <span class="legend-item-line">
<span class="line target"></span> <span class="line target"></span>
预算 预算
</span> </span>
<span class="legend-item-line"> <span class="legend-item-line">
<span class="line real"></span> <span class="line real"></span>
实际 实际
</span> </span>
</div> </div>
<div ref="cockpitEffChip" id="coreLineChart" style="height: 219px; width: 100%;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="height: 219px; width: 100%;"></div>
</div> </div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
name: 'Container', name: 'Container',
props: ["chartData",'dateData','unit'], props: ["chartData",'dateData','unit'],
components: {}, components: {},
data() { data() {
return { return {
myChart: null, // 存储 echarts 实例 myChart: null, // 存储 echarts 实例
}; resizeHandler: null // 窗口resize事件处理器
}, };
// 关键:监听 chartData 变化 },
watch: { // 关键:监听 chartData 变化
chartData: { watch: {
handler(newData) { chartData: {
this.updateChart(newData); handler(newData) {
}, this.updateChart(newData);
immediate: true, // 组件初始化时立即执行一次 },
deep: true, // 深度监听对象内部变化 immediate: true, // 组件初始化时立即执行一次
} deep: true, // 深度监听对象内部变化
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.initChart(); this.$nextTick(() => {
}); this.initChart();
}, });
methods: { // 注册窗口resize事件使用稳定的引用以便后续移除
// 初始化图表实例 this.resizeHandler = () => {
initChart() { if (this.myChart) {
const chartDom = this.$refs.cockpitEffChip; this.myChart.resize();
if (!chartDom) { }
console.error('图表容器未找到!'); };
return; window.addEventListener('resize', this.resizeHandler);
} },
this.myChart = echarts.init(chartDom); methods: {
// 初始化图表实例
// 初始化时调用一次更新 initChart() {
this.updateChart(this.chartData); const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
// 监听窗口缩放 console.error('图表容器未找到!');
window.addEventListener('resize', () => { return;
this.myChart?.resize(); }
}); this.myChart = echarts.init(chartDom);
},
// 初始化时调用一次更新
// 核心:根据数据更新图表 this.updateChart(this.chartData);
updateChart(data) { },
if (!this.myChart) {
// 如果实例还未初始化,则等待 initChart 完成后再更新 // 核心:根据数据更新图表
setTimeout(() => this.updateChart(data), 0); updateChart(data) {
return; if (!this.myChart) {
} // 如果实例还未初始化,则等待 initChart 完成后再更新
setTimeout(() => this.updateChart(data), 0);
// 1. 处理数据,如果 data 无效则清空图表 return;
if (!data || typeof data !== 'object' || (!data.real && !data.target)) { }
this.myChart.setOption({
xAxis: { data: [] }, // 1. 处理数据,如果 data 无效则清空图表
series: [{ data: [] }, { data: [] }] if (!data || typeof data !== 'object' || (!data.real && !data.target)) {
}); this.myChart.setOption({
return; xAxis: { data: [] },
} series: [{ data: [] }, { data: [] }]
});
// 2. 提取 X 轴数据(从 real 或 target 中取键名) return;
const xAxisData = data.real ? Object.keys(data.real) : Object.keys(data.target); }
console.log('xAxisData', xAxisData);
// 2. 提取 X 轴数据(从 real 或 target 中取键名)
// 3. 提取 "实际" 和 "目标" 系列的数据 const xAxisData = data.real ? Object.keys(data.real) : Object.keys(data.target);
const realData = data.real ? Object.values(data.real) : []; console.log('xAxisData', xAxisData);
const targetData = data.target ? Object.values(data.target) : [];
// 3. 提取 "实际" 和 "目标" 系列的数据
// 4. 准备 echarts 的 option 配置 const realData = data.real ? Object.values(data.real) : [];
const option = { const targetData = data.target ? Object.values(data.target) : [];
tooltip: {
trigger: 'axis', // 4. 准备 echarts 的 option 配置
axisPointer: { const option = {
type: 'cross', tooltip: {
label: { trigger: 'axis',
backgroundColor: '#6a7985' axisPointer: {
} type: 'cross',
} label: {
}, backgroundColor: '#6a7985'
grid: { }
top: 35, }
bottom: 20, },
right: 13, grid: {
}, top: 35,
xAxis: [ bottom: 20,
{ right: 13,
type: 'category', },
boundaryGap: false, xAxis: [
axisTick: { show: false }, {
axisLine: { type: 'category',
show: true, boundaryGap: false,
onZero: false, axisTick: { show: false },
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } axisLine: {
}, show: true,
axisLabel: { onZero: false,
color: 'rgba(0, 0, 0, 0.45)', lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
fontSize: 12, },
interval: 0, axisLabel: {
// width: 38, color: 'rgba(0, 0, 0, 0.45)',
overflow: 'break', fontSize: 12,
formatter: (value) => { interval: 0,
const dateParts = value.split('-'); // ["2025", "07", "01"] // width: 38,
if (dateParts.length < 2) return value; overflow: 'break',
formatter: (value) => {
// 去掉月份前面的0然后加上"月" const dateParts = value.split('-'); // ["2025", "07", "01"]
const month = dateParts[1].replace(/^0+/, ''); if (dateParts.length < 2) return value;
return `${month}`;
} // 去掉月份前面的0然后加上"月"
}, const month = dateParts[1].replace(/^0+/, '');
data: xAxisData return `${month}`;
} }
], },
yAxis: { data: xAxisData
type: 'value', }
name: this.unit, ],
// nameLocation:'center', yAxis: {
nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'right' }, type: 'value',
min: 0, name: this.unit,
// max: function (value) { return Math.ceil(value.max * 1.1); }, // 增加一点余量 // nameLocation:'center',
nameTextStyle: { color: 'rgba(0, 0, 0, 0.45)', fontSize: 14, align: 'right' },
axisTick: { show: false }, min: 0,
axisLabel: { // max: function (value) { return Math.ceil(value.max * 1.1); }, // 增加一点余量
color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12 axisTick: { show: false },
}, axisLabel: {
splitLine: { color: 'rgba(0, 0, 0, 0.45)',
lineStyle: { fontSize: 12
color: 'rgba(0, 0, 0, 0.15)', },
} splitLine: {
}, lineStyle: {
axisLine: { color: 'rgba(0, 0, 0, 0.15)',
show: true, }
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
} axisLine: {
}, show: true,
series: [ lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
{ }
name: '实际', },
type: 'line', series: [
// stack: 'Total', // 趋势图通常不需要堆叠 {
symbol: 'circle', name: '实际',
symbolSize: 8, type: 'line',
lineStyle: { // stack: 'Total', // 趋势图通常不需要堆叠
color: 'rgba(255, 132, 0, 1)', // 加深颜色 symbol: 'circle',
width: 2, symbolSize: 8,
}, lineStyle: {
itemStyle: { color: 'rgba(255, 132, 0, 1)', // 加深颜色
color: 'rgba(255, 132, 0, 1)', width: 2,
borderColor: '#fff', },
borderWidth: 2, itemStyle: {
}, color: 'rgba(255, 132, 0, 1)',
areaStyle: { borderColor: '#fff',
opacity: 0.3, borderWidth: 2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ },
{ offset: 0, color: 'rgba(255, 132, 0, .5)' }, areaStyle: {
{ offset: 1, color: 'rgba(255, 132, 0, 0)' }, opacity: 0.3,
]), color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
}, { offset: 0, color: 'rgba(255, 132, 0, .5)' },
data: realData // 使用提取出的 "实际" 数据 { offset: 1, color: 'rgba(255, 132, 0, 0)' },
}, ]),
{ },
name: '预算', data: realData // 使用提取出的 "实际" 数据
type: 'line', },
// stack: 'Total', {
symbol: 'circle', name: '预算',
symbolSize: 8, type: 'line',
lineStyle: { // stack: 'Total',
color: 'rgba(98, 213, 180, 1)', // 加深颜色 symbol: 'circle',
width: 2, symbolSize: 8,
// type: 'dashed' // 目标线使用虚线 lineStyle: {
}, color: 'rgba(98, 213, 180, 1)', // 加深颜色
itemStyle: { width: 2,
color: 'rgba(98, 213, 180, 1)', // type: 'dashed' // 目标线使用虚线
borderColor: '#fff', },
borderWidth: 2, itemStyle: {
}, color: 'rgba(98, 213, 180, 1)',
areaStyle: { borderColor: '#fff',
opacity: 0.3, borderWidth: 2,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ },
{ offset: 0, color: 'rgba(98, 213, 180, .5)' }, areaStyle: {
{ offset: 1, color: 'rgba(98, 213, 180, 0)' }, opacity: 0.3,
]), color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
}, { offset: 0, color: 'rgba(98, 213, 180, .5)' },
data: targetData // 使用提取出的 "目标" 数据 { offset: 1, color: 'rgba(98, 213, 180, 0)' },
}, ]),
] },
}; data: targetData // 使用提取出的 "目标" 数据
},
// 5. 应用配置项更新图表 ]
this.myChart.setOption(option, true); };
}
}, // 5. 应用配置项更新图表
beforeDestroy() { this.myChart.setOption(option, true);
// 组件销毁时清理 }
window.removeEventListener('resize', () => { },
this.myChart?.resize(); beforeDestroy() {
}); // 移除窗口resize事件监听器
this.myChart?.dispose(); if (this.resizeHandler) {
} window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
<style lang="scss" scoped> // 销毁图表,避免内存泄漏
/* (你的样式代码保持不变) */ if (this.myChart) {
.legend { this.myChart.dispose();
position: absolute; this.myChart = null;
right: 12px; }
top: 0px; }
display: flex; };
/* 使用 flex 布局让两个图例项并排且对齐 */ </script>
gap: 5px; <style lang="scss" scoped>
} /* (你的样式代码保持不变) */
.legend {
.legend-item-line { position: absolute;
font-family: PingFangSC, PingFang SC; right: 12px;
font-weight: 400; top: 0px;
font-size: 14px; display: flex;
color: rgba(0, 0, 0, 0.8); /* 使用 flex 布局让两个图例项并排且对齐 */
text-align: left; gap: 5px;
font-style: normal; }
position: relative;
padding-left: 24px; .legend-item-line {
/* 为圆点和线条留出空间 */ font-family: PingFangSC, PingFang SC;
display: flex; font-weight: 400;
align-items: center; font-size: 14px;
color: rgba(0, 0, 0, 0.8);
.line { text-align: left;
position: absolute; font-style: normal;
left: 6px; position: relative;
/* 线条从圆点右侧开始 */ padding-left: 24px;
top: 50%; /* 为圆点和线条留出空间 */
transform: translateY(-50%); display: flex;
display: inline-block; align-items: center;
width: 16px;
/* 线条长度 */ .line {
height: 2px; position: absolute;
margin-right: 4px; left: 6px;
} /* 线条从圆点右侧开始 */
top: 50%;
.target { transform: translateY(-50%);
background: rgba(98, 213, 180, 1); display: inline-block;
} width: 16px;
/* 线条长度 */
.real { height: 2px;
background: rgba(255, 132, 0, 1); margin-right: 4px;
} }
&::before { .target {
content: ""; background: rgba(98, 213, 180, 1);
display: inline-block; }
width: 6px;
height: 6px; .real {
border-radius: 50%; background: rgba(255, 132, 0, 1);
margin-right: 8px; }
background-color: rgba(255, 132, 0, 1);
position: absolute; &::before {
left: 10px; content: "";
top: 50%; display: inline-block;
transform: translateY(-50%); width: 6px;
} height: 6px;
} border-radius: 50%;
margin-right: 8px;
.legend-item-line:nth-child(1) { background-color: rgba(255, 132, 0, 1);
&::before { position: absolute;
background-color: rgba(98, 213, 180, 1); left: 10px;
} top: 50%;
} transform: translateY(-50%);
</style> }
}
.legend-item-line:nth-child(1) {
&::before {
background-color: rgba(98, 213, 180, 1);
}
}
</style>

View File

@@ -9,7 +9,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 保存图表实例,方便更新 myChart: null, // 保存图表实例,方便更新
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -35,6 +36,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initChart(); this.initChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
methods: { methods: {
initChart() { initChart() {
@@ -45,19 +53,18 @@ export default {
} }
this.myChart = echarts.init(chartDom); this.myChart = echarts.init(chartDom);
this.updateChart(); // 初始化图表数据 this.updateChart(); // 初始化图表数据
},
// 窗口缩放适配 beforeDestroy() {
window.addEventListener('resize', () => { // 移除窗口resize事件监听器
this.myChart && this.myChart.resize(); if (this.resizeHandler) {
}); window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
// 组件销毁清理 }
this.$once('hook:destroyed', () => { // 销毁图表,避免内存泄漏
window.removeEventListener('resize', () => { if (this.myChart) {
this.myChart && this.myChart.resize(); this.myChart.dispose();
}); this.myChart = null;
this.myChart && this.myChart.dispose(); }
});
}, },
updateChart() { updateChart() {

View File

@@ -22,7 +22,8 @@ export default {
}, },
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
watch: { watch: {
@@ -38,6 +39,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.initData(); this.initData();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
methods: { methods: {
initData() { initData() {
@@ -259,19 +279,6 @@ export default {
}; };
this.myChart.setOption(option); 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();
});
} }
}, },
}; };

View File

@@ -1,169 +1,182 @@
<template> <template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 500px;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 500px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return {}; return {
}, myChart: null,
props: { resizeHandler: null // 窗口resize事件处理器
seriesData: { };
type: Array, },
default: () => [] props: {
}, seriesData: {
xData: { type: Array,
type: Array, default: () => []
default: () => [] },
}, xData: {
name: { type: Array,
type: String, default: () => []
default: () => { } },
}, name: {
}, type: String,
watch: { default: () => { }
// 监听 xData 变化,触发图表更新 },
xData: { },
handler() { watch: {
this.$nextTick(() => this.initData()); // 监听 xData 变化,触发图表更新
}, xData: {
deep: true // 深度监听数组内元素变化 handler() {
}, this.$nextTick(() => this.initData());
// 监听 seriesData 变化,触发图表更新 },
seriesData: { deep: true // 深度监听数组内元素变化
handler() { },
this.$nextTick(() => this.initData()); // 监听 seriesData 变化,触发图表更新
}, seriesData: {
deep: true // 深度监听数组内元素变化 handler() {
} this.$nextTick(() => this.initData());
}, },
mounted() { deep: true // 深度监听数组内元素变化
this.$nextTick(() => { }
this.initData(); },
}); mounted() {
}, this.$nextTick(() => {
methods: { this.initData();
initData() { });
const chartDom = this.$refs.cockpitEffChip; // 注册窗口resize事件使用稳定的引用以便后续移除
if (!chartDom) { this.resizeHandler = () => {
console.error('图表容器未找到!'); if (this.myChart) {
return; this.myChart.resize();
} }
const myChart = echarts.init(chartDom); };
const option = { window.addEventListener('resize', this.resizeHandler);
tooltip: { },
trigger: 'axis', methods: {
axisPointer: { initData() {
type: 'cross', const chartDom = this.$refs.cockpitEffChip;
label: { if (!chartDom) {
backgroundColor: '#6a7985' console.error('图表容器未找到!');
} return;
}, }
// 优化tooltip内容区分各系列含义 // 销毁已有图表实例
formatter: (params) => { if (this.myChart) {
let html = `${params[0].axisValue}<br/>`; this.myChart.dispose();
params.forEach(item => { }
// 直接使用系列名,无需映射,仅保留单位判断 this.myChart = echarts.init(chartDom);
html += `${item.marker} ${item.seriesName}: ${item.value}${item.seriesName === '完成率' ? '%' : '元'}<br/>`; const option = {
}); tooltip: {
return html; trigger: 'axis',
} axisPointer: {
}, type: 'cross',
grid: { label: {
top: 30, backgroundColor: '#6a7985'
bottom: 30, // 增大底部间距避免柱子与X轴标签重叠 }
right: 70, },
left: 40, // 优化tooltip内容区分各系列含义
}, formatter: (params) => {
xAxis: [ let html = `${params[0].axisValue}<br/>`;
{ params.forEach(item => {
type: 'category', // 直接使用系列名,无需映射,仅保留单位判断
boundaryGap: true, // 开启边界间隙,让柱子居中显示,不贴边 html += `${item.marker} ${item.seriesName}: ${item.value}${item.seriesName === '完成率' ? '%' : '元'}<br/>`;
axisTick: { show: false }, });
axisLine: { return html;
show: true, }
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, grid: {
axisLabel: { top: 30,
color: 'rgba(0, 0, 0, 0.45)', bottom: 30, // 增大底部间距避免柱子与X轴标签重叠
fontSize: 12, right: 70,
interval: 0, left: 40,
padding: [5, 0, 0, 0] // 标签向下偏移,避免与柱子底部重叠 },
}, xAxis: [
data: this.xData {
} type: 'category',
], boundaryGap: true, // 开启边界间隙,让柱子居中显示,不贴边
yAxis: [ axisTick: { show: false },
// 左侧Y轴目标/达标/未达标(数量,单位“片”) axisLine: {
{ show: true,
type: 'value', lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
// name: this.yName, },
nameTextStyle: { axisLabel: {
color: 'rgba(0, 0, 0, 0.45)', color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12, fontSize: 12,
align: 'right' interval: 0,
}, padding: [5, 0, 0, 0] // 标签向下偏移,避免与柱子底部重叠
min: 0, // 最小值设0确保柱子从X轴底部开始不超过X轴 },
max: (value) => Math.ceil(value.max * 1.1), // 最大值留10%余量,避免柱子顶满 data: this.xData
scale: false, // 关闭缩放强制从0开始 }
axisTick: { show: false }, ],
axisLabel: { yAxis: [
color: 'rgba(0, 0, 0, 0.45)', // 左侧Y轴目标/达标/未达标(数量,单位“片”)
fontSize: 12, {
formatter: '{value}' type: 'value',
}, // name: this.yName,
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, nameTextStyle: {
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, color: 'rgba(0, 0, 0, 0.45)',
splitNumber: 4 fontSize: 12,
}, align: 'right'
], },
series: [ min: 0, // 最小值设0确保柱子从X轴底部开始不超过X轴
{ max: (value) => Math.ceil(value.max * 1.1), // 最大值留10%余量,避免柱子顶满
name: this.name, scale: false, // 关闭缩放强制从0开始
type: 'line', axisTick: { show: false },
// yAxisIndex: 1, axisLabel: {
lineStyle: { color: 'rgba(0, 0, 0, 0.45)',
color: 'rgba(40, 138, 255, .5)', fontSize: 12,
width: 2 formatter: '{value}'
}, },
itemStyle: { splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
color: 'rgba(40, 138, 255, 1)', axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
borderColor: 'rgba(40, 138, 255, 1)', splitNumber: 4
borderWidth: 2, },
radius: 4 ],
}, series: [
areaStyle: { {
opacity: 0.2, name: this.name,
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ type: 'line',
{ offset: 0, color: 'rgba(40, 138, 255, .9)' }, // yAxisIndex: 1,
{ offset: 1, color: 'rgba(40, 138, 255, 0)' } lineStyle: {
]) color: 'rgba(40, 138, 255, .5)',
}, width: 2
data: this.seriesData, },
symbol: 'circle', itemStyle: {
symbolSize: 6 color: 'rgba(40, 138, 255, 1)',
}, borderColor: 'rgba(40, 138, 255, 1)',
], borderWidth: 2,
}; radius: 4
},
option && myChart.setOption(option); areaStyle: {
opacity: 0.2,
// 窗口缩放适配 color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
window.addEventListener('resize', () => { { offset: 0, color: 'rgba(40, 138, 255, .9)' },
myChart.resize(); { offset: 1, color: 'rgba(40, 138, 255, 0)' }
}); ])
},
// 组件销毁清理 data: this.seriesData,
this.$once('hook:destroyed', () => { symbol: 'circle',
window.removeEventListener('resize', () => { symbolSize: 6
myChart.resize(); },
}); ],
myChart.dispose(); };
});
} option && this.myChart.setOption(option);
}, }
}; },
</script> beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -1,280 +1,293 @@
<template> <template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 280px;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 280px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return {}; return {
}, myChart: null,
props: { resizeHandler: null // 窗口resize事件处理器
seriesData: { };
type: Array, },
default: () => [] props: {
}, seriesData: {
xData: { type: Array,
type: Array, default: () => []
default: () => [] },
}, xData: {
name: { type: Array,
type: String, default: () => []
default: () => { } },
}, name: {
}, type: String,
watch: { default: () => { }
// 监听 xData 变化,触发图表更新 },
xData: { },
handler() { watch: {
this.$nextTick(() => this.initData()); // 监听 xData 变化,触发图表更新
}, xData: {
deep: true // 深度监听数组内元素变化 handler() {
}, this.$nextTick(() => this.initData());
// 监听 seriesData 变化,触发图表更新 },
seriesData: { deep: true // 深度监听数组内元素变化
handler() { },
this.$nextTick(() => this.initData()); // 监听 seriesData 变化,触发图表更新
}, seriesData: {
deep: true // 深度监听数组内元素变化 handler() {
} this.$nextTick(() => this.initData());
}, },
mounted() { deep: true // 深度监听数组内元素变化
this.$nextTick(() => { }
this.initData(); },
}); mounted() {
}, this.$nextTick(() => {
methods: { this.initData();
initData() { });
const chartDom = this.$refs.cockpitEffChip; // 注册窗口resize事件使用稳定的引用以便后续移除
if (!chartDom) { this.resizeHandler = () => {
console.error('图表容器未找到!'); if (this.myChart) {
return; this.myChart.resize();
} }
const myChart = echarts.init(chartDom); };
const option = { window.addEventListener('resize', this.resizeHandler);
tooltip: { },
trigger: 'axis', methods: {
axisPointer: { initData() {
type: 'cross', const chartDom = this.$refs.cockpitEffChip;
label: { if (!chartDom) {
backgroundColor: '#6a7985' console.error('图表容器未找到!');
} return;
}, }
// 优化tooltip内容区分各系列含义 // 销毁已有图表实例
formatter: (params) => { if (this.myChart) {
let html = `${params[0].axisValue}<br/>`; this.myChart.dispose();
params.forEach(item => { }
// 直接使用系列名,无需映射,仅保留单位判断 this.myChart = echarts.init(chartDom);
html += `${item.marker} ${item.seriesName}: ${item.value}${'元'}<br/>`; const option = {
}); tooltip: {
return html; trigger: 'axis',
} axisPointer: {
}, type: 'cross',
grid: { label: {
top: 50, backgroundColor: '#6a7985'
bottom: 30, // 增大底部间距避免柱子与X轴标签重叠 }
right: 70, },
left: 50, // 优化tooltip内容区分各系列含义
}, formatter: (params) => {
xAxis: [ let html = `${params[0].axisValue}<br/>`;
{ params.forEach(item => {
type: 'category', // 直接使用系列名,无需映射,仅保留单位判断
boundaryGap: true, // 开启边界间隙,让柱子居中显示,不贴边 html += `${item.marker} ${item.seriesName}: ${item.value}${'元'}<br/>`;
axisTick: { show: false }, });
axisLine: { return html;
show: true, }
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, grid: {
axisLabel: { top: 50,
color: 'rgba(0, 0, 0, 0.45)', bottom: 30, // 增大底部间距避免柱子与X轴标签重叠
fontSize: 12, right: 70,
interval: 0, left: 50,
padding: [5, 0, 0, 0] // 标签向下偏移,避免与柱子底部重叠 },
}, xAxis: [
data: this.xData // 绑定监听的 xData {
} type: 'category',
], boundaryGap: true, // 开启边界间隙,让柱子居中显示,不贴边
yAxis: [ axisTick: { show: false },
// 左侧Y轴目标/达标/未达标(数量,单位“片”) axisLine: {
{ show: true,
type: 'value', lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
name: '元', },
nameTextStyle: { axisLabel: {
color: 'rgba(0, 0, 0, 0.45)', color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12, fontSize: 12,
align: 'right' interval: 0,
}, padding: [5, 0, 0, 0] // 标签向下偏移,避免与柱子底部重叠
min: 0, // 最小值设0确保柱子从X轴底部开始不超过X轴 },
max: (value) => Math.ceil(value.max * 1.1), // 最大值留10%余量,避免柱子顶满 data: this.xData // 绑定监听的 xData
scale: false, // 关闭缩放强制从0开始 }
axisTick: { show: false }, ],
axisLabel: { yAxis: [
color: 'rgba(0, 0, 0, 0.45)', // 左侧Y轴目标/达标/未达标(数量,单位“片”)
fontSize: 12, {
formatter: '{value}' type: 'value',
}, name: '元',
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, nameTextStyle: {
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, color: 'rgba(0, 0, 0, 0.45)',
splitNumber: 4 fontSize: 12,
}, align: 'right'
// 右侧Y轴完成率百分比 },
// { min: 0, // 最小值设0确保柱子从X轴底部开始不超过X轴
// type: 'value', max: (value) => Math.ceil(value.max * 1.1), // 最大值留10%余量,避免柱子顶满
// // name: '%', scale: false, // 关闭缩放强制从0开始
// nameTextStyle: { axisTick: { show: false },
// color: 'rgba(0, 0, 0, 0.45)', axisLabel: {
// fontSize: 12, color: 'rgba(0, 0, 0, 0.45)',
// align: 'left' fontSize: 12,
// }, formatter: '{value}'
// min: 0, },
// max: 100, // 完成率最大100%,符合业务逻辑 splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// axisTick: { show: false }, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// axisLabel: { splitNumber: 4
// color: 'rgba(0, 0, 0, 0.45)', },
// fontSize: 12, // 右侧Y轴完成率百分比
// formatter: '{value}%' // {
// }, // type: 'value',
// splitLine: { show: false }, // 不重复显示分割线 // // name: '%',
// axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // nameTextStyle: {
// splitNumber: 4 // color: 'rgba(0, 0, 0, 0.45)',
// } // fontSize: 12,
], // align: 'left'
series: [ // },
// 1. 完成率折线图绑定右侧百分比Y轴 // min: 0,
// { // max: 100, // 完成率最大100%,符合业务逻辑
// name: '产销率', // axisTick: { show: false },
// type: 'line', // axisLabel: {
// yAxisIndex: 1, // 绑定右侧Y轴 // color: 'rgba(0, 0, 0, 0.45)',
// lineStyle: { // fontSize: 12,
// color: 'rgba(40, 138, 255, .5)', // formatter: '{value}%'
// width: 2 // 线条加粗,突出重点 // },
// }, // splitLine: { show: false }, // 不重复显示分割线
// itemStyle: { // axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// color: 'rgba(40, 138, 255, 1)', // splitNumber: 4
// borderColor: 'rgba(40, 138, 255, 1)', // 数据点白色边框,增强辨识度 // }
// borderWidth: 2, ],
// radius: 4 // 数据点圆角,更圆润 series: [
// }, // 1. 完成率折线图绑定右侧百分比Y轴
// areaStyle: { // {
// opacity: 0.2, // 降低面积透明度,不抢柱状图视觉焦点 // name: '产销率',
// color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [ // type: 'line',
// { offset: 0, color: 'rgba(40, 138, 255, .9)' }, // yAxisIndex: 1, // 绑定右侧Y轴
// { offset: 1, color: 'rgba(255, 132, 0, 0)' } // lineStyle: {
// ]) // color: 'rgba(40, 138, 255, .5)',
// }, // width: 2 // 线条加粗,突出重点
// data: [65, 78, 52, 85, 60, 95, 72], // 完成率数据0-100 // },
// symbol: 'circle', // 数据点为圆形 // itemStyle: {
// symbolSize: 6 // 数据点大小 // color: 'rgba(40, 138, 255, 1)',
// }, // borderColor: 'rgba(40, 138, 255, 1)', // 数据点白色边框,增强辨识度
// 2. 目标柱状图绑定左侧数量Y轴 // borderWidth: 2,
{ // radius: 4 // 数据点圆角,更圆润
name:this.name, // },
type: 'bar', // areaStyle: {
yAxisIndex: 0, // opacity: 0.2, // 降低面积透明度,不抢柱状图视觉焦点
barWidth: 24, // color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
label: { // { offset: 0, color: 'rgba(40, 138, 255, .9)' },
show: true, // 开启显示 // { offset: 1, color: 'rgba(255, 132, 0, 0)' }
position: 'top', // 标签位置,可选:'top'、'middle'、'bottom' // ])
// 也可以使用绝对像素值定位,例如 [10, '50%'] // },
// position: [10, '50%'], // data: [65, 78, 52, 85, 60, 95, 72], // 完成率数据0-100
// symbol: 'circle', // 数据点为圆形
// 标签内容格式化,这里直接显示数据值 // symbolSize: 6 // 数据点大小
formatter: '{c}', // },
// 2. 目标柱状图绑定左侧数量Y轴
// 文字样式 {
color: 'rgba(11, 88, 255, 1)', // 文字颜色 name:this.name,
fontSize: 14, // 文字大小 type: 'bar',
// fontWeight: 'bold', // 文字粗细 yAxisIndex: 0,
// fontFamily: 'Arial, sans-serif' // 字体 barWidth: 24,
}, label: {
itemStyle: { show: true, // 开启显示
// 移除多余的 normal 层级,直接配置 color 渐变 position: 'top', // 标签位置,可选:'top'、'middle'、'bottom'
color: { // 也可以使用绝对像素值定位,例如 [10, '50%']
type: 'linear', // position: [10, '50%'],
x: 0,
y: 0, // 标签内容格式化,这里直接显示数据值
x2: 0, formatter: '{c}',
y2: 1,
colorStops: [ // 文字样式
{ offset: 0, color: 'rgba(130, 204, 255, 1)' }, color: 'rgba(11, 88, 255, 1)', // 文字颜色
{ offset: 1, color: 'rgba(75, 157, 255, 1)' } fontSize: 14, // 文字大小
] // fontWeight: 'bold', // 文字粗细
}, // fontFamily: 'Arial, sans-serif' // 字体
borderRadius: [4, 4, 0, 0], },
borderWidth: 0 itemStyle: {
}, // 移除多余的 normal 层级,直接配置 color 渐变
data: this.seriesData color: {
}, type: 'linear',
// 3. 达标柱状图绑定左侧数量Y轴 x: 0,
// { y: 0,
// name: '产量', x2: 0,
// type: 'bar', y2: 1,
// yAxisIndex: 0, colorStops: [
// barWidth: 24, { offset: 0, color: 'rgba(130, 204, 255, 1)' },
// // 关键修复label 直接放在 series 下,而非 itemStyle 内 { offset: 1, color: 'rgba(75, 157, 255, 1)' }
// itemStyle: { ]
// // 移除多余的 normal 层级,直接配置 color 渐变 },
// color: { borderRadius: [4, 4, 0, 0],
// type: 'linear', borderWidth: 0
// x: 0, },
// y: 0, data: this.seriesData
// x2: 0, },
// y2: 1, // 3. 达标柱状图绑定左侧数量Y轴
// colorStops: [ // {
// { offset: 0, color: 'rgba(174, 239, 224, 1)' }, // name: '产量',
// { offset: 1, color: 'rgba(118, 218, 190, 1)' } // type: 'bar',
// ] // yAxisIndex: 0,
// }, // barWidth: 24,
// borderRadius: [4, 4, 0, 0], // // 关键修复label 直接放在 series 下,而非 itemStyle 内
// borderWidth: 0 // itemStyle: {
// }, // // 移除多余的 normal 层级,直接配置 color 渐变
// data: [130, 220, 95, 255, 132, 332] // 达标数据(小于目标) // color: {
// }, // type: 'linear',
// 4. 未达标柱状图绑定左侧数量Y轴 // x: 0,
// { // y: 0,
// name: '未达标', // x2: 0,
// type: 'bar', // y2: 1,
// yAxisIndex: 0, // colorStops: [
// barWidth: 18, // { offset: 0, color: 'rgba(174, 239, 224, 1)' },
// itemStyle: { // { offset: 1, color: 'rgba(118, 218, 190, 1)' }
// color: 'rgba(249, 164, 74, 1)', // ]
// borderRadius: [4, 4, 0, 0], // },
// borderWidth: 0 // borderRadius: [4, 4, 0, 0],
// }, // borderWidth: 0
// data: [70, 60, 85, 45, 88, 18, 78] // 未达标数据(目标-达标) // },
// } // data: [130, 220, 95, 255, 132, 332] // 达标数据(小于目标)
], // },
// 图例:区分各系列,点击可控制显示隐藏 // 4. 未达标柱状图绑定左侧数量Y轴
// legend: { // {
// top: 0, // name: '未达标',
// left: 'center', // type: 'bar',
// itemWidth: 12, // yAxisIndex: 0,
// itemHeight: 8, // barWidth: 18,
// textStyle: { // itemStyle: {
// color: 'rgba(0, 0, 0, 0.45)', // color: 'rgba(249, 164, 74, 1)',
// fontSize: 12 // borderRadius: [4, 4, 0, 0],
// }, // borderWidth: 0
// data: ['完成率', '目标', '达标', '未达标'] // },
// } // data: [70, 60, 85, 45, 88, 18, 78] // 未达标数据(目标-达标)
}; // }
],
option && myChart.setOption(option); // 图例:区分各系列,点击可控制显示隐藏
// legend: {
// 窗口缩放适配 // top: 0,
window.addEventListener('resize', () => { // left: 'center',
myChart.resize(); // itemWidth: 12,
}); // itemHeight: 8,
// textStyle: {
// 组件销毁清理 // color: 'rgba(0, 0, 0, 0.45)',
this.$once('hook:destroyed', () => { // fontSize: 12
window.removeEventListener('resize', () => { // },
myChart.resize(); // data: ['完成率', '目标', '达标', '未达标']
}); // }
myChart.dispose(); };
});
} option && this.myChart.setOption(option);
}, }
}; },
</script> beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -158,18 +158,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -140,18 +140,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -147,18 +147,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -158,18 +158,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -155,18 +155,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -141,18 +141,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -39,6 +40,25 @@ export default {
}, },
mounted() { mounted() {
this.$nextTick(() => this.updateChart()); this.$nextTick(() => this.updateChart());
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
watch: { watch: {
detailData: { detailData: {
@@ -168,19 +188,6 @@ export default {
}; };
this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存 this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存
// 优化防抖resize避免频繁触发
const resizeHandler = () => {
this.myChart && this.myChart.resize();
};
window.removeEventListener('resize', resizeHandler); // 先移除再添加,避免重复绑定
window.addEventListener('resize', resizeHandler);
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', resizeHandler);
this.myChart && this.myChart.dispose();
this.myChart = null;
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -158,19 +166,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,19 +162,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -1,173 +1,181 @@
<template> <template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 380px;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 380px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
}), default: () => ({
// 校验数据格式 }),
// validator: (value) => { // 校验数据格式
// return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); // validator: (value) => {
// } // return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} // }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
this.updateChart(); },
},
deep: true, // 新增:监听 chartData 变化
immediate: true // 初始化时立即执行 watch: {
} // 深度监听数据变化,仅更新图表配置(不销毁实例)
}, chartData: {
methods: { handler() {
updateChart() { console.log(this.chartData,'chartData');
const chartDom = this.$refs.cockpitEffChip; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
return;
const { allPlaceNames, series } = this.chartData || {}; }
console.log('chartData', this.chartData);
if (this.myChart) {
// 处理空数据 this.myChart.dispose();
const xData = allPlaceNames || []; }
const chartSeries = series || []; // 父组件传递的 series
console.log('xData', xData); this.myChart = echarts.init(chartDom);
const option = { const { allPlaceNames, series } = this.chartData || {};
tooltip: { console.log('chartData', this.chartData);
trigger: 'axis',
axisPointer: { // 处理空数据
type: 'cross', const xData = allPlaceNames || [];
label: { const chartSeries = series || []; // 父组件传递的 series
backgroundColor: '#6a7985' console.log('xData', xData);
}
}, const option = {
// formatter: (params) => { tooltip: {
// let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
// params.forEach(item => { axisPointer: {
// const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
// ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
// ); backgroundColor: '#6a7985'
// html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
// }); },
// return html; // formatter: (params) => {
// } // let html = `${params[0].axisValue}<br/>`;
}, // params.forEach(item => {
grid: { // const unit = item.seriesName === '完成率' ? '%' : (
top: 30, // ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 20, // );
right: 10, // html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 25, // });
containLabel: true // return html;
}, // }
xAxis: [ },
{ grid: {
type: 'category', top: 30,
boundaryGap: true, bottom: 20,
axisTick: { show: false }, right: 10,
axisLine: { left: 25,
show: true, containLabel: true
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
name: '万元', },
nameTextStyle: { data: xData
color: 'rgba(0, 0, 0, 0.45)', }
fontSize: 12, ],
align: 'right' yAxis: [
}, // 左侧Y轴营业收入、成本单位万元
{
splitNumber: 4, type: 'value',
axisTick: { show: false }, name: '万元',
axisLabel: { nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)', color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12, fontSize: 12,
formatter: '{value}' align: 'right'
}, },
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: {show:true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
}, axisTick: { show: false },
// 右侧Y轴利润占比百分比 axisLabel: {
{ color: 'rgba(0, 0, 0, 0.45)',
type: 'value', fontSize: 12,
nameTextStyle: { formatter: '{value}'
color: 'rgba(0, 0, 0, 0.45)', },
fontSize: 12, splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
align: 'left' axisLine: {show:true, lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, {
axisTick: { show: false }, type: 'value',
axisLabel: { nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)', color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12, fontSize: 12,
formatter: '{value}%' align: 'left'
}, },
splitLine: { show: false }, // min: 0,
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: 100,
// axisTick: { show: false },
splitNumber: 4, axisLabel: {
} color: 'rgba(0, 0, 0, 0.45)',
], fontSize: 12,
series: chartSeries // 直接使用父组件传递的 series formatter: '{value}%'
}; },
splitLine: { show: false },
option && this.myChart.setOption(option); axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
//
// 窗口缩放适配和销毁逻辑保持不变 splitNumber: 4,
window.addEventListener('resize', () => { }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -139,19 +147,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -18,7 +18,8 @@ export default {
data() { data() {
return { return {
myChart: null, // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
flag:0 flag:0,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -37,6 +38,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -188,19 +196,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -1,176 +1,184 @@
<template> <template>
<div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChipBottom; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChipBottom;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
formatter: (params) => { tooltip: {
let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
params.forEach(item => { axisPointer: {
const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
); backgroundColor: '#6a7985'
html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
}); },
return html; formatter: (params) => {
} let html = `${params[0].axisValue}<br/>`;
}, params.forEach(item => {
grid: { const unit = item.seriesName === '完成率' ? '%' : (
top: 30, ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, );
right: 20, html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, });
}, return html;
xAxis: [ }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
splitNumber: 4, },
name: '万元', data: xData
nameTextStyle: { }
color: 'rgba(0, 0, 0, 0.45)', ],
fontSize: 12, yAxis: [
align: 'right' // 左侧Y轴营业收入、成本单位万元
}, {
// min: 0, type: 'value',
// max: (value) => Math.ceil((value.max || 0) * 1.1), splitNumber: 4,
name: '万元',
axisTick: { show: false }, nameTextStyle: {
axisLabel: { color: 'rgba(0, 0, 0, 0.45)',
color: 'rgba(0, 0, 0, 0.45)', fontSize: 12,
fontSize: 12, align: 'right'
formatter: '{value}' },
}, // min: 0,
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: (value) => Math.ceil((value.max || 0) * 1.1),
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
{ fontSize: 12,
type: 'value', formatter: '{value}'
nameTextStyle: { },
color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
align: 'left' splitNumber: 4
}, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, {
scale:true, type: 'value',
splitNumber: 4, nameTextStyle: {
axisTick: { show: false }, color: 'rgba(0, 0, 0, 0.45)',
axisLabel: { fontSize: 12,
color: 'rgba(0, 0, 0, 0.45)', align: 'left'
fontSize: 12, },
formatter: '{value}%' // min: 0,
}, // max: 100,
splitLine: { show: false }, scale:true,
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
} axisLabel: {
], color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series fontSize: 12,
}; formatter: '{value}%'
},
option && this.myChart.setOption(option); splitLine: { show: false },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 splitNumber: 4
window.addEventListener('resize', () => { }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,19 +162,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -155,19 +163,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -139,19 +147,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -39,6 +40,13 @@ export default {
}, },
mounted() { mounted() {
this.$nextTick(() => this.updateChart()); this.$nextTick(() => this.updateChart());
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
watch: { watch: {
detailData: { detailData: {
@@ -169,20 +177,19 @@ export default {
}; };
this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存 this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存
// 优化防抖resize避免频繁触发
const resizeHandler = () => {
this.myChart && this.myChart.resize();
};
window.removeEventListener('resize', resizeHandler); // 先移除再添加,避免重复绑定
window.addEventListener('resize', resizeHandler);
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', resizeHandler);
this.myChart && this.myChart.dispose();
this.myChart = null;
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -1,176 +1,184 @@
<template> <template>
<div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChipBottom; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChipBottom;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
formatter: (params) => { tooltip: {
let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
params.forEach(item => { axisPointer: {
const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
); backgroundColor: '#6a7985'
html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
}); },
return html; formatter: (params) => {
} let html = `${params[0].axisValue}<br/>`;
}, params.forEach(item => {
grid: { const unit = item.seriesName === '完成率' ? '%' : (
top: 30, ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, );
right: 20, html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, });
}, return html;
xAxis: [ }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
splitNumber: 4, },
name: '万元', data: xData
nameTextStyle: { }
color: 'rgba(0, 0, 0, 0.45)', ],
fontSize: 12, yAxis: [
align: 'right' // 左侧Y轴营业收入、成本单位万元
}, {
// min: 0, type: 'value',
// max: (value) => Math.ceil((value.max || 0) * 1.1), splitNumber: 4,
name: '万元',
axisTick: { show: false }, nameTextStyle: {
axisLabel: { color: 'rgba(0, 0, 0, 0.45)',
color: 'rgba(0, 0, 0, 0.45)', fontSize: 12,
fontSize: 12, align: 'right'
formatter: '{value}' },
}, // min: 0,
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: (value) => Math.ceil((value.max || 0) * 1.1),
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
{ fontSize: 12,
type: 'value', formatter: '{value}'
nameTextStyle: { },
color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
align: 'left' splitNumber: 4
}, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, {
scale:true, type: 'value',
splitNumber: 4, nameTextStyle: {
axisTick: { show: false }, color: 'rgba(0, 0, 0, 0.45)',
axisLabel: { fontSize: 12,
color: 'rgba(0, 0, 0, 0.45)', align: 'left'
fontSize: 12, },
formatter: '{value}%' // min: 0,
}, // max: 100,
splitLine: { show: false }, scale:true,
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
} axisLabel: {
], color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series fontSize: 12,
}; formatter: '{value}%'
},
option && this.myChart.setOption(option); splitLine: { show: false },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 splitNumber: 4
window.addEventListener('resize', () => { }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,19 +162,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -23,6 +24,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -141,19 +149,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -123,19 +131,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -18,7 +18,8 @@ export default {
data() { data() {
return { return {
myChart: null, // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
flag:0 flag:0,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -37,6 +38,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -188,19 +196,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -158,18 +158,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -155,18 +155,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -139,18 +139,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -1,217 +1,225 @@
<template> <template>
<div style="width: 100%; height: 210px;position: relative;"> <div style="width: 100%; height: 210px;position: relative;">
<div style='font-size: 16px;position: absolute;left: 20px;top:10px'> <div style='font-size: 16px;position: absolute;left: 20px;top:10px'>
% %
</div> </div>
<div style='font-size: 16px;position: absolute;right: 20px;top:10px'> <div style='font-size: 16px;position: absolute;right: 20px;top:10px'>
<span>完成率:<span style='color: #0B58FF;'>{{detailData.rate}}%</span></span> <span>完成率:<span style='color: #0B58FF;'>{{detailData.rate}}%</span></span>
<span style='display: inline-block;margin-left: 10px;'>差值:<span :style="{color:flag>0?'#30B590':'#FF9423'}" >{{detailData.diff}}</span></span> <span style='display: inline-block;margin-left: 10px;'>差值:<span :style="{color:flag>0?'#30B590':'#FF9423'}" >{{detailData.diff}}</span></span>
</div> </div>
<div :ref="refName" id="coreLineChart" style="width: 100%; height: 210px;"></div> <div :ref="refName" id="coreLineChart" style="width: 100%; height: 210px;"></div>
</div> </div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null, // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
flag:0 flag: 0,
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
refName: { // 明确接收的props结构增强可读性
type: String, refName: {
default: () => 'verticalBarChart', type: String,
}, default: () => 'verticalBarChart',
detailData: { },
type: Object, detailData: {
default: () => ({ type: Object,
}), default: () => ({
} }),
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
detailData: { }
handler() { };
console.log(this.chartData, 'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} detailData: {
}, handler() {
methods: { console.log(this.chartData, 'chartData');
getRateFlag(rate, real, target) {
if (isNaN(rate) || rate === null || rate === undefined) return 0; this.updateChart();
},
// 1. 完成率 >= 100 => 达标 deep: true,
if (rate >= 100) return 1; immediate: true // 初始化时立即执行
}
// 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标 },
if (rate === 0 && target === 0) return 1; methods: {
getRateFlag(rate, real, target) {
// 其他情况 => 未达标 if (isNaN(rate) || rate === null || rate === undefined) return 0;
return 0;
}, // 1. 完成率 >= 100 => 达标
updateChart() { if (rate >= 100) return 1;
const chartDom = this.$refs[this.refName];
if (!chartDom) { // 2. 完成率 = 0 且 (目标值=0 或 实际值=目标值=0) => 达标
console.error('图表容器未找到!'); if (rate === 0 && target === 0) return 1;
return;
} // 其他情况 => 未达标
return 0;
if (this.myChart) { },
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs[this.refName];
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const diff = this.detailData.diff || 0 return;
const rate = this.detailData.rate || 0 }
const flagValue = this.detailData.rate >=100?1:0
this.flag = flagValue if (this.myChart) {
const option = { this.myChart.dispose();
tooltip: { }
trigger: 'axis',
axisPointer: { this.myChart = echarts.init(chartDom);
type: 'cross', const diff = this.detailData.diff || 0
label: { const rate = this.detailData.rate || 0
backgroundColor: '#6a7985' const flagValue = this.detailData.rate >=100?1:0
} this.flag = flagValue
}, const option = {
}, tooltip: {
grid: { trigger: 'axis',
top: 40, axisPointer: {
bottom: 15, type: 'cross',
right: 80, label: {
left: 10, backgroundColor: '#6a7985'
containLabel: true, }
show: false // 隐藏grid背景避免干扰 },
}, },
xAxis: { grid: {
// 横向柱状图的x轴必须设为数值轴否则无法正常展示数值 top: 40,
type: 'value', bottom: 15,
axisTick: { show: false }, right: 80,
min: 0, left: 10,
// containLabel: true,
splitNumber: 4, show: false // 隐藏grid背景避免干扰
axisLine: { },
show: true, xAxis: {
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } // 横向柱状图的x轴必须设为数值轴否则无法正常展示数值
}, type: 'value',
axisLabel: { axisTick: { show: false },
color: 'rgba(0, 0, 0, 0.45)', min: 0,
fontSize: 12, //
interval: 0, splitNumber: 4,
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
// data: xData // 数值轴不需要手动设置data由series的数据自动生成 lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
}, },
yAxis: { axisLabel: {
type: 'category', color: 'rgba(0, 0, 0, 0.45)',
axisLabel: { fontSize: 12,
color: 'rgba(0, 0, 0, 0.75)', interval: 0,
fontSize: 12, padding: [5, 0, 0, 0]
interval: 0, },
padding: [5, 0, 0, 0] // data: xData // 数值轴不需要手动设置data由series的数据自动生成
}, },
axisLine: { yAxis: {
show: true, // 显示Y轴轴线关键 type: 'category',
lineStyle: { axisLabel: {
color: '#E5E6EB', // 轴线颜色(浅灰色,可自定义) color: 'rgba(0, 0, 0, 0.75)',
width: 1, // 轴线宽度 fontSize: 12,
type: 'solid' // 实线可选dashed虚线、dotted点线 interval: 0,
} padding: [5, 0, 0, 0]
}, },
axisTick: { show: false }, axisLine: {
// padding: [300, 100, 100, 100], show: true, // 显示Y轴轴线关键
data: ['实际', '预算'] // y轴分类实际、预算 lineStyle: {
}, color: '#E5E6EB', // 轴线颜色(浅灰色,可自定义)
series: [ width: 1, // 轴线宽度
{ type: 'solid' // 实线可选dashed虚线、dotted点线
// name: '预算', }
type: 'bar', },
barWidth: 24, axisTick: { show: false },
// barCategoryGap: '50', // 柱子之间的间距(相对于柱子宽度) // padding: [300, 100, 100, 100],
// 数据长度与yAxis的分类数量匹配实际、预算各一个值 data: ['实际', '预算'] // y轴分类实际、预算
data: [{ },
value: this.detailData.real, series: [
label: { {
show: true, // name: '预算',
position: 'right', type: 'bar',
fontSize: 14 barWidth: 24,
}, // barCategoryGap: '50', // 柱子之间的间距(相对于柱子宽度)
itemStyle: { // 数据长度与yAxis的分类数量匹配实际、预算各一个值
color: flagValue === 1 data: [{
? { value: this.detailData.real,
type: 'linear', label: {
x: 0, y: 0, x2: 0, y2: 1, show: true,
colorStops: [ position: 'right',
{ offset: 0, color: 'rgba(174, 239, 224, 1)' }, fontSize: 14
{ offset: 1, color: 'rgba(118, 218, 190, 1)' } },
] itemStyle: {
} color: flagValue === 1
: { ? {
type: 'linear', type: 'linear',
x: 0, y: 0, x2: 0, y2: 1, x: 0, y: 0, x2: 0, y2: 1,
colorStops: [ colorStops: [
{ offset: 0, color: 'rgba(253, 209, 129, 1)' }, { offset: 0, color: 'rgba(174, 239, 224, 1)' },
{ offset: 1, color: 'rgba(249, 164, 74, 1)' } { offset: 1, color: 'rgba(118, 218, 190, 1)' }
] ]
}, }
borderRadius: [4, 4, 0, 0] : {
} type: 'linear',
}, { x: 0, y: 0, x2: 0, y2: 1,
value: this.detailData.target, colorStops: [
label: { { offset: 0, color: 'rgba(253, 209, 129, 1)' },
show: true, { offset: 1, color: 'rgba(249, 164, 74, 1)' }
position: 'right', ]
fontSize: 14 },
}, borderRadius: [4, 4, 0, 0]
itemStyle: { }
// 预算的渐变颜色(蓝系渐变) }, {
color: { value: this.detailData.target,
type: 'linear', label: {
x: 1, y: 0, x2: 0, y2: 1, show: true,
colorStops: [ position: 'right',
{ offset: 0, color: '#82CCFF' }, // 浅蓝 fontSize: 14
{ offset: 1, color: '#4B9DFF' } // 深蓝 },
] itemStyle: {
}, // 预算的渐变颜色(蓝系渐变)
borderRadius: [4, 4, 0, 0], color: {
borderWidth: 0 type: 'linear',
}, x: 1, y: 0, x2: 0, y2: 1,
},], colorStops: [
{ offset: 0, color: '#82CCFF' }, // 浅蓝
}, { offset: 1, color: '#4B9DFF' } // 深蓝
] ]
}; },
borderRadius: [4, 4, 0, 0],
option && this.myChart.setOption(option); borderWidth: 0
},
// 窗口缩放适配和销毁逻辑保持不变 },],
window.addEventListener('resize', () => {
this.myChart && this.myChart.resize(); },
}); ]
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -158,18 +158,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -152,18 +152,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -147,18 +147,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -158,18 +158,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,18 +154,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -155,18 +155,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -139,18 +139,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -39,6 +40,25 @@ export default {
}, },
mounted() { mounted() {
this.$nextTick(() => this.updateChart()); this.$nextTick(() => this.updateChart());
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
watch: { watch: {
detailData: { detailData: {
@@ -167,19 +187,6 @@ export default {
}; };
this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存 this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存
// 优化防抖resize避免频繁触发
const resizeHandler = () => {
this.myChart && this.myChart.resize();
};
window.removeEventListener('resize', resizeHandler); // 先移除再添加,避免重复绑定
window.addEventListener('resize', resizeHandler);
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', resizeHandler);
this.myChart && this.myChart.dispose();
this.myChart = null;
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -158,18 +178,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,18 +174,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -155,18 +175,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -123,18 +143,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -36,6 +37,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -187,18 +207,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -158,19 +166,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -1,172 +1,180 @@
<template> <template>
<div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChip" id="coreLineChart" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChip; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChip;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
// formatter: (params) => { tooltip: {
// let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
// params.forEach(item => { axisPointer: {
// const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
// ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
// ); backgroundColor: '#6a7985'
// html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
// }); },
// return html; // formatter: (params) => {
// } // let html = `${params[0].axisValue}<br/>`;
}, // params.forEach(item => {
grid: { // const unit = item.seriesName === '完成率' ? '%' : (
top: 30, // ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, // );
right: 20, // html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, // });
}, // return html;
xAxis: [ // }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
name: '万元', },
nameTextStyle: { data: xData
color: 'rgba(0, 0, 0, 0.45)', }
fontSize: 12, ],
align: 'right' yAxis: [
}, // 左侧Y轴营业收入、成本单位万元
{
splitNumber: 4, type: 'value',
axisTick: { show: false }, name: '万元',
axisLabel: { nameTextStyle: {
color: 'rgba(0, 0, 0, 0.45)', color: 'rgba(0, 0, 0, 0.45)',
fontSize: 12, fontSize: 12,
formatter: '{value}' align: 'right'
}, },
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
// { fontSize: 12,
// type: 'value', formatter: '{value}'
// nameTextStyle: { },
// color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// align: 'left' splitNumber: 4
// }, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, // {
// axisTick: { show: false }, // type: 'value',
// axisLabel: { // nameTextStyle: {
// color: 'rgba(0, 0, 0, 0.45)', // color: 'rgba(0, 0, 0, 0.45)',
// fontSize: 12, // fontSize: 12,
// formatter: '{value}%' // align: 'left'
// }, // },
// splitLine: { show: false }, // min: 0,
// axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: 100,
// splitNumber: 4 // axisTick: { show: false },
// } // axisLabel: {
], // color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series // fontSize: 12,
}; // formatter: '{value}%'
// },
option && this.myChart.setOption(option); // splitLine: { show: false },
// axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 // splitNumber: 4
window.addEventListener('resize', () => { // }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -155,19 +163,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -139,19 +147,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -39,6 +40,13 @@ export default {
}, },
mounted() { mounted() {
this.$nextTick(() => this.updateChart()); this.$nextTick(() => this.updateChart());
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
watch: { watch: {
detailData: { detailData: {
@@ -167,20 +175,19 @@ export default {
}; };
this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存 this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存
// 优化防抖resize避免频繁触发
const resizeHandler = () => {
this.myChart && this.myChart.resize();
};
window.removeEventListener('resize', resizeHandler); // 先移除再添加,避免重复绑定
window.addEventListener('resize', resizeHandler);
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', resizeHandler);
this.myChart && this.myChart.dispose();
this.myChart = null;
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -158,18 +178,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,18 +174,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -155,18 +175,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -27,6 +28,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -139,18 +159,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -39,6 +40,25 @@ export default {
}, },
mounted() { mounted() {
this.$nextTick(() => this.updateChart()); this.$nextTick(() => this.updateChart());
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
watch: { watch: {
detailData: { detailData: {
@@ -167,19 +187,6 @@ export default {
}; };
this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存 this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存
// 优化防抖resize避免频繁触发
const resizeHandler = () => {
this.myChart && this.myChart.resize();
};
window.removeEventListener('resize', resizeHandler); // 先移除再添加,避免重复绑定
window.addEventListener('resize', resizeHandler);
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', resizeHandler);
this.myChart && this.myChart.dispose();
this.myChart = null;
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -1,176 +1,184 @@
<template> <template>
<div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChipBottom; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChipBottom;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
formatter: (params) => { tooltip: {
let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
params.forEach(item => { axisPointer: {
const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
); backgroundColor: '#6a7985'
html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
}); },
return html; formatter: (params) => {
} let html = `${params[0].axisValue}<br/>`;
}, params.forEach(item => {
grid: { const unit = item.seriesName === '完成率' ? '%' : (
top: 30, ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, );
right: 20, html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, });
}, return html;
xAxis: [ }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
splitNumber: 4, },
name: '万元', data: xData
nameTextStyle: { }
color: 'rgba(0, 0, 0, 0.45)', ],
fontSize: 12, yAxis: [
align: 'right' // 左侧Y轴营业收入、成本单位万元
}, {
// min: 0, type: 'value',
// max: (value) => Math.ceil((value.max || 0) * 1.1), splitNumber: 4,
name: '万元',
axisTick: { show: false }, nameTextStyle: {
axisLabel: { color: 'rgba(0, 0, 0, 0.45)',
color: 'rgba(0, 0, 0, 0.45)', fontSize: 12,
fontSize: 12, align: 'right'
formatter: '{value}' },
}, // min: 0,
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: (value) => Math.ceil((value.max || 0) * 1.1),
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
{ fontSize: 12,
type: 'value', formatter: '{value}'
nameTextStyle: { },
color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
align: 'left' splitNumber: 4
}, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, {
scale:true, type: 'value',
splitNumber: 4, nameTextStyle: {
axisTick: { show: false }, color: 'rgba(0, 0, 0, 0.45)',
axisLabel: { fontSize: 12,
color: 'rgba(0, 0, 0, 0.45)', align: 'left'
fontSize: 12, },
formatter: '{value}%' // min: 0,
}, // max: 100,
splitLine: { show: false }, scale:true,
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
} axisLabel: {
], color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series fontSize: 12,
}; formatter: '{value}%'
},
option && this.myChart.setOption(option); splitLine: { show: false },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 splitNumber: 4
window.addEventListener('resize', () => { }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,18 +174,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -31,6 +32,25 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -149,18 +169,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -31,12 +32,21 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 在 mounted 中统一绑定 resize 事件 // 注册窗口resize事件,使用稳定的引用以便后续移除
window.addEventListener('resize', this.handleResize); this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
beforeDestroy() { // 或 unmounted (Vue3) beforeDestroy() {
// 组件销毁时移除监听器并销毁图表 // 移除窗口resize事件监听器
window.removeEventListener('resize', this.handleResize); if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) { if (this.myChart) {
this.myChart.dispose(); this.myChart.dispose();
this.myChart = null; this.myChart = null;
@@ -162,18 +172,6 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
}; };

View File

@@ -17,7 +17,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null myChart: null,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -43,6 +44,25 @@ export default {
}, },
mounted() { mounted() {
this.$nextTick(() => this.updateChart()); this.$nextTick(() => this.updateChart());
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
},
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}, },
watch: { watch: {
detailData: { detailData: {
@@ -172,19 +192,6 @@ export default {
}; };
this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存 this.myChart.setOption(option, true); // 新增true表示替换所有配置避免缓存
// 优化防抖resize避免频繁触发
const resizeHandler = () => {
this.myChart && this.myChart.resize();
};
window.removeEventListener('resize', resizeHandler); // 先移除再添加,避免重复绑定
window.addEventListener('resize', resizeHandler);
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', resizeHandler);
this.myChart && this.myChart.dispose();
this.myChart = null;
});
} }
}, },
}; };

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -1,176 +1,184 @@
<template> <template>
<div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div> <div ref="cockpitEffChipBottom" id="cockpitEffChipBottom" style="width: 100%; height: 400px;"></div>
</template> </template>
<script> <script>
import * as echarts from 'echarts'; import * as echarts from 'echarts';
export default { export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
}; resizeHandler: null // 窗口resize事件处理器
}, };
props: { },
// 明确接收的props结构增强可读性 props: {
chartData: { // 明确接收的props结构增强可读性
type: Object, chartData: {
default: () => ({ type: Object,
series: [], default: () => ({
allPlaceNames: [] series: [],
}), allPlaceNames: []
// 校验数据格式 }),
validator: (value) => { // 校验数据格式
return Array.isArray(value.series) && Array.isArray(value.allPlaceNames); validator: (value) => {
} return Array.isArray(value.series) && Array.isArray(value.allPlaceNames);
} }
}, }
mounted() { },
this.$nextTick(() => { mounted() {
this.updateChart(); this.$nextTick(() => {
}); this.updateChart();
}, });
// 注册窗口resize事件使用稳定的引用以便后续移除
// 新增:监听 chartData 变化 this.resizeHandler = () => {
watch: { if (this.myChart) {
// 深度监听数据变化,仅更新图表配置(不销毁实例) this.myChart.resize();
chartData: { }
handler() { };
console.log(this.chartData,'chartData'); window.addEventListener('resize', this.resizeHandler);
},
this.updateChart();
}, // 新增:监听 chartData 变化
deep: true, watch: {
immediate: true // 初始化时立即执行 // 深度监听数据变化,仅更新图表配置(不销毁实例)
} chartData: {
}, handler() {
methods: { console.log(this.chartData,'chartData');
updateChart() {
const chartDom = this.$refs.cockpitEffChipBottom; this.updateChart();
if (!chartDom) { },
console.error('图表容器未找到!'); deep: true,
return; immediate: true // 初始化时立即执行
} }
},
if (this.myChart) { methods: {
this.myChart.dispose(); updateChart() {
} const chartDom = this.$refs.cockpitEffChipBottom;
if (!chartDom) {
this.myChart = echarts.init(chartDom); console.error('图表容器未找到!');
const { allPlaceNames, series } = this.chartData || {}; return;
}
// 处理空数据
const xData = allPlaceNames || []; if (this.myChart) {
const chartSeries = series || []; // 父组件传递的 series this.myChart.dispose();
}
const option = {
tooltip: { this.myChart = echarts.init(chartDom);
trigger: 'axis', const { allPlaceNames, series } = this.chartData || {};
axisPointer: {
type: 'cross', // 处理空数据
label: { const xData = allPlaceNames || [];
backgroundColor: '#6a7985' const chartSeries = series || []; // 父组件传递的 series
}
}, const option = {
formatter: (params) => { tooltip: {
let html = `${params[0].axisValue}<br/>`; trigger: 'axis',
params.forEach(item => { axisPointer: {
const unit = item.seriesName === '完成率' ? '%' : ( type: 'cross',
['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元' label: {
); backgroundColor: '#6a7985'
html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`; }
}); },
return html; formatter: (params) => {
} let html = `${params[0].axisValue}<br/>`;
}, params.forEach(item => {
grid: { const unit = item.seriesName === '完成率' ? '%' : (
top: 30, ['产量', '销量'].includes(this.$parent.selectedProfit) ? '片' : '万元'
bottom: 30, );
right: 20, html += `${item.marker} ${item.seriesName}: ${item.value}${unit}<br/>`;
left: 60, });
}, return html;
xAxis: [ }
{ },
type: 'category', grid: {
boundaryGap: true, top: 30,
axisTick: { show: false }, bottom: 30,
axisLine: { right: 20,
show: true, left: 60,
lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
}, xAxis: [
axisLabel: { {
color: 'rgba(0, 0, 0, 0.45)', type: 'category',
fontSize: 12, boundaryGap: true,
interval: 0, axisTick: { show: false },
padding: [5, 0, 0, 0] axisLine: {
}, show: true,
data: xData lineStyle: { color: 'rgba(0, 0, 0, 0.15)' }
} },
], axisLabel: {
yAxis: [ color: 'rgba(0, 0, 0, 0.45)',
// 左侧Y轴营业收入、成本单位万元 fontSize: 12,
{ interval: 0,
type: 'value', padding: [5, 0, 0, 0]
splitNumber: 4, },
name: '万元', data: xData
nameTextStyle: { }
color: 'rgba(0, 0, 0, 0.45)', ],
fontSize: 12, yAxis: [
align: 'right' // 左侧Y轴营业收入、成本单位万元
}, {
// min: 0, type: 'value',
// max: (value) => Math.ceil((value.max || 0) * 1.1), splitNumber: 4,
name: '万元',
axisTick: { show: false }, nameTextStyle: {
axisLabel: { color: 'rgba(0, 0, 0, 0.45)',
color: 'rgba(0, 0, 0, 0.45)', fontSize: 12,
fontSize: 12, align: 'right'
formatter: '{value}' },
}, // min: 0,
splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, // max: (value) => Math.ceil((value.max || 0) * 1.1),
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
splitNumber: 4 axisTick: { show: false },
}, axisLabel: {
// 右侧Y轴利润占比百分比 color: 'rgba(0, 0, 0, 0.45)',
{ fontSize: 12,
type: 'value', formatter: '{value}'
nameTextStyle: { },
color: 'rgba(0, 0, 0, 0.45)', splitLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
fontSize: 12, axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
align: 'left' splitNumber: 4
}, },
// min: 0, // 右侧Y轴利润占比百分比
// max: 100, {
scale:true, type: 'value',
splitNumber: 4, nameTextStyle: {
axisTick: { show: false }, color: 'rgba(0, 0, 0, 0.45)',
axisLabel: { fontSize: 12,
color: 'rgba(0, 0, 0, 0.45)', align: 'left'
fontSize: 12, },
formatter: '{value}%' // min: 0,
}, // max: 100,
splitLine: { show: false }, scale:true,
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } }, splitNumber: 4,
splitNumber: 4 axisTick: { show: false },
} axisLabel: {
], color: 'rgba(0, 0, 0, 0.45)',
series: chartSeries // 直接使用父组件传递的 series fontSize: 12,
}; formatter: '{value}%'
},
option && this.myChart.setOption(option); splitLine: { show: false },
axisLine: { lineStyle: { color: 'rgba(0, 0, 0, 0.15)' } },
// 窗口缩放适配和销毁逻辑保持不变 splitNumber: 4
window.addEventListener('resize', () => { }
this.myChart && this.myChart.resize(); ],
}); series: chartSeries // 直接使用父组件传递的 series
};
this.$once('hook:destroyed', () => {
window.removeEventListener('resize', () => { option && this.myChart.setOption(option);
this.myChart && this.myChart.resize(); }
}); },
this.myChart && this.myChart.dispose(); beforeDestroy() {
}); // 移除窗口resize事件监听器
} if (this.resizeHandler) {
}, window.removeEventListener('resize', this.resizeHandler);
}; this.resizeHandler = null;
</script> }
// 销毁图表,避免内存泄漏
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
};
</script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,19 +162,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -125,19 +125,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -139,19 +139,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -18,7 +18,8 @@ export default {
data() { data() {
return { return {
myChart: null, // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
flag:0 flag:0,
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -37,6 +38,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -187,19 +195,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -154,6 +154,18 @@ export default {
}, },
// 未使用的蒸汽仪表盘可注释/删除 // 未使用的蒸汽仪表盘可注释/删除
// getSteamGaugeOption(value) { ... } // getSteamGaugeOption(value) { ... }
},
beforeDestroy() {
// 销毁 ResizeObserver避免内存泄漏
if (this.resizeObserver) {
this.resizeObserver.disconnect();
this.resizeObserver = null;
}
// 销毁图表实例
if (this.electricityChart) {
this.electricityChart.dispose();
this.electricityChart = null;
}
} }
} }
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -158,19 +166,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -8,7 +8,8 @@ export default {
components: {}, components: {},
data() { data() {
return { return {
myChart: null // 存储图表实例,避免重复创建 myChart: null, // 存储图表实例,避免重复创建
resizeHandler: null // 窗口resize事件处理器
}; };
}, },
props: { props: {
@@ -29,6 +30,13 @@ export default {
this.$nextTick(() => { this.$nextTick(() => {
this.updateChart(); this.updateChart();
}); });
// 注册窗口resize事件使用稳定的引用以便后续移除
this.resizeHandler = () => {
if (this.myChart) {
this.myChart.resize();
}
};
window.addEventListener('resize', this.resizeHandler);
}, },
// 新增:监听 chartData 变化 // 新增:监听 chartData 变化
@@ -154,19 +162,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

View File

@@ -155,19 +155,19 @@ export default {
}; };
option && this.myChart.setOption(option); option && 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();
});
} }
}, },
beforeDestroy() {
// 移除窗口resize事件监听器
if (this.resizeHandler) {
window.removeEventListener('resize', this.resizeHandler);
this.resizeHandler = null;
}
// 销毁图表实例
if (this.myChart) {
this.myChart.dispose();
this.myChart = null;
}
}
}; };
</script> </script>

Some files were not shown because too many files have changed in this diff Show More