Chart.js饼/环形图点击图例后如何计算可见扇区数值总和
需求说明
我正在使用Chart.js展示饼图及其图例,需要实现如下效果:当用户点击图例标签禁用/隐藏对应扇区时,重新计算饼图中所有剩余可见扇区的数值总和。
我已重写默认的Legend Click Handler,尝试在该处理函数中实现上述逻辑,虽不确定该位置是否为最佳实现点,但从逻辑层面判断该位置是合理的。
现有代码框架如下:
const defaultLegendClickHandler = Chart.defaults.plugins.legend.onClick; const pieDoughnutLegendClickHandler = Chart.controllers.doughnut.overrides.plugins.legend.onClick; const newLegendClickHandler = function (e, legendItem, legend) { const index = legendItem.datasetIndex; const type = legend.chart.config.type; if (type === 'pie' || type === 'doughnut') { pieDoughnutLegendClickHandler(e, legendItem, legend) } else { defaultLegendClickHandler(e, legendItem, legend); } let ci = legend.chart; // 待实现:遍历数据集内的可见值完成求和 };
目前不清楚如何遍历数据集内的可见值并完成求和,效果参考示例图:
实现方法
在自定义图例点击处理器中写求和逻辑是可行的:默认点击逻辑执行完成后,Chart.js已经同步更新了所有扇区的隐藏状态,直接调用内置API判断扇区可见性再累加数值即可。
补全后的完整代码:
const defaultLegendClickHandler = Chart.defaults.plugins.legend.onClick; const pieDoughnutLegendClickHandler = Chart.controllers.doughnut.overrides.plugins.legend.onClick; const newLegendClickHandler = function (e, legendItem, legend) { const index = legendItem.datasetIndex; const type = legend.chart.config.type; if (type === 'pie' || type === 'doughnut') { pieDoughnutLegendClickHandler(e, legendItem, legend) } else { defaultLegendClickHandler(e, legendItem, legend); } const chart = legend.chart; // 遍历所有数据集、所有数据点,累加可见项的数值 const visibleTotal = chart.data.datasets.reduce((sumTotal, dataset, datasetIdx) => { return sumTotal + dataset.data.reduce((sumPoint, value, pointIdx) => { // 调用Chart内置API判断当前扇区是否可见 const pointVisible = chart.getDataVisibility(pointIdx, datasetIdx); return sumPoint + (pointVisible ? Number(value) : 0); }, 0); }, 0); // 此处visibleTotal即为所有可见扇区的数值总和,可按需绑定到自定义DOM、或绘制到图表内部 console.log('可见扇区总和:', visibleTotal); }; // 初始化图表时绑定自定义图例点击事件 const pieChart = new Chart(document.getElementById('yourChartCtx'), { type: 'pie', data: {/* 你的图表数据源 */}, options: { plugins: { legend: { onClick: newLegendClickHandler } } } })
- 不要手动维护扇区隐藏状态,直接用
chart.getDataVisibility()获取的状态和框架内部完全同步,不会出现计算偏差 - 如果你用的是常规单数据集饼图,可以简化遍历逻辑,直接取
chart.data.datasets[0]遍历即可,不需要外层数据集循环 - 如果需要把总和展示在饼图中心,可以配合Chart.js的中心文字插件实现,每次求和完成后调用
chart.update()触发重绘即可
内容的提问来源于stack exchange,提问作者gisWeeper
相关产品推荐
相关产品推荐

