Chart builder: intent front door, Heatmap mark, role-aware guidance

This commit is contained in:
2026-06-13 12:08:11 +03:00
parent 4e5108f434
commit 0470389b41
11 changed files with 1129 additions and 37 deletions
+46 -2
View File
@@ -25,6 +25,49 @@
Newest first. The at-a-glance build-order tracker is §4; per-item detail is §3. This log is
the quick "where are we" — read it first.
- **2026-06-13 (guidance: reason over role, not raw type)** — closed a **false-positive class**
in `builderWarnings` (eng-council + council consult). A histogram (bar, binned-Q X, count Y)
tripped "two measures → scatter" because `isMeasureMapping`/`effectiveType` ignored `bin`.
Fix: `isMeasureMapping` is now **bin-aware** (a binned field is a discretized dimension —
mirrors Vega-Lite's own `isDiscrete(fieldDef)`); a new `isReorderableCategory` keeps Sort
from being offered on a histogram's binned axis (the council-flagged regression); the scatter
rule routes through the role predicate + a positive mark list (deletes the `mark !== 'rect'`
bolt-on); `stackMeasureChannel` excludes binned. Pinned with regression tests (no
scatter/Sort on a histogram; real bar still sorts; two raw measures still nudge). Promoted to
**/alignment check #15** ("reason over role, not raw type"). **Not done (deliberately):**
intent-gating the taste warnings — verified no current intent layout trips one, so the gate
would be dead code; recorded as a standing principle in `builderWarnings` instead. The
broader posture (curate good via the front door > enumerate bad via warnings) is the council's
recommended bottom for the combinatorial-warning worry. Verified: typecheck + test (913) +
eslint + build.
- **2026-06-13 (3A + heatmap mark)** — **the intent-first front door shipped (Tier C), and
the mark set gained `rect` (Heatmap).**
- **Heatmap mark** — `rect` added to `MARK_TYPES` (six marks; labelled **Heatmap** in the
picker, which now wraps to two rows in the 320360px pane). Guidance rewired: both-axes
rule covers heatmaps; a new hint nudges a Colour measure on a two-axis heatmap with a
one-click **Colour by count**; `rect` is exempt from the two-measures→scatter nudge (a
binned 2-D histogram is valid). Never the auto-default mark; names read "Heatmap of …".
Spec §06 mark-type + guidance updated.
- **3A intent front door** — a **persistent strip** at the top of the config pane (the
interaction model chosen with the user over a replace-on-open screen — "shows all
controls + a do-it-for-me", the Tableau _Show Me_ parallel). Core (`chart-builder.ts`):
`CHART_INTENTS` (Compare/Ranking/Change-over-time/Correlation/Distribution/Part-to-whole/
Heatmap), `intentLayout` (intent × column-roles → mark + channels), `intentApplicable`
(Show-Me gating), `applyIntent` (reshape, keep dataset/transforms/title), and
`activeIntent` (structural match → the live chart's intent highlights with **no stored
state**; lights the smart default on open). Store: `setIntent`. UI: an APG **toolbar** of
toggle chips (roving tabindex, arrows move / Enter applies, accent-ring selection,
`aria-disabled`+reason on inapplicable intents).
- **Council** run on the front-door copy/flow → toolbar (not radiogroup — select-on-arrow
would reshape the chart), disabled-focusable-with-reason, intent-framing (Heatmap kept as
the one chart-type label, mirroring the mark). Recorded in `architecture/10` §5; spec §06
gained an **Intent (the front door)** subsection.
- **Verified:** `typecheck` + `test` (909, +17: intent core/store, heatmap guidance/naming)
- `eslint` + `build`. **Owed:** a visual pass on the live strip (chips, disabled states,
keyboard) + a heatmap rendered from real data. **Open (user's call):** whether the
_Heatmap_ chip should read as an intent phrase instead (council's intent-framing point).
- **2026-06-12 (3D)** — **entry points & discoverability shipped. Up next: 3A (the
front door now has somewhere to be found).**
- **Library creation surface forked:** primary **Build Chart** (accent, takes the
@@ -557,9 +600,10 @@ Phase 1 1A actionable hints ✓ done
Phase 2 2A value-or-field channels (Property model) ✓ done
2B field shelf + in-place type cycling ✓ done (field-first + on-chart shelves)
Phase 3 3D entry points & discoverability ✓ done (2026-06-12)
3A intent-first front door (Tier C) ← next; built on 2B; the defining feature
3B starter examples
3A intent-first front door (Tier C) ✓ done (2026-06-13); persistent strip
3B starter examples ← next; pairs with 3C
3C open in builder (strict hydration) ← added 2026-06-11; pairs with 3B
Marks +rect (Heatmap) ✓ done (2026-06-13)
Phase 4 (gated) theta/facets/styling-overrides/undo/lookup — decide after Phase 3
Also shipped (builder UX/perf, from dogfooding): near-fullscreen modal, internal-scroll