Isolate a series on legend double-click (Plotly-style)

AL
13d ago
+399-14

Closes #505.

What

Double-clicking a legend row shows only that series/category; double-clicking the row that is already alone restores every entry (Plotly's legenddoubleclick model). Single click keeps toggling one entry exactly as before. New xy.legend(isolate=False) opts out — same default-on, opt-out-only wire rule as toggle/highlight, and independent of toggle (with toggle=False, single clicks are inert while double-click still isolates).

beforeafter double-click on "Beta"
all four seriesonly Beta draws, the other rows fade

How

  • No disambiguation delay. Single clicks commit immediately (Plotly waits 300 ms). So when dblclick fires, the burst's first click has already toggled the row; the client ignores the second click (event.detail >= 2) and decides isolate-vs-restore against the pre-gesture state. End state equals a fresh isolate; the transient first-click frame is the recorded cost (spec §10).
  • One path for every row. _legendToggle is factored into _legendSetOff (row chrome, view-held off-sets, GPU flag, kernel message) + _legendApplyBatch (category re-filter once per affected trace, badges, pick). Isolate walks all linked rows across every legend box in legend order; each changed row ships its own legend_toggle and xy:legendtoggle; one xy:legendisolate {name, isolated, traces, category?} names the gesture (not fired when nothing changed).
  • The second press is preventDefaulted on mousedown so the label text is not selected; single presses keep native focus/selection rules.

Spec / docs

  • spec/api/interaction.md §10: the gesture and its limits. §3 event table now lists xy:legendtoggle — it was dispatched but missing from the "those nine are the whole surface" list — plus xy:legendisolate.
  • spec/design/wire-protocol.md: isolate is not a message of its own.
  • docs/components/legends.md: new "Toggle and Isolate Series" section with a demo.

Tests

  • test_legend_isolate_option: wire opt-out, independence from toggle, public Legend positional order still binds.
  • Browser probes drive a real burst (click detail 1, click detail 2, dblclick) against the built client: default path (isolate, restore, isolate from a partly-hidden chart), isolate=False (byte-identical pre-existing toggle behavior on the wire), toggle=False. They assert vertex-buffer row counts, row data-xy-legend-off state, the exact legend_toggle message sequence, and the xy:legendtoggle/xy:legendisolate events.
  • Full tests/ suite, ruff check/ruff format --check, ty check (no new diagnostics vs main), docs-site tests (119 passed) run locally.

Summary by CodeRabbit

  • New Features

    • Double-click a legend entry to isolate that series or category; double-click the sole visible entry to restore all entries.
    • Configure isolation independently from single-click visibility toggling, with isolation enabled by default.
    • Legend interactions now emit dedicated toggle and isolation events.
  • Documentation

    • Added guidance and examples covering legend hover, toggle, isolation behavior, configuration options, events, and protocol details.