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

Axes incorrect when updating layout but not data #316

Open
who-knows-who opened this issue Apr 4, 2023 · 4 comments
Open

Axes incorrect when updating layout but not data #316

who-knows-who opened this issue Apr 4, 2023 · 4 comments

Comments

@who-knows-who
Copy link

When updating the layout but passing a constant data object (or a new object but with nested constant objects), the traces stay the same but the axes reset to the defaults as if no data is plotted, causing the graph to be incorrect. The data points can also not be hovered over in this state.

Forcing the plot to redraw (e.g. by clicking 'Reset axes') corrects the plot and creating a deep copy of the data object before passing to the Plot component removes the issue.

Example at https://codesandbox.io/s/agitated-babycat-j9hjb8?file=/src/App.js (issue can be seen when changing text in input)

I have been unable to recreate this with pure plotly.js but I am less familiar with that library, so sorry if the issue is there instead.

@msimoni18
Copy link

You have to use useState when updating the layout. Adding the code below should no longer automatically adjust the x-axis.

...

  const [layout, setLayout] = React.useState({
    xaxis: {
      title: axisTitle
    }
  });

  React.useEffect(() => {
    setLayout(prevLayout => ({
      ...prevLayout, 
      xaxis: {
        ...prevLayout.xaxis,
        title: axisTitle
      }
    }))
  }, [axisTitle])

...

@who-knows-who
Copy link
Author

You have to use useState when updating the layout. Adding the code below should no longer automatically adjust the x-axis.

React advices against this pattern (updating one state based on another): https://react.dev/learn/you-might-not-need-an-effect#updating-state-based-on-props-or-state

@msimoni18
Copy link

msimoni18 commented Apr 4, 2023

You can also do it this way if you only want to manage one state.

function App() {
  const [layout, setLayout] = React.useState({
    xaxis: {
      title: "x axis"
    }
  });

  const handleAxisChange = (event) => {
    setLayout((prevLayout) => ({
      ...prevLayout,
      xaxis: {
        ...prevLayout.xaxis,
        title: event.target.value
      }
    }));
  };

  return (
    <div>
      <input value={layout.xaxis.title} onChange={handleAxisChange} />
      <Plot data={data} layout={layout} />
    </div>
  );
}

@who-knows-who
Copy link
Author

Unfortunately the actual use case that lead to this is a bit more complicated (multiple axis titles, switching between 2D/3D so titles are at layout.(x/y)axis.title or layout.scene.(x/y/z)axis.title, wanting to use those strings elsewhere, etc.) so storing the whole layout as state isn't really feasible.

Taking a deep copy of the data object between generation and use is probably the cleanest solution for now

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

No branches or pull requests

2 participants