Skip to content
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

Immutable mode #2389

Open
alexcjohnson opened this issue Feb 20, 2018 · 8 comments
Open

Immutable mode #2389

alexcjohnson opened this issue Feb 20, 2018 · 8 comments

Comments

@alexcjohnson
Copy link
Collaborator

Along with Plotly.react, it would be nice if we would never mutate gd.data and gd.layout, just make new changed objects and alert the user to the change. We can't make this the default behavior in v1 since some users depend on gd.data and gd.layout keeping the identity of the objects they initially passed in - though there are some cases already where they are not. But that rule holds well enough that some folks depend on it, so immutability would have to be a config argument.

In general all of the plot modification methods except Plotly.react (Plotly.restyle, relayout, update, extendTraces etc..) modify gd.data and gd.layout in place to make the requested updates. Most (but not all) then emit an event you can use to see that the plot state has changed. But also there are modifications that happen automatically during drawing the plot, principally (if not entirely) pushing auto values (axis ranges, colorscale ranges) back to gd.data and gd.layout so that future minor updates don't need to recalculate these. This too is something we might be able to avoid doing, but probably not until v2.

So there are two things we should do:

  • Make all updates to gd.data and gd.layout immutably, conditional on a config argument.
  • Streamline the way we alert the user that the state has changed, so that they can feed this new state back into their app state. It seems like once we have immutable changes, it might be possible without any changes to the events from plotly.js... the react wrapper would have to bind to all the events that might carry state changes initiated from the UI, and also check after every update initiated by the wrapper itself, whether gd.data === prevData and gd.layout === prevLayout... but seems like it would be much easier for the react wrapper if there were a single "new state" event that collects all of these.

See plotly/react-plotly.js#43

@alexcjohnson
Copy link
Collaborator Author

cc @nicolaskruchten @etpinard

@nicolaskruchten
Copy link
Member

I'm a big fan of this idea and approach, as it seems to really close the gap between React's view of the world and the way plotly.js works :)

@vdh
Copy link
Contributor

vdh commented Feb 22, 2018

I think for true immutability, it would also be necessary to move away from requiring the external state contain a whole DOM element (graphDiv / gd). While it's forgivable to ask people to cache a DOM element in the immediate component's state, it's not immutable to expect the state manager (such as Redux) to be passing this DOM element around.

For example, you can't serialise or unserialise a DOM element (for saving/loading to a server/local storage), and you can't shallow compare it when rendering.

As a newcomer to Plotly, I've found it quite confusing how to actually handle onUpdate / onInitialized and map the updates back to an immutable state (generating new data and layout props), because all the examples do this whole graphDiv DOM element + revision prop cheat…?

@nicolaskruchten
Copy link
Member

nicolaskruchten commented Feb 22, 2018

@vdh I don't think it's necessary to store a whole DOM node in state. Some of our examples do this for convenience because the DOM node has layout and data etc attached to it but you can just as easily extract those plain, JSON-ify-able objects and store them in your state :)

@nicolaskruchten
Copy link
Member

(I'd be happy to help sort things out with some examples etc if you create an issue in https://github.com/plotly/react-plotly.js or https://github.com/plotly/react-plotly.js-editor as appropriate with your specific concerns!)

@janosh
Copy link

janosh commented Sep 3, 2019

Is there a PR for this yet or is this being developed internally?

@twavv
Copy link

twavv commented Aug 23, 2021

I just ran into this. At least while using react-plotly.js, passing objects that are immutable (they've been Object.freeze'd) results in Plotly just not rendering anything and showing no output (no errors logged or anything). This took me a long while to figure out, so posting here for posterity.

It's probably especially an issue in React land where immutability is the default (and all of hooks is build on the idea of immutability and referential equality is structural equality)

@allsyntax
Copy link

Came across this in the README. Is it still an issue, or being developed?

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

No branches or pull requests

6 participants