ChartJS分组堆叠条形图渲染异常问题求助
问题诊断与解决
核心问题1:Y轴堆叠配置错误
你当前设置了scales.y.stacked: true,但在**横向条形图(indexAxis: "y")**场景下,Y轴是类别轴,不需要开启堆叠。开启Y轴堆叠会导致不同堆叠组的内容在Y方向重叠,虽然数值总和正确,但视觉上只会显示最上层的项目,tooltip也无法正确识别所有数据集。
核心问题2:数据集Label重复
可计费(billable)和不可计费(nonBillable)的数据集使用了相同的projectName作为label,ChartJS会将同名label的数据集视为同一系列,导致tooltip只显示其中一项,即使堆叠高度是多个项目的总和。
修改后的代码
1. 修正数据集Label(添加不可计费标识)
修改createDataSets中nonBillable数据集的label:
function createDataSets() { const billable: { [projectId: string]: { projectName: string; data: number[] } } = {}; const nonBillable: { [projectId: string]: { projectName: string; data: number[] } } = {}; for (const [overviewIndex, overview] of props.userOverviews.entries()) { for (const [projectId, projectOverview] of Object.entries(overview.timeWorkedPerProject)) { const projectName = props.getProjectData(projectId).name; // Billable Dataset if (!billable[projectId]) { billable[projectId] = { projectName, data: Array<number>(props.userOverviews.length).fill(0) }; } billable[projectId].data[overviewIndex] = projectOverview.billableMins; // Non-Billable Dataset if (!nonBillable[projectId]) { nonBillable[projectId] = { projectName, data: Array<number>(props.userOverviews.length).fill(0) }; } nonBillable[projectId].data[overviewIndex] = projectOverview.nonBillableMins; } } return [ ...Object.values(billable).map(({ projectName, data }) => ({ data, label: projectName, stack: "billable", })), // 给不可计费数据集添加唯一标识,避免与可计费系列重名 ...Object.values(nonBillable).map(({ projectName, data }) => ({ data, label: `${projectName} (不可计费)`, stack: "non_billable", backgroundColor: "#cccccc" // 可选:设置灰色背景区分不可计费组 })), ]; }
2. 修正Y轴堆叠配置
修改Bar组件的options:
<Bar height={400} options={{ maintainAspectRatio: false, responsive: true, plugins: { legend: { display: false, }, }, scales: { x: { stacked: true, // 横向条形图仅需X轴开启堆叠,实现同一类别内的分组堆叠 beginAtZero: true, }, y: { stacked: false, // 关闭Y轴堆叠,避免不同类别内容重叠 type: "category", position: "right" }, }, indexAxis: "y", }} data={{ labels: props.userOverviews.map((overview) => overview.fullUserName), // 修正重复拼接用户名的问题 datasets: createDataSets(), }} />
额外优化
注意到你在labels中重复拼接了两次fullUserName,这会导致用户名重复显示,建议改为直接使用overview.fullUserName。
内容的提问来源于stack exchange,提问作者Bram Vanbilsen
相关产品推荐
相关产品推荐

