Powered by AppSignal & Oban Pro

Persist User Changes

18_persist_user_changes.livemd

Persist User Changes

Mix.install([
  {:plotly_ex, "~> 0.3"},
  {:kino, "~> 0.18"}
])

Section

layout.uirevision controls whether plotly.js preserves the user's interactive state (zoom, pan, legend toggles) when the figure is updated via PlotlyLive.push.

When uirevision stays the same value across updates, the user's current view is preserved — only the data changes underneath. This is useful for live dashboards where users want to stay zoomed in while data refreshes.

Two-cell pattern: evaluate Cell A first, zoom in on the chart, then evaluate Cell B to push updates. Your zoom will be preserved.

Cell A — create the widget

alias Plotly.{Figure, Scatter}

kino =
  Figure.new(
    data: [Scatter.new(
      x: Enum.to_list(1..20),
      y: Enum.map(1..20, fn _ -> :rand.uniform() * 10 end),
      mode: "lines+markers",
      name: "live data"
    )],
    layout: %{
      title: "Step 0 — zoom in, then run Cell B",
      uirevision: "constant"
    }
  )
  |> Plotly.show()

Cell B — push updates (zoom is preserved)

for i <- 1..8 do
  new_y = Enum.map(1..20, fn _ -> :rand.uniform() * 10 end)

  Figure.new(
    data: [Scatter.new(x: Enum.to_list(1..20), y: new_y, mode: "lines+markers", name: "live data")],
    layout: %{title: "Update #{i} — zoom preserved (uirevision unchanged)", uirevision: "constant"}
  )
  |> then(&Plotly.Kino.PlotlyLive.push(kino, &1))

  Process.sleep(600)
end

:ok