尝试在ReactJS中制作主细节图



我正在尝试复制这个例子:https://www.highcharts.com/demo/dynamic-master-detail但使用React(+Hooks(
我的问题是细节图表,因为我已经让master工作了,我知道细节图表将由回调生成(我仍然不太擅长回调概念(

在Highcharts文档中,我可以在chart.events.load中创建回调函数,这是我决定在masterChart中执行的操作
然而,我在createDetails函数(回调函数(中得到一个错误,说

undefined is not an object (evaluating 'masterChart.series[0]')

这很奇怪,因为我在创建masterChart时也做了同样的事情,而且它成功了,所以我认为问题不可能是我的RData对象。

这是我现在的代码:

import React, {useEffect,useState} from 'react';
import Highcharts from 'highcharts';
import HighchartsReact from 'highcharts-react-official';
import RData from '../data/RData'
const RChart = () =>  {
    const[masterChart,setMasterChart] = useState([]);
    const[detailChart,setDetailChart] = useState([]);
    //updating masterChart
    useEffect(()=>{
        setMasterChart({
            chart: {
                reflow: false,
                borderWidth: 0,
                backgroundColor: "#ffffff",
                marginLeft: 50,
                marginRight: 20,
                zoomType: 'x',
                events: {
                    // listen to the selection event on the master chart to update the
                    // extremes of the detail chart
                    selection: function (event) {
                        var extremesObject = event.xAxis[0],
                            min = extremesObject.min,
                            max = extremesObject.max,
                            detailData = [],
                            xAxis = this.xAxis[0];
                        // reverse engineer the last part of the data
                        RData.each(this.series[0].RData, function () {
                            if (this.x > min && this.x < max) {
                                detailData.push([this.x, this.y]);
                            }
                        });
                        // move the plot bands to reflect the new detail span
                        xAxis.removePlotBand('mask-before');
                        xAxis.addPlotBand({
                            id: 'mask-before',
                            from: RData[0][0],
                            to: min,
                            color: 'rgba(0, 0, 0, 0.2)'
                        });
                        xAxis.removePlotBand('mask-after');
                        xAxis.addPlotBand({
                            id: 'mask-after',
                            from: max,
                            to: RData[RData.length - 1][0],
                            color: 'rgba(255, 255, 0, 0.2)'
                        });

                        detailChart.series[0].setData(detailData);
                        return false;
                    },
                    load:createDetail(masterChart) //callback!!
                }
            },
            title: {
                text: null
            },
            accessibility: {
                enabled: false
            },
            xAxis: {
                type: 'datetime',
                showLastTickLabel: true,
                maxZoom: 14 * 24 * 3600000, // fourteen days
                plotBands: [{
                    id: 'mask-before',
                    from: RData[0][0],
                    to: RData[RData.length - 1][0],
                    color: 'rgba(0, 0, 0, 0.2)'
                }],
                title: {
                    text: null
                }
            },
            yAxis: {
                gridLineWidth: 0,
                labels: {
                    enabled: false
                },
                title: {
                    text: null
                },
                min: 0.6,
                showFirstLabel: false
            },
            tooltip: {
                formatter: function () {
                    return false;
                }
            },
            legend: {
                enabled: false
            },
            credits: {
                enabled: false
            },
            plotOptions: {
                series: {
                    fillColor: {
                        linearGradient: [0, 0, 0, 255],
                        stops: [
                            [0, Highcharts.getOptions().colors[0]],
                            [1, 'rgba(0,255,255,0)']
                        ]
                    },
                    lineWidth: 1,
                    marker: {
                        enabled: false
                    },
                    shadow: false,
                    states: {
                        hover: {
                            lineWidth: 1
                        }
                    },
                    enableMouseTracking: false
                }
            },
            series: [{
                type: 'area',
                name: 'USD to EUR',
                pointInterval: 24 * 3600 * 1000,
                pointStart: RData[0][0],
                data: RData
            }],
            exporting: {
                enabled: false
            }
        })
    },[]);
    //callback function to create detail chart
    const createDetail = (masterChart) => {
        // prepare the detail chart
        var detailData = [],
        detailStart = RData[0][0];
        //Error here
        RData.each(masterChart.series[0].RData, function () {
            if (this.x >= detailStart) {
                detailData.push(this.y);
            }
        });
        setDetailChart({
            chart: {
                marginBottom: 120,
                reflow: false,
                marginLeft: 50,
                marginRight: 20,
                style: {
                    position: 'absolute'
                }
            },
            credits: {
                enabled: false
            },
            title: {
                text: 'Historical USD to EUR Exchange Rate',
                align: 'left'
            },
            subtitle: {
                text: 'Select an area by dragging across the lower chart',
                align: 'left'
            },
            xAxis: {
                type: 'datetime'
            },
            yAxis: {
                title: {
                    text: null
                },
                maxZoom: 0.1
            },
            tooltip: {
                formatter: function () {
                    var point = this.points[0];
                    return '<b>' + point.series.name + '</b><br/>' + Highcharts.dateFormat('%A %B %e %Y', this.x) + ':<br/>' +
                        '1 USD = ' + Highcharts.numberFormat(point.y, 2) + ' EUR';
                },
                shared: true
            },
            legend: {
                enabled: false
            },
            plotOptions: {
                series: {
                    marker: {
                        enabled: false,
                        states: {
                            hover: {
                                enabled: true,
                                radius: 3
                            }
                        }
                    }
                }
            },
            series: [{
                name: 'USD to EUR',
                pointStart: detailStart,
                pointInterval: 24 * 3600 * 1000,
                data: detailData
            }],
            exporting: {
                enabled: false
            }
        });
    }

    return(
        <React.Fragment>
            <HighchartsReact highcharts={Highcharts} options={masterChart} />
            <HighchartsReact highcharts={Highcharts} options={detailChart} />
        </React.Fragment>
    );
} 
export default RChart;

我愿意接受任何批评和更好的方法。

(已编辑(尝试在空数组中添加setMasterChart和setDetailChart作为效果挂钩的第二个参数。只是个主意。

我认为更好的方法是将Hooks选项设置到一个功能组件中,并将它们作为道具传递到将渲染每个图表的函数中。

演示:https://stackblitz.com/edit/react-lwkgkv?file=index.js

相关内容

  • 没有找到相关文章

最新更新