2017-04-05 79 views
1

我正在使用React和HighCharts。我对这两种技术都比较陌生。我需要生成两个同步的HighStock图表。我能够用下面的布局显示图表。React Component,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实施。我试图给plotOptions分配一个函数(handleEvent(e)):{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> 
    ); 
    } 


} 
+0

您是否定义了图表组件?如果是这样,请将代码粘贴到此处。 – morganfree

+0

是的,我有一个图表组件。 –

+0

@morganfree,我用组件代码更新了原文。 –

回答

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(); 
    }); 
    }; 
    ... 
}