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

react-chartjs-2嵌套环形图渲染异常及标签显示问题求助

解决react-chartjs-2嵌套环形图的渲染与标签问题

我来帮你搞定这个嵌套环形图的问题,核心要解决两个关键问题:环形图重叠/仅显示一个和tooltip/数据标签显示undefined,下面一步步来处理:

1. 修复嵌套环形图的显示问题

你的代码里没给两个环形数据集设置区分内外环的参数,导致它们默认重叠(或者tooltip报错引发渲染异常)。需要给每个dataset添加cutout属性(chart.js v3+版本,旧版用cutoutPercentage)来定义环形空心大小,形成嵌套效果:

修改data中的datasets:

const data = {
  datasets: [
    {
      data: [1, 2, 3],
      pointLabels: ["category1", "category2", "category3"], // 改成自定义字段,避免和全局labels混淆
      backgroundColor: ["#79CAF2", "#80DEEA", "#A5D6A7"],
      hoverBackgroundColor: ["#31B2F2", "#00BCD4", "#4CAF50"],
      cutout: '70%' // 内环,空心占70%
    },
    {
      data: [1, 2, 3, 4, 5],
      pointLabels: ["sub1", "sub2", "sub3", "sub4", "sub5"],
      backgroundColor: ["#79CAF2", "#80DEEA", "#A5D6A7", "#C5E1A5", "#FFF59D"],
      hoverBackgroundColor: ["#31B2F2", "#00BCD4", "#4CAF50", "#8BC34A", "#FFEB3B"],
      cutout: '30%' // 外环,空心占30%
    },
  ]
};

2. 修复Tooltip标签显示问题

你之前的tooltip回调直接取dataset.labels[index],但chart.js的dataset默认没有labels字段,而且两个数据集的data长度不同(3 vs 5),当hover到外环第4/5个数据时,index会超出内环标签数组长度,导致报错进而影响图表渲染。

修改options中的tooltips回调,增加边界判断,同时使用自定义的pointLabels字段:

const options = {
  tooltips: {
    callbacks: {
      label: function(tooltipItem, data) {
        const dataset = data.datasets[tooltipItem.datasetIndex];
        const index = tooltipItem.index;
        // 先判断pointLabels是否存在且index有效
        if (dataset.pointLabels && index < dataset.pointLabels.length) {
          return `${dataset.pointLabels[index]}: ${dataset.data[index]}`;
        }
        // 兜底返回数据值
        return `${dataset.data[index]}`;
      },
    }
  }
}

3. 修复图表上的数据标签显示undefined问题

如果是要在环形图上直接显示数据标签(不是tooltip),react-chartjs-2本身不自带这个功能,需要安装chartjs-plugin-datalabels插件:

首先安装插件:

npm install chartjs-plugin-datalabels --save
# 或者 yarn add chartjs-plugin-datalabels

然后在组件中引入并注册插件:

import { Doughnut } from 'react-chartjs-2';
import { Chart } from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels';

// 注册插件(chart.js v3+用法)
Chart.register(ChartDataLabels);

接着在options中配置数据标签:

const options = {
  // ... 其他配置
  plugins: {
    datalabels: {
      formatter: function(value, context) {
        // 从自定义的pointLabels中获取标签
        return context.dataset.pointLabels[context.dataIndex];
      },
      color: '#333', // 标签颜色
      font: {
        weight: 'bold'
      }
    }
  },
  tooltips: {
    // ... 之前的tooltip配置
  }
}

完整的render函数示例

整合所有修改后,你的render函数应该是这样的:

import React from 'react';
import { Doughnut } from 'react-chartjs-2';
import { Chart } from 'chart.js';
import ChartDataLabels from 'chartjs-plugin-datalabels';

Chart.register(ChartDataLabels);

class NestedDoughnut extends React.Component {
  render() {
    const data = {
      datasets: [
        {
          data: [1, 2, 3],
          pointLabels: ["category1", "category2", "category3"],
          backgroundColor: ["#79CAF2", "#80DEEA", "#A5D6A7"],
          hoverBackgroundColor: ["#31B2F2", "#00BCD4", "#4CAF50"],
          cutout: '70%'
        },
        {
          data: [1, 2, 3, 4, 5],
          pointLabels: ["sub1", "sub2", "sub3", "sub4", "sub5"],
          backgroundColor: ["#79CAF2", "#80DEEA", "#A5D6A7", "#C5E1A5", "#FFF59D"],
          hoverBackgroundColor: ["#31B2F2", "#00BCD4", "#4CAF50", "#8BC34A", "#FFEB3B"],
          cutout: '30%'
        },
      ]
    };

    const options = {
      plugins: {
        datalabels: {
          formatter: (value, context) => context.dataset.pointLabels[context.dataIndex],
          color: '#333',
          font: { weight: 'bold' }
        }
      },
      tooltips: {
        callbacks: {
          label: (tooltipItem, data) => {
            const dataset = data.datasets[tooltipItem.datasetIndex];
            const index = tooltipItem.index;
            if (dataset.pointLabels && index < dataset.pointLabels.length) {
              return `${dataset.pointLabels[index]}: ${dataset.data[index]}`;
            }
            return `${dataset.data[index]}`;
          }
        }
      }
    };

    return (
      <div className="h100per_200pix w100per margin_top_50">
        <Doughnut data={data} options={options} ref="chart" />
      </div>
    );
  }
}

export default NestedDoughnut;

这样修改后,两个嵌套环形图应该能正常显示,tooltip和图表上的数据标签也能正确展示内容了。

内容的提问来源于stack exchange,提问作者D.R

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:15:47