Plotly.js: Adding traces on hover can cause infinite loops

Created on 11 Mar 2017  Â·  11Comments  Â·  Source: plotly/plotly.js

MRE of the problem (hover on any of the markers) -- http://codepen.io/cpsievert/pen/dvWydK

FYI this was working pre-1.24.0 -- http://codepen.io/cpsievert/pen/qrmBVx

discussion needed bug ♥ NEEDS SPON$OR

Most helpful comment

I do a check to make sure I don't add the same trace twice. The example I linked to was a simplified version to help isolate the issue.

After that check do you still have a problem (and if so can you post it?), or were you just hoping not to need the check?

I wouldn't want to add a new event type for rehover, because then people would have to know that in the normal case they need to listen to both types. But we could certainly add something to the event to indicate whether it was triggered by a mouse event or something else like a rehover. Like... the mouse event itself? That could come in handy for other purposes too.

All 11 comments

I think either 1.24.1 or 1.24.2 might already fix this. See: #1446

Thanks for posting @cpsievert !

1446 fixed a plotly_unhover -> Plotly.Fx.hover -> plotly_unhover infinite loop. But looks like addTraces suffers from another https://github.com/plotly/plotly.js/pull/1304 side-effect.

We should fix this before releasing 1.25.0.

Ok. This problem is pretty tricky and is quite frankly (unless @cpsievert can prove otherwise) an edge case.

The infinite loop is triggered only when addTraces adds a trace containing similar enough coordinates to the one given in the plotly_hover event data. For example take http://codepen.io/etpinard/pen/xqrjza which adds traces outside the hover distance and does not trigger an infinite loop.

In @cpsievert 's http://codepen.io/cpsievert/pen/dvWydK, an infinite loop is triggered since https://github.com/plotly/plotly.js/pull/1304 because:

  • addTraces now leads to a Plots.rehover call (via Plotly.redraw),
  • Plots.rehover leads to a Fx.hover cal which then leads to
  • Fx.hover emiiting plotly_hover even though the mouse position hasn't changed (here hoverChanged(gd, evt, oldhoverdaa) is true as the curveNumber changed after the addTraces call)
  • and then the plotly_hover handler triggers addTraces

    - :loop:

Now, how to fix this problem?

In my opinion, I think the most robust solution would be to make rehover not trigger gd.emit('plotly_hover') while still updating gd._hoverdata and the visible hover labels.

@rreusser @alexcjohnson event data updates wasn't :lock: ed down in the https://github.com/plotly/plotly.js/pull/1304 tests, so I guess this would be ok?

Honestly I'm not sure if I would consider this a bug - yes it's an infinite loop, but you'd get an explosion of traces in a case like this anyway, at least for real data sets where you cause hundreds of hover events every time the mouse crosses the plot. And I do think we want rehover-hovers to emit an event so the more typical case of updating something outside the plot (or on a different subplot at least) will still happen.

Is there a more realistic use case for this? There are always going to be ways to trigger infinite loops when you modify a plot from inside an event handler, and I think at some level it's up to the user to avoid these, otherwise we'll be restricting what they can do.

Is there a more realistic use case for this?

I'm using it to implement all of this -- https://cpsievert.github.io/plotly_book/linking-views-without-shiny.html

you'd get an explosion of traces in a case like this anyway

I do a check to make sure I don't add the same trace twice. The example I linked to was a simplified version to help isolate the issue.

@cpsievert just to clarify: the objective of #1304 is to update the hover state when the plot changes, e.g. streaming or animation and maybe a few other cases @alexcjohnson mentioned that were considered long-running issues where the hover state reflected outdated data until new mouse input triggered a new hover.

I think plotly_hoverupdate on rehover wouldn't be bad if it's not too bad to implement and if it's enough to disambiguate hover state changing as the result of input vs. reflecting new data.

I do a check to make sure I don't add the same trace twice. The example I linked to was a simplified version to help isolate the issue.

After that check do you still have a problem (and if so can you post it?), or were you just hoping not to need the check?

I wouldn't want to add a new event type for rehover, because then people would have to know that in the normal case they need to listen to both types. But we could certainly add something to the event to indicate whether it was triggered by a mouse event or something else like a rehover. Like... the mouse event itself? That could come in handy for other purposes too.

After that check do you still have a problem (and if so can you post it?), or were you just hoping not to need the check?

Ooops -- I thought I had implemented that check, but it appears I haven't yet. Will work on it and report back if I still have issues, thanks!

Looks like this issue is up in the air.

Dropping from 1.25.0 for now. Adding discussion needed.

This seems to have broken the last codepen on the hover event docs page https://plot.ly/javascript/hover-events/

https://codepen.io/plotly/pen/eJOyej

FYI @cldougl

This issue has been tagged with NEEDS SPON$OR

A community PR for this feature would certainly be welcome, but our experience is deeper features like this are difficult to complete without the Plotly maintainers leading the effort.

Sponsorship range: $5k-$10k

What Sponsorship includes:

  • Completion of this feature to the Sponsor's satisfaction, in a manner coherent with the rest of the Plotly.js library and API
  • Tests for this feature
  • Long-term support (continued support of this feature in the latest version of Plotly.js)
  • Documentation at plotly.com/javascript
  • Possibility of integrating this feature with Plotly Graphing Libraries (Python, R, F#, Julia, MATLAB, etc)
  • Possibility of integrating this feature with Dash
  • Feature announcement on community.plotly.com with shout out to Sponsor (or can remain anonymous)
  • Gratification of advancing the world's most downloaded, interactive scientific graphing libraries (>50M downloads across supported languages)

Please include the link to this issue when contacting us to discuss.

Was this page helpful?
0 / 5 - 0 ratings