Skip to content

Browser hangs on relayout on hover events (adding/removing annotations) #1640

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
dictaartisan opened this issue May 1, 2017 · 5 comments
Closed
Labels
bug something broken

Comments

@dictaartisan
Copy link

This is probably related with #1446 and #1467 (sorry for duplicate comment)

I see browse hangs (stack overflow) when drawing/removing an annotation on hover and unhover events. Here's a codepen (shamelessly copying etpinard's code)

http://codepen.io/dictaartisan/pen/XRRYwe

Hover in and out of the points often enough and browser will hang - Chrome seems to recover after a while in this case but on another more complex plot I have to kill the browser

@dictaartisan dictaartisan changed the title Browser hangs on relayout (adding/removing annotations) Browser hangs on relayout on hover events (adding/removing annotations) May 1, 2017
@dictaartisan
Copy link
Author

In fact, within that codepen, the infinite recursion seems to be triggered when hovering quickly over the top point (6,4) which triggers the rescaling of the y axis when the annotation is inserted at the top of the chart

The culprit appears to be the gd._fullLayout._rehover function, which appears to create an chain reaction of hover/unhover events

@alexcjohnson
Copy link
Collaborator

This is a bit of an old issue, but adding some thoughts to it that arose while thinking about #2644:
rehover was created for cases like streaming data, where something not driven by immediate user action is altering the data in a plot. Without recalculating the hover state with the new data, we'd either lose hover entirely (if streaming is fast you'd never be able to see hover info) or you'd be looking at out-of-date points.

It becomes tricky though when you're using a hover event to modify the plot. The issue here is that, as you noted, the y axis is rescaled by adding the new annotation, so after adding it the mouse is no longer over that point and you get a new hover event to reflect that. As a result you remove the annotation, the y axis rescales again, and the mouse IS over the point again. ∞

So what's the right behavior, and where should we break this loop? We can't say "no hover events if the hover was from rehover" or the displayed and reacted-to hover information would get out of sync. I suppose we could annotate the event data, to let you know that it came from a rehover and allow you to react accordingly. We could also probably try to detect such an infinite loop and throw an error rather than locking up the page, or perhaps add a small delay somewhere so instead of freezing you'll just see flashing and be able to move your mouse away. I'm thinking maybe if the hover is triggered by rehover, add a delay after displaying the tooltip but before emitting the hover event. That way normal hover events still come immediately but once we get into a potential infinite loop we slow things down.

Thinking about this from an application standpoint, I'm not sure what behavior you would want anyway - if autoranging to the annotation is important, would you want to stop at hover (and annotation) displayed, even though the mouse is not over the point anymore? But then a small mouse move will confirm that the mouse is not over the point, and remove the annotation... so that would replace the infinite loop with one iteration of the loop per mousemove event. Best would be to avoid this altogether, perhaps by disabling autorange when adding this annotation, or I suppose in principle we could add an annotation attribute to tell us not to consider this annotation in autorange calculations... it will still display as long as the arrowhead is pointing to displayed coordinates.

@etpinard
Copy link
Contributor

I'm thinking maybe if the hover is triggered by rehover, add a delay after displaying the tooltip but before emitting the hover event. That way normal hover events still come immediately but once we get into a potential infinite loop we slow things down.

I'm a fan of this.

I suppose in principle we could add an annotation attribute to tell us not to consider this annotation in autorange calculations...

I'm also a fan of this. This could be a thing for traces too.

@KNejad
Copy link

KNejad commented Jul 18, 2019

Strangely, I'm getting a very similar issue with an on click event. It's happening on a large 3d plot (works fine on 2d). I want to add an annotation when the user clicks yet it seems to freeze the browser and call the plotly_click event in an infinite loop. Basically all I am doing is calling a relayout inside of a plotly_click callback.

I wouldn't expect the suspected cause of this issue to cause a problem with plotly_click since there should only be one click event.

@gvwilson
Copy link
Contributor

Hi - this issue has been sitting for a while, so as part of our effort to tidy up our public repositories I'm going to close it. If it's still a concern, we'd be grateful if you could open a new issue (with a short reproducible example if appropriate) so that we can add it to our stack. Cheers - @gvwilson

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug something broken
Projects
None yet
Development

No branches or pull requests

5 participants