@@ -156,51 +156,69 @@ module.exports = function plot(gd, calcData) {
156
156
if ( gd . _fullLayout . hovermode === false ) return ;
157
157
var obj = d . link . trace . link ;
158
158
if ( obj . hoverinfo === 'none' || obj . hoverinfo === 'skip' ) return ;
159
- var rootBBox = gd . _fullLayout . _paperdiv . node ( ) . getBoundingClientRect ( ) ;
160
- var hoverCenterX ;
161
- var hoverCenterY ;
162
- if ( d . link . circular ) {
163
- hoverCenterX = ( d . link . circularPathData . leftInnerExtent + d . link . circularPathData . rightInnerExtent ) / 2 + d . parent . translateX ;
164
- hoverCenterY = d . link . circularPathData . verticalFullExtent + d . parent . translateY ;
165
- } else {
166
- var boundingBox = element . getBoundingClientRect ( ) ;
167
- hoverCenterX = boundingBox . left + boundingBox . width / 2 - rootBBox . left ;
168
- hoverCenterY = boundingBox . top + boundingBox . height / 2 - rootBBox . top ;
169
- }
170
159
171
- var hovertemplateLabels = { valueLabel : d3 . format ( d . valueFormat ) ( d . link . value ) + d . valueSuffix } ;
172
- d . link . fullData = d . link . trace ;
160
+ var hoverItems = [ ] ;
173
161
174
- var tooltip = Fx . loneHover ( {
175
- x : hoverCenterX ,
176
- y : hoverCenterY ,
177
- name : hovertemplateLabels . valueLabel ,
178
- text : [
179
- d . link . label || '' ,
180
- sourceLabel + d . link . source . label ,
181
- targetLabel + d . link . target . label ,
182
- d . link . concentrationscale ? concentrationLabel + d3 . format ( '%0.2f' ) ( d . link . flow . labelConcentration ) : ''
183
- ] . filter ( renderableValuePresent ) . join ( '<br>' ) ,
184
- color : castHoverOption ( obj , 'bgcolor' ) || Color . addOpacity ( d . tinyColorHue , 1 ) ,
185
- borderColor : castHoverOption ( obj , 'bordercolor' ) ,
186
- fontFamily : castHoverOption ( obj , 'font.family' ) ,
187
- fontSize : castHoverOption ( obj , 'font.size' ) ,
188
- fontColor : castHoverOption ( obj , 'font.color' ) ,
189
- idealAlign : d3 . event . x < hoverCenterX ? 'right' : 'left' ,
162
+ function hoverCenterPosition ( link ) {
163
+ var hoverCenterX , hoverCenterY ;
164
+ if ( link . circular ) {
165
+ hoverCenterX = ( link . circularPathData . leftInnerExtent + link . circularPathData . rightInnerExtent ) / 2 + d . parent . translateX ;
166
+ hoverCenterY = link . circularPathData . verticalFullExtent + d . parent . translateY ;
167
+ } else {
168
+ hoverCenterX = ( link . source . x1 + link . target . x0 ) / 2 + d . parent . translateX ;
169
+ hoverCenterY = ( link . y0 + link . y1 ) / 2 + d . parent . translateY ;
170
+ }
171
+ return [ hoverCenterX , hoverCenterY ] ;
172
+ }
190
173
191
- hovertemplate : obj . hovertemplate ,
192
- hovertemplateLabels : hovertemplateLabels ,
193
- eventData : [ d . link ]
194
- } , {
174
+ // For each related links, create a hoverItem
175
+ var anchorIndex = 0 ;
176
+ for ( var i = 0 ; i < d . flow . links . length ; i ++ ) {
177
+ var link = d . flow . links [ i ] ;
178
+ if ( gd . _fullLayout . hovermode === 'closest' && d . link . pointNumber !== link . pointNumber ) continue ;
179
+ if ( d . link . pointNumber === link . pointNumber ) anchorIndex = i ;
180
+ link . fullData = link . trace ;
181
+ obj = d . link . trace . link ;
182
+ var hoverCenter = hoverCenterPosition ( link ) ;
183
+ var hovertemplateLabels = { valueLabel : d3 . format ( d . valueFormat ) ( link . value ) + d . valueSuffix } ;
184
+
185
+ hoverItems . push ( {
186
+ x : hoverCenter [ 0 ] ,
187
+ y : hoverCenter [ 1 ] ,
188
+ name : hovertemplateLabels . valueLabel ,
189
+ text : [
190
+ link . label || '' ,
191
+ sourceLabel + link . source . label ,
192
+ targetLabel + link . target . label ,
193
+ link . concentrationscale ? concentrationLabel + d3 . format ( '%0.2f' ) ( link . flow . labelConcentration ) : ''
194
+ ] . filter ( renderableValuePresent ) . join ( '<br>' ) ,
195
+ color : castHoverOption ( obj , 'bgcolor' ) || Color . addOpacity ( link . color , 1 ) ,
196
+ borderColor : castHoverOption ( obj , 'bordercolor' ) ,
197
+ fontFamily : castHoverOption ( obj , 'font.family' ) ,
198
+ fontSize : castHoverOption ( obj , 'font.size' ) ,
199
+ fontColor : castHoverOption ( obj , 'font.color' ) ,
200
+ idealAlign : d3 . event . x < hoverCenter [ 0 ] ? 'right' : 'left' ,
201
+
202
+ hovertemplate : obj . hovertemplate ,
203
+ hovertemplateLabels : hovertemplateLabels ,
204
+ eventData : [ link ]
205
+ } ) ;
206
+ }
207
+
208
+ var tooltips = Fx . multiHovers ( hoverItems , {
195
209
container : fullLayout . _hoverlayer . node ( ) ,
196
210
outerContainer : fullLayout . _paper . node ( ) ,
197
- gd : gd
211
+ gd : gd ,
212
+ anchorIndex : anchorIndex
198
213
} ) ;
199
214
200
- if ( ! d . link . concentrationscale ) {
201
- makeTranslucent ( tooltip , 0.65 ) ;
202
- }
203
- makeTextContrasty ( tooltip ) ;
215
+ tooltips . each ( function ( ) {
216
+ var tooltip = this ;
217
+ if ( ! d . link . concentrationscale ) {
218
+ makeTranslucent ( tooltip , 0.65 ) ;
219
+ }
220
+ makeTextContrasty ( tooltip ) ;
221
+ } ) ;
204
222
} ;
205
223
206
224
var linkUnhover = function ( element , d , sankey ) {
0 commit comments