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

react-chartjs2点击图表最后一个柱状图时触发崩溃报错求助

React-ChartJS2 柱状图钻取点击最后一个柱子时崩溃问题

我用react-chartjs2 + ChartJS开发公司仪表盘,其中一个组件做了柱状图钻取功能:点击一级柱状图的柱子加载二级图表,点击二级图表的柱子加载三级表格。但点击一级图表的最后一个柱子(对应最后一个index和datasetIndex)时,应用直接崩溃,报错指向二级图表的数据加载环节,且仅在该场景下触发。

核心代码实现

currentLevel是React状态,用于控制当前钻取层级:

const handleFirstLevelClick = async (event, chartElement) => {
  try {
    await firstLevel(chartElement);
    let selectedApplication = getFirstLevelDatasets()[chartElement[0].datasetIndex].label;
    let selectedMonth = getFirstLevelLabels()[chartElement[0].index];

    if (widget[1].arrayList.filter((item) => item.job_number.includes(selectedApplication.substring(selectedApplication.lastIndexOf("#")+1)) && item.month === selectedMonth).length >0) {
      setCurrentLevel(2);
    } else {
      setCurrentLevel(1);
    }
  } catch (error) {
    console.log(error);
  }
}

const handleSecondLevelClick = async (event, chartElement) => {
  try {
    await secondLevel(chartElement);
    let selectedJob = getSecondLevelLabels()[chartElement[0].index];
    if (widget[2].arrayList.filter((item) => item.job_number.includes(selectedJob.substring(selectedJob.lastIndexOf("#")+1))).length >0) {
      setCurrentLevel(3);
    } else {
      setCurrentLevel(2);
    }
  } catch (error) {
    console.log(error);
  }
}

const firstLevel = async (chartElement) => {
  const { datasetIndex } = chartElement[0];
  let selectedApplication = getFirstLevelDatasets()[datasetIndex].label;
  let selectedMonth = getFirstLevelLabels()[chartElement[0].index];
  setSelectedApplication(selectedApplication);
  setSelectedMonth(selectedMonth);
}

const secondLevel = async (chartElement) => {
  const { index } = chartElement[0];
  let selectedJob = getSecondLevelLabels()[index];
  setSelectedJob(selectedJob);
}

const renderComponent = () => {
  switch (currentLevel) {
    case 1: 
      return <Bar data={dataFirstLevel} options={firstLevelChartOptions} />
    case 2:
      return <Bar data={dataSecondLevel} options={secondLevelChartOptions} />
    case 3:
      return <MailingStatusTable data={dataThirdLevel} />
  }
}

dataSecondLevel = {
  labels: getSecondLevelLabels(),
  datasets: [
    {
      label: 'Delivered Percent', 
      data: getSecondLevelDeliveredPercent(),
      backgroundColor: 'rgba(0, 255, 0, 0.2)',
      borderColor: 'rgba(0, 255, 0, 1)',
      borderWidth: 1,
    },
    // 其他数据集结构类似
  ]
}

const secondLevelChartOptions = {
  onClick: handleSecondLevelClick,
  // 其他图表配置项
}

图表渲染时会立即调用数据获取函数,点击事件触发后更新currentLevel状态,触发组件重新渲染加载对应层级内容。

排查与解决建议

  1. 给数据函数加边界兜底
    点击最后一个一级柱子时,selectedApplication或selectedMonth可能导致getSecondLevelLabels()/getSecondLevelDeliveredPercent()返回空数组或undefined,ChartJS渲染空数据会报错。给这些函数加兜底:

    const getSecondLevelLabels = () => {
      const rawLabels = /* 原逻辑 */;
      return rawLabels.length > 0 ? rawLabels : ['暂无数据'];
    }
    
  2. 点击事件加索引合法性校验
    在handleFirstLevelClick里先判断索引是否在有效范围内,避免越界访问:

    const handleFirstLevelClick = async (event, chartElement) => {
      try {
        if (!chartElement || chartElement.length === 0) return;
        const { datasetIndex, index } = chartElement[0];
        const datasets = getFirstLevelDatasets();
        const labels = getFirstLevelLabels();
        // 校验索引是否超出数组长度
        if (datasetIndex >= datasets.length || index >= labels.length) return;
        
        firstLevel(chartElement); // 去掉await,setState不返回Promise
        let selectedApplication = datasets[datasetIndex].label;
        let selectedMonth = labels[index];
        // 后续逻辑...
      } catch (error) {
        console.error('一级图表点击出错:', error);
      }
    }
    
  3. 二级图表渲染前做空数据判断
    在渲染二级图表前先检查数据有效性,避免渲染空图表:

    case 2:
      if (!dataSecondLevel?.labels || dataSecondLevel.labels.length === 0) {
        return <div>暂无二级数据</div>;
      }
      return <Bar data={dataSecondLevel} options={secondLevelChartOptions} />
    

有人遇到过类似问题吗?


内容的提问来源于stack exchange,提问作者Vinicius Bretzke Müller

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 11:04:54