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

如何通过导航栏按钮控制React ECharts旭日图的节点导航?

解决方案

你的代码存在几个关键问题导致按钮无法触发旭日图的节点切换,以下是修正后的实现步骤:

1. 修正按钮点击事件写法

当前onClick直接调用eventsMap会导致组件渲染时就执行函数,而非点击按钮时触发,需要用箭头函数包裹:

<button onClick={() => eventsMap("Flora_1")}>Flora 1</button>
<button onClick={() => eventsMap("Flora_2")}>Flora 2</button>
<button onClick={() => eventsMap("Flora_3")}>Flora 3</button>

2. 正确使用旭日图的dispatchAction动作

旭日图的节点导航(钻取)需要使用sunburstExpand动作,而非select。同时要修正代码里的拼写错误chilNode→childNode,并通过节点名称指定目标节点:

const eventsMap = (targetNodeName) => {
  const chartInstance = chartRef.current.getEchartsInstance();
  // 触发旭日图展开到指定节点
  chartInstance.dispatchAction({
    type: 'sunburstExpand',
    seriesIndex: 0, // 旭日图系列默认索引为0
    name: targetNodeName // 要切换到的节点名称
  });
};

3. 额外优化:节点存在性校验

添加简单校验避免无效节点名称导致的错误:

const eventsMap = (targetNodeName) => {
  const chartInstance = chartRef.current?.getEchartsInstance();
  if (!chartInstance) return;
  
  // 递归校验节点是否存在
  const checkNodeExist = (nodes) => {
    for (let node of nodes) {
      if (node.name === targetNodeName) return true;
      if (node.children && checkNodeExist(node.children)) return true;
    }
    return false;
  };

  if (checkNodeExist(data)) {
    chartInstance.dispatchAction({
      type: 'sunburstExpand',
      seriesIndex: 0,
      name: targetNodeName
    });
  } else {
    console.warn(`节点 ${targetNodeName} 不存在`);
  }
};

完整修正后的组件代码

import React, { useState, useEffect, useRef } from "react";
import PropTypes from "prop-types";
import ReactECharts from "echarts-for-react";
import * as echarts from "echarts";

const SunburstChart = ({ data }) => {
  const chartRef = useRef(null);
  const [options, setOptions] = useState({});

  useEffect(() => {
    setOptions(getOptions());
  }, [data]);

  const getOptions = () => {
    const getChildren = (children) => {
      return children.map((child) => ({
        ...child,
        itemStyle: {
          color: child.color || "#ddd",
          borderWidth: 2,
        },
        children: child.children ? getChildren(child.children) : undefined,
      }));
    };

    return {
      visualMap: {
        type: 'continuous',
        min: 0,
        max: 10,
        left: 'left',
        calculable: false,
        orient: 'vertical',
        inRange: {
          color: ['#2F93C8', '#AEC48F', '#FFDB5C', '#F98862']
        }
      },
      series: {
        radius: ["0%", "95%"],
        type: "sunburst",
        sort: undefined,
        data: getChildren(data),
        label: {
          rotate: "radial",
        },
        levels: [],
        itemStyle: {
          color: "#ddd",
          borderWidth: 2,
        },
      },
    };
  };

  const eventsMap = (targetNodeName) => {
    const chartInstance = chartRef.current?.getEchartsInstance();
    if (!chartInstance) return;

    const checkNodeExist = (nodes) => {
      for (let node of nodes) {
        if (node.name === targetNodeName) return true;
        if (node.children && checkNodeExist(node.children)) return true;
      }
      return false;
    };

    if (checkNodeExist(data)) {
      chartInstance.dispatchAction({
        type: 'sunburstExpand',
        seriesIndex: 0,
        name: targetNodeName
      });
    } else {
      console.warn(`节点 ${targetNodeName} 不存在`);
    }
  };

  return (
    <div>
      <ReactECharts
        ref={chartRef}
        echarts={echarts}
        option={options}
        style={{ height: "500px", width: "100%" }}
      />
      <button onClick={() => eventsMap("Flora_1")}>Flora 1</button>
      <button onClick={() => eventsMap("Flora_2")}>Flora 2</button>
      <button onClick={() => eventsMap("Flora_3")}>Flora 3</button>
    </div>
  );
};

SunburstChart.propTypes = {
  data: PropTypes.array.isRequired,
};

export default SunburstChart;

说明:

  • sunburstExpand动作会将指定节点设为旭日图的中心节点,实现导航切换效果;若需返回根节点,可添加按钮调用sunburstCollapse动作,指定根节点名称即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.30 06:12:32