@@ -46,6 +46,12 @@ var multipleHoverPoints = {
46
46
candlestick : true
47
47
} ;
48
48
49
+ var cartesianScatterPoints = {
50
+ scatter : true ,
51
+ scattergl : true ,
52
+ splom : true
53
+ } ;
54
+
49
55
// fx.hover: highlight data on hover
50
56
// evt can be a mousemove event, or an object with data about what points
51
57
// to hover on
@@ -574,12 +580,15 @@ function _hover(gd, evt, subplot, noHoverEvent) {
574
580
575
581
findHoverPoints ( ) ;
576
582
577
- function selectClosestPoint ( pointsData , spikedistance ) {
583
+ function selectClosestPoint ( pointsData , spikedistance , spikeOnWinning ) {
578
584
var resultPoint = null ;
579
585
var minDistance = Infinity ;
580
586
var thisSpikeDistance ;
587
+
581
588
for ( var i = 0 ; i < pointsData . length ; i ++ ) {
582
589
thisSpikeDistance = pointsData [ i ] . spikeDistance ;
590
+ if ( spikeOnWinning && i === 0 ) thisSpikeDistance = - Infinity ;
591
+
583
592
if ( thisSpikeDistance <= minDistance && thisSpikeDistance <= spikedistance ) {
584
593
resultPoint = pointsData [ i ] ;
585
594
minDistance = thisSpikeDistance ;
@@ -616,19 +625,30 @@ function _hover(gd, evt, subplot, noHoverEvent) {
616
625
} ;
617
626
gd . _spikepoints = newspikepoints ;
618
627
628
+ var sortHoverData = function ( ) {
629
+ hoverData . sort ( function ( d1 , d2 ) { return d1 . distance - d2 . distance ; } ) ;
630
+
631
+ // move period positioned points and box/bar-like traces to the end of the list
632
+ hoverData = orderRangePoints ( hoverData , hovermode ) ;
633
+ } ;
634
+ sortHoverData ( ) ;
635
+
636
+ var axLetter = hovermode . charAt ( 0 ) ;
637
+ var spikeOnWinning = ( axLetter === 'x' || axLetter === 'y' ) && hoverData [ 0 ] && cartesianScatterPoints [ hoverData [ 0 ] . trace . type ] ;
638
+
619
639
// Now if it is not restricted by spikedistance option, set the points to draw the spikelines
620
640
if ( hasCartesian && ( spikedistance !== 0 ) ) {
621
641
if ( hoverData . length !== 0 ) {
622
642
var tmpHPointData = hoverData . filter ( function ( point ) {
623
643
return point . ya . showspikes ;
624
644
} ) ;
625
- var tmpHPoint = selectClosestPoint ( tmpHPointData , spikedistance ) ;
645
+ var tmpHPoint = selectClosestPoint ( tmpHPointData , spikedistance , spikeOnWinning ) ;
626
646
spikePoints . hLinePoint = fillSpikePoint ( tmpHPoint ) ;
627
647
628
648
var tmpVPointData = hoverData . filter ( function ( point ) {
629
649
return point . xa . showspikes ;
630
650
} ) ;
631
- var tmpVPoint = selectClosestPoint ( tmpVPointData , spikedistance ) ;
651
+ var tmpVPoint = selectClosestPoint ( tmpVPointData , spikedistance , spikeOnWinning ) ;
632
652
spikePoints . vLinePoint = fillSpikePoint ( tmpVPoint ) ;
633
653
}
634
654
}
@@ -650,14 +670,6 @@ function _hover(gd, evt, subplot, noHoverEvent) {
650
670
}
651
671
}
652
672
653
- var sortHoverData = function ( ) {
654
- hoverData . sort ( function ( d1 , d2 ) { return d1 . distance - d2 . distance ; } ) ;
655
-
656
- // move period positioned points and box/bar-like traces to the end of the list
657
- hoverData = orderRangePoints ( hoverData , hovermode ) ;
658
- } ;
659
- sortHoverData ( ) ;
660
-
661
673
if (
662
674
helpers . isXYhover ( _mode ) &&
663
675
hoverData [ 0 ] . length !== 0 &&
@@ -1074,7 +1086,7 @@ function createHoverText(hoverData, opts, gd) {
1074
1086
var winningPoint = hoverData [ 0 ] ;
1075
1087
1076
1088
// When the scatter point wins, it's OK for the hovelabel to occlude the bar and other points.
1077
- var scatterWon = winningPoint . trace . type === 'scatter' ;
1089
+ var scatterWon = cartesianScatterPoints [ winningPoint . trace . type ] ;
1078
1090
1079
1091
var lyBottom , lyTop ;
1080
1092
if ( axLetter === 'y' ) {
0 commit comments