我正在与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>
);
}
}
答案 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();
});
};
...
}