React ChartJS Donut Chart多层环对齐 实现子分组与内环楔形匹配问题

实现方案
1. 核心逻辑
要实现外层子分区和内层用户分区完全对齐,核心是同一用户的所有岗位数据总和,等于该用户在内层环的数值,ChartJS会自动按数值比例计算扇区角度,保证同一用户的外层子分区全部落在内层对应用户的楔形范围内。
2. 数据预处理
以工时统计场景为例,按要求拆分两层数据:
// 内层环:按用户维度聚合的总工时 const innerDataset = [ { label: '用户A', total: 40, color: '#ff6384' }, { label: '用户B', total: 60, color: '#ff9f40' } ] // 外层环:按用户-岗位维度拆分的工时,同一用户的子项总和必须等于内层对应用户的总工时 const outerDataset = [ // 用户A的岗位拆分,总和40 { label: '用户A-开发', hours: 15, color: '#9966ff' }, { label: '用户A-测试', hours: 15, color: '#36a2eb' }, { label: '用户A-运维', hours: 10, color: '#003f5c' }, // 用户B的岗位拆分,总和60 { label: '用户B-开发', hours: 30, color: '#4bc0c0' }, { label: '用户B-产品', hours: 20, color: '#ffcd56' }, { label: '用户B-设计', hours: 10, color: '#a3e635' } ]
3. React ChartJS 组件配置
使用react-chartjs-2的Doughnut组件,通过cutout和weight参数控制环的层级和宽度:
import { Doughnut } from 'react-chartjs-2'; import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'; ChartJS.register(ArcElement, Tooltip, Legend); const MultilayerDonut = () => { const chartData = { datasets: [ // 内层环配置 { data: innerDataset.map(item => item.total), backgroundColor: innerDataset.map(item => item.color), borderWidth: 0, cutout: '60%', // 控制空心大小,数值越大环越细 weight: 1 // 数值越小越靠内层 }, // 外层环配置 { data: outerDataset.map(item => item.hours), backgroundColor: outerDataset.map(item => item.color), borderWidth: 0, cutout: '75%', // 要大于内层的cutout值,刚好嵌套在内层外侧 weight: 1.5 } ] }; const options = { responsive: true, plugins: { legend: { position: 'right' } }, // 关闭点击偏移,防止扇区错位 interaction: { mode: 'index' } }; return <Doughnut data={chartData} options={options} />; }; export default MultilayerDonut;
4. 扩展多层环方案
如果需要更多层级的细分,只需要按照同样的规则新增数据集即可:上一层的每个分区数值,等于下一层对应分组的所有子项数值总和,同时依次增大cutout和weight参数即可。
内容的提问来源于stack exchange,提问作者Zaedonn
相关产品推荐
相关产品推荐

