Pauli
Pauli

Reputation: 41

How to synchronise shared tooltip and crosshair in highcharts?

I have a couple of charts, some with a single series, others with multiple series. I show shared tooltips for charts with multiple series. I show a vertical crosshair on each chart.

Now I would like to synchronise the charts. Moving the mouse in one chart should show the described features (crosshair and toolip) on the correct place in all charts, with updated data.

As you can see in fiddle, this does not work completely. The x position is synchronised correctly. Tooltips are updated. But mouseover on the second chart shows a tooltip in the first chart with only one y value instead of two. [Edit: I've found a way to update crosshairs; but it does not not work in every chart, when I set

tooltip: { shared: true,

maybe there is a better solution?]

https://jsfiddle.net/hbaed859/1/

let highlightFunction = function (point) {
Highcharts.charts.forEach(chart => {
  chart.series.forEach(s => {
    if (point.series.name != s.name) {
      s.points.forEach(p => {
        if (p.index === point.index) {
          p.setState('hover')
          p.series.chart.tooltip.refresh(p)
          // shows tooltip, but ignores "shared: true"       
         chart.xAxis[0].drawCrosshair(null, p);
      ...
 

chart = Highcharts.chart('chart1', {
 series: [{
  point: {
    events: {
      mouseOver(e) {
        let point = this;
        highlightFunction(point)
      }
    ...

[edit] ... and the method is nice for small datasets, for large one it needs too long to recalculute the crossjair positions for all the charts.

Upvotes: 0

Views: 695

Answers (1)

ppotaczek
ppotaczek

Reputation: 39079

You are really close to achieve the wanted result. Use the hideCrosshair method for crosshair visibility and add points from all chart's series to the tooltip.refresh method call. Optimized code below:

function setHighlightState() {
  const point = this;

  Highcharts.charts.forEach(chart => {
    if (point.series.chart !== chart) {
      const matchedPoints = [];

      chart.series.forEach(s => {
        const matchedPoint = s.points[point.index];
        matchedPoints.push(matchedPoint);
        matchedPoint.setState('hover');
      });

      chart.tooltip.refresh(matchedPoints)
      chart.xAxis[0].drawCrosshair(null, matchedPoints[0]);
    }
  });
}

function hideHighlightState() {
  const point = this;

  Highcharts.charts.forEach(chart => {
    if (point.series.chart !== chart) {
      chart.series.forEach(s => {
        s.points[point.index].setState('');
      });

      chart.tooltip.hide();
      chart.xAxis[0].hideCrosshair();
    }
  });
}

Live demo: https://jsfiddle.net/BlackLabel/nwj3co0a/

API Reference: https://api.highcharts.com/class-reference/Highcharts.Axis#hideCrosshair

Upvotes: 0

Related Questions