mirror of
https://github.com/olehomelchenko/astrolabe.git
synced 2026-08-08 02:02:33 +00:00
Inspector: multi-view data inspection with a per-table view picker
This commit is contained in:
@@ -42,26 +42,25 @@ above it is data; everything below it is a Vega `View` we own and must tear down
|
||||
|
||||
### The data inspector rides the boundary too
|
||||
|
||||
The data inspector (the Live Preview and Chart Builder panel showing the chart's input
|
||||
vs. resolved rows — spec §04) reads runtime rows through the handle, never the raw view:
|
||||
`RenderHandle.inspectData()` returns the input + resolved tables (`{ input, resolved }`,
|
||||
or `null` when no chart is up), wrapping the view exactly like `toImageURL`. It works in
|
||||
two layers:
|
||||
The data inspector (the Live Preview and Chart Builder panel showing each drawn table's
|
||||
input vs. resolved rows — spec §04) reads runtime rows through the handle, never the raw
|
||||
view: `RenderHandle.inspectData()` returns the inspectable tables (`{ tables }`, or `null`
|
||||
when no chart is up), wrapping the view exactly like `toImageURL`. It works in two layers:
|
||||
|
||||
- **Enumerate + pick (`view.getState` + `core/result-data`).** A compiled Vega dataflow
|
||||
holds many named datasets; Vega-Lite names them by convention — `source_<n>` per parsed
|
||||
source, `data_<n>` per transform stage. The pure `pickSourceDataset` / `pickResultDataset`
|
||||
choose the **most-upstream source** (the input) and **most-downstream output** (what the
|
||||
marks draw), skipping dataflow internals (`marks`, `root`, layout, selection `*_store`s).
|
||||
A spec with no transforms resolves both to the same table. The picking is pure (in `core`,
|
||||
unit-tested); only the enumeration touches the view.
|
||||
- **Read lazily.** `getState` serializes the datasets it lists, so it is **only called while
|
||||
the panel is open** — a collapsed inspector costs nothing, which is why the panel reads on
|
||||
demand rather than on every render.
|
||||
|
||||
Limitation: one name per direction can't represent a multi-view spec (layer/concat/facet
|
||||
produce several `data_<n>`); the most-downstream/upstream ones are returned, and a full
|
||||
dataset selector is left as a future option.
|
||||
- **Enumerate from the compiled spec (`core/inspect-views`).** A composed spec draws
|
||||
several tables; `inspectableViews` walks the compiled Vega spec — the marks tree's
|
||||
`from.data` (what each mark draws) and `data[].source` (the lineage, the documented Vega
|
||||
format) — to list, in document order, one entry per **distinct drawn table** with its
|
||||
`resolved` (post-transform, what the marks draw) and `input` (most-upstream source) ends.
|
||||
Enumerating by drawn table, not by authored view, is forced by Vega-Lite desugaring (a
|
||||
`point: true` line compiles to two layers — a compiled table can't be traced back to one
|
||||
authored view). Selection `*_store`s and `facet_domain*` layout tables aren't drawn, so
|
||||
they fall out for free. The walk is pure (in `core`, unit-tested); the boundary reads each
|
||||
table's rows via `view.data(name)`.
|
||||
- **Read lazily.** Reading serializes rows, so it happens **only while the panel is open** —
|
||||
a collapsed inspector costs nothing, which is why the panel reads on demand rather than on
|
||||
every render. (A multi-view spec yields several tables; the panel's `SelectControl` picker
|
||||
chooses which to show — labels never expose Vega's compiler names, see arch 10.)
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@ collection (`spec-fields`), config baking (`spec-config`), standalone export
|
||||
view's columns in a composition whose views bind different datasets.
|
||||
- **Extract inline data** (`app/stores/ExtractStore`) lifts only the top-level
|
||||
`data` block.
|
||||
- **Data inspector** (`core/result-data`, `DataInspector`) surfaces one input +
|
||||
one resolved table; a composition produces several `source_<n>`/`data_<n>`.
|
||||
- **Data inspector** (`DataInspector`) surfaces one input + one resolved table; a
|
||||
composition produces several `source_<n>`/`data_<n>`.
|
||||
- **`deriveSnippetName`** (`core/snippet`) reads top-level `mark`/`encoding` only,
|
||||
so a composed spec falls back to the default name (graceful, not a bug).
|
||||
- **Chart builder** is single-view by design; its strict round-trip hydration
|
||||
@@ -73,12 +73,25 @@ collection (`spec-fields`), config baking (`spec-config`), standalone export
|
||||
for every form (library ref case-insensitive, inline, named-inline, self-defined
|
||||
`datasets`, url/generator → none); the three Monaco providers and the
|
||||
facet/repeat defaults pass the cursor offset.
|
||||
- **M4 — multi-view inspection** (pulled ahead of M3) — group the dataflow's
|
||||
datasets into per-view input/resolved pairs (`result-data`) and add a view
|
||||
selector to `DataInspector` (new interactive widget → `/council`). The data
|
||||
inspector executes the live pipeline, so it is the place to review post-transform
|
||||
rows (melt/fold/pivot/aggregate); today it surfaces one heuristic input/resolved
|
||||
pair across the whole composition, with no per-view choice.
|
||||
- **M4 — multi-view inspection** ✅ (pulled ahead of M3) — `core/inspect-views`
|
||||
enumerates the distinct tables the marks draw (from the compiled Vega spec's
|
||||
`from.data` + `data[].source` lineage), each with its input + resolved ends;
|
||||
`RenderHandle.inspectData()` returns those tables with rows; `DataInspector` adds
|
||||
a `SelectControl` view picker (hidden for the single-table case), labels via
|
||||
`inspectViewLabel` (named dataset or "View N", never compiler names) + a
|
||||
`columns · rows` cue. Enumerating by drawn table (not authored view) is forced by
|
||||
Vega-Lite desugaring (a `point: true` line compiles to two layers). Replaced the
|
||||
single-pair `core/result-data`.
|
||||
- **M5 — live / interactive inspection** — make the inspector react to interactive
|
||||
selections. A selection-as-**filter** (`filter: {param}`) recomputes a downstream
|
||||
view's `data_N` live, so the inspector should re-read on selection change to show
|
||||
the brushed result ("what am I visualizing _now_"); a selection-as-**highlight**
|
||||
(a `condition` encoding) changes no data, so nothing to react to. Needs a refresh
|
||||
model beyond the per-render `renderEpoch`: subscribe to the live view
|
||||
(`view.addDataListener` / selection signals), debounced (a brush drag pulses
|
||||
continuously — latency/interaction `/council` pass), and a default-on-vs-toggle
|
||||
choice. Selection `*_store` tables are not drawn, so the M4 enumeration already
|
||||
ignores them.
|
||||
- **M3 — view-scoped extract** — seed Extract from the focused view's inline data
|
||||
(reusing the cursor-scope machinery) and rewrite that view's `data`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user