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

Angular中ApexCharts fill属性报TypeError: Cannot read 'length'问题

Angular中ApexCharts配置fill属性报错"TypeError: Cannot read properties of undefined (reading 'length')"的解决

问题概述

在Angular项目中使用ApexCharts时,配置fill属性的colors函数时抛出错误:TypeError: Cannot read properties of undefined (reading 'length'),但dataLabels使用完全相同的逻辑却能正常工作。打印opts.dataPointIndex仅输出0和1就触发报错,仿佛数组只有2个元素。

代码片段

HTML模板

<apx-chart
          class="chart"
          [series]="emodChartConfig.routingOverviewSeries"
          [chart]="emodChartConfig.routingOverviewChartOptions.chart"
          [stroke]="emodChartConfig.routingOverviewChartOptions.stroke"
          [tooltip]="emodChartConfig.routingOverviewChartOptions.tooltip"
          [fill]="emodChartConfig.routingOverviewChartOptions.fill"
          [legend]="emodChartConfig.routingOverviewChartOptions.legend"
          [xaxis]="emodChartConfig.overviewXAxis"
          [yaxis]="emodChartConfig.routingOverviewChartOptions.yaxis"
          [plotOptions]="emodChartConfig.routingOverviewChartOptions.plotOptions"
          [dataLabels]="emodChartConfig.routingOverviewChartOptions.dataLabels"
></apx-chart>

TypeScript代码

async loadOverviewData() {
    this.monthlyEMODService.getOverviewMonthlyEMOD().subscribe({
      next: (data) => {
        const categories = data.map((item) => IdToUn[item.departmentId]);
        const routingData = data.map((item) => item.emod);
        const totalData = data.map((item) => item.pureEMOD);
        const totalBudget = data.map((item) => item.totalBudget);
        const routingBudget = data.map((item) => item.routingBudget);

        this.routingOverviewSeries = [
          {
            name: 'EMOD',
            type: 'column',
            data: [...routingData],
          },
          {
            name: 'Objetivo',
            type: 'line',
            data: [...routingBudget],
          },
        ];

        this.routingOverviewChartOptions = {
          dataLabels: {
            enabled: true,
            enabledOnSeries: [0],
            style: {
              fontSize: '14px',
              fontWeight: 'bold',
              colors: [
                function (opts: any) {
                  const routingBudget = opts.w.config.series[1].data;
                  const routingData = opts.w.config.series[0].data;
                  
                  return routingData[opts.dataPointIndex] > routingBudget[opts.dataPointIndex] 
                    ? '#00FF00' 
                    : '#FF0000';
                },
              ],
            },
          },
          plotOptions: {
            bar: {
              distributed: true,
            },
          },
          fill: {
            colors: [function(opts:any) {
              const routingBudget = opts.w.config.series[1].data;
              const routingData = opts.w.config.series[0].data;
              
              return routingData[opts.dataPointIndex] > routingBudget[opts.dataPointIndex] 
                ? '#00FF00' 
                : '#FF0000';
            }]
          },
        };
      }
    });
}

接口返回数据示例

[
  {
    "departmentId": 1,
    "emod": 64.24,
    "pureEMOD": 59.59,
    "noCEDISEMOD": null,
    "noCEDISPureEMOD": null,
    "totalBudget": 82,
    "routingBudget": 70
  },
  {
    "departmentId": 2,
    "emod": 84.25,
    "pureEMOD": 73.05,
    "noCEDISEMOD": null,
    "noCEDISPureEMOD": null,
    "totalBudget": 82,
    "routingBudget": 86
  },
  {
    "departmentId": 3,
    "emod": 90.32,
    "pureEMOD": 79.77,
    "noCEDISEMOD": null,
    "noCEDISPureEMOD": null,
    "totalBudget": 85,
    "routingBudget": 87
  },
  {
    "departmentId": 4,
    "emod": 75.61,
    "pureEMOD": 67.6,
    "noCEDISEMOD": null,
    "noCEDISPureEMOD": null,
    "totalBudget": 82,
    "routingBudget": 87
  },
  {
    "departmentId": 5,
    "emod": 89.03,
    "pureEMOD": 81.18,
    "noCEDISEMOD": null,
    "noCEDISPureEMOD": null,
    "totalBudget": 82,
    "routingBudget": 85
  },
  {
    "departmentId": 6,
    "emod": 87.12,
    "pureEMOD": 70.93,
    "noCEDISEMOD": null,
    "noCEDISPureEMOD": null,
    "totalBudget": 82,
    "routingBudget": 82
  },
  {
    "departmentId": 7,
    "emod": 79.66,
    "pureEMOD": 70.91,
    "noCEDISEMOD": 91.23,
    "noCEDISPureEMOD": 70.91,
    "totalBudget": 82,
    "routingBudget": 82
  }
]

原因分析

  1. 系列数量不匹配:你的series数组包含2个系列(柱状图和折线图),但fill.colors数组只提供了1个颜色函数。当ApexCharts渲染第二个系列时,会尝试读取colors数组的第二个元素,由于该元素不存在,内部逻辑在访问其length属性时抛出错误。
  2. dataLabels正常的原因:dataLabels配置了enabledOnSeries: [0],仅对第一个系列生效,不会触发第二个系列的颜色函数逻辑,因此未出现报错。

ApexCharts Fill配置说明(翻译自官方文档)

  • colors:数组类型,用于设置每个系列的填充颜色。数组索引与系列索引一一对应,每个元素可以是颜色字符串或返回颜色值的函数。
  • 若某个系列未配置对应颜色,框架会尝试使用默认颜色;但当使用函数作为颜色值时,必须确保每个系列都有对应的函数或值,否则会触发未定义属性访问错误。

解决方案

方案一:补充对应系列的颜色配置

给fill.colors数组添加第二个元素,第二个系列可以设置默认颜色或相同逻辑:

fill: {
  colors: [
    function(opts:any) {
      const routingBudget = opts.w.config.series[1].data;
      const routingData = opts.w.config.series[0].data;
      
      return routingData[opts.dataPointIndex] > routingBudget[opts.dataPointIndex] 
        ? '#00FF00' 
        : '#FF0000';
    },
    '#888888' // 给第二个系列设置默认颜色
  ]
}

方案二:在系列对象中单独配置fill

直接在每个系列的定义中设置fill.color,仅给需要动态颜色的系列配置函数:

this.routingOverviewSeries = [
  {
    name: 'EMOD',
    type: 'column',
    data: [...routingData],
    fill: {
      color: function(opts:any) {
        const routingBudget = opts.w.config.series[1].data;
        const routingData = opts.w.config.series[0].data;
        
        return routingData[opts.dataPointIndex] > routingBudget[opts.dataPointIndex] 
          ? '#00FF00' 
          : '#FF0000';
      }
    }
  },
  {
    name: 'Objetivo',
    type: 'line',
    data: [...routingBudget],
    fill: {
      color: '#888888' // 折线图的填充颜色
    }
  },
];

方案三:使用seriesOverride指定特定系列

通过fill.seriesOverride配置仅针对第一个系列应用动态颜色:

fill: {
  seriesOverride: [
    {
      color: function(opts:any) {
        const routingBudget = opts.w.config.series[1].data;
        const routingData = opts.w.config.series[0].data;
        
        return routingData[opts.dataPointIndex] > routingBudget[opts.dataPointIndex] 
          ? '#00FF00' 
          : '#FF0000';
      }
    }
  ],
  colors: ['#888888'] // 第二个系列使用默认颜色
}

内容的提问来源于stack exchange,提问作者Fernando Hernandez

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 20:24:53