简体   繁体   中英

Highcharts synchronize tooltip on multiple charts with multiple series

I am trying to synchronize shared tooltip across multiple charts, each having multiple series.

The problem is in the below example, the tooltip always shows the 3 series, even though at that particular point there are only two series present.

1) How do I make sure that a series is shown in tooltip only when it is actually present?

2) How do I make sure the tooltip is closed when we move out of the chart?

JSFiddle: https://jsfiddle.net/qoL7fx27/1/

Code for synchronization in fiddle:

$('#container').bind('mousemove touchmove touchstart', function (e) {
    var chart,
        point,
        i,
        event;

    for (i = 0; i < Highcharts.charts.length; i = i + 1) {
        chart = Highcharts.charts[i];
        var points = [];
        // Find coordinates within the chart
        event = chart.pointer.normalize(e.originalEvent);
        // Get the hovered point
        for(var j=0; j<chart.series.length; j++) {
           point = chart.series[j].searchPoint(event, true);
           points.push(point);  
        }

        chart.tooltip.refresh(points);

    }
});

1) How do I make sure that a series is shown in tooltip only when it is actually present?

The unwanted behavior is caused by searchPoint function - it returns the nearest point even though the x position doesn't mach with other points. So if the series has only one point it'll be always found.

Solution:

Manually select points to display in tooltip.formatter :

        formatter: function() {
          var outputString = '';

          this.points.forEach(function(point) {
            if (point.x === this.x) {
              outputString += "<span style='color:" + point.color + "'>\u25CF</span> " + point.series.name + ": <b>" + point.y + "</b><br/>";
            }
          }, this);
          return outputString;
        }

API reference: https://api.highcharts.com/highcharts/tooltip.formatter


2) How do I make sure the tooltip is closed when we move out of the chart?

Restore the default Highcharts.Pointer.prototype.reset function by removing these lines:

 Highcharts.Pointer.prototype.reset = function() { return undefined; }; 


Demo for both questions: https://jsfiddle.net/BlackLabel/2mxxrk5n/


Update:

I posted the wrong answer for the second question. This code hides tooltips:

$('#container').bind('mouseout', function(e) {
  Highcharts.charts.forEach(function(chart) {
    chart.tooltip.hide();
    // undo point highlight
    chart.series.forEach(function(series) {
        series.points.forEach((point) => point.setState(''));
    });
  });
});

can you please tell me how to highlight the corresponding points in each chart? As of now, the tooltip shows correctly, however the points are not highlighted in three charts

This piece of highlights points:

points.forEach(function(point_) {
  if (point_) {
    point_.highlight(e);
  }
}, this);

To achieve the desired behavior you must provide a logic for filtering points that should be Highlighted. Here's a very simplified example adjusted to this particular case:

// provide a logic for filtering points
if(points[0] && points[1].x > 0) {
    points.pop(); // remove the unwanted point
}

Here is my solution. It's perfectly working for me. I made adjustments based on Synchronisation of multiple charts

Demo here

影响

The following code shows/hides the tooltip and makes sure they are aligned on mousemove and mouseleave .

Note that I found that I only need to find the first point searched and use it to show/hide the tooltip. It's because all my time series share the same x values.

$("#container").bind("mousemove mouseleave", function(e) {
  for (let i = 0; i < Highcharts.charts.length; ++i) {
    let hart = Highcharts.charts[i];
    let event = chart.pointer.normalize(e.originalEvent); // Find coordinates within the chart
    let point;
    for (let j = 0; j < chart.series.length && !point; ++j) {
      point = chart.series[j].searchPoint(event, true);
    }
    if (!point) return;

    if (e.type === "mousemove") {
       point.onMouseOver();
      chart.xAxis[0].drawCrosshair(event, point); // Show the crosshair
    } else {
      point.onMouseOut();
      chart.tooltip.hide(point);
      chart.xAxis[0].hideCrosshair();
    }

  }
});

Keep reseting the reset function so as to disallow HighCharts resetting the points -- we take over the control.

Highcharts.Pointer.prototype.reset = function() {
  return undefined;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM