@@ -29,28 +29,50 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
29
29
// even if hoveron is 'fills', only use it if we have polygons too
30
30
if ( trace . hoveron === 'fills' && trace . _polygons ) {
31
31
var polygons = trace . _polygons ,
32
+ polygonsIn = [ ] ,
32
33
inside = false ,
33
- x0 = Infinity ,
34
- x1 = - Infinity ,
35
- y0 = Infinity ,
36
- y1 = - Infinity ;
37
-
38
- for ( var i = 0 ; i < polygons . length ; i ++ ) {
39
- var polygon = polygons [ i ] ;
34
+ xmin = Infinity ,
35
+ xmax = - Infinity ,
36
+ ymin = Infinity ,
37
+ ymax = - Infinity ,
38
+ i , j , polygon , pts , xCross , x0 , x1 , y0 , y1 ;
39
+
40
+ for ( i = 0 ; i < polygons . length ; i ++ ) {
41
+ polygon = polygons [ i ] ;
40
42
// TODO: this is not going to work right for curved edges, it will
41
43
// act as though they're straight. That's probably going to need
42
44
// the elements themselves to capture the events. Worth it?
43
45
if ( polygon . contains ( pt ) ) {
44
46
inside = ! inside ;
45
47
// TODO: need better than just the overall bounding box
46
- x0 = Math . min ( x0 , polygon . xmin ) ;
47
- x1 = Math . max ( x1 , polygon . xmax ) ;
48
- y0 = Math . min ( y0 , polygon . ymin ) ;
49
- y1 = Math . max ( y1 , polygon . ymax ) ;
48
+ polygonsIn . push ( polygon ) ;
49
+ ymin = Math . min ( ymin , polygon . ymin ) ;
50
+ ymax = Math . max ( ymax , polygon . ymax ) ;
50
51
}
51
52
}
52
53
53
54
if ( inside ) {
55
+ // find the overall left-most and right-most points of the
56
+ // polygon(s) we're inside at their combined vertical midpoint.
57
+ // This is where we will draw the hover label.
58
+ // Note that this might not be the vertical midpoint of the
59
+ // whole trace, if it's disjoint.
60
+ var yAvg = ( ymin + ymax ) / 2 ;
61
+ for ( i = 0 ; i < polygonsIn . length ; i ++ ) {
62
+ pts = polygonsIn [ i ] . pts ;
63
+ for ( j = 1 ; j < pts . length ; j ++ ) {
64
+ y0 = pts [ j - 1 ] [ 1 ] ;
65
+ y1 = pts [ j ] [ 1 ] ;
66
+ if ( ( y0 > yAvg ) !== ( y1 >= yAvg ) ) {
67
+ x0 = pts [ j - 1 ] [ 0 ] ;
68
+ x1 = pts [ j ] [ 0 ] ;
69
+ xCross = x0 + ( x1 - x0 ) * ( yAvg - y0 ) / ( y1 - y0 ) ;
70
+ xmin = Math . min ( xmin , xCross ) ;
71
+ xmax = Math . max ( xmax , xCross ) ;
72
+ }
73
+ }
74
+ }
75
+
54
76
// get only fill or line color for the hover color
55
77
var color = Color . defaultLine ;
56
78
if ( Color . opacity ( trace . fillcolor ) ) color = trace . fillcolor ;
@@ -61,14 +83,20 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
61
83
Lib . extendFlat ( pointData , {
62
84
// never let a 2D override 1D type as closest point
63
85
distance : constants . MAXDIST + 10 ,
64
- x0 : x0 ,
65
- x1 : x1 ,
66
- y0 : y0 ,
67
- y1 : y1 ,
86
+ x0 : xmin ,
87
+ x1 : xmax ,
88
+ y0 : yAvg ,
89
+ y1 : yAvg ,
68
90
color : color
69
91
} ) ;
70
92
71
93
delete pointData . index ;
94
+
95
+ if ( trace . text && ! Array . isArray ( trace . text ) ) {
96
+ pointData . text = String ( trace . text ) ;
97
+ }
98
+ else pointData . text = trace . name ;
99
+
72
100
return [ pointData ] ;
73
101
}
74
102
}
0 commit comments