@@ -29,28 +29,50 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
2929 // even if hoveron is 'fills', only use it if we have polygons too
3030 if ( trace . hoveron === 'fills' && trace . _polygons ) {
3131 var polygons = trace . _polygons ,
32+ polygonsIn = [ ] ,
3233 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 ] ;
4042 // TODO: this is not going to work right for curved edges, it will
4143 // act as though they're straight. That's probably going to need
4244 // the elements themselves to capture the events. Worth it?
4345 if ( polygon . contains ( pt ) ) {
4446 inside = ! inside ;
4547 // 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 ) ;
5051 }
5152 }
5253
5354 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+
5476 // get only fill or line color for the hover color
5577 var color = Color . defaultLine ;
5678 if ( Color . opacity ( trace . fillcolor ) ) color = trace . fillcolor ;
@@ -61,14 +83,20 @@ module.exports = function hoverPoints(pointData, xval, yval, hovermode) {
6183 Lib . extendFlat ( pointData , {
6284 // never let a 2D override 1D type as closest point
6385 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 ,
6890 color : color
6991 } ) ;
7092
7193 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+
72100 return [ pointData ] ;
73101 }
74102 }
0 commit comments