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

Angular中Chart.js嵌套数组实现可复用堆叠条形图报错排查

Angular 堆叠条形图组件报错排查

报错信息

开发基于@Input()传值的可复用ng2-charts堆叠条形图组件时,控制台抛出如下错误:

Error: Uncaught (in promise): TypeError: Cannot read property '0' of undefined
TypeError: Cannot read property '0' of undefined

复现代码

测试数据

barData = [[65, 59, 80, 81, 56, 55, 40], [28, 48, 40, 19, 86, 27, 90]];
barLabels = ["2006", "2007", "2008", "2009", "2010", "2011", "2012"];

原组件逻辑

@Input() barData!: (number | ScatterDataPoint | BubbleDataPoint)[][];
@Input() barLabels!: string[];

public barChartType: ChartType = "bar";
public barChartData: ChartConfiguration["data"];

defaultBarChartData: Partial<ChartConfiguration["data"]> = {
  labels: this.barLabels,
  datasets: [
    {
      data: this.barData[0],
      label: "Income",
      backgroundColor: "#3ABD32"
    },
    {
      data: this.barData[1],
      label: "Expense",
      backgroundColor: "#E02A45"
    },
  ],
};

ngOnInit(): void {
  if (
    this.barData !== undefined &&
    this.barLabels !== undefined &&
    Array.isArray(this.barData) &&
    this.barData.length > 0 &&
    Array.isArray(this.barLabels) &&
    this.barLabels.length > 0
  ) {
    this.barChartData = {
      ...this.defaultBarChartData,
      ...{ labels: this.barLabels },
    } as ChartConfiguration["data"];
    this.barChartData.datasets[0].data = this.barData[0];
  } else {
    throw new Error("Charts must have their data and labels inputs defined.");
  }
}
public barChartOptions: ChartConfiguration["options"] = {...}

原组件模板

<canvas
  baseChart
  [data]="barChartData"
  [options]="barChartOptions"
  [type]="barChartType">
</canvas>

错误根因

  • 类属性初始化时机错误:defaultBarChartData是类实例属性,在构造函数阶段就会执行初始化,此时@Input()装饰的属性还未完成绑定赋值,this.barData和this.barLabels均为undefined,直接读取this.barData[0]会触发类型错误,这是控制台报错的直接原因。
  • 数据集赋值不完整:ngOnInit中仅对第一个数据集datasets[0]的data做了重新赋值,第二个数据集datasets[1]的data始终是初始化阶段读取到的undefined值,会导致图表渲染异常。
  • 缺少堆叠配置:原代码未在图表配置中开启x、y轴的堆叠属性,即便数据加载正确也无法实现堆叠条形图效果。

修复方案

  1. 移除提前初始化的defaultBarChartData属性,所有图表数据组装逻辑放到ngOnInit生命周期中,待@Input()值完成绑定、且通过合法性校验后再构建完整的图表配置。
  2. 组装数据集时,同时给两个系列的data赋值,避免遗漏。
  3. 在图表options中开启x、y轴的stacked配置,实现堆叠效果。
  4. 如果父组件的barData、barLabels是异步接口返回的数据,需要在组件标签上加*ngIf判断数据存在后再渲染组件,避免初始传空值触发校验错误。

修复后的组件逻辑代码如下:

import { Component, Input, OnInit } from '@angular/core';
import { ChartConfiguration, ChartType } from 'chart.js';

@Component({
  selector: 'app-stacked-bar-chart',
  templateUrl: './stacked-bar-chart.component.html'
})
export class StackedBarChartComponent implements OnInit {
  @Input() barData!: (number | ScatterDataPoint | BubbleDataPoint)[][];
  @Input() barLabels!: string[];

  public barChartType: ChartType = "bar";
  public barChartData!: ChartConfiguration["data"];
  // 补全堆叠必要配置
  public barChartOptions: ChartConfiguration["options"] = {
    responsive: true,
    scales: {
      x: { stacked: true },
      y: { stacked: true }
    }
  };

  ngOnInit(): void {
    // 强化输入校验,要求barData至少包含2组数据
    if (
      !Array.isArray(this.barData) ||
      this.barData.length < 2 ||
      !Array.isArray(this.barLabels) ||
      this.barLabels.length === 0
    ) {
      throw new Error("Charts must have valid data and labels inputs, barData should contain at least 2 data groups.");
    }

    // Input值可用后再组装完整图表数据
    this.barChartData = {
      labels: this.barLabels,
      datasets: [
        {
          data: this.barData[0],
          label: "Income",
          backgroundColor: "#3ABD32"
        },
        {
          data: this.barData[1],
          label: "Expense",
          backgroundColor: "#E02A45"
        }
      ]
    };
  }
}

模板部分无需修改即可正常渲染堆叠条形图。


内容的提问来源于stack exchange,提问作者Macy Narancs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 09:27:32