在 React 中刷新数据后动态更新 highcharts 对象

Dynamically updating a highcharts object after data refresh in React

我正在尝试使用 Highcharts 网络图构建员工组织结构图,但我 运行 出错了。这个想法很简单。我想与总统和他们的一些直接下属一起绘制初始图表。之后,如果用户单击图表中的一个节点,我想为该个人的直接下属提取数据并使用该个人下属的子节点更新图表。数据拉取的后端 API 工作正常

这是我的代码:

import React, { useState, useEffect, useRef } from 'react';
import axios from 'axios';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';

import networkgraph from "highcharts/modules/networkgraph";
networkgraph(Highcharts);

const Employees3 = () => {

    const chartComponent = useRef(null); // reference to chart obj 
    const [nodeData, setNodeData] = useState([
        { 'id': 'A', dataLabels: { enabled: true }, marker: { radius: 11, fillColor: 'red' } },
        { 'id': 'P', dataLabels: { enabled: true } },
        { 'id': 'K', dataLabels: { enabled: true } },
        { 'id': 'S', dataLabels: { enabled: true } },
        { 'id': 'D', dataLabels: { enabled: true } },
    ]);

    const [linkData, setLinkData] = useState([
        { 'from': 'D', 'to': 'A' },
        { 'from': 'S', 'to': 'A' },
        { 'from': 'K', 'to': 'A' },
        { 'from': 'P', 'to': 'A' }
    ]);


    const [chartOptions, setChartOptions] = useState({
        chart: {
            type: 'networkgraph',
            plotBorderWidth: 1,
        },
        title: {
            text: 'Phrasal verbs'
        },
        subtitle: {
            text: 'Integration: ' + 'euler'
        },
        credits: false,
        plotOptions: {
            networkgraph: {
                layoutAlgorithm: {
                    enableSimulation: false,
                    integration: 'euler',
                    linkLength: 25,
                },
                keys: ['from', 'to'],
                marker: {
                    radius: 5,
                    lineWidth: 1
                }
            },
            series: {
                point: {
                    events: {
                        click: function () {
                            var name = this.id.replace(' ', '%20');
                            axios.get('api/employee_data/' + name)
                                .then(response => { 
                                    setNodeData(nodeData.concat(response.data.nodes));
                                    setLinkData(linkData.concat(response.data.links));
                                     chartComponent.current.chart.redraw();
                                }).catch( err => {
                                })
                            },
                    }
                }
            }
        },
        series: [{
            allowPointSelect: true,
            nodes: nodeData,
            data: linkData,
        }]
    });

    console.log('nodes: ', nodeData)
    console.log('links: ', linkData)
    
    return (
        <div>
            <HighchartsReact
                highcharts={Highcharts}
                options={chartOptions}
                containerProps={{ style: { height: 700 } }}
                allowChartUpdate = {true}
                ref={chartComponent}
            />
        </div>
    )
};

export default Employees3;

我在 series.event.click 对象上使用一个函数来呈现 GET 调用以从服务器拉出子节点和链接并更新我的 nodeData 和 linkData 状态。当我对这些状态数组进行控制台日志时,它向我显示了正确的数据。然后,我尝试使用图表引用上的重绘方法使用更新后的数据重新呈现图表对象。问题是图表没有使用这种方法重新呈现新数据。相反,它会继续显示旧数据。

关于我在这里可能做错了什么以及如何在数据更新后重新呈现图表有什么想法吗?

非常感谢

编辑 (2-6-21)

axios.get('api/employee_data/' + name)
    .then(response => {

        setNodeData((prevState) => {
            return [...prevState, ...response.data.nodes]
        });
        setLinkData((prevState) => {
            return [...prevState, ...response.data.links]
        });

        setChartOptions({
            series: [{
                nodes: nodeData, //doesnt work
                data: linkData //doesnt work
                nodes: response.data.nodes,  // works but doesn't give me what I need
                data: response.data.links,
            }]
        });
    });

您需要更新与图表组件选项道具直接相关的状态:

    plotOptions: {
        ...,
        series: {
            point: {
                events: {
                    click: function () {
                        var name = this.id.replace(' ', '%20');
                        axios.get('api/employee_data/' + name)
                            .then(response => { 
                                setChartOptions({
                                    series: [{
                                        nodes: response.data.nodes,
                                        data: response.data.links
                                    }]
                                });
                            }).catch( err => {})
                        }
                }
            }
        }
    }

现场演示: https://codesandbox.io/s/highcharts-react-demo-ngq7w?file=/demo.jsx