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

React项目中Highcharts Sunburst图表无法渲染API数据问题排查

Highcharts Sunburst图表空白问题排查与修复

问题描述

我正在开发一个React项目,使用Highcharts渲染Sunburst图表,需要可视化从API获取的数据,但图表无法渲染且控制台无报错,怀疑问题出在数据转换为Highcharts适配格式的过程中。

组件代码如下:

import React from "react";
import Highcharts from "highcharts";
import HighchartsReact from "highcharts-react-official";
import sunburst from "highcharts/modules/sunburst";
import { useQuery } from "@tanstack/react-query";

function extractData(data) {
  const ids = [];
  const labels = [];
  const parents = [];
  const values = [];

  function traverse(element, parentId) {
    if (element.children) {
      element.children.forEach((child) => {
        if (child.Código && child["Sub-Setor"]) {
          ids.push(child.Código);
          labels.push(child["Sub-Setor"]);
          parents.push(parentId);
          values.push(child["Part. (%)"]);
        }
        if (child.children) {
          traverse(child, child.name);
        }
      });
    }
  }

  data.forEach((sector) => {
    if (sector.children) {
      sector.children.forEach((subSector) => {
        traverse(subSector, sector.name);
      });
    }
  });

  return { ids, labels, parents, values };
}

function fetchData() {
  return fetch("http://rar.xxx.xxx/api/indices/data/IBOV").then((res) =>
    res.json()
  );
}

// Inicializa o módulo Sunburst
sunburst(Highcharts);

function SunburstChart({ data }) {
  const { data: indices, isLoading, error } = useQuery(["sunburst"], fetchData);

  if (isLoading) {
    return <p>Carregando...</p>;
  }

  if (error) {
    return <p>Ocorreu um erro: {error.message}</p>;
  }

  const extratedData = extractData(indices);
  console.log(extratedData);

  // Configura as opções do gráfico
  const options = {
    series: [
      {
        type: "sunburst",
        data: extratedData,
        allowDrillToNode: true,
        cursor: "pointer",
        dataLabels: {
          format: "{point.name}",
        },
      },
    ],
    title: {
      text: "Meu Gráfico Sunburst",
    },
  };

  return <HighchartsReact highcharts={Highcharts} options={options} />;
}

export default SunburstChart;

extractData函数用于将API数据转换为Highcharts适配格式,但图表仍为空白。转换后的数据结构如下:

Object
ids: ["EMBR3", "AZUL4", "CCRO3", "GOLL4", "RAIL3", "BRFS3", "JBSS3", "MRFG3", "BEEF3", "SMTO3", …] (85)
labels: ["Mat Transporte", "Transporte", "Transporte", "Transporte", "Transporte", "Alimentos Processados", "Alimentos Processados", "Alimentos Processados", "Alimentos Processados", "Alimentos Processados", …] (85)
parents: ["Bens Indls", "Bens Indls", "Bens Indls", "Bens Indls", "Bens Indls", "Consumo Não-Cíclico", "Consumo Não-Cíclico", "Consumo Não-Cíclico", "Consumo Não-Cíclico", "Consumo Não-Cíclico", …] (85)
values: [0.667, 0.261, 0.591, 0.082, 1.305, 1.092, 1.127, 0.11, 0.084, 0.224, …] (85)

期望Sunburst图表能展示行业、子行业、代码及其对应数值,但图表容器始终空白,无任何错误提示,需要排查extractData函数或数据传递给Highcharts的方式是否存在问题。

核心问题分析

  1. 数据格式不匹配:Highcharts Sunburst要求data是对象数组,每个对象必须包含id、name、parent、value字段,而当前返回的是包含四个独立数组的对象,格式完全不符合要求。
  2. 层级链不完整:没有添加顶层行业节点和子行业节点,Sunburst需要完整的层级结构,否则子节点无法关联到正确的父级。
  3. 父节点ID传递错误:递归遍历中传递的parentId逻辑错误,导致节点层级关联混乱。

修复方案

1. 修正extractData函数

重构函数生成符合要求的对象数组,并补全完整层级:

function extractData(data) {
  const sunburstData = [];

  // 遍历顶层行业,添加行业节点
  data.forEach(sector => {
    // 添加顶层行业节点
    sunburstData.push({
      id: sector.name,
      name: sector.name,
      parent: null,
      value: 0
    });

    if (sector.children) {
      sector.children.forEach(subSector => {
        // 生成子行业唯一ID,避免重复
        const subSectorId = `${sector.name}-${subSector["Sub-Setor"]}`;
        // 添加子行业节点
        sunburstData.push({
          id: subSectorId,
          name: subSector["Sub-Setor"],
          parent: sector.name,
          value: 0
        });

        // 遍历子行业下的公司节点
        function traverseCompanies(node, parentId) {
          // 存在代码和占比数据时添加节点
          if (node.Código && node["Part. (%)"]) {
            sunburstData.push({
              id: node.Código,
              name: node.Código,
              parent: parentId,
              value: node["Part. (%)"]
            });
          }
          // 递归处理更深层级的子节点
          if (node.children) {
            node.children.forEach(child => {
              traverseCompanies(child, parentId);
            });
          }
        }

        traverseCompanies(subSector, subSectorId);
      });
    }
  });

  return sunburstData;
}

2. 修正图表配置的数据传递

确保series.data使用修正后的数组:

const options = {
  series: [
    {
      type: "sunburst",
      data: extratedData, // 现在是符合要求的对象数组
      allowDrillToNode: true,
      cursor: "pointer",
      dataLabels: {
        format: "{point.name}",
      },
    },
  ],
  title: {
    text: "Meu Gráfico Sunburst",
  },
};

额外说明

  • 顶层节点和子行业节点的value设为0时,Highcharts会自动根据子节点的数值计算其占比,无需手动求和。
  • 确保sector.name、subSector["Sub-Setor"]、node.Código都是唯一值,避免节点ID冲突导致层级关联错误。

内容的提问来源于stack exchange,提问作者Rafael Rodrigues

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:57:33