新增页面
This commit is contained in:
288
src/views/home/unitPriceAnalysisComponents/pieChart.vue
Normal file
288
src/views/home/unitPriceAnalysisComponents/pieChart.vue
Normal file
@@ -0,0 +1,288 @@
|
||||
<template>
|
||||
<!-- 动态绑定 ref:使用 props 中的 chartRef,而非硬编码 -->
|
||||
<div :ref="chartRef" id="coreLineChart" style="height: 100%; width: 100%;"></div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import * as echarts from 'echarts';
|
||||
|
||||
export default {
|
||||
name: 'Container',
|
||||
props: {
|
||||
// 1. 重命名 props:ref → chartRef,避免关键字冲突,同时定义类型和默认值
|
||||
chartRef: {
|
||||
type: String,
|
||||
required: true, // 强制父组件传值,避免获取不到 DOM
|
||||
default: () =>'pieChartRef' // 默认空数组,避免报错
|
||||
|
||||
// validator: (value) => {
|
||||
// // 验证:ref 名不能为空,确保有效
|
||||
// return value.trim() !== '';
|
||||
// }
|
||||
},
|
||||
pieData: {
|
||||
type: Object,
|
||||
default: () => { } // 默认空数组,避免报错
|
||||
},
|
||||
},
|
||||
data() {
|
||||
return {};
|
||||
},
|
||||
computed: {},
|
||||
watch: {
|
||||
// 监听 pieData 变化,只要数据变了,就更新图表
|
||||
pieData: {
|
||||
handler() {
|
||||
this.initData(); // 直接调用更新,无需判断 myChart 是否存在
|
||||
},
|
||||
deep: true,
|
||||
immediate: true // 初始化时立即执行
|
||||
},
|
||||
},
|
||||
mounted() {
|
||||
this.$nextTick(() => {
|
||||
this.initData(); // 只负责初始化图表实例
|
||||
});
|
||||
},
|
||||
methods: {
|
||||
initData() {
|
||||
console.log(this.pieData,'this.pieData.value');
|
||||
|
||||
const chartDom = this.$refs[this.chartRef];
|
||||
if (!chartDom) {
|
||||
console.error(`图表容器未找到!请确认父组件传递的 chartRef 为 "${this.chartRef}"`);
|
||||
return;
|
||||
}
|
||||
const myChart = echarts.init(chartDom);
|
||||
|
||||
// 自定义颜色数组(与系列一一对应)
|
||||
const customColors = [
|
||||
'rgba(113, 100, 255, 1)',
|
||||
'rgba(40, 138, 255, 1)',
|
||||
'rgba(118, 218, 190, 1)',
|
||||
'rgba(255, 206, 106, 1)',
|
||||
];
|
||||
|
||||
const option = {
|
||||
// 标题配置(主标题+副标题)
|
||||
title: [
|
||||
{
|
||||
text: '客户销量分析',
|
||||
left: 'center',
|
||||
top: '35%',
|
||||
textStyle: {
|
||||
fontSize: 18,
|
||||
letterSpacing: 5,
|
||||
color: 'rgba(0, 0, 0, 0.55)',
|
||||
fontFamily: 'PingFangSC, PingFang SC'
|
||||
}
|
||||
},
|
||||
{
|
||||
text: '单位:万m²',
|
||||
left: 'center',
|
||||
top: '50%',
|
||||
textStyle: {
|
||||
fontSize: 16,
|
||||
color: 'rgba(0, 0, 0, 0.55)',
|
||||
fontFamily: 'PingFangSC, PingFang SC'
|
||||
}
|
||||
}
|
||||
],
|
||||
series: [
|
||||
{
|
||||
name: '销量',
|
||||
type: 'pie',
|
||||
radius: ['60%', '80%'],
|
||||
center: ['50%', '50%'],
|
||||
avoidLabelOverlap: false,
|
||||
label: {
|
||||
show: true,
|
||||
position: 'outside',
|
||||
distance: 10,
|
||||
formatter: '{c}万m²\n{b}',
|
||||
textStyle: {
|
||||
fontSize: 14,
|
||||
color: 'rgba(0, 0, 0, 0.7)',
|
||||
fontFamily: 'PingFangSC, PingFang SC',
|
||||
lineHeight: 1.5
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
show: true,
|
||||
length: 0,
|
||||
length2: 10,
|
||||
lineStyle: {
|
||||
color: (params) => customColors[params.dataIndex]
|
||||
}
|
||||
},
|
||||
itemStyle: {
|
||||
color: (params) => customColors[params.dataIndex]
|
||||
},
|
||||
data: [
|
||||
{
|
||||
value: this.pieData?.value || 0, name: '单镀面板',
|
||||
label: {
|
||||
normal: {
|
||||
align: 'left',
|
||||
distanceToLabelLine: 2,
|
||||
formatter: (params) => [
|
||||
`{b|${params.value.toLocaleString()}}`,
|
||||
`{hr|■}{c|${params.name}}`
|
||||
].join('\n'),
|
||||
rich: {
|
||||
hr: {
|
||||
color: 'rgba(39, 96, 255, 1)',
|
||||
fontSize: 20,
|
||||
padding: [26, 8, 0, 0]
|
||||
},
|
||||
b: {
|
||||
color: 'rgba(0, 0, 0, 0.75)',
|
||||
fontSize: 18,
|
||||
padding: [0, 0, 0, 0]
|
||||
},
|
||||
c: {
|
||||
color: 'rgba(64, 64, 64, 1)',
|
||||
fontSize: 14,
|
||||
padding: [30, 0, 0, -5]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
lineStyle: { color: 'rgba(39, 96, 255, 1)' },
|
||||
length: 10,
|
||||
length2: 20,
|
||||
},
|
||||
itemStyle: { color: 'rgba(39, 96, 255, 1)' }
|
||||
},
|
||||
{
|
||||
value: 735, name: '双镀面板',
|
||||
label: {
|
||||
normal: {
|
||||
align: 'left',
|
||||
distanceToLabelLine: 2,
|
||||
formatter: (params) => [
|
||||
`{b|${params.value.toLocaleString()}}`,
|
||||
`{hr|■}{c|${params.name}}`
|
||||
].join('\n'),
|
||||
rich: {
|
||||
hr: {
|
||||
color: 'rgba(40, 138, 255, 1)',
|
||||
fontSize: 20,
|
||||
padding: [6, 8, 0, 10]
|
||||
},
|
||||
b: {
|
||||
color: 'rgba(0, 0, 0, 0.75)',
|
||||
fontSize: 18,
|
||||
padding: [-30, 0, 0, 30]
|
||||
},
|
||||
c: {
|
||||
color: 'rgba(64, 64, 64, 1)',
|
||||
fontSize: 14,
|
||||
padding: [10, 0, 0, -5]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
length: 0,
|
||||
length2: 10,
|
||||
lineStyle: { color: 'rgba(40, 138, 255, 1)' },
|
||||
},
|
||||
itemStyle: { color: 'rgba(40, 138, 255, 1)' }
|
||||
},
|
||||
{
|
||||
value: 580, name: '丝印打孔',
|
||||
label: {
|
||||
normal: {
|
||||
align: 'left',
|
||||
distanceToLabelLine: 2,
|
||||
formatter: (params) => [
|
||||
`{b|${params.value.toLocaleString()}}`,
|
||||
`{hr|■}{c|${params.name}}`
|
||||
].join('\n'),
|
||||
rich: {
|
||||
hr: {
|
||||
color: 'rgba(118, 218, 190, 1)',
|
||||
fontSize: 20,
|
||||
padding: [36, 5, 0, 0]
|
||||
},
|
||||
b: {
|
||||
color: 'rgba(0, 0, 0, 0.75)',
|
||||
fontSize: 18,
|
||||
padding: [0, 10, 0, 0]
|
||||
},
|
||||
c: {
|
||||
color: 'rgba(64, 64, 64, 1)',
|
||||
fontSize: 14,
|
||||
padding: [40, -5, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
lineStyle: { color: 'rgba(118, 218, 190, 1)' },
|
||||
length: 0,
|
||||
length2: 10,
|
||||
},
|
||||
itemStyle: { color: 'rgba(118, 218, 190, 1)' }
|
||||
},
|
||||
{
|
||||
value: 484, name: '无印打孔',
|
||||
label: {
|
||||
normal: {
|
||||
align: 'left',
|
||||
distanceToLabelLine: 2,
|
||||
formatter: (params) => [
|
||||
`{b|${params.value.toLocaleString()}}`,
|
||||
`{hr|■}{c|${params.name}}`
|
||||
].join('\n'),
|
||||
rich: {
|
||||
hr: {
|
||||
color: 'rgba(255, 206, 106, 1)',
|
||||
fontSize: 20,
|
||||
padding: [36, 5, 0, 0]
|
||||
},
|
||||
b: {
|
||||
color: 'rgba(0, 0, 0, 0.75)',
|
||||
fontSize: 18,
|
||||
padding: [0, 20, 0, 0]
|
||||
},
|
||||
c: {
|
||||
color: 'rgba(64, 64, 64, 1)',
|
||||
fontSize: 14,
|
||||
padding: [40, 15, 0, 0]
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
labelLine: {
|
||||
lineStyle: { color: 'rgba(255, 206, 106, 1)' },
|
||||
length: 10,
|
||||
length2: 10,
|
||||
},
|
||||
itemStyle: { color: 'rgba(255, 206, 106, 1)' }
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
option && myChart.setOption(option);
|
||||
|
||||
// 窗口缩放监听
|
||||
window.addEventListener('resize', () => {
|
||||
myChart.resize();
|
||||
});
|
||||
|
||||
// 组件销毁清理
|
||||
this.$once('hook:destroyed', () => {
|
||||
window.removeEventListener('resize', () => {
|
||||
myChart.resize();
|
||||
});
|
||||
myChart.dispose();
|
||||
});
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
Reference in New Issue
Block a user