React Component,Highstock:同步多个图表?

时间:2017-04-05 21:53:38

标签: reactjs highcharts

我正在与React和HighCharts合作。我对这两种技术都比较陌生。我需要生成两个同步的HighStock图表。我能够以下面的布局显示图表。

<div class=container>
<div class=chart1>new highcharts.StockChart(newChartOptions) </div>
<div class=chart2>new highcharts.StockChart(newChartOptions)</div>
</div> 

显示图表。我想同步图表以获得一个常见的工具提示,我看到http://www.highcharts.com/demo/synchronized-charts,不知道如何使用React实现。我试图将一个函数(handleEvent(e))分配给plotOptions:{line:{point:{event:{click:and MouseOver}}}}但它没有帮助。不知道如何调用handleEvent(e)方法。我不知道如何/何时调用handleEvent(e)。非常感谢任何帮助。

以下是组件代码:

import $ from 'jQuery';
import React from 'react';
import highcharts from 'highcharts-release/highstock';

export default class SynchronizedStatusChart extends React.Component {

    constructor (props) {
        super(props);
        this.state = {
            chartName: `chart${this.props.chartNum}`,
        };
    }

 handleEvent(e){

        let allCharts = highcharts.charts;
        console("SynchronizedStatusChart:handleEvent:ChartsLength = " + allCharts.length);
        var chart, point, i, event;


        for (i = 0; i < allCharts.length; i = i + 1)
        {
            chart = highcharts.charts[i];
            event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
            point = chart.series[0].searchPoint(event, true); // Get the hovered point
            if (point) {
                this.onMouseOver(); // Show the hover marker
                this.series.chart.tooltip.refresh(this); // Show the tooltip
                this.series.chart.xAxis[0].drawCrosshair(event, this);
            }
        }
    }


   componentDidMount () {

    }


    componentWillUpdate (nextProps) {
        for(let i=0; i<nextProps.data.length; i++){
           this.generateChart(nextProps.data[i],i+1,nextProps.titles[i]);
       }  
     }

    generateChart(data, i, title) {
        if(data == null)
        {
            data = [];
        }

        let ticksData = [0,1];
        let newChartOptions =
            {
                chart: {
                    //renderTo: document.getElementById(this.state.chartName),
                    renderTo: document.getElementById(`SyncChart${i}`),
                    height:'125'
                },
                rangeSelector: {
                    enabled: false
                },
                credits: {
                    enabled: false
                },
                navigator: {
                   enabled: false
                },
                scrollbar: {
                    enabled: false
                },
                tooltip: {
                    shared: true,
                    pointFormat: '<span style="color:{series.color}">{series.name}</span>: <b>{point.y:.2f}</b> <br/>'
                },
                xAxis:{

                },
                yAxis: {
                    offset: 15,
                    labels: {
                        align: 'center',
                        x: -3,
                        y: 6  
                    },
                    tickPositioner: function () {
                        var positions = ticksData;
                        return positions;
                    },
                    opposite:false,
                    showLastLabel: true,
                    title:{
                        text:title
                    }
                },
                series: [{
                    name: title,
                    type: this.props.status ? 'area' : 'line',
                    data: data,
                    showInNavigator: false

                }],
       };
        new highcharts.StockChart(newChartOptions);
    }


render () {

    return (
      <div className="med-chart col-md-9" id={this.state.chartName} style={this.props.chartStyle}> 
         <div id='SyncChart1'></div>
         <div id='SyncChart2'></div>
     </div>
    );
  }


}

1 个答案:

答案 0 :(得分:1)

我最近遇到了同样的问题。这对我有用。 我正在使用通用父组件为每个图表DOM元素添加'mousemove'和'mouseleave'的纯javascript事件监听器。

class ParentComponent extends Component {
  ...
  componentDidMount() {
    this.charts = document.querySelectorAll('.chart-container');
    [].forEach.call(this.charts, (chart) => {
      chart.addEventListener('mousemove', this.handleChartMouseMove);
      chart.addEventListener('mouseleave', this.handleChartMouseLeave);
    });
    Highcharts.Pointer.prototype.reset = () => undefined;
  }
  componentWillUnmount() {
    [].forEach.call(this.charts, (chart) => {
      chart.removeEventListener('mousemove', this.handleChartMouseMove);
      chart.removeEventListener('mousemove', this.handleChartMouseLeave);
    });
  }
  handleChartMouseMove = (e) => {
    const chartIndex = e.currentTarget.dataset.highchartsChart;
    const chart = Highcharts.charts[chartIndex];
    const event = chart.pointer.normalize(e);
    const pointIndex = chart.series[0].searchPoint(event, true).index;
    Highcharts.charts.forEach((chart) => {
      const xAxis = chart.xAxis[0];
      const point = chart.series[0].points[pointIndex];
      const points = chart.series.map(s => s.points[pointIndex]); // if more than one series
      point.onMouseOver();
      xAxis.drawCrosshair(event, point);
      // if more than one series, pass an array of points, took a me a long time to figure it out
      chart.tooltip.refresh(points, event);
    });
  };
  handleChartMouseLeave = () => {
    Highcharts.charts.forEach((chart) => {
      chart.tooltip.hide();
      chart.xAxis[0].hideCrosshair();
    });
  };
  ...
}