vue-chart-3/Chart.js堆叠柱状图失效问题求助
堆叠柱状图配置失效问题排查与解决
问题说明
使用vue-chart-3结合Chart.js制作堆叠柱状图,预期实现堆叠效果,但实际生成的柱状图为并列排列。已尝试设置stacked: true但未生效,相关数据及代码如下:
现有chartData示例
{"labels": ["2020-10","2020-11","2023-04","2023-05","2023-06","2023-07"],"datasets": [{"label": "above_120","data": [0,0,0,0,7.9597462909733085,10.92147729254032,12.128219538943902,13.092781081826708,16.982628499580606,17.622395653806972,36.51382339697158,45.423623102032764,58.474440088803384],"backgroundColor": "#1E5662","stack": "stackabove_120"},{"label": "up_to_120","data": [0,0,15.875881135502462,3.165108353314404],"backgroundColor": "#3E300D","stack": "stackup_to_120"},{"label": "up_to_90","data": [0,0,0,0,0,6.197500821665821,8.2908889492772],"backgroundColor": "#DBD383","stack": "stackup_to_90"},{"label": "up_to_60","data": [0,0,0,0,0,0,1.5561216578540855,0,0,0,0,0,0,3.376176540913938],"backgroundColor": "#0A35AC","stack": "stackup_to_60"},{"label": "up_to_30","data": [0,0,11.186721091033386,0,0,1.7895529268699548,0,0,0,0,0.06295971365877787],"backgroundColor": "#AE95B3","stack": "stackup_to_15"}]}
未生效的配置
const chartOptions = ref( { scales: { yAxes: [{ticks: {beginAtZero: true},stacked: true}], xAxes: [{stacked: true,}] } } );
问题根源
- Chart.js版本适配错误:Chart.js v3+版本已废弃
xAxes、yAxes数组格式,改为直接使用x、y对象配置坐标轴 - Stack属性不统一:每个数据集的
stack属性值都不同,Chart.js会将不同stack值的数据集视为独立分组,无法堆叠
修复方案
1. 修正坐标轴配置
将chartOptions中的scales结构改为Chart.js v3+支持的格式:
const chartOptions = ref({ scales: { y: { ticks: { beginAtZero: true }, stacked: true }, x: { stacked: true } } });
2. 统一数据集的Stack属性
所有需要堆叠的数据集必须使用相同的stack名称,比如统一设为"total":
在handleChartData函数中,修改dataset的stack赋值:
datasets.push({ label: key, data: dataArrays[key], backgroundColor: randomColor(), stack: "total" // 统一stack名称 });
完整修复后的组件代码
<template> <div> <BarChart :chartData="barChartData" :chartOptions="chartOptions" /> </div> </template> <script setup lang="ts"> import { ref } from 'vue'; import { BarChart } from "vue-chart-3"; import { Chart, registerables, ChartData } from "chart.js"; Chart.register(...registerables); interface DataObject { label: string; data: { above_120: number; up_to_120: number; up_to_90: number; up_to_60: number; up_to_30: number; up_to_15: number; }; } const props = defineProps({ data: { type: Array, required: true } }); const barChartData = ref<ChartData>({ labels: [], datasets: [] }); handleChartData(); // 修正后的chartOptions const chartOptions = ref({ scales: { y: { ticks: { beginAtZero: true }, stacked: true }, x: { stacked: true } } }); function handleChartData() { const chartData: Array<DataObject> = props.data; if (chartData) { const labels: Array<string> = []; const datasets: Array<any> = []; const legendKeys = Object.keys(chartData[0].data); const dataArrays: { [key: string]: Array<number> } = {}; for (const key of legendKeys) { dataArrays[key] = []; } for (const dataObj of chartData) { labels.push(dataObj.label); for (const [key, value] of Object.entries(dataObj.data)) { dataArrays[key].push(value); } } for (const key of legendKeys) { datasets.push({ label: key, data: dataArrays[key], backgroundColor: randomColor(), stack: "total" // 统一stack名称 }); } barChartData.value = { labels: labels, datasets: datasets }; } } function randomColor() { const letters = '0123456789ABCDEF'; let color = '#'; for (let i = 0; i < 6; i++) { color += letters[Math.floor(Math.random() * 16)]; } return color; } </script>
内容的提问来源于stack exchange,提问作者Kali
相关产品推荐
相关产品推荐

