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的方式是否存在问题。
核心问题分析
- 数据格式不匹配:Highcharts Sunburst要求
data是对象数组,每个对象必须包含id、name、parent、value字段,而当前返回的是包含四个独立数组的对象,格式完全不符合要求。 - 层级链不完整:没有添加顶层行业节点和子行业节点,Sunburst需要完整的层级结构,否则子节点无法关联到正确的父级。
- 父节点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
相关产品推荐
相关产品推荐

