处理监听图表的函数,确保及时移除&生产环境不打印log
This commit is contained in:
@@ -1,4 +1,5 @@
|
|||||||
# 生产环境配置
|
# 生产环境配置
|
||||||
|
NODE_ENV = production
|
||||||
ENV = 'production'
|
ENV = 'production'
|
||||||
|
|
||||||
# 页面标题
|
# 页面标题
|
||||||
|
|||||||
@@ -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().
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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() {
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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();
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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
Reference in New Issue
Block a user