Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 3b9de53

Browse files
authored
Merge pull request #6963 from plotly/fix6960-hoversubplots
Ensure winning points of hover are listed first when `hoversubplots` is set to "axis" and sorting by distance
2 parents f673ce6 + 5b6998d commit 3b9de53

File tree

3 files changed

+71
-5
lines changed

3 files changed

+71
-5
lines changed

draftlogs/6963_fix.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
- Ensure winning points of hover are listed first when hoversubplots is set to "axis" and sorting by distance [[#6963](https://github.com/plotly/plotly.js/pull/6963)]

src/components/fx/hover.js

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,10 @@ var cartesianScatterPoints = {
5353
splom: true
5454
};
5555

56+
function distanceSort(a, b) {
57+
return a.distance - b.distance;
58+
}
59+
5660
// fx.hover: highlight data on hover
5761
// evt can be a mousemove event, or an object with data about what points
5862
// to hover on
@@ -270,15 +274,21 @@ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
270274
var hovermodeHasX = (hovermode || '').charAt(0) === 'x';
271275
var hovermodeHasY = (hovermode || '').charAt(0) === 'y';
272276

277+
var firstXaxis;
278+
var firstYaxis;
279+
273280
if(hasCartesian && (hovermodeHasX || hovermodeHasY) && hoversubplots === 'axis') {
274281
var subplotsLength = subplots.length;
275282
for(var p = 0; p < subplotsLength; p++) {
276283
spId = subplots[p];
277284
if(plots[spId]) {
278285
// 'cartesian' case
279286

287+
firstXaxis = Axes.getFromId(gd, spId, 'x');
288+
firstYaxis = Axes.getFromId(gd, spId, 'y');
289+
280290
var subplotsWith = (
281-
Axes.getFromId(gd, spId, hovermodeHasX ? 'x' : 'y')
291+
hovermodeHasX ? firstXaxis : firstYaxis
282292
)._subplotsWith;
283293

284294
if(subplotsWith && subplotsWith.length) {
@@ -661,6 +671,9 @@ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
661671
var thisSpikeDistance;
662672

663673
for(var i = 0; i < pointsData.length; i++) {
674+
if(firstXaxis && firstXaxis._id !== pointsData[i].xa._id) continue;
675+
if(firstYaxis && firstYaxis._id !== pointsData[i].ya._id) continue;
676+
664677
thisSpikeDistance = pointsData[i].spikeDistance;
665678
if(spikeOnWinning && i === 0) thisSpikeDistance = -Infinity;
666679

@@ -700,9 +713,26 @@ function _hover(gd, evt, subplot, noHoverEvent, eventTarget) {
700713
gd._spikepoints = newspikepoints;
701714

702715
var sortHoverData = function() {
703-
if(hoversubplots !== 'axis') {
704-
hoverData.sort(function(d1, d2) { return d1.distance - d2.distance; });
705-
}
716+
// When sorting keep the points in the main subplot at the top
717+
// then add points in other subplots
718+
719+
var hoverDataInSubplot = hoverData.filter(function(a) {
720+
return (
721+
(firstXaxis && firstXaxis._id === a.xa._id) &&
722+
(firstYaxis && firstYaxis._id === a.ya._id)
723+
);
724+
});
725+
726+
var hoverDataOutSubplot = hoverData.filter(function(a) {
727+
return !(
728+
(firstXaxis && firstXaxis._id === a.xa._id) &&
729+
(firstYaxis && firstYaxis._id === a.ya._id)
730+
);
731+
});
732+
733+
hoverDataInSubplot.sort(distanceSort);
734+
hoverDataOutSubplot.sort(distanceSort);
735+
hoverData = hoverDataInSubplot.concat(hoverDataOutSubplot);
706736

707737
// move period positioned points and box/bar-like traces to the end of the list
708738
hoverData = orderRangePoints(hoverData, hovermode);

test/jasmine/tests/hover_label_test.js

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2445,6 +2445,12 @@ describe('hover on subplots when hoversubplots is set to *single* and x hovermod
24452445
});
24462446
});
24472447

2448+
function assertFirstPointOn(gd, xaxisId, yaxisId) {
2449+
// first point should be on the main subplot
2450+
expect(gd._hoverdata[0].xaxis._id).toBe(xaxisId);
2451+
expect(gd._hoverdata[0].yaxis._id).toBe(yaxisId);
2452+
}
2453+
24482454
describe('hover on subplots when hoversubplots is set to *axis* and x hovermodes', function() {
24492455
'use strict';
24502456

@@ -2494,6 +2500,9 @@ describe('hover on subplots when hoversubplots is set to *axis* and x hovermodes
24942500
Lib.clearThrottle();
24952501
Plotly.Fx.hover(gd, {xval: pos}, subplot);
24962502
expect(gd._hoverdata.length).toBe(3);
2503+
2504+
assertFirstPointOn(gd, 'x', 'y');
2505+
24972506
assertHoverLabelContent({
24982507
nums: ['1', '10', '100'],
24992508
name: ['trace 0', 'trace 1', 'trace 2'],
@@ -2505,6 +2514,8 @@ describe('hover on subplots when hoversubplots is set to *axis* and x hovermodes
25052514
Lib.clearThrottle();
25062515
Plotly.Fx.hover(gd, {xval: pos}, subplot);
25072516

2517+
assertFirstPointOn(gd, 'x', 'y2');
2518+
25082519
expect(gd._hoverdata.length).toBe(3);
25092520
assertHoverLabelContent({
25102521
nums: ['2', '20', '200'],
@@ -2517,6 +2528,8 @@ describe('hover on subplots when hoversubplots is set to *axis* and x hovermodes
25172528
Lib.clearThrottle();
25182529
Plotly.Fx.hover(gd, {xval: pos}, subplot);
25192530

2531+
assertFirstPointOn(gd, 'x', 'y3');
2532+
25202533
expect(gd._hoverdata.length).toBe(3);
25212534
assertHoverLabelContent({
25222535
nums: ['3', '30', '300'],
@@ -2530,6 +2543,8 @@ describe('hover on subplots when hoversubplots is set to *axis* and x hovermodes
25302543
Lib.clearThrottle();
25312544
Plotly.Fx.hover(gd, {xval: pos}, subplot);
25322545
expect(gd._hoverdata.length).toBe(3);
2546+
2547+
assertFirstPointOn(gd, 'x', 'y');
25332548
});
25342549
});
25352550

@@ -2582,6 +2597,9 @@ describe('hover on subplots when hoversubplots is set to *axis* and y hovermodes
25822597
Lib.clearThrottle();
25832598
Plotly.Fx.hover(gd, {yval: pos}, subplot);
25842599
expect(gd._hoverdata.length).toBe(3);
2600+
2601+
assertFirstPointOn(gd, 'x', 'y');
2602+
25852603
assertHoverLabelContent({
25862604
nums: ['1', '10', '100'],
25872605
name: ['trace 0', 'trace 1', 'trace 2'],
@@ -2594,6 +2612,9 @@ describe('hover on subplots when hoversubplots is set to *axis* and y hovermodes
25942612
Plotly.Fx.hover(gd, {yval: pos}, subplot);
25952613

25962614
expect(gd._hoverdata.length).toBe(3);
2615+
2616+
assertFirstPointOn(gd, 'x2', 'y');
2617+
25972618
assertHoverLabelContent({
25982619
nums: ['2', '20', '200'],
25992620
name: ['trace 0', 'trace 1', 'trace 2'],
@@ -2606,6 +2627,9 @@ describe('hover on subplots when hoversubplots is set to *axis* and y hovermodes
26062627
Plotly.Fx.hover(gd, {yval: pos}, subplot);
26072628

26082629
expect(gd._hoverdata.length).toBe(3);
2630+
2631+
assertFirstPointOn(gd, 'x3', 'y');
2632+
26092633
assertHoverLabelContent({
26102634
nums: ['3', '30', '300'],
26112635
name: ['trace 0', 'trace 1', 'trace 2'],
@@ -2618,6 +2642,8 @@ describe('hover on subplots when hoversubplots is set to *axis* and y hovermodes
26182642
Lib.clearThrottle();
26192643
Plotly.Fx.hover(gd, {yval: pos}, subplot);
26202644
expect(gd._hoverdata.length).toBe(3);
2645+
2646+
assertFirstPointOn(gd, 'x', 'y');
26212647
});
26222648
});
26232649

@@ -2640,6 +2666,7 @@ describe('splom hover on subplots when hoversubplots is set to *axis* and (x|y)
26402666
it('splom hoversubplots: *axis*', function() {
26412667
Lib.clearThrottle();
26422668
Plotly.Fx.hover(gd, {x: 200, y: 200}, 'xy');
2669+
assertFirstPointOn(gd, 'x', 'y');
26432670
expect(gd._hoverdata.length).toBe(2);
26442671
assertHoverLabelContent({
26452672
nums: ['100', '100k'],
@@ -2648,14 +2675,15 @@ describe('splom hover on subplots when hoversubplots is set to *axis* and (x|y)
26482675
});
26492676

26502677
Plotly.relayout(gd, 'hovermode', 'x unified');
2651-
26522678
Lib.clearThrottle();
26532679
Plotly.Fx.hover(gd, {x: 200, y: 200}, 'xy');
2680+
assertFirstPointOn(gd, 'x', 'y');
26542681
expect(gd._hoverdata.length).toBe(2);
26552682

26562683
Plotly.relayout(gd, 'hovermode', 'y unified');
26572684
Lib.clearThrottle();
26582685
Plotly.Fx.hover(gd, {x: 200, y: 200}, 'xy');
2686+
assertFirstPointOn(gd, 'x', 'y');
26592687
expect(gd._hoverdata.length).toBe(2);
26602688
});
26612689
});
@@ -2696,6 +2724,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
26962724
it('splom *axis* hoversubplots', function() {
26972725
Lib.clearThrottle();
26982726
Plotly.Fx.hover(gd, {}, 'xy');
2727+
assertFirstPointOn(gd, 'x', 'y');
26992728
expect(gd._hoverdata.length).toBe(4);
27002729
assertHoverLabelContent({
27012730
nums: ['1', '1', '1', '1'],
@@ -2705,6 +2734,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
27052734

27062735
Lib.clearThrottle();
27072736
Plotly.Fx.hover(gd, {}, 'xy2');
2737+
assertFirstPointOn(gd, 'x', 'y2');
27082738
expect(gd._hoverdata.length).toBe(3);
27092739
assertHoverLabelContent({
27102740
nums: ['1', '2', '2'],
@@ -2714,6 +2744,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
27142744

27152745
Lib.clearThrottle();
27162746
Plotly.Fx.hover(gd, {}, 'xy3');
2747+
assertFirstPointOn(gd, 'x', 'y3');
27172748
expect(gd._hoverdata.length).toBe(3);
27182749
assertHoverLabelContent({
27192750
nums: ['1', '2', '2'],
@@ -2723,6 +2754,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
27232754

27242755
Lib.clearThrottle();
27252756
Plotly.Fx.hover(gd, {}, 'xy4');
2757+
assertFirstPointOn(gd, 'x', 'y4');
27262758
expect(gd._hoverdata.length).toBe(4);
27272759
assertHoverLabelContent({
27282760
nums: ['1', '3', '3', '3'],
@@ -2732,6 +2764,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
27322764

27332765
Lib.clearThrottle();
27342766
Plotly.Fx.hover(gd, {}, 'x2y');
2767+
assertFirstPointOn(gd, 'x2', 'y');
27352768
expect(gd._hoverdata.length).toBe(4);
27362769
assertHoverLabelContent({
27372770
nums: ['1', '3', '3', '3'],
@@ -2741,6 +2774,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
27412774

27422775
Lib.clearThrottle();
27432776
Plotly.Fx.hover(gd, {}, 'x3y');
2777+
assertFirstPointOn(gd, 'x3', 'y');
27442778
expect(gd._hoverdata.length).toBe(4);
27452779
assertHoverLabelContent({
27462780
nums: ['1', '3', '3', '3'],
@@ -2750,6 +2784,7 @@ describe('splom hover *axis* hoversubplots splom points on same position should
27502784

27512785
Lib.clearThrottle();
27522786
Plotly.Fx.hover(gd, {}, 'x4y');
2787+
assertFirstPointOn(gd, 'x4', 'y');
27532788
expect(gd._hoverdata.length).toBe(4);
27542789
assertHoverLabelContent({
27552790
nums: ['1', '3', '3', '3'],

0 commit comments

Comments
 (0)