@@ -34,7 +34,12 @@ export default class HistoryGraph extends React.Component {
34
34
}
35
35
} ;
36
36
window . addEventListener ( 'resize' , this . resizeHandle ) ;
37
- this . bodyClickHandle = ( ) => this . setState ( { show : false } ) ;
37
+ this . bodyClickHandle = ( event ) => {
38
+ if ( event . target && event . target . tagName === 'circle' ) {
39
+ return ;
40
+ }
41
+ this . setState ( { show : false } ) ;
42
+ } ;
38
43
document . body . addEventListener ( 'click' , this . bodyClickHandle ) ;
39
44
}
40
45
@@ -240,6 +245,58 @@ export default class HistoryGraph extends React.Component {
240
245
.attr('stroke-width', 3);
241
246
*/
242
247
248
+ const updateTooltipPosition = ( ) => {
249
+ const e = d3 . mouse ( document . getElementById ( 'history-graph-container' ) ) ;
250
+ const profileModalContainerEl = document . querySelector ( '.ProfileModalContainer' ) ;
251
+ const profileModalContainerRect = profileModalContainerEl
252
+ ? profileModalContainerEl . getBoundingClientRect ( ) : null ;
253
+ const graphEl = document . getElementById ( 'history-graph-container' ) ;
254
+ const graphRect = graphEl ? graphEl . getBoundingClientRect ( ) : null ;
255
+ const tooltipElement = document . getElementById ( 'chart-tooltip-history-graph' ) ;
256
+
257
+ let cx = e [ 0 ] ;
258
+ let cy = e [ 1 ] ;
259
+ let rotated = false ;
260
+ const defaultWidth = 320 ;
261
+ const defaultHeight = 115 ;
262
+ if ( tooltipElement ) {
263
+ const { clientWidth, clientHeight } = tooltipElement ;
264
+ cx -= ( ( clientWidth || defaultWidth ) / 2 ) ;
265
+ cy += 15 ;
266
+
267
+ if ( graphRect && profileModalContainerRect ) {
268
+ const minLeft = profileModalContainerRect . x - graphRect . x ;
269
+ const minTop = profileModalContainerRect . y - graphRect . y ;
270
+ const maxRight = profileModalContainerRect . width + minLeft ;
271
+ const maxBottom = profileModalContainerRect . height + minTop ;
272
+ const minXTooltipPosition = minLeft ;
273
+ const maxXTooltipPosition = maxRight - ( clientWidth || defaultWidth ) ;
274
+ const minYTooltipPosition = minTop ;
275
+ const maxYTooltipPosition = maxBottom - ( clientHeight || defaultHeight ) ;
276
+ if ( cx < minXTooltipPosition ) {
277
+ cx = minXTooltipPosition ;
278
+ }
279
+ if ( cx > maxXTooltipPosition ) {
280
+ cx = maxXTooltipPosition ;
281
+ }
282
+ if ( cy < minYTooltipPosition ) {
283
+ cy = minYTooltipPosition ;
284
+ }
285
+ if ( cy > maxYTooltipPosition ) {
286
+ cy -= clientHeight + 25 ;
287
+ rotated = true ;
288
+ }
289
+ }
290
+ }
291
+
292
+ $scope . setState ( {
293
+ rotated,
294
+ show : true ,
295
+ left : cx ,
296
+ top : cy ,
297
+ } ) ;
298
+ } ;
299
+
243
300
svg . selectAll ( 'circle' )
244
301
. data ( history )
245
302
. enter ( )
@@ -249,24 +306,25 @@ export default class HistoryGraph extends React.Component {
249
306
. attr ( 'r' , 5.5 )
250
307
. attr ( 'fill' , d => getRatingColor ( d . newRating ) )
251
308
. on ( 'mouseover' , ( d ) => {
252
- const e = d3 . event ;
253
309
$scope . setState ( {
254
- show : true ,
255
- left : e . pageX ,
256
- top : e . pageY ,
257
310
challengeName : d . challengeName ,
258
311
challengeData : moment ( d . ratingDate ) . format ( 'MMM DD, YYYY' ) ,
259
312
rating : d . newRating ,
260
313
ratingColor : getRatingColor ( d . newRating ) ,
261
314
href : getChallengeLink ( d . challengeId ) ,
262
315
} ) ;
316
+
317
+ updateTooltipPosition ( ) ;
318
+ } )
319
+ . on ( 'mousemove' , ( ) => {
320
+ updateTooltipPosition ( ) ;
263
321
} ) ;
264
322
}
265
323
266
324
render ( ) {
267
325
return (
268
- < div styleName = "history-graph" ref = { this . graphRef } >
269
- < ChartTooltip { ...this . state } />
326
+ < div id = "history-graph-container" styleName = "history-graph" ref = { this . graphRef } >
327
+ < ChartTooltip id = "history-graph" { ...this . state } />
270
328
</ div >
271
329
) ;
272
330
}
0 commit comments