Chart theming: selectable chart theme + spec↔config merge/extract

This commit is contained in:
2026-06-12 16:48:48 +03:00
parent fe9d588103
commit 44a601affd
27 changed files with 1103 additions and 121 deletions
+7
View File
@@ -76,3 +76,10 @@ When a snippet's spec embeds its data inline, the user can lift that data out in
- A toast confirms the dataset was created, and the modal closes.
- The user can cancel the modal at any time, leaving the spec unchanged.
- Dataset-side specifics (formats, storage, the bidirectional snippet↔dataset link) are described in _Datasets_.
## G. Spec ↔ Config Actions
Two editor actions make the injected chart theme portable (see _Live Preview → Chart theme_). Their visible home is a **Config** menu in the editor toolbar (a value-select disclosure listing both actions with a one-line description each), disabled when no snippet is active or the read-only published view is shown; the editor's right-click context menu and F1 command palette offer the same actions as expert accelerators. Both actions replace the document as a single undoable edit (⌘/Ctrl+Z restores), reformatted in the app's JSON style, and both refuse with a clear toast when the document is not a valid JSON object.
- **Merge Chart Theme into Spec** — bakes the currently selected chart theme into the spec's own `config` block, deep-merging under any existing `config` so the spec's own keys win and the rendered result is unchanged. Use it before publishing a spec somewhere the app's theme won't follow. When the selected theme injects nothing (Stock Vega-Lite), the action explains there is nothing to merge.
- **Extract Config from Spec** — removes the spec's `config` block and copies it to the clipboard, for cleaning baked-in styling out of a pasted spec. The clipboard copy happens **before** the removal; if the copy fails, the spec is left unchanged so the config is never lost. A spec with no config block reports that and changes nothing.
+15
View File
@@ -36,6 +36,21 @@ Behavior of the selected mode:
- The selected mode persists across sessions, stored in _Settings_ as `previewFitMode`.
- The default is the natural Original mode.
## Chart theme
The preview pane header carries a **Chart theme** picker — a value-select disclosure choosing which Vega-Lite config is injected when charts render:
- **Astrolabe** (default) — the house style; follows the app's light/dark theme.
- **Stock Vega-Lite** — injects nothing; charts render exactly as plain Vega-Lite defaults would anywhere else (white background, default palette and fonts).
- **Presets** — the `vega-themes` preset configs (Excel, ggplot2, FiveThirtyEight, LA Times, Power BI, the Carbon family, …), rendered verbatim and independent of the app's light/dark theme.
Behavior:
- The choice is a **global preference**, not per-snippet; it persists across sessions, stored in _Settings_ as `ui.chartTheme`.
- The injected config applies at render time only — it is never written into the snippet's stored spec. A spec's own `config` block overrides the injected config property by property, so a snippet can opt out of any part of it locally (see also _Spec Editor → Spec ↔ config actions_).
- Image export reflects the selected theme: exports render from the same themed view.
- The Chart Builder preview and onboarding thumbnails are app surfaces and stay house-styled regardless of this choice.
## Export control
The preview pane header also carries a per-chart **Export** control — a disclosure for copying or downloading the current chart's spec, or downloading its rendered image (PNG/SVG). It exports what the preview shows. The behavior is specified in _Import & Export → Per-chart export_; it lives in this header because the image formats are produced from the live rendered view.
+1
View File
@@ -74,6 +74,7 @@ Governs how dates are rendered throughout the app, for example the timestamps sh
The following preferences also persist locally across sessions and, like the clusters above, are managed by controls in the pane they affect; they are documented in their own sections:
- **Preview fit mode** — how the preview is sized/fit; see _Live Preview_.
- **Chart theme** — which config charts render and export with (`ui.chartTheme`); see _Live Preview → Chart theme_.
- **Snippet sort preference** — the snippet list's sort field and direction; see _Snippet Library_.
## Behaviors
+2 -1
View File
@@ -77,12 +77,13 @@ The current **Dataset** version is `2`. The v1→v2 migration reflects the URL-s
| `performance.renderDebounce` | number | Delay (ms) before re-rendering the preview after edits. |
| `ui.theme` | string | App theme: `light` or `dark`. |
| `ui.previewFitMode` | string | Preview sizing: `default`, `width`, `height`, or `full`. |
| `ui.chartTheme` | string | Chart theme: `astrolabe`, `stock`, or a preset id. |
| `formatting.dateFormat` | string | Date display mode: `smart`, `iso`, or `custom`. |
| `formatting.customDateFormat` | string | Pattern used when `dateFormat = custom`. |
A reference shape:
UserSettings = { version, editor: { fontSize, theme, minimap, wordWrap, lineNumbers, tabSize }, performance: { renderDebounce }, ui: { theme, previewFitMode }, formatting: { dateFormat, customDateFormat } }
UserSettings = { version, editor: { fontSize, theme, minimap, wordWrap, lineNumbers, tabSize }, performance: { renderDebounce }, ui: { theme, previewFitMode, chartTheme }, formatting: { dateFormat, customDateFormat } }
## D. App / UI preferences (persisted separately)