WholeProcessPlatform/frontend/src/modules/yunXingGaoJIng/Aisbdbyx/composables/usePieChart.ts

120 lines
2.7 KiB
TypeScript
Raw Normal View History

2026-07-06 08:54:58 +08:00
import * as echarts from 'echarts';
import type { ECharts, EChartsOption } from 'echarts';
export interface ChartDataItem {
name: string;
value: number;
key: string;
}
export function usePieChart(
chartRefs: Map<string, HTMLElement>,
chartData: { value: ChartDataItem[] },
tabIndex: { value: string },
typeMap: Record<string, string>,
legendCallback?: (e: any) => void
) {
let chartInstance: ECharts | null = null;
const initChart = (retryCount = 0) => {
const dom = chartRefs.get(tabIndex.value);
if (!dom) {
if (retryCount < 10) {
setTimeout(() => initChart(retryCount + 1), 100);
}
return;
}
const rect = dom.getBoundingClientRect();
if (rect.width === 0 || rect.height === 0) {
if (retryCount < 10) {
setTimeout(() => initChart(retryCount + 1), 100);
}
return;
}
if (!chartInstance) {
chartInstance = echarts.init(dom);
}
const option: EChartsOption = {
tooltip: {
trigger: 'item',
formatter: (params: any) => `${params.marker} ${params.name}: ${params.value}(次)`
},
legend: {
orient: 'vertical',
right: 10,
top: 80,
textStyle: { fontSize: 12 }
},
series: []
};
if (!chartData.value || chartData.value.length === 0) {
chartInstance.setOption(option, true);
return;
}
const total = chartData.value.reduce((acc: number, item: ChartDataItem) => acc + (item.value || 0), 0);
const titleText = typeMap[tabIndex.value] || '识别(次)';
option.series = [
{
type: 'pie',
radius: ['26%', '35%'],
center: ['35%', '50%'],
avoidLabelOverlap: false,
label: {
show: true,
formatter: '{c}'
},
labelLine: {
show: true,
length: 12,
length2: 12
},
data: chartData.value.map((item: ChartDataItem) => ({
name: item.name,
value: item.value
}))
}
];
option.title = {
text: String(total),
left: '34%',
top: '44%',
textAlign: 'center',
textStyle: {
fontSize: 24,
fontWeight: 'bold',
color: '#333'
},
subtext: titleText,
subtextStyle: {
fontSize: 12,
color: '#333'
}
};
chartInstance.setOption(option, true);
if (legendCallback) {
chartInstance.off('legendselectchanged');
chartInstance.on('legendselectchanged', legendCallback);
}
};
const dispose = () => {
chartInstance?.dispose();
chartInstance = null;
};
const resize = () => {
chartInstance?.resize();
};
return { initChart, dispose, resize };
}