You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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,}]
  }
} );

问题根源

  1. Chart.js版本适配错误:Chart.js v3+版本已废弃xAxes、yAxes数组格式,改为直接使用x、y对象配置坐标轴
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.14 21:56:01