i working react , highcharts. relatively new both these technologies. need generate 2 synchronized highstock charts. able display charts below layout.
<div class=container> <div class=chart1>new highcharts.stockchart(newchartoptions) </div> <div class=chart2>new highcharts.stockchart(newchartoptions)</div> </div>
the charts displayed. want synchronize charts have common tool tip, see http://www.highcharts.com/demo/synchronized-charts , not sure how implement react. have tried assign function(handleevent(e)) plotoptions:{line:{ point:{ event:{click: , mouseover}}}} did not help. not sure how invoke handleevent(e) method. not sure how/when invoke handleevent(e). appreciated.
below component code:
import $ 'jquery'; import react 'react'; import highcharts '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; (i = 0; < allcharts.length; = + 1) { chart = highcharts.charts[i]; event = chart.pointer.normalize(e.originalevent); // find coordinates within chart point = chart.series[0].searchpoint(event, true); // hovered point if (point) { this.onmouseover(); // show hover marker this.series.chart.tooltip.refresh(this); // show 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> ); } }
i had same problem recently. here's has worked me. using common parent component add pure javascript event listeners 'mousemove' , 'mouseleave' each chart dom element.
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 1 series point.onmouseover(); xaxis.drawcrosshair(event, point); // if more 1 series, pass array of points, took me long time figure out chart.tooltip.refresh(points, event); }); }; handlechartmouseleave = () => { highcharts.charts.foreach((chart) => { chart.tooltip.hide(); chart.xaxis[0].hidecrosshair(); }); }; ... }
Comments
Post a Comment