Powered by AppSignal & Oban Pro

Binding to Click Events

02_binding_to_click_events.livemd

Binding to Click Events

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

Section

Spawn a dedicated listener process and subscribe it so click events stream into a Kino.Frame in real time — no need to re-evaluate cells.

alias Plotly.{Figure, Scatter}
alias Plotly.Kino.PlotlyLive

output = Kino.Frame.new()

chart =
  Figure.new()
  |> Figure.add_trace(Scatter.new(
    x: [1, 2, 3, 4, 5],
    y: [2, 4, 1, 5, 3],
    mode: "markers+text",
    text: ["Alpha", "Beta", "Gamma", "Delta", "Epsilon"],
    textposition: "top center",
    marker: %{size: 12}
  ))
  |> Figure.update_layout(title: "Click points — output appears below")
  |> PlotlyLive.new()

# Spawn a persistent listener process and subscribe IT to click events
listener =
  spawn(fn ->
    for _ <- 1..1000 do
      receive do
        {:click, event} ->
          [point | _] = event["data"]["points"] || []
          text = "**Clicked:** x=#{point["x"]}, y=#{point["y"]}, label=#{point["text"]}"
          Kino.Frame.render(output, Kino.Markdown.new(text))
      after
        60_000 -> :timeout
      end
    end
  end)

PlotlyLive.subscribe(chart, listener, :click, :click)

Kino.Layout.grid([chart, output])