@@ -85,10 +85,9 @@ export class ChartCanvas<Item> extends React.Component<
8585 State < Item >
8686> {
8787 _devicePixelRatio : number = 1 ;
88- // The current mouse position. Needs to be stored for tooltip
89- // hit-test if props update.
90- _offsetX : CssPixels = 0 ;
91- _offsetY : CssPixels = 0 ;
88+ // The current mouse position inside the canvas, or null if the mouse
89+ // is outside. Needs to be stored for tooltip hit-test if props update.
90+ _mousePosition : { x : CssPixels ; y : CssPixels } | null = null ;
9291 // The position of the most recent mouse down event. Needed for
9392 // comparison with the current mouse position in order to
9493 // distinguish between clicks and drags.
@@ -267,8 +266,9 @@ export class ChartCanvas<Item> extends React.Component<
267266 this . props . onMouseMove ( event ) ;
268267 }
269268
270- this . _offsetX = event . nativeEvent . offsetX ;
271- this . _offsetY = event . nativeEvent . offsetY ;
269+ const offsetX = event . nativeEvent . offsetX ;
270+ const offsetY = event . nativeEvent . offsetY ;
271+ this . _mousePosition = { x : offsetX , y : offsetY } ;
272272 // event.buttons is a bitfield representing which buttons are pressed at the
273273 // time of the mousemove event. The first bit is for the left click.
274274 // This operation checks if the left button is clicked, but this will also
@@ -281,15 +281,15 @@ export class ChartCanvas<Item> extends React.Component<
281281 if (
282282 ! this . _mouseMovedWhileClicked &&
283283 hasLeftClick &&
284- ( Math . abs ( this . _offsetX - this . _mouseDownOffsetX ) >
284+ ( Math . abs ( offsetX - this . _mouseDownOffsetX ) >
285285 MOUSE_CLICK_MAX_MOVEMENT_DELTA ||
286- Math . abs ( this . _offsetY - this . _mouseDownOffsetY ) >
286+ Math . abs ( offsetY - this . _mouseDownOffsetY ) >
287287 MOUSE_CLICK_MAX_MOVEMENT_DELTA )
288288 ) {
289289 this . _mouseMovedWhileClicked = true ;
290290 }
291291
292- const maybeHoveredItem = this . props . hitTest ( this . _offsetX , this . _offsetY ) ;
292+ const maybeHoveredItem = this . props . hitTest ( offsetX , offsetY ) ;
293293 if ( maybeHoveredItem !== null ) {
294294 if ( this . state . selectedItem === null ) {
295295 // Update both the hovered item and the pageX and pageY values. The
@@ -323,6 +323,7 @@ export class ChartCanvas<Item> extends React.Component<
323323 } ;
324324
325325 _onMouseOut = ( ) => {
326+ this . _mousePosition = null ;
326327 if (
327328 this . state . hoveredItem !== null &&
328329 // This persistTooltips property is part of the web console API. It helps
@@ -390,18 +391,16 @@ export class ChartCanvas<Item> extends React.Component<
390391 } ;
391392
392393 override UNSAFE_componentWillReceiveProps ( ) {
393- // It is possible that the data backing the chart has been
394- // changed, for instance after symbolication. Clear the
395- // hoveredItem if the mouse no longer hovers over it.
396- const { hoveredItem } = this . state ;
397- if (
398- hoveredItem !== null &&
399- ! hoveredItemsAreEqual (
400- this . props . hitTest ( this . _offsetX , this . _offsetY ) ,
401- hoveredItem
402- )
403- ) {
404- this . setState ( { hoveredItem : null } ) ;
394+ // Update the hovered item if the rendered data has changed or if
395+ // the chart has been scrolled so that a new element is under the
396+ // mouse cursor.
397+ if ( ! this . _mousePosition ) {
398+ return ;
399+ }
400+ const { x, y } = this . _mousePosition ;
401+ const newHoveredItem = this . props . hitTest ( x , y ) ;
402+ if ( ! hoveredItemsAreEqual ( newHoveredItem , this . state . hoveredItem ) ) {
403+ this . setState ( { hoveredItem : newHoveredItem } ) ;
405404 }
406405 }
407406
0 commit comments