Vue中ECharts饼图单非零值选中隐藏标签后零值项显示异常问题
ECharts饼图零值项异常显示问题解决
问题场景
使用ECharts绘制饼图时,当数据为[0, 0, 0, 0, 1](仅E为非零值),选中图例项E隐藏后,饼图错误显示所有零值项各占1/4的区域,不符合预期。需要实现:选中E后,零值项完全不显示,且E的图例标签显示为0%。
原核心代码:
import * as echarts from 'echarts'; type EChartsOption = echarts.EChartsOption; var chartDom = document.getElementById('main')!; var myChart = echarts.init(chartDom); var option: EChartsOption; const values = [0, 0, 0, 0, 1]; const names = ['A', 'B', 'C', 'D', 'E']; const initialValues = values.map((v, i) => ({ name: names[i], value: v })); option = { tooltip: { trigger: 'item', formatter: '{a} <br/>{b} : {c} ({d}%)' }, legend: { bottom: 10, left: 'center', data: names }, series: [ { type: 'pie', radius: '65%', center: ['50%', '50%'], selectedMode: 'single', data: initialValues, emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ] }; option && myChart.setOption(option);
解决方案
通过动态过滤零值数据、自定义图例格式化和监听图例点击事件来实现需求,修改后的完整代码如下(适配Vue3 + TypeScript环境):
import * as echarts from 'echarts'; import { onMounted, ref } from 'vue'; type EChartsOption = echarts.EChartsOption; export default { setup() { const chartRef = ref<HTMLElement | null>(null); let myChart: echarts.ECharts | null = null; const values = [0, 0, 0, 0, 1]; const names = ['A', 'B', 'C', 'D', 'E']; // 记录图例选中状态,默认全选 const selectedStatus = ref<Record<string, boolean>>({ A: true, B: true, C: true, D: true, E: true }); // 根据选中状态生成要渲染的饼图数据 const getRenderData = () => { const validData = values.map((v, i) => ({ name: names[i], value: selectedStatus.value[names[i]] ? v : 0 })); const total = validData.reduce((sum, item) => sum + item.value, 0); // 总和为0时(如E被隐藏),返回空数组,饼图自动隐藏零值项 return total === 0 ? [] : validData.filter(item => item.value > 0); }; // 自定义图例显示文本,未选中项显示0% const legendFormatter = (name: string) => { const value = values[names.indexOf(name)]; const total = values.reduce((sum, v) => sum + v, 0); const percentage = selectedStatus.value[name] ? total > 0 ? ((value / total) * 100).toFixed(1) : 0 : 0; return `${name} ${percentage}%`; }; const initChart = () => { if (!chartRef.value) return; myChart = echarts.init(chartRef.value); const option: EChartsOption = { tooltip: { trigger: 'item', formatter: (params: any) => { const percentage = selectedStatus.value[params.name] ? params.percent : 0; return `饼图<br/>${params.name} : ${params.value} (${percentage}%)`; } }, legend: { bottom: 10, left: 'center', data: names, formatter: legendFormatter, selected: selectedStatus.value, selectedMode: 'single', // 监听图例点击,更新状态后重新渲染 onClick: (name) => { selectedStatus.value[name] = !selectedStatus.value[name]; myChart?.setOption({ series: [{ data: getRenderData() }], legend: { formatter: legendFormatter, selected: selectedStatus.value } }); } }, series: [ { type: 'pie', radius: '65%', center: ['50%', '50%'], data: getRenderData(), emphasis: { itemStyle: { shadowBlur: 10, shadowOffsetX: 0, shadowColor: 'rgba(0, 0, 0, 0.5)' } } } ] }; myChart.setOption(option); }; onMounted(() => { initChart(); window.addEventListener('resize', () => myChart?.resize()); }); return { chartRef }; } };
关键逻辑说明
getRenderData:根据图例选中状态过滤数据,当总和为0时返回空数组,饼图将不渲染任何区域,避免零值项被错误分配占比。legendFormatter:强制显示所有图例项,未选中的项直接显示0%,选中项根据总数据计算真实占比。- 图例点击监听:切换选中状态后立即更新图表数据和图例文本,保证显示状态同步。
内容的提问来源于stack exchange,提问作者matheus1714
相关产品推荐
相关产品推荐

