Ittikorn S. Ittikorn S. - 4 months ago 24
jQuery Question

Highcharts showing nearest point causes flickering crosshair and strange order

According to my question a year ago Highchart tooltip show nearest point

Which show the nearest point in the tooltip when the two or more series doesn't have an equal length

However when you're moving mouse around the chart you can see that the order of series are switching around and crosshair are going back and fourth. I've recorded a quick video here

http://recordit.co/PxgJ8COnhF (on the video you won't notice the crosshair bug)

and here is example on jsfiddle https://jsfiddle.net/ittikorns/ygscLp3h/4/

Highcharts.wrap(Highcharts.Tooltip.prototype, 'refresh', function (proceed) {

var args = arguments,
points = args[1],
point = points[0];
if (typeof points[0] !== "undefined") {
chart = point.series.chart;
} else {
chart = points;
}

// Loop over all the series of the chart
Highcharts.each(chart.series, function(series) {
// This one already exist
if (series == point.series || series.visible==false) return;

var current,
dist,
distance = Number.MAX_VALUE;
// Loop over all the points
Highcharts.each(series.points, function(p) {
// use the distance in X to determine the closest point
dist = Math.abs(p.x - point.x);
if (dist < distance) {
distance = dist;
current = p;
}
});

// Add the closest point to the array
if(points.indexOf(current)==-1)
points.push(current);
});

proceed.apply(this, [].slice.call(args, 1));

});


$(function () {

$('#container').highcharts({

title: {
text: 'Monthly Average Temperature',
x: -20 //center
},
subtitle: {
text: 'Source: WorldClimate.com',
x: -20
},
xAxis: {
categories: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun',
'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
crosshair: true,
},
yAxis: {
title: {
text: 'Temperature (°C)'
},
plotLines: [{
value: 0,
width: 1,
color: '#808080'
}]
},
tooltip: {
valueSuffix: '°C',
shared: true,
},
legend: {
layout: 'vertical',
align: 'right',
verticalAlign: 'middle',
borderWidth: 0
},
series: [{
name: 'Tokyo',
data: [25.2, 26.5, 23.3, 18.3, 13.9, 9.6]
}, {
name: 'New York',
data: [-0.2, 0.8, 5.7, 11.3, 17.0, 22.0, 24.8, 24.1, 20.1, 14.1, 8.6, 2.5]
}]

});
});

Answer

I think that all depends on the order of points in your points array. Right now it is not always the same. You may add sorting method that will sort your points with an order of the series they belong to. Look at this code:

var compare = function (a, b) {
    if (a.series._i < b.series._i) {
      return -1
    } else if (a.series._i > b.series._i) {
      return 1
    }
    return 0
}

Here you can see an example how it can work: https://jsfiddle.net/ygscLp3h/5/

And here you can find the changes I have made:

points = points.sort(compare);
proceed.apply(this, [].slice.call(args, 1));

As you can see I have added sorting function before applying the standard function.

Best regards,