Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions draftlogs/8079_fix.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Pick the trace drawn last on a hover tie in `scattergl` and `splom` (matching `scatter`) [[#8079](https://github.com/plotly/plotly.js/pull/8079)]
8 changes: 5 additions & 3 deletions src/traces/scattergl/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ function hoverPoints(pointData, xval, yval, hovermode) {
) ? 0 : Infinity;
}

if(dx < minDist) {
// Accept a tie so that the point drawn last wins, as in `Fx.getClosest`
if(dx <= minDist) {
minDist = dx;
pty = y[k];
dy = ya.c2p(pty) - ypx;
Expand All @@ -84,15 +85,16 @@ function hoverPoints(pointData, xval, yval, hovermode) {
}
}
} else {
for(i = ids.length - 1; i > -1; i--) {
for(i = 0; i < ids.length; i++) {
k = ids[i];
ptx = x[k];
pty = y[k];
dx = xa.c2p(ptx) - xpx;
dy = ya.c2p(pty) - ypx;

dist = Math.sqrt(dx * dx + dy * dy);
if(dist < minDist) {
// Accept a tie so that the trace drawn last wins, as in `Fx.getClosest`
if(dist <= minDist) {
minDist = dxy = dist;
closestId = k;
}
Expand Down
3 changes: 2 additions & 1 deletion src/traces/splom/hover.js
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,8 @@ function _hoverPoints(pointData, xval, yval, axisHoversubplots) {
var dy = ya.c2p(pty) - ypx;
var dist = Math.sqrt(dx * dx + dy * dy);

if(axisHoversubplots || dist < minDist) {
// Accept a tie so that the point drawn last wins, as in `Fx.getClosest`
if(axisHoversubplots || dist <= minDist) {
minDist = dxy = dist;
id = i;
}
Expand Down
52 changes: 45 additions & 7 deletions test/jasmine/tests/hover_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -3281,28 +3281,28 @@ describe('splom hover *axis* hoversubplots splom points on same position should
assertFirstPointOn(gd, 'x', 'y');
expect(gd._hoverdata.length).toBe(4);
assertHoverLabelContent({
nums: ['1', '1', '1', '1'],
nums: ['1', '4', '4', '4'],
name: ['', '', '', ''],
axis: '1'
});

Lib.clearThrottle();
Plotly.Fx.hover(gd, {}, 'xy2');
assertFirstPointOn(gd, 'x', 'y2');
expect(gd._hoverdata.length).toBe(3);
expect(gd._hoverdata.length).toBe(4);
assertHoverLabelContent({
nums: ['1', '2', '2'],
name: ['', '', ''],
nums: ['1', '3', '3', '3'],
name: ['', '', '', ''],
axis: '1'
});

Lib.clearThrottle();
Plotly.Fx.hover(gd, {}, 'xy3');
assertFirstPointOn(gd, 'x', 'y3');
expect(gd._hoverdata.length).toBe(3);
expect(gd._hoverdata.length).toBe(4);
assertHoverLabelContent({
nums: ['1', '2', '2'],
name: ['', '', ''],
nums: ['1', '3', '3', '3'],
name: ['', '', '', ''],
axis: '1'
});

Expand Down Expand Up @@ -5617,6 +5617,44 @@ describe('hover working with zorder', function () {
});
});

describe('hover on points at the same position', () => {
afterEach(destroyGraphDiv);

['scatter', 'scattergl', 'splom'].forEach((type) => {
const makeTrace = (x, y) =>
type === 'splom' ? { type, dimensions: [{ values: x }, { values: y }] } : { type, x, y };
// splom plots dimension 0 against dimension 1 on subplot xy2
const subplot = type === 'splom' ? 'xy2' : 'xy';

it(`picks the trace drawn last for ${type} in closest hovermode`, async () => {
const gd = createGraphDiv();
await Plotly.newPlot(gd, {
data: [makeTrace([0, 1, 2], [1, 0, 1]), makeTrace([0, 1, 2], [2, 0, 2])],
layout: { width: 400, height: 400, hovermode: 'closest' }
});

Fx.hover(gd, { xval: 1, yval: 0 }, subplot);

expect(gd._hoverdata.length).toEqual(1);
expect(gd._hoverdata[0].curveNumber).toEqual(1);
expect(gd._hoverdata[0].pointNumber).toEqual(1);
});

it(`picks the point drawn last for ${type} in x hovermode`, async () => {
const gd = createGraphDiv();
await Plotly.newPlot(gd, {
data: [makeTrace([0, 1, 1, 2], [1, 0, 0, 1])],
layout: { width: 400, height: 400, hovermode: 'x' }
});

Fx.hover(gd, { xval: 1, yval: 0 }, subplot);

expect(gd._hoverdata.length).toEqual(1);
expect(gd._hoverdata[0].pointNumber).toEqual(2);
});
});
});

describe('hover label rotation:', function () {
var gd;

Expand Down
2 changes: 1 addition & 1 deletion test/jasmine/tests/select_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -677,7 +677,7 @@ describe('Click-to-select', function() {
[
testCase('scatterpolargl', require('../../image/mocks/glpolar_scatter.json'), 130, 290,
[[], [], [], [19], [], []], { dragmode: 'zoom' }),
testCase('splom', require('../../image/mocks/splom_lower.json'), 427, 400, [[], [7], []])
testCase('splom', require('../../image/mocks/splom_lower.json'), 427, 400, [[], [43], []])
]
.forEach(function(testCase) {
it('@gl trace type ' + testCase.label, function(done) {
Expand Down
Loading