feat(js): linked brushing via SelectionBus + Vega-Lite bridge demo#859
feat(js): linked brushing via SelectionBus + Vega-Lite bridge demo#859paddymul wants to merge 1 commit into
Conversation
Introduces a frontend-only selection bus for linked brushing between
DFViewer instances and external publishers (e.g. Vega-Lite brushes).
Subscribers receive same-page events via EventTarget; BroadcastChannel
fan-out covers cross-iframe / cross-tab cases. Messages dedupe by
source so a publisher does not receive its own echo.
DFViewer gains an optional onGridApiReady callback so consumers can
drive `applyTransaction` + `refreshCells({force: true})` directly,
avoiding the remount-via-key workaround. Registers the AG-Grid v33
modules that back those APIs (Event/Row/Render/ClientSideRowModelApi).
Two Storybook stories demo the bus: LinkedBrushing (two DFViewers +
button publisher) and LinkedBrushingVega (a Vega-Lite scatter <->
DFViewer). vega-embed is a devDependency only and is loaded via
dynamic import(), so it never ships in the published bundle.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c0026105d9
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const updated = (view.data("source_0") as Row[]).map( | ||
| (d) => ({ | ||
| ...d, | ||
| __selected: ids.has(d.id) ? 1 : null, |
There was a problem hiding this comment.
Drive Vega highlight from a field used by the spec
This bus-to-Vega handler mutates __selected, but the Vega-Lite spec in this story never encodes __selected in any mark/encoding, so incoming selections from the grid do not produce a visible chart highlight despite the comment and story text claiming they do. In practice, clicking a DFViewer row publishes on the bus, the dataset is replaced, and the chart appears unchanged unless the local brush state changes. Either bind __selected into a visual channel/layer or update the brush signal directly so remote selection is actually rendered.
Useful? React with 👍 / 👎.
📦 TestPyPI package publishedpip install --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==0.14.8.dev26464044337or with uv: uv pip install --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo==0.14.8.dev26464044337MCP server for Claude Codeclaude mcp add buckaroo-table -- uvx --from "buckaroo[mcp]==0.14.8.dev26464044337" --index-strategy unsafe-best-match --index-url https://test.pypi.org/simple/ --extra-index-url https://pypi.org/simple/ buckaroo-table📖 Docs preview🎨 Storybook preview |
Summary
SelectionBus(packages/buckaroo-js-core/src/selection/SelectionBus.ts) — a frontend-only pub/sub for linked brushing. Same-page subscribers viaEventTarget, cross-iframe / cross-tab viaBroadcastChannel, dedupe bysourceso publishers don't receive their own echo.onGridApiReady?: (api: GridApi) => voidprop onDFViewer(threaded throughDFViewerInfinite/DFViewerInfiniteInner). Consumers use the AG-Grid API directly to driveapplyTransaction+refreshCells({ force: true }), so a remote selection updates highlights without remounting the grid (scroll position preserved).EventApiModule,RowApiModule,RenderApiModule,ClientSideRowModelApiModule.vega-embedis a devDependency only and is loaded via dynamicimport()inside the story, so it never ends up in the publishedbuckaroo-js-corebundle.Test plan
pnpm test— 280 passed including newSelectionBus.test.ts(pub/sub roundtrip, source dedupe, channel filter, singleton).pnpm exec tsc --noEmitclean.pnpm storybook, openBuckaroo / LinkedBrushing— clicking rows in Grid A highlights Grid B (and vice versa); preset buttons broadcast on the bus.Buckaroo / LinkedBrushingVega— brush a region on the scatter; matching rows highlight in the DFViewer.BroadcastChannel(not exercised in CI).Notes
selection_channel/selection_keyprop pair onDFViewer. That higher-level API is the natural follow-up — the bus and the api-ready callback are the load-bearing primitives it would sit on.🤖 Generated with Claude Code