# ggsvelte — full docs corpus for language models
Generated from the docs guide sources and the examples manifest (one source, three uses). Each example shows its canonical PortableSpec JSON (what an agent should emit) and the equivalent Svelte component usage.
## Current release facts
- Package version: 0.37.0
- Defaults edition: 2
- Registered chart themes (33): default, light, dark, minimal, ggplot2, classic, bw, hrbr, few, clean, fivethirtyeight, economist, tufte, linedraw, void, stata, stata_s1color, solarized, solarizeddark, economist_white, solarized_2, solarized_2dark, wsj, hc, hcdark, pander, base, igray, map, solid, grey, gray, test
---
# Getting started
ggsvelte is ggplot2's layered grammar for Svelte 5. A plot is data + an
aesthetic mapping + one or more layers, and every plot normalizes to a
PortableSpec: strict JSON, no functions, no closures. That JSON is the surface
to generate, validate, and correct against.
## Install
```sh complete
bun add @ggsvelte/svelte
# or: npm install @ggsvelte/svelte
# or: pnpm add @ggsvelte/svelte
```
`@ggsvelte/spec` (schema, validate, builder) and `@ggsvelte/core`
(pipeline, headless render) are dependencies of the Svelte package. Install
them directly for spec-only or headless work. The `ggsvelte-render` CLI is
its own package — install `@ggsvelte/cli` in every sandbox where an agent
authors specs, so validation errors and chart-quality warnings surface
before a chart ships. The agent skill is also its own package:
`@ggsvelte/skill` (`SKILL.md` + `references/` at the package root) —
install it and copy/symlink `node_modules/@ggsvelte/skill` into the agent's
skills directory as `ggsvelte/` (or point the agent at
`node_modules/@ggsvelte/skill/SKILL.md` directly). Bundled teaching data
lives at `@ggsvelte/svelte/data`.
## A complete Svelte file
`src/routes/+page.svelte`:
```svelte complete
```
Omitted width follows the container; default height is 400px. No chart CSS is
required. During server rendering the plot uses a deterministic 832 x 400
fallback, then measures the real container after hydration; inside
`display: none` or a zero-width track it stays not-ready until the container
has positive width.
## The PortableSpec contract
The same chart as JSON. This is the canonical form — the Svelte component and
the TypeScript builder both normalize to it.
```json fragment
{
"data": {
"name": "kyotoSakura"
},
"aes": {
"x": {
"field": "year"
},
"y": {
"field": "bloomDate"
}
},
"layers": [
{
"geom": "rect",
"data": {
"values": [
{
"epoch": "Medieval warm period",
"year": 950,
"until": 1250,
"top": "03-18",
"bottom": "05-10"
},
{
"epoch": "Little Ice Age",
"year": 1300,
"until": 1850,
"top": "03-18",
"bottom": "05-10"
},
{
"epoch": "Industrial era",
"year": 1850,
"until": 2026,
"top": "03-18",
"bottom": "05-10"
}
]
},
"aes": {
"x": null,
"y": null,
"xmin": {
"field": "year"
},
"xmax": {
"field": "until"
},
"ymin": {
"field": "top"
},
"ymax": {
"field": "bottom"
},
"fill": {
"field": "epoch"
}
},
"params": {
"alpha": 0.55
},
"inspect": false
},
{
"geom": "text",
"data": {
"values": [
{
"epoch": "Medieval warm period",
"midYear": 1100,
"nameDate": "03-14"
},
{
"epoch": "Little Ice Age",
"midYear": 1575,
"nameDate": "03-14"
},
{
"epoch": "Industrial era",
"midYear": 1938,
"nameDate": "03-14"
}
]
},
"aes": {
"x": {
"field": "midYear"
},
"y": {
"field": "nameDate"
},
"label": {
"field": "epoch"
},
"color": {
"value": "#6b7075"
}
},
"params": {
"size": 11
},
"inspect": false
},
{
"geom": "rule",
"aes": {
"color": {
"value": "#b7c1cd"
},
"linetype": {
"value": "dotted"
}
},
"params": {
"yintercept": "04-05",
"linewidth": 0.75
},
"inspect": false
},
{
"geom": "rule",
"aes": {
"color": {
"value": "#b7c1cd"
},
"linetype": {
"value": "dotted"
}
},
"params": {
"yintercept": "04-25",
"linewidth": 0.75
},
"inspect": false
},
{
"geom": "point",
"aes": {
"color": {
"value": "#4a5568"
}
},
"params": {
"alpha": 0.55,
"size": 1.4
}
},
{
"geom": "rule",
"aes": {
"color": {
"value": "#6b7075"
}
},
"params": {
"yintercept": "04-15",
"linewidth": 1
},
"inspect": false
},
{
"geom": "text",
"data": {
"values": [
{
"year": 812,
"bloomDate": "04-15",
"label": "median"
}
]
},
"aes": {
"x": {
"field": "year"
},
"y": {
"field": "bloomDate"
},
"label": {
"field": "label"
},
"color": {
"value": "#6b7075"
}
},
"params": {
"size": 9,
"anchor": "start",
"dy": 22
},
"inspect": false
},
{
"geom": "line",
"stat": "summary_rolling",
"aes": {
"color": {
"value": "#262626"
}
},
"params": {
"fun": "median",
"window": 30,
"curve": "linear",
"linewidth": 1.8
}
},
{
"geom": "point",
"data": {
"values": [
{
"year": 1323,
"bloomDate": "05-04"
}
]
},
"aes": {
"x": {
"field": "year"
},
"y": {
"field": "bloomDate"
},
"color": {
"value": "#2c5282"
}
},
"params": {
"shape": "circle-open",
"size": 3.5
}
},
{
"geom": "point",
"data": {
"values": [
{
"year": 1409,
"bloomDate": "03-27"
}
]
},
"aes": {
"x": {
"field": "year"
},
"y": {
"field": "bloomDate"
},
"color": {
"value": "#c53030"
}
},
"params": {
"shape": "circle-open",
"size": 3.5
}
},
{
"geom": "point",
"data": {
"values": [
{
"year": 2023,
"bloomDate": "03-25"
}
]
},
"aes": {
"x": {
"field": "year"
},
"y": {
"field": "bloomDate"
},
"color": {
"value": "#c53030"
}
},
"params": {
"size": 3
}
},
{
"geom": "segment",
"data": {
"values": [
{
"year": 1323,
"bloomDate": "05-04",
"label": "1323 · May 4, latest on record",
"labelYear": 1305,
"labelDate": "05-07"
},
{
"year": 1409,
"bloomDate": "03-27",
"label": "1409 · March 27, earliest for six centuries",
"labelYear": 1400,
"labelDate": "03-22"
},
{
"year": 2023,
"bloomDate": "03-25",
"label": "2023 · March 25, earliest in 1,200 years",
"labelYear": 2014,
"labelDate": "03-20"
}
]
},
"aes": {
"x": {
"field": "labelYear"
},
"y": {
"field": "labelDate"
},
"xend": {
"field": "year"
},
"yend": {
"field": "bloomDate"
},
"color": {
"value": "#b3452f"
}
},
"params": {
"linewidth": 0.7,
"alpha": 0.9
}
},
{
"geom": "text",
"data": {
"values": [
{
"year": 1323,
"bloomDate": "05-04",
"label": "1323 · May 4, latest on record",
"labelYear": 1305,
"labelDate": "05-07"
},
{
"year": 1409,
"bloomDate": "03-27",
"label": "1409 · March 27, earliest for six centuries",
"labelYear": 1400,
"labelDate": "03-22"
},
{
"year": 2023,
"bloomDate": "03-25",
"label": "2023 · March 25, earliest in 1,200 years",
"labelYear": 2014,
"labelDate": "03-20"
}
]
},
"aes": {
"x": {
"field": "labelYear"
},
"y": {
"field": "labelDate"
},
"label": {
"field": "label"
},
"color": {
"value": "#b3452f"
}
},
"params": {
"size": 11,
"anchor": "end",
"dx": -4
}
}
],
"scales": {
"x": {
"type": "linear",
"labels": "d",
"domain": [
800,
2030
]
},
"y": {
"type": "time",
"temporalKind": "monthDay",
"reverse": true,
"breaks": [
"04-05",
"04-15",
"04-25"
],
"dateLabels": "%b %e",
"domain": [
"05-10",
"03-10"
]
},
"fill": {
"type": "manual",
"domain": [
"Medieval warm period",
"Little Ice Age",
"Industrial era"
],
"range": [
"#f5edc4",
"#dce8f2",
"#f3dcda"
]
}
},
"guides": {
"fill": {
"type": "none"
}
},
"labs": {
"x": "Year",
"y": "Bloom date (earlier ↑)"
},
"theme": "tufte"
}
```
Rules that matter when generating specs:
- Channels are objects, never bare strings: `{"field": "year"}` maps a
column, `{"value": "#777777"}` sets a constant, `null` unsets a channel
inherited from the plot-level `aes`.
- Data has three forms. `{"values": [...]}` inlines rows; `{"columns": {...}}`
is the columnar form; `{"name": "..."}` refers to a `datasets` entry.
Inline `values` for data small enough to read, `datasets` + `columns`
for anything large or shared between layers. Never truncate rows silently —
say so, or point at the full source.
- `layers` is ordered bottom to top and must hold at least one layer. A layer
may carry its own `data`, which then replaces the plot's for that layer.
- Stats are declarative. `{"geom": "smooth", "params": {"method": "loess"}}`
fits in the pipeline; do not precompute a trend column and pass it off as
raw data.
The full machine-readable contract is /schema/v0.json.
## The validate loop
`validate(spec)` checks schema shape; `validate(spec, { profile })` adds
data-aware checks without shipping data; `{ lint: true }` also returns
advisories for valid-but-questionable specs.
Every error carries a stable `code`, a JSON `path` into the spec, a
`message`, and a `fix` naming the change to make. That is the correction
loop: emit, validate, apply the fix at the path, re-emit. Do not guess, and do
not fall back to a different chart — the fix says what is wrong.
```ts fragment
import { validate } from "@ggsvelte/spec";
const result = validate(spec);
if (!result.ok) {
for (const error of result.errors) {
console.error(error.code, error.path, error.fix);
}
}
```
The complete error catalog, with the fix for each code, is at /guide/errors;
advisories are at /guide/advisories.
## Headless rendering
No browser, no DOM. `renderToSVGString` is pure:
```ts fragment
import { registerAll, renderToSVGString } from "@ggsvelte/core";
// Headless/spec-driven rendering opts into the full grammar explicitly (#1420).
registerAll();
const svg = renderToSVGString(spec, { width: 900, height: 360 });
```
The installed CLI writes SVG to stdout and JSON Lines diagnostics to stderr,
with exit classes documented at /reference/cli:
```sh fragment
ggsvelte-render spec.json > chart.svg 2> diagnostics.jsonl
```
## Building specs in TypeScript
The fluent builder produces the same PortableSpec, with types:
```ts fragment
import { aes, gg } from "@ggsvelte/svelte";
import { kyotoSakura } from "@ggsvelte/svelte/data";
const spec = gg(kyotoSakura, aes({ x: "year", y: "bloomDate" }))
.geomPoint()
.geomLine({
stat: "summary_rolling",
fun: "median",
window: 30,
curve: "linear",
})
.spec();
```
## Bundled data
`@ggsvelte/svelte/data` exports seven cited teaching tables (each also served
as JSON under the same name on the docs site):
- `kyotoSakura` — 838 peak cherry-blossom dates for Kyoto, 812-2026 CE
(`year`, `bloomDate`, `bloomDoy`). Time series. Data
copyright Yasuyuki Aono; cite `KYOTO_SAKURA_CITATION`.
- `palmerPenguins` — 333 complete Palmer Archipelago penguin measurements
(`species`, `island`, bill/flipper/mass, `sex`, `year`, stable `id`).
Distribution and categorical groups. CC0; cite `PALMER_PENGUINS_CITATION`.
- `mpg` — 234 EPA fuel-economy rows for 38 popular models, 1999/2008
(`manufacturer`, `model`, `displ`, `class`, `drv`, `cty`, `hwy`, …).
Categorical comparison. Cite `MPG_CITATION`.
- `chocolateBars` — 2,530 Flavors of Cacao bar reviews (`cocoaPercent`,
`rating`, company location, bean origin). Dense scatter and heatmaps.
Via TidyTuesday 2022-01-18; cite `CHOCOLATE_BARS_CITATION`.
- `coffeeRatings` — 1,338 Coffee Quality Institute cupping lots
(`totalCupPoints`, aroma/flavor, origin, processing). Distributions and
continuous scatter. Via TidyTuesday 2020-07-07; cite `COFFEE_RATINGS_CITATION`.
- `beerProduction` — 36 US national beer-production totals by package type,
2008–2019 (`year`, `package`, `barrelsMillions`). Dodged multi-series bars.
Via TidyTuesday 2020-03-31; cite `BEER_PRODUCTION_CITATION`.
- `fastfoodMenu` — 515 US fast-food entrée nutrition rows (`restaurant`,
`calories`, fat/protein/sodium). Categorical scatter and jitter. Via
TidyTuesday 2018-09-04; cite `FASTFOOD_MENU_CITATION`.
## Grammar vocabulary
- [Geoms](https://ggsvelte.sh/reference/geoms) — every mark, defaults, stats, positions, and params
- [Guides and legends](https://ggsvelte.sh/reference/guides) — GuideLegend, colorbar, colorsteps, axis, none
- [Labs](https://ggsvelte.sh/reference/labs) — title, subtitle, caption, axis/legend titles
- [Axes and ticks](https://ggsvelte.sh/reference/axes) — GuideAxis, breaks/labels, collision, grids
- [Labels](https://ggsvelte.sh/reference/labels) — chrome vs ticks vs GeomText/GeomLabel/SF labels
- [Statistics and positions](https://ggsvelte.sh/guide/statistics-positions) — stats, jitter, stacking
- [Scales](https://ggsvelte.sh/reference/scales) — every Scale* component (position, color, style)
- [Scales and guides](https://ggsvelte.sh/guide/scales-guides) — continuous, discrete, manual, temporal
- [Facets and coordinates](https://ggsvelte.sh/guide/facets-coordinates) — small multiples, flip, fixed aspect
- [Chart themes](https://ggsvelte.sh/themes) and [palettes](https://ggsvelte.sh/palettes) — paper/ink chrome and data color
- [Themes reference](https://ggsvelte.sh/reference/themes) and [palettes reference](https://ggsvelte.sh/reference/palettes) — props, tokens, scheme → scale helpers
- [Interactions](https://ggsvelte.sh/guide/interactions) — inspect, pin, selection, zoom, linked views
- [Production](https://ggsvelte.sh/guide/production) — sizing, SVG/canvas, SSR, export, support matrix
- [Lifecycle](https://ggsvelte.sh/guide/lifecycle) — what is stable and what is not
---
# Statistics and positions
Stats derive marks from mapped rows. Positions control how derived marks share
coordinate space.
The full list of statistical transforms lives in the
[stat reference](https://ggsvelte.sh/reference/stats): after_stat columns and which geoms accept
each value. Open a specific stat, for example [count](https://ggsvelte.sh/reference/stats/count)
or [smooth](https://ggsvelte.sh/reference/stats/smooth).
Position adjustments are listed in the
[position reference](https://ggsvelte.sh/reference/positions): stack, fill, dodge, jitter, nudge,
and identity, with `positionParams` for jitter and nudge.
## Statistical summaries
```svelte fragment
```
[Loess example](https://ggsvelte.sh/examples/smooth/loess-scatter): smoother and confidence ribbon
on source points. Histogram, density, boxplot, and errorbar use the same
derive-then-render path.
For discrete x, `stat: "summary"` collapses each group to one summary (default
mean ± se). For continuous x, use `stat: "summary_bin"` instead.
## Binned y summaries (`summary_bin`)
`stat: "summary_bin"` (ggplot2 `stat_summary_bin`) bins continuous `x` with
the same break rules as `stat_bin`, then summarizes `y` in each non-empty
(group × bin). Default fun is mean ± se. Available on **point**, **line**, and
**errorbar**. Empty bins are omitted (unlike count bins).
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y" }))
.geomPoint({ alpha: 0.35 })
.geomErrorbar({ stat: "summary_bin", binwidth: 1, boundary: 0 })
.geomLine({ stat: "summary_bin", binwidth: 1, boundary: 0 })
.spec();
```
Bin knobs match histogram / freqpoly: `bins`, `binwidth`, `boundary`,
`center`, `closed`. Summary knobs: `fun`, `funMin`, `funMax`.
[Binned mean ± se](https://ggsvelte.sh/examples/errorbar/summary-bin): raw points with per-bin
errorbars and a summary line.
## Quantile regression lines
Linear quantile regression (ggplot2 `geom_quantile` / `stat_quantile`): fit
`y ~ x` at each conditional quantile τ and draw one line per τ (default
0.25 / 0.5 / 0.75). v1 is linear only — no rqss, no weights.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y" }))
.geomPoint()
.geomQuantile({ quantiles: [0.1, 0.5, 0.9] })
.spec();
```
[Quantile lines](https://ggsvelte.sh/examples/point/quantile-lines): scatter with three RQ lines.
## Contour isolines
Contour isolines (ggplot2 `geom_contour` / `stat_contour`) draw open path
polylines of constant `z` over a **regular** continuous `x` × `y` grid.
Levels come from `params.breaks`, else `binwidth`, else `bins` evenly
spaced from min(z)..max(z) inclusive (default 10). v1 is open polylines only
— no `contour_filled`, no irregular triangulation, no default color-by-level.
```svelte fragment
```
```ts fragment
gg(grid, aes({ x: "x", y: "y", z: "z" }))
.geomContour({ breaks: [0.25, 0.5, 0.75] })
.spec();
```
Incomplete grid cells (missing/NaN corners) are skipped; groups without a
usable grid or levels are dropped with a warning. after_stat `level` is
carried for tooltips.
[Contour isolines](https://ggsvelte.sh/examples/contour/basic): nested levels of a radial peak.
## 2D density isolines
Bivariate KDE isolines (ggplot2 `geom_density_2d` / `stat_density_2d`) estimate
a product Gaussian density over continuous `x` and `y`, then draw open path
polylines of constant density. Bandwidth follows MASS `bandwidth.nrd` then
kde2d's h/4 scaling (or `params.h` as one number or `[hx, hy]`). Grid
`params.n`×`n` (default 100) spans a 5%-expanded data range. Levels use the
same breaks / binwidth / bins rules as contour. Weights deferred.
```svelte fragment
```
```ts fragment
gg(scatter, aes({ x: "x", y: "y" }))
.geomPoint({ alpha: 0.5 })
.geomDensity2d({ bins: 5, n: 40 })
.spec();
```
Groups with fewer than two finite points are dropped with a warning.
after_stat `level` and `density` are carried for tooltips.
[2D density isolines](https://ggsvelte.sh/examples/density/kde-2d): scatter under nested KDE
contours.
## 2D density filled bands
`geom_density_2d_filled` / `stat_density_2d_filled` reuses the same KDE grid
and draws **closed** isoline rings as filled polygons (ggplot2
`geom_density_2d_filled`). Open rings are dropped with
`density-2d-filled-open-dropped`. Fill defaults to after_stat `level`.
```svelte fragment
```
```ts fragment
gg(scatter, aes({ x: "x", y: "y" }))
.geomPoint({ alpha: 0.45 })
.geomDensity2dFilled({ bins: 5, n: 40 })
.spec();
```
True isobands between consecutive levels and weights are deferred.
[2D density filled bands](https://ggsvelte.sh/examples/density/kde-2d-filled): scatter under
closed KDE rings colored by level.
## Dotplot (histodot)
Histodot stacked dots (ggplot2 `geom_dotplot` / `stat_bindot`): continuous
`x` is binned with the same break rules as `stat_bin`, then **one point per
observation** is stacked in each bin. y is after_stat `stackpos` only (not
count). Diameter tracks binwidth in x pixels (`dotsize` multiplier; `size`
for an absolute px override). `stackdir`: `up` | `down` | `center` |
`centerwhole`; `stackratio` scales vertical spacing (default 1).
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "v" }))
.geomDotplot({ binwidth: 0.5, boundary: 0 })
.spec();
```
v1 is histodot only — no Wilkinson `dotdensity`, no `binaxis = "y"`, no
weights. Mapping aes.y fails loud (`computed-y-mapped`).
[Dotplot histodot](https://ggsvelte.sh/examples/dotplot/histodot): stacked points in fixed bins.
## Simple features (`geom_sf`)
`geom_sf` draws already-projected GeoJSON **Geometry** values stored as JSON
**strings** in a data column (default `geometry`; override with
`params.geometry`). Point/MultiPoint → points; LineString/MultiLineString →
open paths; Polygon/MultiPolygon → closed fills. Multipart geometries expand
to multiple marks. **Interior rings** are even-odd **holes** (SVG
`fill-rule="evenodd"`, canvas, and hit-testing). `GeometryCollection` is
flattened to leaf Point/Line/Polygon families (recursive, nesting depth
capped). Mixed families in one layer still error (split layers).
Default stat is public **`stat_sf`** (ggplot2 `stat_sf`): geometry expand
runs on the normal non-identity frame path. Layer JSON stamps
`stat: "sf"` (not `identity`). No CRS / `coord_sf` yet — coordinates are
treated as already projected.
```svelte fragment
```
```ts fragment
gg(regions, aes({ fill: "rate" })).geomSf().spec();
// layer.stat === "sf"; geometry column holds JSON.stringify({ type: "Polygon", ... })
```
[SF polygons](https://ggsvelte.sh/examples/sf/basic): three triangles filled by a rate field.
[GeometryCollection expand](https://ggsvelte.sh/examples/sf/geometry-collection): one GC cell
renders as two polygon parts.
### SF text labels (`geom_sf_text`)
`geom_sf_text` (ggplot2 `geom_sf_text`) defaults to `stat_sf_coordinates`:
one representative point per geometry part, then draws `aes.label` there.
Point coordinates pass through; LineString uses the vertex mean;
Polygon uses the exterior-ring shoelace centroid. **MultiPoint /
MultiLineString / MultiPolygon emit one label per part** (feature aesthetics
duplicated onto each part). **GeometryCollection** expands to leaves first,
then the same per-part rule applies (one label per leaf part). Requires
`aes.label` (no `aes.x`/`aes.y`).
**Migration (multi-part labels):** earlier releases labeled only the first
Multi* component. Callers that relied on a single first-component label will
now see one label per part — filter geometries or aggregate labels if you need
the old single-label behavior.
```svelte fragment
```
```ts fragment
gg(regions, aes({ fill: "rate", label: "region" }))
.geomSf({ alpha: 0.55 })
.geomSfText({ size: 14 })
.spec();
```
[SF region labels](https://ggsvelte.sh/examples/sf/labels): filled polygons with names at centroids.
### SF boxed labels (`geom_sf_label`)
`geom_sf_label` is the boxed sibling of `geom_sf_text`: same
`stat_sf_coordinates` placement, plus a measured rounded rect behind the text.
`color` is ink + box stroke; `fill` is the box background (theme paper by
default). Params include `padding`, `radius`, `linewidth`, and text
`size`/`anchor`/`dx`/`dy`.
```svelte fragment
```
```ts fragment
gg(regions, aes({ fill: "rate", label: "region" }))
.geomSf({ alpha: 0.45 })
.geomSfLabel({ padding: 3, radius: 2, size: 13 })
.spec();
```
[SF boxed labels](https://ggsvelte.sh/examples/sf/boxed-labels): names on paper-backed label boxes.
## Ellipse confidence rings
Bivariate normal confidence ellipses (ggplot2 `stat_ellipse`, type `norm`
only) on **path** layers: per group, estimate mean and sample covariance,
scale by √χ²₂(level), and sample the perimeter (`segments`, default 51)
plus a closing duplicate for a closed ring.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y", color: "g" }))
.geomPoint()
.geomPath({ stat: "ellipse", level: 0.95 })
.spec();
```
Path-only in v1 (not polygon). Groups with fewer than two finite points or
zero variance are dropped with a warning. Rejected on other geoms.
[Ellipse confidence rings](https://ggsvelte.sh/examples/path/ellipse-rings): scatter under 95%
rings per series.
## Frequency polygon
Frequency polygon (ggplot2 `geom_freqpoly`) bins continuous `x` and draws a
line through bin centers (y defaults to count). Canonical form is `line` +
`stat: "bin"` + position identity — not a separate mark type:
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "v", color: "g" })).geomFreqpoly({ bins: 30 }).spec();
// → { geom: "line", stat: "bin", position: "identity", y: { stat: "count" } }
```
[Frequency polygon](https://ggsvelte.sh/examples/freqpoly/basic): Michelson light-speed runs as a
line through bin centers (companion to the histogram specimen).
## Unique (first-wins aesthetic dedupe)
`stat: "unique"` drops duplicate rows on the combination of mapped aesthetic
fields before drawing — first occurrence wins, panel-local (ggplot2
`stat_unique`). Available on identity-capable geoms (point, line, path, text,
col, area, rect, ribbon, rule, segment, errorbar).
```svelte fragment
```
[stat unique overplotting](https://ggsvelte.sh/examples/point/stat-unique): stacked identical
`(x, y, series)` triples collapse to one mark.
## Blank (scale training without marks)
`geom: "blank"` (ggplot2 `geom_blank`) contributes mapped aesthetics to
**scale training and layout only** — no paint, no hit targets. Use it to expand
domains, force axes open for sparse marks, or reserve layout without drawing.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y" }))
.geomPoint()
.geomBlank({ aes: aes({ x: "x2", y: "y2" }) }) // expands domains only
.spec();
```
No channels are required. Mapped style channels (color, size, …) train their
scales without drawing marks. Surfaces: `.geomBlank()`, ``.
[Blank domain expand](https://ggsvelte.sh/examples/blank/domain-expand): co-layer blank rows stretch
axes past the plotted points. [Blank axes only](https://ggsvelte.sh/examples/blank/axes-only): axes
and scales with no marks.
## Convenience geoms (jitter, hline, vline)
Name aliases that normalize to existing marks — no new paint paths:
| Sugar | Normalizes to |
|-------|----------------|
| `jitter` | `point` + `position: "jitter"` |
| `hline` | `rule` (horizontal) |
| `vline` | `rule` (vertical) |
`geomJitter` / `` accept flat `width` / `height` / `seed` and
assemble them into `positionParams` at the builder/component boundary.
`hline` / `vline` annotation intercepts (`yintercept` / `xintercept`)
suppress plot-aes inheritance (ggplot2 `inherit.aes = FALSE`). Data-driven
forms drop the orthogonal axis so the one-axis rule contract holds.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y" }))
.geomJitter({ width: 0.2, height: 0.2 })
.geomHline({ yintercept: 0 })
.geomVline({ xintercept: 10 })
.spec();
```
[Jitter sugar](https://ggsvelte.sh/examples/jitter/basic): overplotted points with position jitter.
[Hline threshold](https://ggsvelte.sh/examples/hline/threshold) and
[Vline cutoff](https://ggsvelte.sh/examples/vline/cutoff): annotation intercepts as rule aliases.
## Manual (portable named per-group transforms)
`stat: "manual"` (ggplot2 `stat_manual`, portable v1) applies a **named**
per-group transform — no JS callbacks (PortableSpec only). Required
`params.fun`:
| fun | Behavior |
|-----|----------|
| `first` / `last` | Keep one source row per aesthetic group |
| `mean` / `median` / `min` / `max` / `sum` | One synthetic row; x and y aggregated independently |
Surfaces: **point**, **line**, **path**. Missing `fun` fails with
`manual-fun-required`; unknown names are schema `invalid-enum-value`.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y", color: "g" }))
.geomPoint({ stat: "manual", fun: "mean" })
.spec();
```
[stat manual mean centroids](https://ggsvelte.sh/examples/point/stat-manual-mean): identity
scatter under large mean points per series.
## Align (shared continuous-x grid for stack)
`stat: "align"` (ggplot2 `stat_align`) is for continuous-x `area` / `line`
when series sample different x values. It unions finite x across groups,
linearly interpolates each series onto that shared grid, and sets y to 0
outside a group's observed x range so `position: "stack"` / `"fill"` can
compose without jagged seams.
```ts fragment
gg(data, aes({ x: "t", y: "v", fill: "series" }))
.geomArea({ stat: "align", position: "stack" })
.spec();
```
```svelte fragment
```
Available on **area** and **line** only (not point or shared identity-only
geoms). Outside a group's x span y is 0 (stack-friendly).
Discrete x joins the default grouping interaction (ggplot2 parity), so a
band-x area/line with a discrete series field derives one group per
(category, series) cell — every ribbon degenerates and a
`group-single-observation` warning fires. Map `aes.group` to the
series field to join categories into ribbons.
Stacked **area** rescues sparse groups on its own: when a group's continuous x
samples skip an interior grid point (a shape that would render as a floating
band chorded over the stack below), the default identity stat auto-applies
this align transform and emits a `stack-align-applied` advisory. The rescue
stands down when the x scale may train discrete, or when a group repeats an x
value (identity stacking sums repeats; align keeps the last). Pre-fill the
data to control every cell exactly.
## Connect (named path joins)
`stat: "connect"` (ggplot2 `stat_connect`) expands successive finite points
into intermediate vertices so stepped joins are real path geometry — not only
a stroke curve flag. `params.connection`: `hv` (default), `vh`, `mid`,
`linear`. On **path** expansion is in data order; on **line** points are sorted
by x first, and geometry skips a second x-sort so tied-x elbows stay intact.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y" }))
.geomPath({ stat: "connect", connection: "hv" })
.spec();
```
[Connect hv path](https://ggsvelte.sh/examples/path/connect-hv): three data points expand to a
horizontal-then-vertical polyline.
## Curve connectors
Curved connectors (ggplot2 `geom_curve`): one quadratic Bezier per row from
`(x,y)` to `(xend,yend)`, tessellated in **panel px** so curvature is not
aspect-skewed. Params: `curvature` (default 0.5), `angle` (degrees, default
90), `ncp` (control-point density). Same required channels as segment;
`lineend` maps to SVG stroke-linecap (default butt).
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y", xend: "xend", yend: "yend" }))
.geomCurve({ curvature: 0.5, angle: 90, ncp: 5 })
.spec();
```
Intentional subset: quadratic approximation, not full grid xspline.
[Curve connectors](https://ggsvelte.sh/examples/curve/connectors): Darwin maize pairs as arcs.
## Spoke (origin + angle + radius)
`geom: "spoke"` (ggplot2 `geom_spoke`) draws one finite segment per row from
`(x, y)` in direction `angle` (radians; 0 = +x, π/2 = +y) with length
`radius` in **data units**. Endpoints are
`xend = x + radius·cos(angle)`, `yend = y + radius·sin(angle)`, then the same
position transform as x/y. Tips train domains; paint reuses segment strokes.
`angle` and `radius` come from aes and/or constant `params`. Continuous x
and y required.
```svelte fragment
```
```ts fragment
gg(data, aes({ x: "x", y: "y", angle: "theta", radius: "r" }))
.geomSpoke({ linewidth: 1.5, lineend: "round" })
.spec();
// constants: .geomSpoke({ angle: 0, radius: 1 })
```
[Spoke vector field](https://ggsvelte.sh/examples/spoke/vector-field): synthetic 5×5 field with
mapped angle and radius.
## Map (fortified choropleth)
`geom: "map"` (ggplot2 `geom_map`) joins a **fortified map table** to value
rows. Map coordinates come from `long`+`lat` or `x`+`y`; the join key is
`aes.map_id` on the value table matched to `params.mapId` on the map
(default `"region"`, then `"id"`). Optional map `group` splits multipoly
rings. Missing regions drop with a `map-region-missing` warning.
```svelte fragment
```
```ts fragment
gg(rates, aes({ map_id: "region", fill: "rate" }))
.geomMap({ map: { values: fortified }, mapId: "region" })
.spec();
```
Intentional subset: no network map fetches, no sf/CRS, no public
`geom_polygon` (map ships the closed-path renderer only).
[Map choropleth](https://ggsvelte.sh/examples/map/choropleth): three toy regions filled by rate.
## Positions
Stack sums, dodge side-by-side groups, fill normalizes each stack to one, jitter
separates overlaps with a deterministic seed. [Bar examples](https://ggsvelte.sh/examples?category=bar).
---
# Scales and guides
A scale translates semantic data values into a visual position or color. A
position transform runs before statistics; an axis explains the trained scale
without changing its meaning.
## Continuous position scales
Numeric x and y fields use a continuous linear scale by default. Non-temporal
continuous scales reserve 5% multiplicative display expansion at both ends.
Expansion affects only display training, never filtering or statistics. Restore
flush bounds with `expand: { mult: 0, add: 0 }`.
Use the closed `identity`, `log10`, and `sqrt` transforms. The scale family
stays `linear`: GuidePlan and RenderModel report `type/scaleType: "linear"`
plus the transform. Authored `type: "log"` remains an accepted alias and
canonicalizes to `{ type: "linear", transform: "log10" }`.
```json fragment
{
"scales": {
"x": { "type": "linear", "transform": "log10" },
"y": { "type": "linear", "transform": "sqrt", "reverse": true }
}
}
```
Builder helpers and their ggplot2 aliases produce the same canonical spec:
```ts fragment
import {
scaleXLog10,
scaleYSqrt,
scale_x_log10,
scaleColorGradient,
scale_color_gradient2,
scale_fill_gradientn,
} from "@ggsvelte/spec";
const camel = scaleXLog10({ domain: [1, 10_000] });
const alias = scale_x_log10({ limits: [1, 10_000] });
const root = scaleYSqrt({ reverse: true });
// Continuous colour gradients (#826): map to sequential scales with explicit range.
const twoStop = scaleColorGradient({ low: "#132B43", high: "#56B1F7" });
const diverging = scale_color_gradient2({ low: "#B2182B", mid: "#F7F7F7", high: "#2166AC" });
const nStop = scale_fill_gradientn({ colours: ["#440154", "#21918c", "#fde725"] });
```
Svelte shells: ``, ``,
`` (and fill / colour aliases). gradientn requires ≥2
hex stops via `colours` / `colors` / `values`. See
[gradient colour example](https://ggsvelte.sh/examples/point/gradient-continuous).
The Svelte surface accepts the same JSON and re-exports the same helpers:
```svelte fragment
```
The smooth receives transformed x and y. This is intentionally different from
a post-stat coordinate transform: scale transformation can change a fit,
histogram, density estimate, summary, or boxplot.
## Limits, missing values, and OOB policy
`domain` and helper `limits` pin an unexpanded interval in semantic source
units. Supplying both to a helper is an error. The default `oob: "censor"`
replaces out-of-limit values with missing before stats; `oob: "squish"`
clamps them to the nearest limit first. `naValue` replaces missing/censored
positions before transform-domain validation.
Log10 requires positive values and sqrt requires non-negative values. Recovery
is explicit: filter or repair the data, select identity, widen limits, or choose
the intended OOB policy. See
[scale-transform-domain](https://ggsvelte.sh/guide/errors#scale-transform-domain),
[scale-oob-censored](https://ggsvelte.sh/guide/errors#scale-oob-censored), and
[scale-oob-squished](https://ggsvelte.sh/guide/errors#scale-oob-squished).
## Binned positions
A binned scale assigns quantitative values to bounded transformed-space bins
while preserving source values for tooltips and events:
```svelte fragment
```
The runtime keeps integer bin identities private for count/stack/fill/dodge.
Geometry, jitter, guides, and synthesized candidates use transformed centers
and semantic inverse values. Explicit or automatic bins are right-closed with
an inclusive lowest edge and are capped at 64.
## Breaks and labels
`breaks` and `minorBreaks` are bounded semantic source values. Major breaks
win when a major and minor coincide. Explicit breaks outside the trained domain
are omitted with
[scale-break-outside-domain](https://ggsvelte.sh/guide/errors#scale-break-outside-domain).
Temporal `dateMinorBreaks` outranks generic `minorBreaks`.
`reverse` changes the pixel direction but not semantic tick order. `nice`
controls numeric domain rounding. Guides retain complete semantic values and
apply the forward transform exactly once. For the full split between scale
formats, axis guides, and plot titles, see
[Axes and ticks](https://ggsvelte.sh/reference/axes) and [Labs](https://ggsvelte.sh/reference/labs).
## Categorical color
Use a named categorical scheme when color identifies groups:
```svelte fragment
```
Stable assignments preserve category identity as rows filter or reorder. See
registered schemes and capacities on
[Color palettes](https://ggsvelte.sh/palettes). Palette exhaustion is
`onExhaust: "cycle"` (default, warn once) or `"error"` — diagnostics at
[palette-exhausted](https://ggsvelte.sh/guide/errors#palette-exhausted) and
[palette-exhausted — warning](https://ggsvelte.sh/guide/errors#palette-exhausted-warning).
ggplot2-shaped discrete helpers (portable named schemes, not bake-only):
```svelte fragment
```
```ts fragment
import { scaleColorHue, scaleColorGrey, scaleColorOrdinal } from "@ggsvelte/spec";
scaleColorHue(); // { color: { type: "ordinal", scheme: "hue" } }
scaleColorGrey(); // bakes a 10-stop greyscale range (US gray is a binding-identical alias)
scaleColorOrdinal({ scheme: "colorblind" }); // alias of scaleColorDiscrete
// Custom h/c/l (hue) or start/end (grey) bake a fixed 10-stop range instead.
```
[Hue discrete colour](https://ggsvelte.sh/examples/point/hue-discrete): even-hue groups via
`scale_color_hue`. There is no registered `"grey"` / `"gray"` scheme —
use `scaleColorGrey()` / `` for greyscale discrete color.
## Continuous, binned, manual, and identity color
Quantitative color/fill defaults to a continuous viridis colorbar. Named
viridis-family constructors match ggplot2 `scale_*_viridis_{c,d,b}`
(`option` selects `viridis`/`magma`/`plasma`/`inferno`/`cividis`/`turbo`;
`direction: -1` reverses). Discrete viridis samples evenly across the ramp.
The `identity`, `log10`, and `sqrt` transforms run before color-domain
training; they do not change position statistics. Explicit reference
`breaks` stay in semantic source units.
```ts fragment
import {
scaleColorLog10,
scaleColorViridisD,
scaleFillViridisC,
} from "@ggsvelte/spec";
const color = scaleColorLog10({ domain: [1, 1000] });
const fill = scaleFillViridisC({ option: "plasma" });
const groups = scaleColorViridisD({ option: "viridis" });
```
Binned color/fill uses deterministic `[lower, upper)` intervals with the final
upper edge included. At most 65 boundaries (64 steps) are portable. A
colorsteps guide exposes every boundary, label, swatch, and inclusivity rule:
```svelte fragment
```
Manual scales pair each domain value with exactly one color and never recycle
unknown values. Identity scales validate source `#rgb`/`#rrggbb` values and
show no guide by default. `naValue` handles missing values; `unknownValue`
handles invalid, unmapped, or censored values. Multi-aesthetic helpers expand
the same identity or manual config across channels (British `colour` aliases
`color`):
```ts fragment
import {
scaleContinuousIdentity,
scaleDiscreteManual,
scaleType,
} from "@ggsvelte/spec";
const linked = scaleDiscreteManual({
aesthetics: ["colour", "fill"],
values: ["#4477aa", "#ee6677"],
domain: ["control", "treated"],
});
const rawSize = scaleContinuousIdentity({ aesthetics: ["size", "alpha"] });
// Agent default: scaleType({ aesthetic: "color", dataKind: "nominal" }) → "ordinal"
```
```ts fragment
const manual = scaleColorManual({
domain: ["control", "treated"],
values: ["#4477aa", "#ee6677"],
unknownValue: "#999999",
});
const identity = scaleFillIdentity({ naValue: "#cccccc" });
```
Color and colour spellings are binding-identical exports, including
`scaleColorBinned`, `scaleColourBinned`, `scale_color_binned`, and
`scale_colour_binned`. Fill exports use the same families. Date/datetime
helpers reuse the strict parser registry and semantic epoch representation:
`scaleColorDate`, `scaleColorDatetime`, `scaleFillDate`, and
`scaleFillDatetime`.
Open [binned color](https://ggsvelte.sh/examples/color/binned) for colorsteps, and continuous
color scales via `scaleColorContinuous` / `scale_color_continuous`.
## Size, linewidth, alpha, shape, and linetype
The remaining visual channels use the same stable scale contract. Quantitative
`size`, `linewidth`, and `alpha` default to sequential scales; categorical
values default to ordinal scales. Size interpolation is perceptually linear in
symbol area. Alpha is bounded to 0–1, while size and linewidth must stay
positive.
```ts fragment
import {
scaleSizeContinuous,
scaleLinewidthBinned,
scaleAlphaDate,
scaleShapeManual,
scaleLinetypeDiscrete,
} from "@ggsvelte/spec";
const scales = {
...scaleSizeContinuous({ range: [2, 10] }),
...scaleLinewidthBinned({ breaks: [0, 10, 20, 50] }),
...scaleShapeManual({
domain: ["control", "treated"],
values: ["circle", "triangle"],
}),
...scaleLinetypeDiscrete(),
};
```
Shape and linetype are finite perceptual sets. Continuous values therefore
require an explicit `binned` scale; they are never silently interpolated.
Manual scales require one output per domain value, and exhaustion errors by
default unless `onExhaust: "cycle"` is explicitly selected. Identity scales
validate literal outputs and suppress guides.
Discrete and binned style mappings participate in grouping; continuous numeric
styles do not. Mapped values survive stats, positions, SVG/Canvas rendering,
server rendering, inspection, legend focus/filtering, and hit testing. Literal
constants remain unscaled unless authored as `{ value, scale: true }`.
Missing and invalid values use distinct `naValue` and `unknownValue` outputs.
Date/datetime helpers reuse the strict parser and timezone semantics used by
position and color scales.
The five style channels each have their own scale families in the
[scales reference](https://ggsvelte.sh/reference/scales): [size](https://ggsvelte.sh/reference/scales/size_continuous),
[alpha](https://ggsvelte.sh/reference/scales/alpha_continuous),
[shape](https://ggsvelte.sh/reference/scales/shape_ordinal),
[linetype](https://ggsvelte.sh/reference/scales/linetype_discrete), and
[linewidth](https://ggsvelte.sh/reference/scales/linewidth_continuous).
## Responsive guide presentation
Guide appearance is downstream of scale training. The full list of guide shells
and helpers lives in the [guides reference](https://ggsvelte.sh/reference/guides):
[GuideLegend](https://ggsvelte.sh/reference/guides/legend),
[GuideColorbar](https://ggsvelte.sh/reference/guides/colorbar),
[GuideColorsteps](https://ggsvelte.sh/reference/guides/colorsteps),
[GuideAxis](https://ggsvelte.sh/reference/guides/axis), and
[GuideNone](https://ggsvelte.sh/reference/guides/none). Author top-level `guides`,
a scale-local `guide`, or fluent `.guides()` with `guideAxis`,
`guideLegend`, `guideColorbar`, `guideColorsteps`, and `guideNone`.
Top-level entries win over scale-local entries. Axis shells, collision, and
band label layout are catalogued under [Axes and ticks](https://ggsvelte.sh/reference/axes);
plot titles stay on [Labs](https://ggsvelte.sh/reference/labs).
```ts fragment
import { guideAxis, guideColorsteps } from "@ggsvelte/spec";
const guides = {
x: guideAxis({ title: "Hour", showTicks: false }),
color: guideColorsteps({ position: "bottom", direction: "horizontal" }),
};
```
In Svelte that object is a `` child:
```svelte fragment
```
Automatic legends stay right only when the viewport is wider than 480px and at
least 320px of readable panel remains; otherwise they move below. Bottom keys
wrap without shrinking type and bottom ramps are horizontal. Discrete guides
merge only across exact semantic and presentation identities. Exact raw-value
entries stay interactive after merging; numeric ticks and bins do not become
filter targets. Identity/manual guides with fewer than two entries remain
hidden unless `force: true` is explicit.
## Date and time axes
Declare a time scale for ISO 8601 values and let the scale choose UTC calendar
ticks. Time axes preserve temporal parsing and expansion behavior and always
use the identity position transform. Pin breaks or labels only when the
audience needs a fixed convention. The
[time-axis example](https://ggsvelte.sh/examples/line/time-axis) is the runnable contract.
---
# Facets and coordinates
Facets partition rows into panels before panel stats. Coordinates present
trained scales (flip, etc.) without rewriting aesthetic mappings.
## Facet a comparison
```svelte fragment
```
[facet wrap](https://ggsvelte.sh/examples/facet/wrap), [free-y](https://ggsvelte.sh/examples/facet/wrap-free-y).
## Coordinates
Prefer `coord flip` for horizontal bars over swapping x/y semantics.
[Horizontal bar](https://ggsvelte.sh/examples/bar/horizontal).
## Scale transforms versus coordinate transforms
A scale transform changes the values consumed by statistics and positions. A
coordinate transform leaves those computations alone and projects the final
geometry:
```ts fragment
// The linear fit consumes log10(exposure).
gg(rows, aes({ x: "exposure", y: "response" }))
.geomSmooth({ method: "lm" })
.scaleXLog10();
// The fit consumes exposure; only its rendered geometry is curved.
gg(rows, aes({ x: "exposure", y: "response" }))
.geomSmooth({ method: "lm" })
.coordTransform({ x: "log10" });
```
The portable JSON form is strict and callback-free:
```json complete
{
"type": "transform",
"x": {
"transform": "log10",
"limits": [1, 1000],
"reverse": false,
"expand": false
},
"clip": true
}
```
Use `coordTransform` or its identical ggplot2-style alias
`coord_transform`. In Svelte it is a `` child, which takes
the same options (`` is the escape
hatch for a coordinate computed elsewhere):
```svelte fragment
```
Coordinate limits create a post-stat viewport: they do not censor rows or
recompute a fit. Coordinate inversion runs before scale inversion, so tooltip,
interval, and brush-zoom values remain semantic. Nonlinear lines, smooths,
areas, smooth confidence bands, and segments use bounded adaptive tessellation;
synthetic render vertices never become inspectable data. Set `clip: false`
only for intentional panel overflow.
## Preserve physical data-unit ratios
Use `coordFixed()` when equal data units must have equal physical lengths. The
layout reserves titles, axes, and responsive guides first, then centers the
largest exact-ratio data rectangle in the remaining allocation. Panel fill,
grids, marks, clipping, axes, and facet strips occupy only that rectangle;
letterbox gutters use the theme paper role by default.
```ts fragment
gg(rows, aes({ x: "x", y: "y" }))
.geomLine()
.coordFixed({ ratio: 1 });
```
`ratio` is physical y-unit length divided by physical x-unit length. The
camelCase helper, builder `.coordFixed()`, `coord_fixed`, `coordEqual`, and
`coord_equal` all emit the same strict JSON. Free positional facet scales are
rejected with `coord-fixed-free-scales`; use fixed facet scales when panels must
share one physical comparison. On an unusually constrained container the ratio
is never stretched: minor furniture is removed, the SVG declares
`data-gg-layout="degraded"`, and authors receive one `coord-fixed-degraded`
warning. See the runnable [fixed-aspect example](https://ggsvelte.sh/examples/point/fixed-aspect).
Non-identity coordinate transforms reject band and temporal axes with
`coord-transform-continuous` or `coord-transform-temporal`. Domains that
cross log10/sqrt boundaries fail with `coord-transform-domain` and exact
recovery guidance.
---
# Dates without preprocessing
ggsvelte infers strict ISO dates/date-times, four-digit year strings,
year-months, month-years, year-quarters, and runtime `Date` values from data.
Classification inspects at most the first and last 32 non-null values; after it
selects one parser family, every non-null value must validate. A partially valid
column never becomes partially temporal.
## Let the default work
`"1835"`, `"1900"`, and `"2026"` are spaced as calendar years, not as
three equally spaced categories. Numeric `1835` stays quantitative.
```svelte fragment
```
## Inspect the choice
Read `model.scaleDecisions` in `onrender` for field, parser, precision,
bounded evidence, validated count, trained domain, ambiguity, and a portable
override. Exceptional or advisory choices also appear in
`model.scaleDiagnostics` as stable problem/cause/fix records. The responsive
axis decisions live in `model.guidePlans`: each drawn panel axis reports its
calendar interval, visible and complete labels, major/minor tier, locale,
timezone, overlap state, and stable ID. `ScaleDecision.guidePlanIds` links
inference to those panel plans without copying facet-specific arrays.
## Responsive calendar labels
Automatic temporal axes score calendar-aligned candidates from milliseconds to
centuries against the actual panel extent and measured label widths. They prefer
3–7 major labels, but no-overlap wins. Month, quarter, year, week, and day
stepping follows civil boundaries rather than average milliseconds. The planner
runs inside the existing two layout passes and may move only to a coarser
interval during pass B.
Default date labels keep UTC calendar meaning. Datetime labels use the configured
IANA timezone. The deterministic defaults are `en-US`, UTC, and Monday week
starts. Visible labels may suppress repeated context; every SVG major tick keeps
a complete standalone label in its ``.
Use exact portable controls when the default is not the editorial choice:
```ts fragment
const spec = gg(rows, aes({ x: "when", y: "value" }))
.geomLine()
.scaleXDatetime({
dateBreaks: "2 weeks",
dateMinorBreaks: "1 day",
dateLabels: "%e %b",
locale: "en-GB",
timezone: "Europe/London",
weekStart: "monday",
})
.spec();
```
Canonical JSON uses the same fields. Interval strings are a positive integer plus
`millisecond`, `second`, `minute`, `hour`, `day`, `week`, `month`,
`quarter`, or `year` (singular or plural). Explicit `breaks` outrank
`dateBreaks`; `dateLabels` outranks the older soft-fallback `labels` field.
Authored breaks and labels are never silently thinned, rotated, or truncated.
If they cannot fit, the render keeps them and emits a structured scale
diagnostic with a coarser-interval or wider-layout fix.
## Override one choice
Ambiguous values such as `03/04/2024` stay discrete. Pick the intended order:
```ts fragment
const spec = gg(rows, aes({ x: "when", y: "value" }))
.geomLine()
.scaleXDate({ parse: "dmy" })
.spec();
```
Canonical JSON uses `scales: { x: { type: "time", parse: "dmy" } }`.
The closed parser names are generated from the runtime registry:
`iso`, `year`, `ym`, `my`, `yq`, `md`, `ymd`, `ydm`, `mdy`, `myd`, `dmy`, `dym`, `ymd_hm`, `ymd_hms`, `ydm_hm`, `ydm_hms`, `mdy_hm`, `mdy_hms`, `myd_hm`, `myd_hms`, `dmy_hm`, `dmy_hms`, `dym_hm`, `dym_hms`. Exact bounded formats and epoch
seconds/milliseconds are object parser forms. Timezone-less values mean UTC;
IANA zones use Temporal with explicit DST disambiguation.
If four-digit strings are identifiers, force categories with
`.scaleXDiscrete()`, `scale_x_discrete()`, or
`scales: { x: { type: "band" } }`.
## PortableSpec boundary
PortableSpec remains strict JSON: no `Date`, callback, or regular expression.
The checked capability ledger records the temporal family as
`implemented`; docs, helper tests, and agent checks consume that ledger.
Builder and Svelte authoring may contain runtime Dates; they canonicalize to ISO
before validation. The standalone `ymd`, `mdy`, `dmy`, related order and
timestamp helpers, exact-format parser, and epoch helpers return authoring Dates.
---
# Interactions
Static by default. Opt in with ``, `select`, `zoom`, and GuideLegend
`focus` / `filter` (or the legacy GGPlot `inspect` prop, and deprecated plot
props `legendFocus` / `legendFilter`). With more than one draw tool, an
accessible tool rail keeps gestures from competing.
Without a controller, state is private to one chart and callbacks report
changes. Pass `createPlotInteraction()` when plots, controls, or tables share
semantic state (required, stable semantic scope via `interactionScope`).
Examples: [inspect](https://ggsvelte.sh/examples/interactions/inspection),
[interval/zoom](https://ggsvelte.sh/examples/interactions/interval-selection),
[linked views](https://ggsvelte.sh/examples/interaction/linked-views),
[legend focus](https://ggsvelte.sh/examples/interaction/legend-focus),
[legend filter](https://ggsvelte.sh/examples/interaction/legend-filter),
[facet intervals](https://ggsvelte.sh/examples/interaction/facet-intervals).
Contracts: [interaction reference](https://ggsvelte.sh/guide/interaction-reference).
## Inspection
`` enables the default HTML tooltip, semantic crosshair, keyboard
traversal, and click-or-Enter pinning (same as the legacy `inspect={true}`
prop on ``). Configure it when the chart has a natural comparison
axis:
```svelte fragment
console.log(event)}
>
```
The modes are `auto`, `exact`, `x`, `y`, and `xy`. `auto` resolves to a
concrete mode before an event is emitted. `x` and `y` return one
representative per semantic series at the focused axis value; `exact` and
`xy` return the focused datum. `maxDistance` is measured in CSS pixels: the
dominant axis for `x` or `y`, Euclidean distance for `xy`, and geometry
containment plus tolerance for `exact`. Rect marks (`geom_col` / `geom_bar`)
never draw a point ring; default hover is tooltip-only. Pass
`muteSiblings` on `` to mute non-focused bars via the interaction mask.
For custom HTML, pass a Svelte 5 snippet on `content`. Informational content is
the default; choose `contentMode="interactive"` only when the pinned tooltip
contains controls that need focus.
```svelte fragment
{#snippet details(inspection)}
{inspection.focus.row?.name}{inspection.members.length} series at this value
{/snippet}
```
## Point and interval selection
Point selection is durable identity, not a renderer index. Identity defaults
to an `id` column or row index; override with `identity` on Select / Inspect
for a non-`id` natural key:
```svelte fragment
{
if (event.mode === "point") selectedKeys = event.keys;
}}
/>
```
Use interval selection for brushing. The callback receives both the selected
domain and normalized plot-pixel rectangle, plus semantic keys and a lineage
count for aggregate marks.
```svelte fragment
{
if (event.mode !== "point" && event.phase === "end") {
selectedDomain = event.domain;
}
}}
/>
```
Faceted intervals use stable field-and-value panel identities rather than panel
indices. Choose a preset for the relationship between panels:
- `independent` (default) replaces the interval in only the origin panel.
- `union` keeps independently drawn panel intervals and combines their keys.
- `cross-panel` projects one semantic domain through every compatible panel.
`cross-panel` intersects the interval with each panel's domain when facet
scales are free; a disjoint panel selects nothing instead of clamping to an
unrelated edge. Panel identity survives row reordering and temporary absence.
See the [runnable facet example](https://ggsvelte.sh/examples/interaction/facet-intervals).
## Shared controlled state
`createPlotInteraction()` owns selection, emphasis, and continuous zoom
domains outside any chart. Give linked consumers the same controller and a
required, stable semantic scope via `interactionScope`. A transition is
published once by its origin; passive charts render the new snapshot without
emitting the callback again. Controlled plots never infer channel names: add an
`x` and/or `y` scope whenever controlled zoom uses that channel.
```svelte fragment
```
Use `setSelection`, `toggleSelection`, and `clearSelection` for durable
keys. `setEmphasis` is presentation-only: linked charts update their highlight
overlay without retraining scales or rerunning the render pipeline. Matching
`x` and `y` scope names share numeric zoom domains. When application data is
replaced, call `reconcileKeys(validKeys, { scope })` explicitly; a chart never
guesses whether a temporary subset should erase another view's selection.
Durable facet intervals use their own optional `interactionScope.intervals`
namespace (falling back to `keys`). Read them with `intervals(scope)`, write
one with `setInterval`, clear one panel with `clearInterval`, or clear the
scope with `clearIntervals`. Interval state is semantic data-space state, not
pixels or renderer indices.
## Legend focus
`` adds real HTML controls over that
aesthetic's discrete legend. Hover and DOM focus preview one chart without
mutating shared state. Click, touch, Enter, or Space commits the matching
stable row keys; the active entry or Escape clears them. Arrow keys traverse
entries in rendered legend order, with Home and End moving to the boundaries.
`focus={{ preview: false }}` keeps committed activation but disables transient
previews. Continuous ramps remain static. A stable `key` is required: encoded
legend values are reported as values, never used as controller keys. Focused
and muted marks share one semantic mask across SVG and canvas, and the mask
does not retrain scales, recompute statistics, change layout, or reassign
colors. Author discrete legend appearance with
[GuideLegend](https://ggsvelte.sh/reference/guides/legend); see the full
[guides reference](https://ggsvelte.sh/reference/guides) and the
[runnable three-view example](https://ggsvelte.sh/examples/interaction/legend-focus). The plot prop
`legendFocus` is deprecated since 0.19.0.
## Legend filtering
GuideLegend `focus` is presentation emphasis only — it does not change data.
`` adds Show-group checkboxes on that
aesthetic's discrete legend and filters rows before facets, stats, scales,
layout, and render. Hidden groups stay in the legend catalog and keep the same
categorical color when shown again.
Use `filter={{ mode: "exclude", multiple: true }}` for the default independent
checkboxes. `mode: "include"` stores the shown values instead; `multiple:
false` makes a toggle isolate one group. `onlegendfilter` reports the raw
typed values and field in a `LegendFilterClause`. Reset legend filters
restores the data pipeline; Clear legend focus only removes presentation
emphasis. The plot prop `legendFilter` is deprecated since 0.19.0. See the
[stable-color example](https://ggsvelte.sh/examples/interaction/legend-filter).
## Brush zoom
`zoom={true}` enables two-dimensional brush zoom. Set `zoom={{ mode: "x" }}`
or `zoom={{ mode: "y" }}` for a single axis. The tool rail separates Zoom area
from Select area when both are enabled. A completed zoom emits explicit
domains; Reset zoom or double-click emits a clear event.
Faceted interval selection is supported, but faceted brush zoom remains
disabled with `INTERACTION_INTERVAL_FACET_UNSUPPORTED`; use a linked detail
view when each facet needs a zoomed inspection surface.
```svelte fragment
console.log(event.domains)}
/>
```
## Precise bounds without dragging
After an interval selection or zoom is committed, the tool rail exposes Edit x
or y bounds alongside its drag controls. The inline HTML form stages edits:
typing does not rerun the chart, Apply commits once, Cancel or Escape discards
the draft, and validation focuses the first invalid field. This provides a
keyboard and assistive-technology path to the same semantic result as brushing.
- Linear and reversed scales accept ascending data-space numbers. Reversal is
presentation only, so do not enter screen order.
- Log scales accept positive ascending numbers.
- Time scales accept ISO 8601 dates or date-times with `Z` or an explicit
offset; events store Unix milliseconds.
- Band scales use two native selects and include both endpoint categories.
Recovery actions are deliberately separate: Clear panel selection removes one
facet interval, Clear all selections removes interval state, Reset zoom restores
natural domains, and Reset legend filters restores excluded rows. None of these
controls silently performs another reset.
## Event reference
All events carry `type`, `phase`, and `source` (`pointer`, `keyboard`,
`touch`, or `programmatic`). Use the focused callback for one capability or
`oninteraction` for the discriminated union of every event.
### `oninspect(event: PlotInspection)`
- A change is `{ type: "inspect", phase: "change", state, source, mode,
panelId, focus, members }`.
- `state` is `transient` or `pinned`; `members` is always non-empty and
`focus` is the member under direct inspection.
- `x` and `y` changes also carry the original logical `axisValue` and its
formatted `axisLabel`.
- Dismissal is the small event `{ type: "inspect", phase: "clear", source }`.
Each `PlotDatum` has `key`, source `row` when one exists, aggregate
`sourceKeys` and `lineageCount`, `layerIndex`, `panelId`, mapped `fields`,
and a plot-pixel `anchor`. Keyless or synthetic marks expose `key: null`;
internal renderer indices never leak into callbacks.
### `onselect(event: PlotSelection)`
- Point selection emits `{ type: "select", phase: "end" | "clear",
mode: "point", keys, source }`.
- Interval selection emits `start`, `change`, `end`, and `clear` phases with
`mode`, `panelId`, `domain`, `pixels`, `keys`, `lineageCount`, and
`source`.
### `onzoom(event: ZoomEvent)`
- Zoom completion is `{ type: "zoom", phase: "end", source, domains }`.
- Reset is `{ type: "zoom", phase: "clear", source, domains: null }`.
### `onlegendfocus(event: LegendFocusEvent)`
- Preview and commit emit `{ type: "legend-focus", phase: "change", state,
source, scale, value, label, keys }`.
- `state` is `transient` or `committed`. `value` is the raw encoded
domain value while `keys` are distinct stable source-row identities.
- Dismissal emits `{ type: "legend-focus", phase: "clear", source }`.
### `onlegendfilter(event: LegendFilterEvent)`
- A change emits `{ type: "legend-filter", phase: "change", source, clause }`.
- `clause` names the color or fill scale, source field, typed values, and
include or exclude mode. Reset emits `phase: "clear"` and `clause: null`.
- Filtering is data-changing and intentionally separate from the
presentation-only `onlegendfocus` event.
`oninteraction(event: PlotInteractionEvent)` receives the same objects. It
does not wrap or duplicate them. A linked chart that consumes shared state
should not re-emit the origin chart's event.
## Keyboard and accessibility defaults
Name charts with `ariaLabel` (subject or takeaway — not generic image alt).
Focus the plot, then use arrow keys or brackets to traverse data. Enter or
Space pins inspection, activates point selection, or sets the two corners of
an area, depending on the active tool. Escape dismisses the current
interaction. Keyboard inspection updates a polite live region with a concise
axis, count, and pin summary; complete pinned content remains ordinary labelled
and navigable DOM. Canvas marks keep SVG axes/legends and the accessible
description path.
## Identity and diagnostics
Ordinary charts omit custom identity: the engine uses an `id` column when
present, otherwise the row index (order-stable only). For a non-`id` natural
key or accessor, set `identity` on ``, object-form `select`, or
`createPlotInteraction({ identity })` — not plot-level `key` (deprecated).
Keys must be non-null unique `PropertyKey` values and stable across updates.
Invalid or duplicate keys emit structured diagnostics through `ondiagnostic`.
Stable identity lets pinned inspection and point selection follow a datum when
data is updated.
---
# Production
## Responsive sizing
Omit width: GGPlot observes its container. Positive-width block, no chart CSS.
Omitted height: 400px default. Collapsed parent, hidden tab, or zero-width track
→ not-ready until ResizeObserver reports positive width. Do not paper over that
with a fake fixed width. [Troubleshooting](https://ggsvelte.sh/guide/errors#quickstart-troubleshooting).
SSR uses an 832×400 deterministic fallback and stays not-ready in HTML until
hydration measures the real container. Reserve layout space to avoid CLS.
## Rendering
Renderer follows mark density and interaction needs. Axes, legends, labels, and
a11y chrome stay semantic regardless of SVG vs canvas.
SVG: DOM marks. Canvas: dense strata. Auto: switches above the published
threshold (`CANVAS_AUTO_THRESHOLD`) and emits `canvas-auto`. Force with
layer `"render": "canvas"` or `render="canvas"`; axes, legends, and a11y
chrome stay SVG.
Inspection and selection use the model-owned candidate store, not DOM hit tests.
Stable keys keep identity across SVG/canvas; renderer indices never appear in
public callbacks. Measure with repo fixtures before forcing canvas globally.
For a real-data scatter surface, see [scatter color](https://ggsvelte.sh/examples/point/scatter-color).
## Server and export
Three paths, one PortableSpec: Svelte SSR, pure `renderToSVGString`, CLI.
```ts fragment
import { registerAll, renderToSVGString } from "@ggsvelte/core";
// Headless full-grammar rendering (#1420): explicit opt-in.
registerAll();
const svg = renderToSVGString(spec, { width: 640, height: 400 });
```
```sh fragment
# npm install -g @ggsvelte/cli
ggsvelte-render spec.json > chart.svg
```
SVG on stdout; JSON Lines diagnostics on stderr — the agent feedback loop.
[CLI reference](https://ggsvelte.sh/reference/cli).
## Compatibility
Every release is tested as an installed package: clean install, strict
type-check, client build, server render, pure Node render, and the
`ggsvelte-render` CLI.
- Node.js `>=22` (22 and 24 in CI; 26 nightly)
- Svelte `^5.33.1` (tested floor 5.33.1, current 5.56.5)
- npm bundled with Node, pnpm 11.13.0, Bun 1.3.14
- Chromium, Firefox, and WebKit (Playwright 1.61.1)
- Ubuntu and Windows in CI; macOS nightly
Exact machine-checked rows live in
[support-matrix.json](https://github.com/ljodea/ggsvelte/blob/main/support-matrix.json).
Bun is the contributor toolchain only; consumers can use any installer above.
---
# Interaction reference
Searchable interaction contract. Chart-local state and callbacks by default.
`createPlotInteraction()` for shared semantic state across plots and UI.
## Static default
No capture layer, tooltip, selection, or zoom until a capability is enabled.
Page scroll is not hijacked by unused tools.
## Capability props
### `inspect`
Prefer the declaration child `` (or ``,
etc.). Options match the legacy GGPlot prop: `mode`, `pin`, `maxDistance`,
`content`, `contentMode`, `muteSiblings`. Empty `` equals
`inspect={true}`. The GGPlot `inspect` prop still works. The heading id stays
`inspect` for stable deep links.
### Point selection
`select={{ type: "point", multiple: true }}` stores stable semantic keys.
Identity defaults to an `id` column or row index; override with
`select={{ type: "point", identity: "…" }}` or ``.
### Interval selection
`select={{ type: "interval", mode: "x" | "y" | "xy", persistent: true }}`
enables an explicit Select area tool and emits domain and pixel bounds. In
facets, add `preset: "independent" | "union" | "cross-panel"` to replace one
panel, combine panel selections, or project one domain through compatible
panels.
### `zoom`
`zoom={{ mode: "x" | "y" | "xy" }}` enables the explicit Zoom area tool.
Reset zoom and double-click return to the natural domains.
### `legendFocus`
Prefer `` (boolean or
`{ preview?: boolean }`) for discrete legend preview and committed focus on
that aesthetic. Host-only — never a PortableSpec / `guideLegend()` field. Use
`focus={{ preview: false }}` to disable hover/focus preview while retaining
click, touch, Enter, Space, Escape, and arrow-key controls. Requires stable
row `key` values; continuous ramps stay static.
The plot prop `legendFocus={true}` is deprecated since 0.19.0 (removed in
0.20.0) and still enables focus plot-wide during the dual-read window — see
[Legend focus on GuideLegend](https://ggsvelte.sh/guide/upgrading#legend-focus-on-guidelegend).
### `legendFilter`
Prefer `` (boolean or
`{ mode?: "exclude" | "include", multiple?: boolean }`) for data-changing
checkboxes on that aesthetic's discrete legend. Host-only — never a
PortableSpec / `guideLegend()` field. It changes the rows supplied to facets,
statistics, scales, and rendering while preserving the full legend catalog and
categorical color identity. Receive typed clauses through `onlegendfilter`.
Independent of presentation-only GuideLegend `focus`.
The plot prop `legendFilter={true}` is deprecated since 0.19.0 (removed in
0.20.0) and still enables filter plot-wide during the dual-read window — see
[Legend filter on GuideLegend](https://ggsvelte.sh/guide/upgrading#legend-filter-on-guidelegend).
## Controlled tool
`tool` and `ontoolchange` control the active Inspect, Select area, or Zoom
area mode. Keep the value in Svelte state when application controls and the
plot tool rail must stay synchronized:
```svelte fragment
(activeTool = next)}
>
```
A controlled unavailable tool requests a change and emits a diagnostic; it
does not silently arm a different drag behavior. The active tool remains local
to one chart; shared controllers coordinate data semantics, not UI modes.
## Shared controller
`createPlotInteraction({ onchange? })` returns a reactive
`PlotInteractionController`. Pass it through the `interaction` prop and
name the semantic channels with the required
`interactionScope={{ keys, x?, y? }}`; controlled plots never fall back to a
generic scope or infer x/y channel names from encodings. Controlled zoom
requires an explicit scope for every active channel (x, y, or both).
- Reads: `selected(scope)`, `emphasized(scope)`, `intervals(scope)`,
`isSelected(key, scope)`, `zoom(scope)`, `snapshot`, and `revision`.
- Selection: `setSelection`, `toggleSelection`, and `clearSelection`.
- Lightweight presentation: `setEmphasis` and `clearEmphasis`.
- Facet intervals: `setInterval`, `clearInterval`, and `clearIntervals`.
- Domains: `setZoom` and `resetZoom` for finite numeric x/y pairs.
- Data replacement: `reconcileKeys(validKeys, { scope })` explicitly removes
selected or emphasized keys that no longer exist.
Scopes are application-level names. Reuse a key scope only where keys mean the
same thing, and reuse x/y scopes only where their data domains are compatible.
Every mutation returns one immutable transition or `null` for a no-op. Passive
consumers never republish controller state, preventing linked-view feedback
loops. Do not mutate the controller inside its synchronous `onchange`
callback; schedule a later Svelte application update instead. See the
[linked views example](https://ggsvelte.sh/examples/interaction/linked-views).
## Identity
`key` is a field name or accessor returning a unique stable `PropertyKey`. Public
events expose semantic keys, aggregate `sourceKeys`, and `lineageCount`,
never renderer indices.
## Events
### `oninspect`
Receives `PlotInspection`: `change` with transient or pinned focus and
members, or `clear`.
### `onselect`
Receives `PlotSelection`. Point selection emits `end` and `clear`.
Interval selection emits `start`, `change`, `end`, and `clear`.
### `onzoom`
Receives `ZoomEvent`: `end` with explicit domains or `clear` with null
domains.
### `onlegendfocus`
Receives `LegendFocusEvent`: a transient or committed `change` carrying the
raw encoded value, formatted label, scale channel, and stable row keys, or a
small `clear` event. The same object is included in `oninteraction`.
### `onlegendfilter`
Receives `LegendFilterEvent`: a `change` with one typed
`LegendFilterClause`, or `clear` with `clause: null`. Legend filtering
changes pipeline input and is not folded into the presentation interaction
union.
### `oninteraction`
Receives the same discriminated `PlotInteractionEvent` union emitted by the
focused callbacks. Narrow on `type` and `phase`.
### `ondiagnostic`
Receives structured `PlotDiagnostic` objects (`InteractionDiagnostic` or
`DeprecationDiagnostic`) with `severity`, `code`, `message`, `prop`,
`suggestions`, and `docUrl`. Deprecation advisories also carry `since`
and `removeIn`.
```svelte fragment
console.warn(diagnostic.code, diagnostic.message, diagnostic.suggestions)}
/>
```
Every event has a `source`: `pointer`, `keyboard`, `touch`, or
`programmatic`.
## Diagnostics
### `INTERACTION_INTERVAL_FACET_UNSUPPORTED`
Brush zoom currently requires one unfaceted panel.
- Prop: `zoom`
- Severity: `warning`
- Try: Remove the facet; Use faceted interval selection; Zoom a linked detail view
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-interval-facet-unsupported](https://ggsvelte.sh/guide/interaction-reference#interaction-interval-facet-unsupported)
### `INTERACTION_INVALID_MAX_DISTANCE`
inspect.maxDistance must be a finite non-negative CSS-pixel distance.
- Prop: `inspect.maxDistance`
- Severity: `error`
- Try: Use a finite number greater than or equal to zero
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-invalid-max-distance](https://ggsvelte.sh/guide/interaction-reference#interaction-invalid-max-distance)
### `INTERACTION_POINT_REQUIRES_KEY`
Durable point selection requires resolved row identity.
- Prop: `identity`
- Severity: `warning`
- Try: Ordinary charts omit identity — defaults to an id column or row index; Override with or select={{ type: "point", identity: "id" }}
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-point-requires-key](https://ggsvelte.sh/guide/interaction-reference#interaction-point-requires-key)
### `INTERACTION_INTERVAL_PRESET_REQUIRES_KEY`
Coordinated interval presets (union, cross-panel) require resolved row identity; without it they combine no rows.
- Prop: `identity`
- Severity: `warning`
- Try: Ordinary charts omit identity — defaults to an id column or row index; Override with select={{ type: "interval", identity: "id", … }} or
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-interval-preset-requires-key](https://ggsvelte.sh/guide/interaction-reference#interaction-interval-preset-requires-key)
### `INTERACTION_INVALID_KEY`
A key accessor returned null, undefined, or a non-PropertyKey value.
- Prop: `identity`
- Severity: `error`
- Try: Return a stable string, number, or symbol for every row
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-invalid-key](https://ggsvelte.sh/guide/interaction-reference#interaction-invalid-key)
### `INTERACTION_DUPLICATE_KEY`
The key accessor returned a duplicate value; durable interaction is disabled for that value.
- Prop: `identity`
- Severity: `error`
- Try: Use a field that uniquely identifies each source row
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-duplicate-key](https://ggsvelte.sh/guide/interaction-reference#interaction-duplicate-key)
### `INTERACTION_UNSTABLE_KEY`
The key accessor returned a different value for the same source row.
- Prop: `identity`
- Severity: `error`
- Try: Return an immutable field that uniquely identifies each row
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-unstable-key](https://ggsvelte.sh/guide/interaction-reference#interaction-unstable-key)
### `INTERACTION_MISSING_LINEAGE`
A synthetic or aggregate mark did not expose source-row lineage.
- Prop: `layers`
- Severity: `warning`
- Try: Use a stat that preserves source-row lineage
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-missing-lineage](https://ggsvelte.sh/guide/interaction-reference#interaction-missing-lineage)
### `INTERACTION_LEGEND_REQUIRES_KEY`
Legend focus requires resolved row identity so encoded legend values never become identities.
- Prop: `identity`
- Severity: `warning`
- Try: Ordinary charts omit identity — defaults to an id column or row index; Override with or createPlotInteraction({ identity: "id" })
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-legend-requires-key](https://ggsvelte.sh/guide/interaction-reference#interaction-legend-requires-key)
### `INTERACTION_LEGEND_DISCRETE_ONLY`
Legend focus currently applies to discrete color and fill legends; continuous ramps remain static.
- Prop: `focus`
- Severity: `advisory`
- Try: Enable focus on a discrete guide: ; Use a discrete color or fill mapping; Keep the continuous ramp static
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-legend-discrete-only](https://ggsvelte.sh/guide/interaction-reference#interaction-legend-discrete-only)
### `INTERACTION_INTERVAL_SCALE_UNSUPPORTED`
Interval domains and brush zoom require continuous linear, log, or time scales.
- Prop: `scales`
- Severity: `warning`
- Try: Use a continuous positional scale; Use point inspection for band data
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-interval-scale-unsupported](https://ggsvelte.sh/guide/interaction-reference#interaction-interval-scale-unsupported)
### `INTERACTION_TOOL_UNAVAILABLE`
The requested interaction tool is unavailable for the enabled capabilities.
- Prop: `tool`
- Severity: `warning`
- Try: Enable the matching capability; Choose an available interaction tool
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-tool-unavailable](https://ggsvelte.sh/guide/interaction-reference#interaction-tool-unavailable)
### `INTERACTION_SCOPE_WITHOUT_CONTROLLER`
interactionScope is ignored without an interaction controller; chart-local scope is derived from key and aes.
- Prop: `interactionScope`
- Severity: `advisory`
- Try: Pass interaction={createPlotInteraction()} to control this plot; Remove interactionScope from uncontrolled plots
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-scope-without-controller](https://ggsvelte.sh/guide/interaction-reference#interaction-scope-without-controller)
### `INTERACTION_HANDLER_WITHOUT_CAPABILITY`
An interaction handler is set but its capability prop is not enabled, so the handler never fires.
- Prop: `oninspect / onselect / onzoom / onlegendfocus / onlegendfilter`
- Severity: `advisory`
- Try: Enable the matching capability prop (for example select for onselect); Remove the unused handler
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-handler-without-capability](https://ggsvelte.sh/guide/interaction-reference#interaction-handler-without-capability)
### `INTERACTION_INSPECT_X_ON_COL`
inspect.mode x/xy draws a crosshair on the x (band) axis through column marks; columns already encode x as a filled band, so the guide cuts the bar body and rarely adds information. Under coord_flip the guide is horizontal but still tracks the band.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomCol; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-on-col](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-on-col)
### `INTERACTION_INSPECT_X_ON_BAR`
inspect.mode x/xy draws a crosshair through bar marks; bars are filled regions on the band axis, so the guide cuts the bar body and rarely adds information. Under coord_flip the guide orientation swaps with the axes but still fights the marks.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomBar; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-on-bar](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-on-bar)
### `INTERACTION_INSPECT_X_BISECTS_COL_LABELS`
inspect.mode x/xy draws a crosshair through GeomCol marks that also carry GeomText/GeomLabel values; the guide bisects the on-bar totals and makes them hard to read (including under coord_flip, when the guide is horizontal).
- Prop: `inspect.mode`
- Severity: `warning`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") when columns have value labels; Keep value labels; drop the x/xy guide rather than dropping the labels
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-bisects-col-labels](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-bisects-col-labels)
### `INTERACTION_INSPECT_X_BISECTS_BAR_LABELS`
inspect.mode x/xy draws a crosshair through GeomBar marks that also carry GeomText/GeomLabel values; the guide bisects the on-bar totals and makes them hard to read (including under coord_flip).
- Prop: `inspect.mode`
- Severity: `warning`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") when bars have value labels; Keep value labels; drop the x/xy guide rather than dropping the labels
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-bisects-bar-labels](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-x-bisects-bar-labels)
### `INTERACTION_INSPECT_AXIS_ON_VIOLIN`
inspect.mode draws an axis guide through violin marks; violins sit on a discrete band, so freescrolling x/y/xy guides cut the density body and often leave the band tooltip row blank.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomViolin; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-violin](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-violin)
### `INTERACTION_INSPECT_AXIS_ON_BOXPLOT`
inspect.mode draws an axis guide through boxplot marks; boxes sit on a discrete band, so freescrolling x/y/xy guides cut the box body and rarely add information.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomBoxplot; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-boxplot](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-boxplot)
### `INTERACTION_INSPECT_AXIS_ON_ERRORBAR`
inspect.mode draws an axis guide through errorbar marks; interval geoms on a discrete band are better inspected on the mark itself than via a freescrolling guide.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomErrorbar; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-errorbar](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-errorbar)
### `INTERACTION_INSPECT_AXIS_ON_LINERANGE`
inspect.mode draws an axis guide through linerange marks; interval geoms on a discrete band are better inspected on the mark itself than via a freescrolling guide.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomLinerange; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-linerange](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-linerange)
### `INTERACTION_INSPECT_AXIS_ON_POINTRANGE`
inspect.mode draws an axis guide through pointrange marks; interval geoms on a discrete band are better inspected on the mark itself than via a freescrolling guide.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomPointrange; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-pointrange](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-pointrange)
### `INTERACTION_INSPECT_AXIS_ON_CROSSBAR`
inspect.mode draws an axis guide through crossbar marks; even when hits pin to a category, freescrolling x/y/xy guides rarely add information beyond exact mark focus.
- Prop: `inspect.mode`
- Severity: `advisory`
- Try: Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomCrossbar; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-crossbar](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-axis-on-crossbar)
### `INTERACTION_INSPECT_HIGH_CARDINALITY_DISCRETE`
Inspect is enabled with a high-cardinality discrete color/fill domain; the default tooltip shows the focused series, the largest contributors at that x (or y), a stack total, and an overflow line — not every series.
- Prop: `inspect`
- Severity: `advisory`
- Try: Prep top-n data before plotting if only the largest series matter; Pass a custom content snippet on for a full multi-series listing; Pin the tooltip to scroll the full group when every series must be readable
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-high-cardinality-discrete](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-high-cardinality-discrete)
### `INTERACTION_INSPECT_IDENTITY_DROPPED`
An child replaced the inspect prop whole (REPLACE), so the prop's `identity` no longer applies; rows fall back to an id column or row index.
- Prop: `Inspect`
- Severity: `advisory`
- Try: Move identity onto the child; Drop identity from the inspect prop if the default row identity is intended
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-identity-dropped](https://ggsvelte.sh/guide/interaction-reference#interaction-inspect-identity-dropped)
### `INTERACTION_DUPLICATE_INSPECT_CAPABILITY`
Multiple children are registered; only the last one's options apply (REPLACE).
- Prop: `Inspect`
- Severity: `advisory`
- Try: Keep a single child; Merge options onto one instead of stacking siblings
- More: [https://ggsvelte.sh/guide/interaction-reference#interaction-duplicate-inspect-capability](https://ggsvelte.sh/guide/interaction-reference#interaction-duplicate-inspect-capability)
## Accessibility
The plot surface is named and keyboard focusable when interaction is enabled.
Arrow keys or brackets traverse data; Enter or Space pins or commits the active
tool; Escape dismisses. A polite live region announces concise state while
pinned HTML remains labelled, navigable DOM. Area tools remain explicit so
ordinary page scrolling is available until a user chooses a drag mode.
Committed interval and zoom state exposes precise Edit-bounds buttons in the
tool rail. Their inline form uses labelled native inputs, stages drafts until
Apply, validates log/time/category constraints, restores trigger focus after
Apply or Cancel, and supports Escape. Linear and reversed domains use ascending
data values; time uses ISO 8601 text; band intervals use inclusive native
selects. Clear panel selection, Clear all selections, Reset zoom, and Reset
legend filters remain separate operations.
---
# Errors reference
Diagnostics are generated from the catalogs used by validation, rendering,
interaction, and the CLI. Identity is the pair `(source, code)`: a bare code
can intentionally exist in more than one source with a different consequence.
## Quickstart troubleshooting
- **Collapsed or zero-width container:** the responsive plot remains
`data-gg-ready="false"` until ResizeObserver reports a positive width.
Give the parent a real grid/flex track width; no fixed chart width is needed.
- **SSR and hydration:** omitted width server-renders at 832 × 400, stays
not-ready on the server, then measures its real container after hydration.
- **Unexpected height:** omitted height is 400px unless the spec supplies one.
- **TypeScript or linked-package mismatch:** install one compatible
`@ggsvelte/svelte` version and let it resolve matching core/spec packages;
remove stale lockfile overrides that mix versions.
- **CLI input failure:** run `ggsvelte-render --help`; keep SVG stdout
separate from JSON Lines stderr while correcting the reported input.
## Validation errors (@ggsvelte/spec)
Each entry answers what failed, why, how to recover safely, and whether output was blocked or degraded.
### `invalid-spec-root`
**Code + severity:** `invalid-spec-root` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** The spec is not a JSON object.
**Fix:** Provide an object with at least one layer: {"layers": [{"geom": "point", ...}]}.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-spec-root](https://ggsvelte.sh/guide/errors#invalid-spec-root)
### `missing-layers`
**Code + severity:** `missing-layers` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** `layers` is missing or not an array.
**Fix:** Add a layers array with at least one layer object.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#missing-layers](https://ggsvelte.sh/guide/errors#missing-layers)
### `empty-layers`
**Code + severity:** `empty-layers` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** `layers` is present but empty (a plot needs at least one layer).
**Fix:** Add a layer, e.g. {"geom": "point"}.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#empty-layers](https://ggsvelte.sh/guide/errors#empty-layers)
### `invalid-layer`
**Code + severity:** `invalid-layer` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A layer is not an object.
**Fix:** Replace the entry with a layer object carrying a "geom".
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-layer](https://ggsvelte.sh/guide/errors#invalid-layer)
### `missing-geom`
**Code + severity:** `missing-geom` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A layer has no "geom" discriminator.
**Fix:** Add a geom name to the layer, e.g. {"geom": "point"}.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#missing-geom](https://ggsvelte.sh/guide/errors#missing-geom)
### `unknown-geom`
**Code + severity:** `unknown-geom` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A layer's "geom" is not a known geom name.
**Fix:** Use one of the allowed geoms (the error lists them, with a did-you-mean).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#unknown-geom](https://ggsvelte.sh/guide/errors#unknown-geom)
### `invalid-channel-value`
**Code + severity:** `invalid-channel-value` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A channel value is not one of the canonical forms {field}/{value}/{stat}/null (bare strings are builder-only shorthand).
**Fix:** Wrap field mappings as {"field": "column_name"} and constants as {"value": ...}.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-channel-value](https://ggsvelte.sh/guide/errors#invalid-channel-value)
### `unexpected-property`
**Code + severity:** `unexpected-property` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** An object carries a property the schema does not allow.
**Fix:** Remove or rename the property (the error suggests the closest allowed name).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#unexpected-property](https://ggsvelte.sh/guide/errors#unexpected-property)
### `missing-property`
**Code + severity:** `missing-property` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A required property is missing.
**Fix:** Add the named property.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#missing-property](https://ggsvelte.sh/guide/errors#missing-property)
### `invalid-enum-value`
**Code + severity:** `invalid-enum-value` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A value is outside its declared enum/literal set.
**Fix:** Use one of the allowed values (the error lists them, with a did-you-mean).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-enum-value](https://ggsvelte.sh/guide/errors#invalid-enum-value)
### `value-out-of-range`
**Code + severity:** `value-out-of-range` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A numeric value is outside its declared bounds.
**Fix:** Set the value inside the bounds stated by the error message.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#value-out-of-range](https://ggsvelte.sh/guide/errors#value-out-of-range)
### `invalid-data`
**Code + severity:** `invalid-data` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** `data` (or a dataset entry) matches none of the data forms.
**Fix:** Use {"values": [...rows]}, {"columns": {...arrays}}, or {"name": "dataset"}.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-data](https://ggsvelte.sh/guide/errors#invalid-data)
### `invalid-type`
**Code + severity:** `invalid-type` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** Fallback: a value has the wrong JSON type.
**Fix:** Give the property the JSON type the message names.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-type](https://ggsvelte.sh/guide/errors#invalid-type)
### `scale-scheme-type`
**Code + severity:** `scale-scheme-type` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A named color scheme is incompatible with the configured color scale type.
**Fix:** Use a categorical scheme with "ordinal" (or a sequential-family scheme like "viridis" for discrete viridis), or "viridis"/hex stops with "sequential".
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#scale-scheme-type](https://ggsvelte.sh/guide/errors#scale-scheme-type)
### `scale-range-color`
**Code + severity:** `scale-range-color` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A custom color range contains a color outside the supported hex syntax.
**Fix:** Replace each custom color with #rgb or #rrggbb syntax.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#scale-range-color](https://ggsvelte.sh/guide/errors#scale-range-color)
### `scale-type-transform-conflict`
**Code + severity:** `scale-type-transform-conflict` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A scale declares an incompatible type/family with its transform (temporal/discrete/manual/identity with a non-identity transform, or type: "log" with a non-log10 transform).
**Fix:** Use identity for temporal/discrete/manual/identity scales; for base-10 log use type: "linear" with transform: "log10"; or choose a quantitative family that admits the transform.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#scale-type-transform-conflict](https://ggsvelte.sh/guide/errors#scale-type-transform-conflict)
### `color-manual-domain-range`
**Code + severity:** `color-manual-domain-range` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A manual color/fill scale has a different number of domain values and range colors.
**Fix:** Provide exactly one range color for every domain value.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#color-manual-domain-range](https://ggsvelte.sh/guide/errors#color-manual-domain-range)
### `scale-binned-breaks`
**Code + severity:** `scale-binned-breaks` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A binned style scale's authored breaks are missing, non-finite after parsing, duplicated, or not strictly increasing.
**Fix:** Provide 2+ strictly increasing boundaries (numeric, or temporal strings that parse under the scale's parser).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#scale-binned-breaks](https://ggsvelte.sh/guide/errors#scale-binned-breaks)
### `scale-binned-domain`
**Code + severity:** `scale-binned-domain` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A binned style scale's explicit domain does not match the first and last authored breaks.
**Fix:** Set domain to the first and last break values, or omit domain and let breaks define it.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#scale-binned-domain](https://ggsvelte.sh/guide/errors#scale-binned-domain)
### `guide-aesthetic-incompatible`
**Code + severity:** `guide-aesthetic-incompatible` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** A guide variant is incompatible with its aesthetic or trained scale family.
**Fix:** Use axis for x/y, legend for discrete/style scales, colorbar for sequential color, or colorsteps for binned color.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#guide-aesthetic-incompatible](https://ggsvelte.sh/guide/errors#guide-aesthetic-incompatible)
### `coord-fixed-free-scales`
**Code + severity:** `coord-fixed-free-scales` · error
**What failed:** Spec validation rejected the value at its reported path (schema shape).
**Why:** Fixed-aspect coordinates cannot represent free positional facet scales truthfully.
**Fix:** Use facet.scales = "fixed", or remove coord_fixed / coord_sf.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#coord-fixed-free-scales](https://ggsvelte.sh/guide/errors#coord-fixed-free-scales)
### `missing-required-channel`
**Code + severity:** `missing-required-channel` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A geom is missing a required aesthetic channel (x, y, label, ...).
**Fix:** Map the named channel to a data field in the layer's aes or the plot-level aes.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#missing-required-channel](https://ggsvelte.sh/guide/errors#missing-required-channel)
### `rule-form-ambiguous`
**Code + severity:** `rule-form-ambiguous` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A rule layer mixes the annotation form (params.xintercept/yintercept) with mapped aes.x/aes.y.
**Fix:** Use fixed intercepts OR a data mapping, never both (unset the other with null).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#rule-form-ambiguous](https://ggsvelte.sh/guide/errors#rule-form-ambiguous)
### `rule-form-missing`
**Code + severity:** `rule-form-missing` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A rule layer has neither intercept params nor a mapped aes.x/aes.y — nothing to draw.
**Fix:** Set params.yintercept/xintercept (annotation) or map aes.x/aes.y (data-driven).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#rule-form-missing](https://ggsvelte.sh/guide/errors#rule-form-missing)
### `rule-both-axes`
**Code + severity:** `rule-both-axes` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A data-driven rule layer maps BOTH aes.x and aes.y (pick one direction).
**Fix:** Keep one direction (vertical: map x; horizontal: map y) and unset the other with null.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#rule-both-axes](https://ggsvelte.sh/guide/errors#rule-both-axes)
### `computed-y-mapped`
**Code + severity:** `computed-y-mapped` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A layer whose stat computes y (count, bin, density) maps aes.y to a data field.
**Fix:** Unset y with null — or, for pre-computed bar heights, switch the layer to geom "col".
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#computed-y-mapped](https://ggsvelte.sh/guide/errors#computed-y-mapped)
### `bin-center-and-boundary`
**Code + severity:** `bin-center-and-boundary` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A bin-stat layer sets BOTH params.center and params.boundary.
**Fix:** Keep one bin-grid alignment parameter and remove the other.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#bin-center-and-boundary](https://ggsvelte.sh/guide/errors#bin-center-and-boundary)
### `facet-form-ambiguous`
**Code + severity:** `facet-form-ambiguous` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A facet sets BOTH the wrap form and the rows/cols grid form.
**Fix:** Keep facet.wrap (and drop rows/cols), or keep rows/cols (and drop wrap).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#facet-form-ambiguous](https://ggsvelte.sh/guide/errors#facet-form-ambiguous)
### `facet-form-missing`
**Code + severity:** `facet-form-missing` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A facet sets neither wrap nor rows/cols — nothing to partition by.
**Fix:** Set facet.wrap (wrap form) or facet.rows/facet.cols (grid form).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#facet-form-missing](https://ggsvelte.sh/guide/errors#facet-form-missing)
### `facet-ncol-without-wrap`
**Code + severity:** `facet-ncol-without-wrap` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** facet.ncol only applies to the wrap form.
**Fix:** Remove ncol, or switch to the wrap form.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#facet-ncol-without-wrap](https://ggsvelte.sh/guide/errors#facet-ncol-without-wrap)
### `unsupported-geom-aesthetic`
**Code + severity:** `unsupported-geom-aesthetic` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A mapped style aesthetic is not consumed by the selected geom.
**Fix:** Remove the mapping or move it to one of the compatible geoms listed in the error.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#unsupported-geom-aesthetic](https://ggsvelte.sh/guide/errors#unsupported-geom-aesthetic)
### `ribbon-orientation-ambiguous`
**Code + severity:** `ribbon-orientation-ambiguous` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A ribbon layer maps both x-orientation (x+ymin+ymax) and y-orientation (y+xmin+xmax) contracts without params.orientation.
**Fix:** Set params.orientation to "x" or "y", or map only one complete interval contract.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#ribbon-orientation-ambiguous](https://ggsvelte.sh/guide/errors#ribbon-orientation-ambiguous)
### `paint-stops-unordered`
**Code + severity:** `paint-stops-unordered` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A gradient paint's color stops are not in non-decreasing offset order.
**Fix:** Sort stops by offset ascending (each offset between 0 and 1 inclusive).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#paint-stops-unordered](https://ggsvelte.sh/guide/errors#paint-stops-unordered)
### `paint-scale-conflict`
**Code + severity:** `paint-scale-conflict` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** Within-mark fillPaint/strokePaint cannot combine with a data-mapped fill/color scale channel.
**Fix:** Remove the data-mapped fill/color aesthetic, or remove the paint and keep the scale.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#paint-scale-conflict](https://ggsvelte.sh/guide/errors#paint-scale-conflict)
### `unknown-field`
**Code + severity:** `unknown-field` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A channel maps a field that does not exist in the data.
**Fix:** Map the channel to one of the available fields (the error lists them, with a did-you-mean).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#unknown-field](https://ggsvelte.sh/guide/errors#unknown-field)
**Minimal illustration — copy only the relevant fragment:**
```json fragment copy
{
"aes": {
"x": { "field": "weight" },
"y": { "field": "economy" }
}
}
```
### `all-null-column`
**Code + severity:** `all-null-column` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A mapped column contains only null values.
**Fix:** Map the channel to a column with actual values, or fix the data.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#all-null-column](https://ggsvelte.sh/guide/errors#all-null-column)
### `scale-type-mismatch`
**Code + severity:** `scale-type-mismatch` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A configured scale type is incompatible with the mapped field's type.
**Fix:** Change the scale type to match the field (band for categories, time for temporal), or map a compatible field.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#scale-type-mismatch](https://ggsvelte.sh/guide/errors#scale-type-mismatch)
### `channel-type-mismatch`
**Code + severity:** `channel-type-mismatch` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A mapped field's type is incompatible with the layer's geom/stat (e.g. a nominal x on smooth/bin/density, a continuous x on boxplot).
**Fix:** Map a field of the type the geom/stat needs, or switch to a geom that fits the field (the message suggests one).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#channel-type-mismatch](https://ggsvelte.sh/guide/errors#channel-type-mismatch)
### `unknown-stat-column`
**Code + severity:** `unknown-stat-column` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A { stat } channel names a column the layer's stat does not generate.
**Fix:** Use one of the columns the stat generates (the error lists them), or change the layer's stat.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#unknown-stat-column](https://ggsvelte.sh/guide/errors#unknown-stat-column)
### `manual-fun-required`
**Code + severity:** `manual-fun-required` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A layer uses stat manual without params.fun.
**Fix:** Set params.fun to one of first|last|mean|median|min|max|sum (portable named registry; #814).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#manual-fun-required](https://ggsvelte.sh/guide/errors#manual-fun-required)
### `summary-rolling-window-required`
**Code + severity:** `summary-rolling-window-required` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A layer uses stat summary_rolling without params.window.
**Fix:** Set params.window to the rolling-window width in x data units (greater than 0).
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#summary-rolling-window-required](https://ggsvelte.sh/guide/errors#summary-rolling-window-required)
### `summary-fun-unsupported`
**Code + severity:** `summary-fun-unsupported` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** A summary stat uses params.fun first|last, which only stat manual implements.
**Fix:** Use mean, median, or sum (min/max via funMin/funMax where supported); first|last belong to stat manual.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#summary-fun-unsupported](https://ggsvelte.sh/guide/errors#summary-fun-unsupported)
### `invalid-data-profile`
**Code + severity:** `invalid-data-profile` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** The provided DataProfile is malformed.
**Fix:** Provide { fields: [{ name, type: "quantitative"|"temporal"|"ordinal"|"nominal" }], rowCount? }.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#invalid-data-profile](https://ggsvelte.sh/guide/errors#invalid-data-profile)
### `validation-limit`
**Code + severity:** `validation-limit` · error
**What failed:** Spec validation rejected the value at its reported path (grammar or data-aware check).
**Why:** Validation input exceeded a documented limit (rows/bytes/depth/diagnostics).
**Fix:** Validate with a DataProfile instead of huge inline data, or raise the limit via options.limits.
**Consequence (blocked):** Validation failed; no chart should be rendered from this spec.
**Stable link:** [/guide/errors#validation-limit](https://ggsvelte.sh/guide/errors#validation-limit)
## Render-time errors (@ggsvelte/core)
Each entry answers what failed, why, how to recover safely, and whether output was blocked or degraded.
### `guide-aesthetic-incompatible` — pipeline
**Code + severity:** `guide-aesthetic-incompatible` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A guide variant is incompatible with its aesthetic or trained scale family.
**Fix:** Use axis for x/y, legend for discrete/style scales, colorbar for sequential color, or colorsteps for binned color.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#guide-aesthetic-incompatible-pipeline](https://ggsvelte.sh/guide/errors#guide-aesthetic-incompatible-pipeline)
### `guide-layout-overflow`
**Code + severity:** `guide-layout-overflow` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A guide configured with collision: error cannot fit its authored label.
**Fix:** Use collision: "ellipsis" for long labels; increase the chart size, reduce categories, or suppress an oversized guide.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#guide-layout-overflow](https://ggsvelte.sh/guide/errors#guide-layout-overflow)
### `no-data`
**Code + severity:** `no-data` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A layer has neither plot-level data nor its own layer.data.
**Fix:** Set spec.data and/or layer.data ({values}, {columns}, or {name}), or pass named data via RunOptions.data.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#no-data](https://ggsvelte.sh/guide/errors#no-data)
### `dataset-collision`
**Code + severity:** `dataset-collision` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A dataset name is defined in both spec.datasets and RunOptions.data.
**Fix:** Rename one of them, or pass allowOverride: true to let the runtime data win.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#dataset-collision](https://ggsvelte.sh/guide/errors#dataset-collision)
### `unknown-dataset`
**Code + severity:** `unknown-dataset` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A {"name": ...} data ref names a dataset that is not defined anywhere.
**Fix:** Define it in spec.datasets or RunOptions.data (the message lists the available names).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unknown-dataset](https://ggsvelte.sh/guide/errors#unknown-dataset)
### `unknown-field` — pipeline
**Code + severity:** `unknown-field` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A channel maps a field that does not exist in the data.
**Fix:** Map the channel to one of the available fields (the error lists them, with a did-you-mean).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unknown-field-pipeline](https://ggsvelte.sh/guide/errors#unknown-field-pipeline)
### `all-null-column` — pipeline
**Code + severity:** `all-null-column` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A mapped column contains only null values.
**Fix:** Map the channel to a column with actual values, or fix the data.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#all-null-column-pipeline](https://ggsvelte.sh/guide/errors#all-null-column-pipeline)
### `missing-channel`
**Code + severity:** `missing-channel` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A geom is missing a required aesthetic channel at render time.
**Fix:** Map the named channel in the layer's aes or the plot-level aes.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#missing-channel](https://ggsvelte.sh/guide/errors#missing-channel)
### `unknown-stat-column` — pipeline
**Code + severity:** `unknown-stat-column` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A { stat } channel names a column the layer's stat does not generate.
**Fix:** Use one of the columns the stat generates (the error lists them), or change the layer's stat.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unknown-stat-column-pipeline](https://ggsvelte.sh/guide/errors#unknown-stat-column-pipeline)
### `channel-type-mismatch` — pipeline
**Code + severity:** `channel-type-mismatch` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A mapped field's type is incompatible with the layer's geom/stat (e.g. a nominal x on smooth/bin/density, a continuous x on boxplot).
**Fix:** Map a field of the type the geom/stat needs, or switch to a geom that fits the field (the message suggests one).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#channel-type-mismatch-pipeline](https://ggsvelte.sh/guide/errors#channel-type-mismatch-pipeline)
### `computed-y-mapped` — pipeline
**Code + severity:** `computed-y-mapped` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A layer whose stat computes y (count, bin, density) maps aes.y to a data field.
**Fix:** Unset y with null — or, for pre-computed bar heights, switch the layer to geom "col".
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#computed-y-mapped-pipeline](https://ggsvelte.sh/guide/errors#computed-y-mapped-pipeline)
### `bin-center-and-boundary` — pipeline
**Code + severity:** `bin-center-and-boundary` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A bin-stat layer sets BOTH params.center and params.boundary.
**Fix:** Keep one bin-grid alignment parameter and remove the other.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#bin-center-and-boundary-pipeline](https://ggsvelte.sh/guide/errors#bin-center-and-boundary-pipeline)
### `rule-form-ambiguous` — pipeline
**Code + severity:** `rule-form-ambiguous` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A rule layer mixes the annotation form (params.xintercept/yintercept) with mapped aes.x/aes.y.
**Fix:** Use fixed intercepts OR a data mapping, never both (unset the other with null).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#rule-form-ambiguous-pipeline](https://ggsvelte.sh/guide/errors#rule-form-ambiguous-pipeline)
### `rule-form-missing` — pipeline
**Code + severity:** `rule-form-missing` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A rule layer has neither intercept params nor a mapped aes.x/aes.y — nothing to draw.
**Fix:** Set params.yintercept/xintercept (annotation) or map aes.x/aes.y (data-driven).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#rule-form-missing-pipeline](https://ggsvelte.sh/guide/errors#rule-form-missing-pipeline)
### `rule-both-axes` — pipeline
**Code + severity:** `rule-both-axes` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A data-driven rule layer maps BOTH aes.x and aes.y (pick one direction).
**Fix:** Keep one direction (vertical: map x; horizontal: map y) and unset the other with null.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#rule-both-axes-pipeline](https://ggsvelte.sh/guide/errors#rule-both-axes-pipeline)
### `ribbon-orientation-ambiguous` — pipeline
**Code + severity:** `ribbon-orientation-ambiguous` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A ribbon layer maps both x-orientation (x+ymin+ymax) and y-orientation (y+xmin+xmax) contracts without params.orientation.
**Fix:** Set params.orientation to "x" or "y", or map only one complete interval contract.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#ribbon-orientation-ambiguous-pipeline](https://ggsvelte.sh/guide/errors#ribbon-orientation-ambiguous-pipeline)
### `ribbon-inverted-bounds`
**Code + severity:** `ribbon-inverted-bounds` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A ribbon layer has one or more rows where the lower bound exceeds the upper bound.
**Fix:** Swap or correct ymin/ymax (or xmin/xmax) so lower ≤ upper on every finite row.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#ribbon-inverted-bounds](https://ggsvelte.sh/guide/errors#ribbon-inverted-bounds)
### `facet-form-ambiguous` — pipeline
**Code + severity:** `facet-form-ambiguous` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A facet sets BOTH the wrap form and the rows/cols grid form.
**Fix:** Keep facet.wrap (and drop rows/cols), or keep rows/cols (and drop wrap).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#facet-form-ambiguous-pipeline](https://ggsvelte.sh/guide/errors#facet-form-ambiguous-pipeline)
### `facet-form-missing` — pipeline
**Code + severity:** `facet-form-missing` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A facet sets neither wrap nor rows/cols — nothing to partition by.
**Fix:** Set facet.wrap (wrap form) or facet.rows/facet.cols (grid form).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#facet-form-missing-pipeline](https://ggsvelte.sh/guide/errors#facet-form-missing-pipeline)
### `invalid-scale-domain`
**Code + severity:** `invalid-scale-domain` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** An explicit scale domain is malformed for its scale type.
**Fix:** Provide a two-element [min, max] for continuous scales (values of the field's type).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#invalid-scale-domain](https://ggsvelte.sh/guide/errors#invalid-scale-domain)
### `invalid-scale-breaks`
**Code + severity:** `invalid-scale-breaks` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** One or more explicit scale breaks do not match the scale's parser.
**Fix:** Use numeric breaks for numeric scales or values matching the temporal parse option.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#invalid-scale-breaks](https://ggsvelte.sh/guide/errors#invalid-scale-breaks)
### `invalid-temporal-labels`
**Code + severity:** `invalid-temporal-labels` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A temporal dateLabels string uses an unsupported or incomplete token.
**Fix:** Use only the documented closed dateLabels token grammar.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#invalid-temporal-labels](https://ggsvelte.sh/guide/errors#invalid-temporal-labels)
### `invalid-temporal-locale`
**Code + severity:** `invalid-temporal-locale` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A temporal scale locale is not a valid supported BCP 47 locale.
**Fix:** Use a canonical BCP 47 locale such as en-US, en-GB, fr-FR, or ja-JP.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#invalid-temporal-locale](https://ggsvelte.sh/guide/errors#invalid-temporal-locale)
### `temporal-parse-failed`
**Code + severity:** `temporal-parse-failed` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** An explicit temporal parser rejected one or more source values.
**Fix:** Correct the rejected values, choose the matching parser, or explicitly opt into censoring.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#temporal-parse-failed](https://ggsvelte.sh/guide/errors#temporal-parse-failed)
### `temporal-break-limit`
**Code + severity:** `temporal-break-limit` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** An explicit temporal interval would generate more bounded ticks than allowed.
**Fix:** Choose a coarser calendar interval.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#temporal-break-limit](https://ggsvelte.sh/guide/errors#temporal-break-limit)
### `temporal-break-progression`
**Code + severity:** `temporal-break-progression` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Calendar interval progression failed to advance monotonically.
**Fix:** Choose another timezone, disambiguation policy, or interval and report the failing case.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#temporal-break-progression](https://ggsvelte.sh/guide/errors#temporal-break-progression)
### `invalid-scale-transform`
**Code + severity:** `invalid-scale-transform` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** The scale transform registry was asked for an unknown transform key.
**Fix:** Use a supported transform (identity, log10, sqrt). This indicates malformed runtime input.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#invalid-scale-transform](https://ggsvelte.sh/guide/errors#invalid-scale-transform)
### `scale-transform-domain`
**Code + severity:** `scale-transform-domain` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** An explicit scale domain falls outside the transform's valid range (log10 <= 0, sqrt < 0).
**Fix:** Restrict the domain to the transform's valid range, or use the identity transform.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#scale-transform-domain](https://ggsvelte.sh/guide/errors#scale-transform-domain)
### `scale-type-transform-conflict` — pipeline
**Code + severity:** `scale-type-transform-conflict` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A scale declares an incompatible type/family with its transform (temporal/discrete/manual/identity with a non-identity transform, or type: "log" with a non-log10 transform).
**Fix:** Use identity for temporal/discrete/manual/identity scales; for base-10 log use type: "linear" with transform: "log10"; or choose a quantitative family that admits the transform.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#scale-type-transform-conflict-pipeline](https://ggsvelte.sh/guide/errors#scale-type-transform-conflict-pipeline)
### `scale-zero-invalid-for-transform`
**Code + severity:** `scale-zero-invalid-for-transform` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** zero: true was requested under a transform with no valid image for semantic zero (log10).
**Fix:** Remove zero: true; log10 positions use the transformed-space origin (semantic 1), never log10(0).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#scale-zero-invalid-for-transform](https://ggsvelte.sh/guide/errors#scale-zero-invalid-for-transform)
### `coord-transform-domain`
**Code + severity:** `coord-transform-domain` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A post-stat coordinate transform cannot project its trained or explicit viewport domain.
**Fix:** Choose coordinate limits inside the transform domain, or use the identity coordinate transform.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#coord-transform-domain](https://ggsvelte.sh/guide/errors#coord-transform-domain)
### `coord-transform-temporal`
**Code + severity:** `coord-transform-temporal` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A non-identity coordinate transform was requested for a temporal axis.
**Fix:** Keep temporal coordinates on identity; use identity coordinate limits/reverse for a viewport.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#coord-transform-temporal](https://ggsvelte.sh/guide/errors#coord-transform-temporal)
### `coord-transform-continuous`
**Code + severity:** `coord-transform-continuous` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A quantitative coordinate transform or numeric limits were requested for a band axis.
**Fix:** Use identity coordinates for categories, or configure a continuous quantitative scale.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#coord-transform-continuous](https://ggsvelte.sh/guide/errors#coord-transform-continuous)
### `coord-fixed-free-scales` — pipeline
**Code + severity:** `coord-fixed-free-scales` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Fixed-aspect coordinates cannot represent free positional facet scales truthfully.
**Fix:** Use facet.scales = "fixed", or remove coord_fixed / coord_sf.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#coord-fixed-free-scales-pipeline](https://ggsvelte.sh/guide/errors#coord-fixed-free-scales-pipeline)
### `coord-fixed-invalid-aspect`
**Code + severity:** `coord-fixed-invalid-aspect` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A fixed-aspect target or fitted data rectangle is non-finite or non-positive after chrome is allocated.
**Fix:** Use a moderate finite ratio and non-degenerate positional domains, or enlarge the plot allocation.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#coord-fixed-invalid-aspect](https://ggsvelte.sh/guide/errors#coord-fixed-invalid-aspect)
### `binned-scale-requires-continuous`
**Code + severity:** `binned-scale-requires-continuous` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A type: "binned" scale is bound to a discrete or temporal field.
**Fix:** Map a quantitative field, or use type: "band"/"time" instead of "binned".
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#binned-scale-requires-continuous](https://ggsvelte.sh/guide/errors#binned-scale-requires-continuous)
### `binned-scale-break-limit`
**Code + severity:** `binned-scale-break-limit` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A binned scale's automatic or explicit breaks would exceed MAX_BINNED_BREAKS (64).
**Fix:** Supply fewer explicit breaks, or widen them so automatic binning stays under the limit.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#binned-scale-break-limit](https://ggsvelte.sh/guide/errors#binned-scale-break-limit)
### `palette-exhausted`
**Code + severity:** `palette-exhausted` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A discrete color scale with onExhaust: "error" ran out of palette entries (the default "cycle" only warns).
**Fix:** Provide a larger range, set an explicit domain, or accept cycling by removing onExhaust.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#palette-exhausted](https://ggsvelte.sh/guide/errors#palette-exhausted)
### `color-temporal-parse`
**Code + severity:** `color-temporal-parse` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A temporal color/fill scale could not parse the complete mapped column.
**Fix:** Set the exact parse order, correct the rejected values, or explicitly choose parseFailure: censor.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-temporal-parse](https://ggsvelte.sh/guide/errors#color-temporal-parse)
### `color-temporal-kind`
**Code + severity:** `color-temporal-kind` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A temporal color/fill scale requested date or datetime precision that the data does not have.
**Fix:** Use the matching date/datetime helper or correct the source precision.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-temporal-kind](https://ggsvelte.sh/guide/errors#color-temporal-kind)
### `color-manual-domain-range` — pipeline
**Code + severity:** `color-manual-domain-range` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A manual color/fill scale has a different number of domain values and range colors.
**Fix:** Provide exactly one range color for every domain value.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-manual-domain-range-pipeline](https://ggsvelte.sh/guide/errors#color-manual-domain-range-pipeline)
### `color-binned-breaks`
**Code + severity:** `color-binned-breaks` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Binned color/fill boundaries are invalid, unparseable, duplicated, or unordered.
**Fix:** Provide 2–65 strictly increasing boundaries valid for the parser and transform.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-binned-breaks](https://ggsvelte.sh/guide/errors#color-binned-breaks)
### `color-binned-empty`
**Code + severity:** `color-binned-empty` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A binned color/fill scale has no values inside its parser/transform domain.
**Fix:** Correct the mapped values, parser, or transform, or provide a valid explicit domain.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-binned-empty](https://ggsvelte.sh/guide/errors#color-binned-empty)
### `color-binned-domain`
**Code + severity:** `color-binned-domain` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A binned color/fill domain is degenerate or invalid for its transform.
**Fix:** Provide two distinct domain endpoints valid for identity, log10, or sqrt.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-binned-domain](https://ggsvelte.sh/guide/errors#color-binned-domain)
### `color-domain-invalid`
**Code + severity:** `color-domain-invalid` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A sequential color/fill domain does not contain exactly two parseable values.
**Fix:** Provide a two-value semantic domain matching the mapped field and parser.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-domain-invalid](https://ggsvelte.sh/guide/errors#color-domain-invalid)
### `color-transform-empty`
**Code + severity:** `color-transform-empty` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Every mapped color/fill value is invalid for the requested transform.
**Fix:** Correct the mapped data or choose a transform whose domain contains the values.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-transform-empty](https://ggsvelte.sh/guide/errors#color-transform-empty)
### `color-domain-transform`
**Code + severity:** `color-domain-transform` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A sequential color/fill domain is invalid for its requested transform.
**Fix:** Use positive endpoints for log10, non-negative endpoints for sqrt, or identity.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#color-domain-transform](https://ggsvelte.sh/guide/errors#color-domain-transform)
### `unsupported-aesthetic-scale`
**Code + severity:** `unsupported-aesthetic-scale` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A finite shape/linetype aesthetic was configured as a continuous scale.
**Fix:** Use a binned scale for quantitative values or an ordinal scale for categories.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unsupported-aesthetic-scale](https://ggsvelte.sh/guide/errors#unsupported-aesthetic-scale)
### `unsupported-geom-aesthetic` — pipeline
**Code + severity:** `unsupported-geom-aesthetic` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A mapped style aesthetic is not consumed by the selected geom.
**Fix:** Remove the mapping or move it to one of the compatible geoms listed in the error.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unsupported-geom-aesthetic-pipeline](https://ggsvelte.sh/guide/errors#unsupported-geom-aesthetic-pipeline)
### `unsupported-annotation-style`
**Code + severity:** `unsupported-annotation-style` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A fixed-intercept annotation rule maps a style to a field or after-stat column, but it has no data rows to map.
**Fix:** Use a constant style value (optionally { value, scale: true }) on the annotation rule.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unsupported-annotation-style](https://ggsvelte.sh/guide/errors#unsupported-annotation-style)
### `tile-nonpositive-size`
**Code + severity:** `tile-nonpositive-size` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A tile layer has a non-positive or non-finite width/height.
**Fix:** Map a positive width/height or set params.width / params.height to a positive number.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#tile-nonpositive-size](https://ggsvelte.sh/guide/errors#tile-nonpositive-size)
### `raster-duplicate-cells`
**Code + severity:** `raster-duplicate-cells` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A raster layer has duplicate (x, y) coordinates.
**Fix:** Aggregate to one value per cell, or use geom "tile" for overlapping cells.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#raster-duplicate-cells](https://ggsvelte.sh/guide/errors#raster-duplicate-cells)
### `unsupported-param`
**Code + severity:** `unsupported-param` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A layer param value is not supported by this runtime.
**Fix:** Use a documented supported value for the param (see the error message).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unsupported-param](https://ggsvelte.sh/guide/errors#unsupported-param)
### `invalid-aesthetic-constant`
**Code + severity:** `invalid-aesthetic-constant` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A literal style constant is outside the aesthetic's supported output domain.
**Fix:** Use a positive size/linewidth, alpha in [0,1], or a documented shape/linetype name.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#invalid-aesthetic-constant](https://ggsvelte.sh/guide/errors#invalid-aesthetic-constant)
### `style-temporal-parse`
**Code + severity:** `style-temporal-parse` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A temporal numeric style scale could not parse the complete mapped column.
**Fix:** Set the exact parser, correct the rejected values, or explicitly choose censoring.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-temporal-parse](https://ggsvelte.sh/guide/errors#style-temporal-parse)
### `style-temporal-kind`
**Code + severity:** `style-temporal-kind` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A temporal numeric style scale requested the wrong date/datetime precision.
**Fix:** Use the matching date/datetime helper or correct the source precision.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-temporal-kind](https://ggsvelte.sh/guide/errors#style-temporal-kind)
### `style-manual-domain-range`
**Code + severity:** `style-manual-domain-range` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A manual style scale has different domain and range lengths.
**Fix:** Provide exactly one output style for every domain value.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-manual-domain-range](https://ggsvelte.sh/guide/errors#style-manual-domain-range)
### `style-palette-exhausted`
**Code + severity:** `style-palette-exhausted` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A finite style scale needs more distinguishable outputs than its range provides.
**Fix:** Provide a larger range, reduce categories/bins, or deliberately opt into cycling.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-palette-exhausted](https://ggsvelte.sh/guide/errors#style-palette-exhausted)
### `style-domain-empty`
**Code + severity:** `style-domain-empty` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** No finite values can train the requested numeric or binned style scale.
**Fix:** Correct the mapped values or provide a valid explicit domain.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-domain-empty](https://ggsvelte.sh/guide/errors#style-domain-empty)
### `style-domain-invalid`
**Code + severity:** `style-domain-invalid` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** An explicit style domain is malformed or contradicts its binned boundaries.
**Fix:** Provide two finite semantic endpoints matching the first and last boundaries.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-domain-invalid](https://ggsvelte.sh/guide/errors#style-domain-invalid)
### `style-range-invalid`
**Code + severity:** `style-range-invalid` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A numeric sequential/binned style range has fewer than two endpoints.
**Fix:** Provide at least two valid output values in the aesthetic's supported bounds.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-range-invalid](https://ggsvelte.sh/guide/errors#style-range-invalid)
### `style-binned-breaks`
**Code + severity:** `style-binned-breaks` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Binned style boundaries are missing, non-finite, duplicated, or unordered.
**Fix:** Provide 2–65 strictly increasing numeric boundaries.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#style-binned-breaks](https://ggsvelte.sh/guide/errors#style-binned-breaks)
### `stat-channel-unsupported`
**Code + severity:** `stat-channel-unsupported` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A { stat } style mapping names an output the selected stat does not publish.
**Fix:** Use a generated output listed for that stat or map the original field instead.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#stat-channel-unsupported](https://ggsvelte.sh/guide/errors#stat-channel-unsupported)
### `manual-fun-required` — pipeline
**Code + severity:** `manual-fun-required` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A layer uses stat manual without params.fun.
**Fix:** Set params.fun to one of first|last|mean|median|min|max|sum (portable named registry; #814).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#manual-fun-required-pipeline](https://ggsvelte.sh/guide/errors#manual-fun-required-pipeline)
### `manual-fun-unknown`
**Code + severity:** `manual-fun-unknown` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A layer uses stat manual with an unregistered params.fun (defense for unvalidated specs).
**Fix:** Use a registered name: first, last, mean, median, min, max, sum.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#manual-fun-unknown](https://ggsvelte.sh/guide/errors#manual-fun-unknown)
### `unknown-theme`
**Code + severity:** `unknown-theme` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** spec.theme names a theme that is not registered.
**Fix:** Use a registered name (default, light, dark, minimal) or a theme object.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#unknown-theme](https://ggsvelte.sh/guide/errors#unknown-theme)
### `renderer-failure`
**Code + severity:** `renderer-failure` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** The SVG renderer threw while drawing a scene (never blank output — failure policy).
**Fix:** This is a ggsvelte bug; the message carries the underlying error. Please report it.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#renderer-failure](https://ggsvelte.sh/guide/errors#renderer-failure)
### `max-marks-exceeded`
**Code + severity:** `max-marks-exceeded` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** renderToSVGString refused to render more marks than its maxMarks safety limit.
**Fix:** Raise options.maxMarks deliberately, reduce the data, or render interactively (canvas).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#max-marks-exceeded](https://ggsvelte.sh/guide/errors#max-marks-exceeded)
### `sf-geometry-missing`
**Code + severity:** `sf-geometry-missing` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** geom_sf data is missing the geometry column.
**Fix:** Provide a column of GeoJSON Geometry JSON strings (default field "geometry", or params.geometry).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#sf-geometry-missing](https://ggsvelte.sh/guide/errors#sf-geometry-missing)
### `sf-geometry-invalid`
**Code + severity:** `sf-geometry-invalid` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** A geom_sf geometry cell could not be parsed as drawable GeoJSON Geometry.
**Fix:** Use valid GeoJSON Geometry JSON strings with finite coordinates.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#sf-geometry-invalid](https://ggsvelte.sh/guide/errors#sf-geometry-invalid)
### `sf-geometry-unsupported`
**Code + severity:** `sf-geometry-unsupported` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** geom_sf received a GeoJSON type outside the v1 point/line/polygon families.
**Fix:** Use Point/MultiPoint, LineString/MultiLineString, Polygon/MultiPolygon, or GeometryCollection of those families (no CRS).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#sf-geometry-unsupported](https://ggsvelte.sh/guide/errors#sf-geometry-unsupported)
### `sf-geometry-mixed`
**Code + severity:** `sf-geometry-mixed` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** One geom_sf layer mixes geometry families (point vs line vs polygon).
**Fix:** Split mixed types into separate geom_sf layers (v1 is single-family per layer).
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#sf-geometry-mixed](https://ggsvelte.sh/guide/errors#sf-geometry-mixed)
### `map-data-required`
**Code + severity:** `map-data-required` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** geom_map was used without params.map.
**Fix:** Pass params.map as { values }, { columns }, or { name } against spec.datasets.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#map-data-required](https://ggsvelte.sh/guide/errors#map-data-required)
### `map-coords-missing`
**Code + severity:** `map-coords-missing` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Map data is missing long/lat or x/y coordinate columns.
**Fix:** Provide "long"+"lat" or "x"+"y" columns in the fortified map table.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#map-coords-missing](https://ggsvelte.sh/guide/errors#map-coords-missing)
### `map-id-column-missing`
**Code + severity:** `map-id-column-missing` · error
**What failed:** The render pipeline stopped at the path reported by PipelineError.
**Why:** Map data is missing a region join column.
**Fix:** Set params.mapId or include a "region" / "id" column in the map table.
**Consequence (blocked):** Rendering stopped; ggsvelte does not substitute blank or partial output.
**Stable link:** [/guide/errors#map-id-column-missing](https://ggsvelte.sh/guide/errors#map-id-column-missing)
## Render warnings
Each entry answers what failed, why, how to recover safely, and whether output was blocked or degraded.
### `facet-levels-missing`
**Code + severity:** `facet-levels-missing` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** An explicit facet levels list includes values absent from the data; empty panels are kept.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#facet-levels-missing](https://ggsvelte.sh/guide/errors#facet-levels-missing)
### `facet-levels-unknown`
**Code + severity:** `facet-levels-unknown` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Data values for a facet field were omitted from the closed levels list and are excluded from every panel.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#facet-levels-unknown](https://ggsvelte.sh/guide/errors#facet-levels-unknown)
### `empty-data`
**Code + severity:** `empty-data` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** The data has no rows; the frame and axes render as a placeholder.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#empty-data](https://ggsvelte.sh/guide/errors#empty-data)
### `empty-layer`
**Code + severity:** `empty-layer` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A layer produced no drawable marks after stats/positions; it was skipped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#empty-layer](https://ggsvelte.sh/guide/errors#empty-layer)
### `empty-domain`
**Code + severity:** `empty-domain` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A positional scale found no finite values; a placeholder domain is used.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#empty-domain](https://ggsvelte.sh/guide/errors#empty-domain)
### `removed-missing`
**Code + severity:** `removed-missing` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Rows with missing/non-finite values in required channels were dropped (count in message).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#removed-missing](https://ggsvelte.sh/guide/errors#removed-missing)
### `raster-irregular-spacing`
**Code + severity:** `raster-irregular-spacing` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Raster cell centers are not on a regular grid; the minimum spacing is used (prefer geom tile).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#raster-irregular-spacing](https://ggsvelte.sh/guide/errors#raster-irregular-spacing)
### `scale-transform-domain` — warning
**Code + severity:** `scale-transform-domain` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A pre-stat transform dropped values outside its domain (log10 <= 0, sqrt < 0); count in message.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#scale-transform-domain-warning](https://ggsvelte.sh/guide/errors#scale-transform-domain-warning)
### `scale-oob-censored`
**Code + severity:** `scale-oob-censored` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Values outside explicit source limits were censored to missing before stats.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#scale-oob-censored](https://ggsvelte.sh/guide/errors#scale-oob-censored)
### `scale-oob-squished`
**Code + severity:** `scale-oob-squished` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Values outside explicit source limits were squished to the nearest limit before stats.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#scale-oob-squished](https://ggsvelte.sh/guide/errors#scale-oob-squished)
### `scale-break-outside-domain`
**Code + severity:** `scale-break-outside-domain` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** One or more explicit continuous breaks were outside the trained display domain and omitted.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#scale-break-outside-domain](https://ggsvelte.sh/guide/errors#scale-break-outside-domain)
### `sequential-discrete-field`
**Code + severity:** `sequential-discrete-field` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A sequential color scale is fed a discrete field; unparseable values render unknown.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#sequential-discrete-field](https://ggsvelte.sh/guide/errors#sequential-discrete-field)
### `color-temporal-censored`
**Code + severity:** `color-temporal-censored` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A temporal color/fill parser censored invalid source values by explicit author request.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#color-temporal-censored](https://ggsvelte.sh/guide/errors#color-temporal-censored)
### `color-transform-invalid`
**Code + severity:** `color-transform-invalid` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Some color/fill values are outside the requested transform domain and render unknown.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#color-transform-invalid](https://ggsvelte.sh/guide/errors#color-transform-invalid)
### `color-na-values`
**Code + severity:** `color-na-values` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Missing color/fill values render with the configured NA color (count in message).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#color-na-values](https://ggsvelte.sh/guide/errors#color-na-values)
### `color-unknown-values`
**Code + severity:** `color-unknown-values` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Invalid, unmapped, transformed, or censored color/fill values render with the configured unknown color (count in message).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#color-unknown-values](https://ggsvelte.sh/guide/errors#color-unknown-values)
### `style-temporal-censored`
**Code + severity:** `style-temporal-censored` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A temporal numeric style parser censored invalid source values by explicit request.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-temporal-censored](https://ggsvelte.sh/guide/errors#style-temporal-censored)
### `style-na-values`
**Code + severity:** `style-na-values` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Missing mapped style values use the configured NA output.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-na-values](https://ggsvelte.sh/guide/errors#style-na-values)
### `style-unknown-values`
**Code + severity:** `style-unknown-values` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Invalid or out-of-domain mapped style values use the configured unknown output.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-unknown-values](https://ggsvelte.sh/guide/errors#style-unknown-values)
### `style-palette-exhausted` — warning
**Code + severity:** `style-palette-exhausted` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A finite style range cycled after explicit author opt-in.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-palette-exhausted-warning](https://ggsvelte.sh/guide/errors#style-palette-exhausted-warning)
### `style-fingerprint-mismatch`
**Code + severity:** `style-fingerprint-mismatch` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Restored style state used a different output range; assignments start fresh.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-fingerprint-mismatch](https://ggsvelte.sh/guide/errors#style-fingerprint-mismatch)
### `style-version-mismatch`
**Code + severity:** `style-version-mismatch` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Restored style state has an unknown schema version; assignments start fresh.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-version-mismatch](https://ggsvelte.sh/guide/errors#style-version-mismatch)
### `style-out-of-domain`
**Code + severity:** `style-out-of-domain` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Values outside an explicit style domain use the unknown output.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#style-out-of-domain](https://ggsvelte.sh/guide/errors#style-out-of-domain)
### `invalid-label-format`
**Code + severity:** `invalid-label-format` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A labels format string was not recognized; the default format is used.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#invalid-label-format](https://ggsvelte.sh/guide/errors#invalid-label-format)
### `unknown-edition`
**Code + severity:** `unknown-edition` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** The spec targets a defaults edition this build does not know; the latest known edition's defaults are used.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#unknown-edition](https://ggsvelte.sh/guide/errors#unknown-edition)
### `color-on-fill-geom`
**Code + severity:** `color-on-fill-geom` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** The color channel is mapped on a fill-styled geom (bar/col/area); fill is what varies.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#color-on-fill-geom](https://ggsvelte.sh/guide/errors#color-on-fill-geom)
### `weight-unsupported`
**Code + severity:** `weight-unsupported` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** aes.weight is mapped on a stat that does not consume weights.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#weight-unsupported](https://ggsvelte.sh/guide/errors#weight-unsupported)
### `density-group-dropped`
**Code + severity:** `density-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A density group had too few finite values and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#density-group-dropped](https://ggsvelte.sh/guide/errors#density-group-dropped)
### `contour-group-dropped`
**Code + severity:** `contour-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A contour group lacked a usable 2D grid or levels and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#contour-group-dropped](https://ggsvelte.sh/guide/errors#contour-group-dropped)
### `density-2d-group-dropped`
**Code + severity:** `density-2d-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A density_2d group had too few points or produced no contours and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#density-2d-group-dropped](https://ggsvelte.sh/guide/errors#density-2d-group-dropped)
### `density-2d-filled-open-dropped`
**Code + severity:** `density-2d-filled-open-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** density_2d_filled dropped open isoline rings; v1 fills closed rings only.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#density-2d-filled-open-dropped](https://ggsvelte.sh/guide/errors#density-2d-filled-open-dropped)
### `sf-coordinates-dropped`
**Code + severity:** `sf-coordinates-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** stat_sf_coordinates dropped features with no finite representative point.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#sf-coordinates-dropped](https://ggsvelte.sh/guide/errors#sf-coordinates-dropped)
### `map-region-missing`
**Code + severity:** `map-region-missing` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** One or more value rows had no matching map region and were dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#map-region-missing](https://ggsvelte.sh/guide/errors#map-region-missing)
### `group-single-observation`
**Code + severity:** `group-single-observation` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Connected path/area marks derived one observation per group (often a discrete x joining default grouping), so each stroke or ribbon degenerates; map aes.group to join rows into series.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#group-single-observation](https://ggsvelte.sh/guide/errors#group-single-observation)
### `stack-align-skipped`
**Code + severity:** `stack-align-skipped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Sparse stacked-area groups were left unaligned because the shared-grid expansion exceeds the auto-rescue budget; bands with interior gaps may render as floating polygons.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#stack-align-skipped](https://ggsvelte.sh/guide/errors#stack-align-skipped)
### `smooth-group-dropped`
**Code + severity:** `smooth-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A smooth group had too few points for the fit and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#smooth-group-dropped](https://ggsvelte.sh/guide/errors#smooth-group-dropped)
### `quantile-empty`
**Code + severity:** `quantile-empty` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** No valid quantiles in (0,1) after filtering; nothing drawn.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#quantile-empty](https://ggsvelte.sh/guide/errors#quantile-empty)
### `quantile-group-dropped`
**Code + severity:** `quantile-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A quantile group was too small or had constant x and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#quantile-group-dropped](https://ggsvelte.sh/guide/errors#quantile-group-dropped)
### `manual-group-dropped`
**Code + severity:** `manual-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A manual-stat group had no finite x or y under an aggregate fun and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#manual-group-dropped](https://ggsvelte.sh/guide/errors#manual-group-dropped)
### `ellipse-group-dropped`
**Code + severity:** `ellipse-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** An ellipse group had fewer than two finite (x,y) points or zero variance and was dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#ellipse-group-dropped](https://ggsvelte.sh/guide/errors#ellipse-group-dropped)
### `stat-channel-unsupported` — warning
**Code + severity:** `stat-channel-unsupported` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A color/fill after-stat mapping names an output the selected stat does not publish; the mapping is ignored (style channels throw the same code as an error).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#stat-channel-unsupported-warning](https://ggsvelte.sh/guide/errors#stat-channel-unsupported-warning)
### `palette-exhausted` — warning
**Code + severity:** `palette-exhausted` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A discrete color scale ran out of palette entries and cycled (the default onExhaust).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#palette-exhausted-warning](https://ggsvelte.sh/guide/errors#palette-exhausted-warning)
### `fingerprint-mismatch`
**Code + severity:** `fingerprint-mismatch` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Restored scale state was trained on a different palette; assignments start fresh.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#fingerprint-mismatch](https://ggsvelte.sh/guide/errors#fingerprint-mismatch)
### `version-mismatch`
**Code + severity:** `version-mismatch` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Restored scale state has an unknown schema version; assignments start fresh.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#version-mismatch](https://ggsvelte.sh/guide/errors#version-mismatch)
### `out-of-domain`
**Code + severity:** `out-of-domain` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Values outside an explicit scale domain render the unknown color (deduplicated).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#out-of-domain](https://ggsvelte.sh/guide/errors#out-of-domain)
### `temporal-values-censored`
**Code + severity:** `temporal-values-censored` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** An explicit temporal parser censored invalid source values by author request.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#temporal-values-censored](https://ggsvelte.sh/guide/errors#temporal-values-censored)
### `guide-auto-bottom`
**Code + severity:** `guide-auto-bottom` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** An auto-positioned guide moved below the panel to preserve readable width.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#guide-auto-bottom](https://ggsvelte.sh/guide/errors#guide-auto-bottom)
### `unused-scale-option`
**Code + severity:** `unused-scale-option` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A lower-precedence scale option was ignored in favor of an explicit winner.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#unused-scale-option](https://ggsvelte.sh/guide/errors#unused-scale-option)
### `temporal-label-overlap`
**Code + severity:** `temporal-label-overlap` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Authored or exhausted automatic temporal labels overlap at the available extent.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#temporal-label-overlap](https://ggsvelte.sh/guide/errors#temporal-label-overlap)
### `temporal-label-margin-overflow`
**Code + severity:** `temporal-label-margin-overflow` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A complete temporal label exceeds the bounded axis margin.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#temporal-label-margin-overflow](https://ggsvelte.sh/guide/errors#temporal-label-margin-overflow)
### `temporal-break-outside-domain`
**Code + severity:** `temporal-break-outside-domain` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** One or more explicit temporal breaks were outside the trained domain and omitted.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#temporal-break-outside-domain](https://ggsvelte.sh/guide/errors#temporal-break-outside-domain)
### `band-label-overlap`
**Code + severity:** `band-label-overlap` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Categorical (band) axis labels overlap even after wrapping and rotation.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#band-label-overlap](https://ggsvelte.sh/guide/errors#band-label-overlap)
### `band-label-margin-overflow`
**Code + severity:** `band-label-margin-overflow` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A band label exceeds a bounded axis margin — single-line end truncation, forced-wrap height/side overflow, or a rotated label past the bottom/side cap.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#band-label-margin-overflow](https://ggsvelte.sh/guide/errors#band-label-margin-overflow)
### `coord-tessellation-cap`
**Code + severity:** `coord-tessellation-cap` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Adaptive coordinate tessellation reached a deterministic depth/vertex cap and retained a bounded approximation.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#coord-tessellation-cap](https://ggsvelte.sh/guide/errors#coord-tessellation-cap)
### `coord-invalid-geometry`
**Code + severity:** `coord-invalid-geometry` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** Path vertices outside a coordinate transform's domain were removed without bridging the remaining finite runs.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#coord-invalid-geometry](https://ggsvelte.sh/guide/errors#coord-invalid-geometry)
### `coord-fixed-degraded`
**Code + severity:** `coord-fixed-degraded` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** A fixed-aspect data rectangle is below the documented readable minimum; the ratio remains exact and minor furniture is removed.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#coord-fixed-degraded](https://ggsvelte.sh/guide/errors#coord-fixed-degraded)
### `abline-scale-unsupported`
**Code + severity:** `abline-scale-unsupported` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom_abline needs continuous x and y scales to clip y = intercept + slope · x; the layer is skipped on band axes.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#abline-scale-unsupported](https://ggsvelte.sh/guide/errors#abline-scale-unsupported)
### `function-domain-missing`
**Code + severity:** `function-domain-missing` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom/stat function could not resolve an x evaluation domain (no xlim, mapped x, or peer layer domain).
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#function-domain-missing](https://ggsvelte.sh/guide/errors#function-domain-missing)
### `function-fun-missing`
**Code + severity:** `function-fun-missing` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom/stat function is missing the required params.fun registry function name.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#function-fun-missing](https://ggsvelte.sh/guide/errors#function-fun-missing)
### `function-fun-unknown`
**Code + severity:** `function-fun-unknown` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom/stat function named an unknown params.fun registry function.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#function-fun-unknown](https://ggsvelte.sh/guide/errors#function-fun-unknown)
### `hex-band-scale`
**Code + severity:** `hex-band-scale` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom_hex needs continuous x and y scales for hexagonal binning; the layer is skipped on band axes.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#hex-band-scale](https://ggsvelte.sh/guide/errors#hex-band-scale)
### `hex-missing-size`
**Code + severity:** `hex-missing-size` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom_hex is missing per-cell width/height from bin_hex (identity or incomplete frame); the layer is skipped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#hex-missing-size](https://ggsvelte.sh/guide/errors#hex-missing-size)
### `ydensity-group-dropped`
**Code + severity:** `ydensity-group-dropped` · warning
**What failed:** A render step could not use every requested row, value, or default exactly as supplied.
**Why:** geom_violin needs at least two data points per group to estimate a density; smaller groups are dropped.
**Fix:** Inspect the warning message for its path and count, then correct the named data, scale, or option.
**Consequence (degraded):** The chart rendered, but the warning identifies dropped, cycled, or fallback output.
**Stable link:** [/guide/errors#ydensity-group-dropped](https://ggsvelte.sh/guide/errors#ydensity-group-dropped)
## Interaction diagnostics (@ggsvelte/svelte)
Each entry answers what failed, why, how to recover safely, and whether output was blocked or degraded.
### `INTERACTION_INTERVAL_FACET_UNSUPPORTED`
**Code + severity:** `INTERACTION_INTERVAL_FACET_UNSUPPORTED` · warning
**What failed:** The zoom interaction contract could not be applied as requested.
**Why:** Brush zoom currently requires one unfaceted panel.
**Fix:** Remove the facet; Use faceted interval selection; Zoom a linked detail view
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-interval-facet-unsupported](https://ggsvelte.sh/guide/errors#interaction-interval-facet-unsupported)
### `INTERACTION_INVALID_MAX_DISTANCE`
**Code + severity:** `INTERACTION_INVALID_MAX_DISTANCE` · error
**What failed:** The inspect.maxDistance interaction contract could not be applied as requested.
**Why:** inspect.maxDistance must be a finite non-negative CSS-pixel distance.
**Fix:** Use a finite number greater than or equal to zero
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-invalid-max-distance](https://ggsvelte.sh/guide/errors#interaction-invalid-max-distance)
### `INTERACTION_POINT_REQUIRES_KEY`
**Code + severity:** `INTERACTION_POINT_REQUIRES_KEY` · warning
**What failed:** The identity interaction contract could not be applied as requested.
**Why:** Durable point selection requires resolved row identity.
**Fix:** Ordinary charts omit identity — defaults to an id column or row index; Override with or select={{ type: "point", identity: "id" }}
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-point-requires-key](https://ggsvelte.sh/guide/errors#interaction-point-requires-key)
### `INTERACTION_INTERVAL_PRESET_REQUIRES_KEY`
**Code + severity:** `INTERACTION_INTERVAL_PRESET_REQUIRES_KEY` · warning
**What failed:** The identity interaction contract could not be applied as requested.
**Why:** Coordinated interval presets (union, cross-panel) require resolved row identity; without it they combine no rows.
**Fix:** Ordinary charts omit identity — defaults to an id column or row index; Override with select={{ type: "interval", identity: "id", … }} or
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-interval-preset-requires-key](https://ggsvelte.sh/guide/errors#interaction-interval-preset-requires-key)
### `INTERACTION_INVALID_KEY`
**Code + severity:** `INTERACTION_INVALID_KEY` · error
**What failed:** The identity interaction contract could not be applied as requested.
**Why:** A key accessor returned null, undefined, or a non-PropertyKey value.
**Fix:** Return a stable string, number, or symbol for every row
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-invalid-key](https://ggsvelte.sh/guide/errors#interaction-invalid-key)
### `INTERACTION_DUPLICATE_KEY`
**Code + severity:** `INTERACTION_DUPLICATE_KEY` · error
**What failed:** The identity interaction contract could not be applied as requested.
**Why:** The key accessor returned a duplicate value; durable interaction is disabled for that value.
**Fix:** Use a field that uniquely identifies each source row
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-duplicate-key](https://ggsvelte.sh/guide/errors#interaction-duplicate-key)
### `INTERACTION_UNSTABLE_KEY`
**Code + severity:** `INTERACTION_UNSTABLE_KEY` · error
**What failed:** The identity interaction contract could not be applied as requested.
**Why:** The key accessor returned a different value for the same source row.
**Fix:** Return an immutable field that uniquely identifies each row
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-unstable-key](https://ggsvelte.sh/guide/errors#interaction-unstable-key)
### `INTERACTION_MISSING_LINEAGE`
**Code + severity:** `INTERACTION_MISSING_LINEAGE` · warning
**What failed:** The layers interaction contract could not be applied as requested.
**Why:** A synthetic or aggregate mark did not expose source-row lineage.
**Fix:** Use a stat that preserves source-row lineage
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-missing-lineage](https://ggsvelte.sh/guide/errors#interaction-missing-lineage)
### `INTERACTION_LEGEND_REQUIRES_KEY`
**Code + severity:** `INTERACTION_LEGEND_REQUIRES_KEY` · warning
**What failed:** The identity interaction contract could not be applied as requested.
**Why:** Legend focus requires resolved row identity so encoded legend values never become identities.
**Fix:** Ordinary charts omit identity — defaults to an id column or row index; Override with or createPlotInteraction({ identity: "id" })
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-legend-requires-key](https://ggsvelte.sh/guide/errors#interaction-legend-requires-key)
### `INTERACTION_LEGEND_DISCRETE_ONLY`
**Code + severity:** `INTERACTION_LEGEND_DISCRETE_ONLY` · advisory
**What failed:** The focus interaction contract could not be applied as requested.
**Why:** Legend focus currently applies to discrete color and fill legends; continuous ramps remain static.
**Fix:** Enable focus on a discrete guide: ; Use a discrete color or fill mapping; Keep the continuous ramp static
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-legend-discrete-only](https://ggsvelte.sh/guide/errors#interaction-legend-discrete-only)
### `INTERACTION_INTERVAL_SCALE_UNSUPPORTED`
**Code + severity:** `INTERACTION_INTERVAL_SCALE_UNSUPPORTED` · warning
**What failed:** The scales interaction contract could not be applied as requested.
**Why:** Interval domains and brush zoom require continuous linear, log, or time scales.
**Fix:** Use a continuous positional scale; Use point inspection for band data
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-interval-scale-unsupported](https://ggsvelte.sh/guide/errors#interaction-interval-scale-unsupported)
### `INTERACTION_TOOL_UNAVAILABLE`
**Code + severity:** `INTERACTION_TOOL_UNAVAILABLE` · warning
**What failed:** The tool interaction contract could not be applied as requested.
**Why:** The requested interaction tool is unavailable for the enabled capabilities.
**Fix:** Enable the matching capability; Choose an available interaction tool
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-tool-unavailable](https://ggsvelte.sh/guide/errors#interaction-tool-unavailable)
**Minimal illustration — copy only the relevant fragment:**
```svelte fragment copy
```
### `INTERACTION_SCOPE_WITHOUT_CONTROLLER`
**Code + severity:** `INTERACTION_SCOPE_WITHOUT_CONTROLLER` · advisory
**What failed:** The interactionScope interaction contract could not be applied as requested.
**Why:** interactionScope is ignored without an interaction controller; chart-local scope is derived from key and aes.
**Fix:** Pass interaction={createPlotInteraction()} to control this plot; Remove interactionScope from uncontrolled plots
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-scope-without-controller](https://ggsvelte.sh/guide/errors#interaction-scope-without-controller)
### `INTERACTION_HANDLER_WITHOUT_CAPABILITY`
**Code + severity:** `INTERACTION_HANDLER_WITHOUT_CAPABILITY` · advisory
**What failed:** The oninspect / onselect / onzoom / onlegendfocus / onlegendfilter interaction contract could not be applied as requested.
**Why:** An interaction handler is set but its capability prop is not enabled, so the handler never fires.
**Fix:** Enable the matching capability prop (for example select for onselect); Remove the unused handler
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-handler-without-capability](https://ggsvelte.sh/guide/errors#interaction-handler-without-capability)
### `INTERACTION_INSPECT_X_ON_COL`
**Code + severity:** `INTERACTION_INSPECT_X_ON_COL` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode x/xy draws a crosshair on the x (band) axis through column marks; columns already encode x as a filled band, so the guide cuts the bar body and rarely adds information. Under coord_flip the guide is horizontal but still tracks the band.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomCol; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-x-on-col](https://ggsvelte.sh/guide/errors#interaction-inspect-x-on-col)
**Minimal illustration — copy only the relevant fragment:**
```svelte fragment copy
```
### `INTERACTION_INSPECT_X_ON_BAR`
**Code + severity:** `INTERACTION_INSPECT_X_ON_BAR` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode x/xy draws a crosshair through bar marks; bars are filled regions on the band axis, so the guide cuts the bar body and rarely adds information. Under coord_flip the guide orientation swaps with the axes but still fights the marks.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomBar; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-x-on-bar](https://ggsvelte.sh/guide/errors#interaction-inspect-x-on-bar)
### `INTERACTION_INSPECT_X_BISECTS_COL_LABELS`
**Code + severity:** `INTERACTION_INSPECT_X_BISECTS_COL_LABELS` · warning
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode x/xy draws a crosshair through GeomCol marks that also carry GeomText/GeomLabel values; the guide bisects the on-bar totals and makes them hard to read (including under coord_flip, when the guide is horizontal).
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") when columns have value labels; Keep value labels; drop the x/xy guide rather than dropping the labels
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-inspect-x-bisects-col-labels](https://ggsvelte.sh/guide/errors#interaction-inspect-x-bisects-col-labels)
**Minimal illustration — copy only the relevant fragment:**
```svelte fragment copy
```
### `INTERACTION_INSPECT_X_BISECTS_BAR_LABELS`
**Code + severity:** `INTERACTION_INSPECT_X_BISECTS_BAR_LABELS` · warning
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode x/xy draws a crosshair through GeomBar marks that also carry GeomText/GeomLabel values; the guide bisects the on-bar totals and makes them hard to read (including under coord_flip).
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") when bars have value labels; Keep value labels; drop the x/xy guide rather than dropping the labels
**Consequence (degraded):** The chart remains rendered, but the affected interaction is disabled or reduced.
**Stable link:** [/guide/errors#interaction-inspect-x-bisects-bar-labels](https://ggsvelte.sh/guide/errors#interaction-inspect-x-bisects-bar-labels)
### `INTERACTION_INSPECT_AXIS_ON_VIOLIN`
**Code + severity:** `INTERACTION_INSPECT_AXIS_ON_VIOLIN` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode draws an axis guide through violin marks; violins sit on a discrete band, so freescrolling x/y/xy guides cut the density body and often leave the band tooltip row blank.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomViolin; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-axis-on-violin](https://ggsvelte.sh/guide/errors#interaction-inspect-axis-on-violin)
**Minimal illustration — copy only the relevant fragment:**
```svelte fragment copy
```
### `INTERACTION_INSPECT_AXIS_ON_BOXPLOT`
**Code + severity:** `INTERACTION_INSPECT_AXIS_ON_BOXPLOT` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode draws an axis guide through boxplot marks; boxes sit on a discrete band, so freescrolling x/y/xy guides cut the box body and rarely add information.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomBoxplot; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-axis-on-boxplot](https://ggsvelte.sh/guide/errors#interaction-inspect-axis-on-boxplot)
### `INTERACTION_INSPECT_AXIS_ON_ERRORBAR`
**Code + severity:** `INTERACTION_INSPECT_AXIS_ON_ERRORBAR` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode draws an axis guide through errorbar marks; interval geoms on a discrete band are better inspected on the mark itself than via a freescrolling guide.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomErrorbar; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-axis-on-errorbar](https://ggsvelte.sh/guide/errors#interaction-inspect-axis-on-errorbar)
### `INTERACTION_INSPECT_AXIS_ON_LINERANGE`
**Code + severity:** `INTERACTION_INSPECT_AXIS_ON_LINERANGE` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode draws an axis guide through linerange marks; interval geoms on a discrete band are better inspected on the mark itself than via a freescrolling guide.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomLinerange; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-axis-on-linerange](https://ggsvelte.sh/guide/errors#interaction-inspect-axis-on-linerange)
### `INTERACTION_INSPECT_AXIS_ON_POINTRANGE`
**Code + severity:** `INTERACTION_INSPECT_AXIS_ON_POINTRANGE` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode draws an axis guide through pointrange marks; interval geoms on a discrete band are better inspected on the mark itself than via a freescrolling guide.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomPointrange; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-axis-on-pointrange](https://ggsvelte.sh/guide/errors#interaction-inspect-axis-on-pointrange)
### `INTERACTION_INSPECT_AXIS_ON_CROSSBAR`
**Code + severity:** `INTERACTION_INSPECT_AXIS_ON_CROSSBAR` · advisory
**What failed:** The inspect.mode interaction contract could not be applied as requested.
**Why:** inspect.mode draws an axis guide through crossbar marks; even when hits pin to a category, freescrolling x/y/xy guides rarely add information beyond exact mark focus.
**Fix:** Use inspect={{ mode: "exact" }} (or leave mode as "auto") for GeomCrossbar; Prefer muteSiblings for sibling de-emphasis instead of an axis guide
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-axis-on-crossbar](https://ggsvelte.sh/guide/errors#interaction-inspect-axis-on-crossbar)
### `INTERACTION_INSPECT_HIGH_CARDINALITY_DISCRETE`
**Code + severity:** `INTERACTION_INSPECT_HIGH_CARDINALITY_DISCRETE` · advisory
**What failed:** The inspect interaction contract could not be applied as requested.
**Why:** Inspect is enabled with a high-cardinality discrete color/fill domain; the default tooltip shows the focused series, the largest contributors at that x (or y), a stack total, and an overflow line — not every series.
**Fix:** Prep top-n data before plotting if only the largest series matter; Pass a custom content snippet on for a full multi-series listing; Pin the tooltip to scroll the full group when every series must be readable
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-high-cardinality-discrete](https://ggsvelte.sh/guide/errors#interaction-inspect-high-cardinality-discrete)
### `INTERACTION_INSPECT_IDENTITY_DROPPED`
**Code + severity:** `INTERACTION_INSPECT_IDENTITY_DROPPED` · advisory
**What failed:** The Inspect interaction contract could not be applied as requested.
**Why:** An child replaced the inspect prop whole (REPLACE), so the prop's `identity` no longer applies; rows fall back to an id column or row index.
**Fix:** Move identity onto the child; Drop identity from the inspect prop if the default row identity is intended
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-inspect-identity-dropped](https://ggsvelte.sh/guide/errors#interaction-inspect-identity-dropped)
### `INTERACTION_DUPLICATE_INSPECT_CAPABILITY`
**Code + severity:** `INTERACTION_DUPLICATE_INSPECT_CAPABILITY` · advisory
**What failed:** The Inspect interaction contract could not be applied as requested.
**Why:** Multiple children are registered; only the last one's options apply (REPLACE).
**Fix:** Keep a single child; Merge options onto one instead of stacking siblings
**Consequence (advisory):** The chart remains available; review the ignored or inferred interaction behavior.
**Stable link:** [/guide/errors#interaction-duplicate-inspect-capability](https://ggsvelte.sh/guide/errors#interaction-duplicate-inspect-capability)
**Minimal illustration — copy only the relevant fragment:**
```svelte fragment copy
```
## CLI diagnostics (ggsvelte-render)
SVG is written only to stdout; JSON Lines diagnostics are written only to stderr. Exit 1 means rendering failed, exit 2 means usage/input failed, and exit 3 means spec validation failed.
### `usage`
**Code + severity:** `usage` · error
**What failed:** ggsvelte-render stopped with exit 2 and wrote this JSON Line to stderr.
**Why:** Bad flags or arguments (exit 2). --help shows usage.
**Fix:** Run ggsvelte-render --help, then remove unsupported or conflicting arguments.
**Consequence (blocked):** No successful SVG is available on stdout for this invocation.
**Stable link:** [/guide/errors#usage](https://ggsvelte.sh/guide/errors#usage)
### `unreadable-input`
**Code + severity:** `unreadable-input` · error
**What failed:** ggsvelte-render stopped with exit 2 and wrote this JSON Line to stderr.
**Why:** The spec/data file (or stdin) could not be read (exit 2).
**Fix:** Check the file path and permissions, or pipe readable JSON on stdin.
**Consequence (blocked):** No successful SVG is available on stdout for this invocation.
**Stable link:** [/guide/errors#unreadable-input](https://ggsvelte.sh/guide/errors#unreadable-input)
### `invalid-json`
**Code + severity:** `invalid-json` · error
**What failed:** ggsvelte-render stopped with exit 2 and wrote this JSON Line to stderr.
**Why:** The spec or data file is not valid JSON (exit 2).
**Fix:** Correct the JSON syntax before running the command again.
**Consequence (blocked):** No successful SVG is available on stdout for this invocation.
**Stable link:** [/guide/errors#invalid-json](https://ggsvelte.sh/guide/errors#invalid-json)
**Minimal illustration — copy only the relevant fragment:**
```sh fragment copy
printf '%s\n' '{"data":{"values":[{"x":1,"y":2}]},"layers":[{"geom":"point","aes":{"x":{"field":"x"},"y":{"field":"y"}}}]}' \
| ggsvelte-render > chart.svg
```
### `invalid-data-file`
**Code + severity:** `invalid-data-file` · error
**What failed:** ggsvelte-render stopped with exit 2 and wrote this JSON Line to stderr.
**Why:** --data must be a JSON object mapping dataset names to inline data (exit 2).
**Fix:** Make --data point to a JSON object whose keys are dataset names.
**Consequence (blocked):** No successful SVG is available on stdout for this invocation.
**Stable link:** [/guide/errors#invalid-data-file](https://ggsvelte.sh/guide/errors#invalid-data-file)
### `max-marks-exceeded` — cli
**Code + severity:** `max-marks-exceeded` · error
**What failed:** ggsvelte-render stopped with exit 1 and wrote this JSON Line to stderr.
**Why:** The plot renders more marks than --max-marks allows (exit 1).
**Fix:** Reduce the data or deliberately raise --max-marks after checking output cost.
**Consequence (blocked):** No successful SVG is available on stdout for this invocation.
**Stable link:** [/guide/errors#max-marks-exceeded-cli](https://ggsvelte.sh/guide/errors#max-marks-exceeded-cli)
### `internal`
**Code + severity:** `internal` · error
**What failed:** ggsvelte-render stopped with exit 1 and wrote this JSON Line to stderr.
**Why:** An unexpected internal error (exit 1). Please report it.
**Fix:** Capture stderr and report the reproducible command, versions, and input shape.
**Consequence (blocked):** No successful SVG is available on stdout for this invocation.
**Stable link:** [/guide/errors#internal](https://ggsvelte.sh/guide/errors#internal)
---
# Advisories
Advisories never block a render. Two distinct kinds, two sources:
## Spec-lint advisories (@ggsvelte/spec lintSpec)
Valid-but-questionable specs (Hadley: "we can produce many plots that don't make sense, yet are grammatically valid"). Run `lintSpec(spec, { profile? })` directly, pass `{ lint: true }` to `validate()`, or read the CLI's stderr advisories (source "spec-lint"). Data-dependent rules skip silently without evidence.
### `line-over-nominal-x` (needs: data-or-profile)
A line layer connects points across a nominal (unordered) x field.
### `many-discrete-colors` (needs: data)
A discrete color/fill field has more than 10 distinct values.
### `stacked-area-negative` (needs: data)
A stacked area layer's y field contains negative values.
### `discrete-discrete-scatter` (needs: data-or-profile)
A point layer maps discrete fields on BOTH x and y.
### `transform-domain-data` (needs: data)
A transform scale (log10/sqrt) is configured over data that mixes in-domain and out-of-domain values.
### `fractional-calendar-years` (needs: data)
A position channel holds year-like numbers with month fractions (year + month/12) on a linear scale.
## Pipeline heuristic advisories (@ggsvelte/core)
Every heuristic decision the pipeline takes is disclosed as `{ code, path, chosen, howToOverride }` on `RenderModel.advisories` — agents see the guess and can correct it.
### `scale-type-inferred`
A positional scale's type was inferred from the mapped data.
### `zero-forced`
Bars/areas forced the measure axis to include zero.
### `scale-baseline-transformed-origin`
A bar/col/area/histogram/density measure axis under transform: log10 baselines at the transformed-space origin (semantic 1), since log10 has no semantic-zero image.
### `bar-x-discretized`
A numeric x on a count-stat bar layer was treated as discrete categories.
### `bin-default-bins`
The bin stat used its default bin count; set params.binwidth to control it.
### `smooth-method-inferred`
The smooth stat chose its method (lm vs loess) from the group size.
### `jitter-seeded`
The jitter position used its default deterministic seed.
### `stack-align-applied`
A stacked area layer auto-aligned its groups onto the shared x grid; groups sampled different x, and a raw stack would render floating bands.
### `palette-inferred`
A color scale used the edition's default palette/ramp.
### `canvas-auto`
A high-count layer auto-switched to the canvas backend (a11y/copy-SVG tradeoff disclosed).
### `temporal-year-inferred`
A four-digit string field was inferred as calendar years; a discrete override is available.
### `temporal-inference-ambiguous`
A date-like field remained discrete because multiple date orders matched.
### `temporal-inference-invalid`
A date-like field remained discrete because whole-column validation failed.
### `band-labels-wrapped`
Long categorical x labels were wrapped onto multiple lines to avoid collisions; pin with scales.x.guide.mode or coordFlip().
### `band-labels-rotated`
Long categorical x labels were rotated to avoid collisions; pin with scales.x.guide.mode/angle, or coordFlip() for horizontal rows.
### `percent-labels-out-of-range`
A continuous scale uses a percent labels format (…%) but its domain is far outside proportion space — ticks/tooltips would print values like 87300%.
---
# Lifecycle & editions
## Lifecycle tags
Every public export carries a lifecycle tag (generated into
`lifecycle.json` from the source annotations — regenerate with
`bun run lifecycle:gen`):
- **experimental** — may change or disappear in any 0.x release. The default
for APIs not explicitly promoted.
- **stable-intent** — committed enough that changes pay the migration tax.
Covers (1) the agent core path (PortableSpec, normalize, validate,
renderToSVGString, GGPlot and their direct result contracts) and
(2) the recommended Svelte composition children (`Geom*` shells and the
theme/scale/coord/facet/labs/guides/legend grammar children). Not frozen
pre-1.0, but changes here are treated as breaking: they get a changeset, a
migration note, and a deprecation window where feasible. Registry and
factory helpers stay experimental.
- **stable** — committed API under semver (none in v0.1).
- **superseded** — keeps working but stops being recommended; docs point to
the replacement. Protects agent-generated code from silent breakage.
## Defaults editions
`normalize()` stamps `edition: 2` onto every spec that doesn't carry one,
freezing which generation of DEFAULT aesthetics (theme role tokens,
categorical palette, sequential ramp) the spec was authored against. When a
future edition ships better defaults, stamped specs keep their original look
— old charts never reshuffle. Explicit settings (`theme`,
`scales.*.range`, `scales.*.scheme`) always win over edition defaults, and
unknown editions degrade to the latest known with an `unknown-edition`
warning.
## @ggsvelte/spec
### experimental (925)
`A11yMode` (type), `ALIAS_GEOMS`, `AblineLayer` (type), `AblineLayerInput` (type), `AblineLayerSchema`, `AblineParams` (type), `Aes` (type), `AesInput` (type), `AesSchema`, `AliasGeomName` (type), `AlphaScaleSpec` (type), `AreaLayer` (type), `AreaLayerInput` (type), `AreaLayerSchema`, `AreaParams` (type), `AuthoringCellValue` (type), `AuthoringColumns` (type), `AuthoringDataRef` (type), `AuthoringRows` (type), `AxisGuideOptions` (type), `AxisGuideSpec` (type), `BarLayer` (type), `BarLayerInput` (type), `BarLayerSchema`, `BarParams` (type), `Bin2dLayer` (type), `Bin2dLayerInput` (type), `Bin2dLayerSchema`, `Bin2dParams` (type), `BinnedColorScaleOptions` (type), `BinnedFiniteStyleScaleOptions` (type), `BlankLayer` (type), `BlankLayerInput` (type), `BlankParams` (type), `BoxplotLayer` (type), `BoxplotLayerInput` (type), `BoxplotLayerSchema`, `BoxplotParams` (type), `CATEGORICAL_SCHEME_NAMES`, `CHANNELS`, `COLOR_SCHEME_NAMES`, `COORD_REFERENCE`, `CURRENT_EDITION`, `CellValue` (type), `ChannelFn` (type), `ChannelInput` (type), `ChannelName` (type), `ChannelValue` (type), `ChannelValueSchema`, `ColLayer` (type), `ColLayerInput` (type), `ColLayerSchema`, `ColParams` (type), `ColorBrewerScaleOptions` (type), `ColorDistillerScaleOptions` (type), `ColorFermenterScaleOptions` (type), `ColorScaleOptions` (type), `ColorScaleSpec` (type), `ColorStop` (type), `ColorStopInput` (type), `ColorbarGuideOptions` (type), `ColorbarGuideSpec` (type), `ColorstepsGuideOptions` (type), `ColorstepsGuideSpec` (type), `ContinuousPositionScaleOptions` (type), `ContourLayer` (type), `ContourLayerInput` (type), `ContourParams` (type), `CoordFixedOptions` (type), `CoordFixedSpec` (type), `CoordFixedSpecSchema`, `CoordParamDoc` (type), `CoordPolarOptions` (type), `CoordRadialOptions` (type), `CoordRadialReverse` (type), `CoordRadialSpec` (type), `CoordRadialSpecSchema`, `CoordRadialTheta` (type), `CoordReferenceEntry` (type), `CoordSfOptions` (type), `CoordSfSpec` (type), `CoordSfSpecSchema`, `CoordSpec` (type), `CoordSpecSchema`, `CoordTransformAxisOptions` (type), `CoordTransformAxisSpec` (type), `CoordTransformAxisSpecSchema`, `CoordTransformName` (type), `CoordTransformOptions` (type), `CoordTransformSpec` (type), `CoordTransformSpecSchema`, `CoordTypeName` (type), `CountLayer` (type), `CountLayerInput` (type), `CountLayerSchema`, `CrossbarLayer` (type), `CrossbarLayerInput` (type), `CrossbarLayerSchema`, `CrossbarParams` (type), `CurveLayer` (type), `CurveLayerInput` (type), `CurveLayerSchema`, `CurveParams` (type), `DEFAULT_VALIDATE_LIMITS`, `DataColumns` (type), `DataInput` (type), `DataName` (type), `DataProfile` (type), `DataProfileField` (type), `DataRef` (type), `DataRefSchema`, `DataValues` (type), `Density2dFilledLayer` (type), `Density2dFilledLayerInput` (type), `Density2dLayer` (type), `Density2dLayerInput` (type), `Density2dParams` (type), `DensityLayer` (type), `DensityLayerInput` (type), `DensityLayerSchema`, `DensityParams` (type), `DiscreteColorScaleOptions` (type), `DiscreteFiniteStyleScaleOptions` (type), `DiscreteNumericStyleScaleOptions` (type), `DiscretePositionScaleOptions` (type), `DotplotLayer` (type), `DotplotLayerInput` (type), `DotplotLayerSchema`, `DotplotParams` (type), `ERROR_CATALOG`, `ERROR_CODES`, `ErrorCatalogEntry` (type), `ErrorbarLayer` (type), `ErrorbarLayerInput` (type), `ErrorbarLayerSchema`, `ErrorbarParams` (type), `FacetFieldInput` (type), `FacetFieldRef` (type), `FacetFieldRefSchema`, `FacetInput` (type), `FacetScales` (type), `FacetSpec` (type), `FacetSpecSchema`, `FacetStripSpec` (type), `FacetStripSpecSchema`, `FiniteStyleScaleOptions` (type), `FreqpolyLayer` (type), `FreqpolyLayerInput` (type), `FreqpolyLayerSchema`, `FunctionArgs` (type), `FunctionLayer` (type), `FunctionLayerInput` (type), `FunctionLayerSchema`, `FunctionParams` (type), `FunctionRegistryName` (type), `GEOM_ALIASES`, `GEOM_DEFAULTS`, `GEOM_PARAM_KEYS`, `GEOM_REFERENCE`, `GGBuilder`, `GREY_PALETTE_10`, `GUIDE_CHANNELS`, `GUIDE_REFERENCE`, `GeomAblineOptions` (type), `GeomAreaOptions` (type), `GeomBarOptions` (type), `GeomBin2dOptions` (type), `GeomBlankOptions` (type), `GeomBoxplotOptions` (type), `GeomColOptions` (type), `GeomContourOptions` (type), `GeomCountOptions` (type), `GeomCrossbarOptions` (type), `GeomCurveOptions` (type), `GeomDensity2dFilledOptions` (type), `GeomDensity2dOptions` (type), `GeomDensityOptions` (type), `GeomDotplotOptions` (type), `GeomErrorbarOptions` (type), `GeomFreqpolyOptions` (type), `GeomFunctionOptions` (type), `GeomHexOptions` (type), `GeomHistogramOptions` (type), `GeomHlineOptions` (type), `GeomJitterOptions` (type), `GeomLabelOptions` (type), `GeomLineOptions` (type), `GeomLinerangeOptions` (type), `GeomMapOptions` (type), `GeomName` (type), `GeomParamDoc` (type), `GeomPathOptions` (type), `GeomPointOptions` (type), `GeomPointrangeOptions` (type), `GeomPolygonOptions` (type), `GeomQqLineOptions` (type), `GeomQqOptions` (type), `GeomQuantileOptions` (type), `GeomRasterOptions` (type), `GeomRectOptions` (type), `GeomReferenceEntry` (type), `GeomRugOptions` (type), `GeomRuleOptions` (type), `GeomSegmentOptions` (type), `GeomSfLabelOptions` (type), `GeomSfOptions` (type), `GeomSfTextOptions` (type), `GeomSmoothOptions` (type), `GeomSpokeOptions` (type), `GeomStepOptions` (type), `GeomTextOptions` (type), `GeomTileOptions` (type), `GeomViolinOptions` (type), `GeomVlineOptions` (type), `GlowOptions` (type), `GlowSpec` (type), `Gradient2ScaleOptions` (type), `GradientPaint` (type), `GradientScaleOptions` (type), `GradientnScaleOptions` (type), `GreyScaleOptions` (type), `GuideChannelName` (type), `GuideParamDoc` (type), `GuideReferenceEntry` (type), `GuideSpec` (type), `GuideThemeSpec` (type), `GuideTypeName` (type), `GuidesSpec` (type), `HUE_PALETTE_10`, `HexLayer` (type), `HexLayerInput` (type), `HexLayerSchema`, `HexParams` (type), `HistogramLayer` (type), `HistogramLayerInput` (type), `HistogramLayerSchema`, `HlineLayer` (type), `HlineLayerInput` (type), `HlineLayerSchema`, `HlineParams` (type), `HueScaleOptions` (type), `IdentityColorScaleOptions` (type), `IdentityFiniteStyleScaleOptions` (type), `IdentityNumericStyleScaleOptions` (type), `InlineData` (type), `JSONValue` (type), `JitterLayer` (type), `JitterLayerInput` (type), `JitterLayerSchema`, `KNOWN_COORD_TYPES`, `KNOWN_GEOMS`, `KNOWN_GUIDE_TYPES`, `KNOWN_POSITIONS`, `KNOWN_STATS`, `LINETYPE_NAMES`, `LINT_CATALOG`, `LabelLayer` (type), `LabelLayerInput` (type), `LabelLayerSchema`, `LabelParams` (type), `Labs` (type), `LayerInput` (type), `LayerSpec` (type), `LayerSpecSchema`, `LegendGuideOptions` (type), `LegendGuideSpec` (type), `LegendSpec` (type), `LineLayer` (type), `LineLayerInput` (type), `LineLayerSchema`, `LineParams` (type), `LinearGradientPaint` (type), `LinearPaintOptions` (type), `LinerangeLayer` (type), `LinerangeLayerInput` (type), `LinerangeLayerSchema`, `LinerangeParams` (type), `LinetypeName` (type), `LinetypeScaleSpec` (type), `LintAdvisoryCode` (type), `LintCatalogEntry` (type), `LossyResult` (type), `MAX_BINNED_BREAKS`, `MAX_GLOW_RADIUS`, `MAX_PAINT_STOPS`, `MAX_TEMPORAL_CANDIDATES`, `MAX_TEMPORAL_MAJOR_TICKS`, `MAX_TEMPORAL_MINOR_TICKS`, `MIN_TEMPORAL_LABEL_GAP_PX`, `MONTH_DAY_REFERENCE_YEAR`, `ManualColorScaleOptions` (type), `ManualFiniteStyleScaleOptions` (type), `ManualNumericStyleScaleOptions` (type), `MapLayer` (type), `MapLayerInput` (type), `MapParams` (type), `MultiIdentityScaleOptions` (type), `MultiManualScaleOptions` (type), `MultiScaleAesthetic` (type), `MultiScaleChannel` (type), `NoneGuideSpec` (type), `NormalizedGeomName` (type), `NormalizedLayerSpec` (type), `NormalizedSpec` (type), `NumericStyleScaleOptions` (type), `OrdinalColorScaleOptions` (type), `PIPELINE_ERROR_CATALOG`, `POINT_SHAPE_NAMES`, `POSITION_REFERENCE`, `PaintSpace` (type), `ParsedTemporalColumn` (type), `PathLayer` (type), `PathLayerInput` (type), `PathLayerSchema`, `PathParams` (type), `PipelineErrorCatalogEntry` (type), `PipelineErrorCode` (type), `PlotSpecSchema`, `PointLayer` (type), `PointLayerInput` (type), `PointLayerSchema`, `PointParams` (type), `PointPosition` (type), `PointShapeName` (type), `PointrangeLayer` (type), `PointrangeLayerInput` (type), `PointrangeLayerSchema`, `PointrangeParams` (type), `PolygonLayer` (type), `PolygonLayerInput` (type), `PolygonLayerSchema`, `PolygonParams` (type), `PortabilityIssue` (type), `PositionName` (type), `PositionParamDoc` (type), `PositionParams` (type), `PositionReferenceEntry` (type), `PositionScaleSpec` (type), `PositiveStyleScaleSpec` (type), `ProfileFieldType` (type), `QqLayer` (type), `QqLayerInput` (type), `QqLayerSchema`, `QqLineLayer` (type), `QqLineLayerInput` (type), `QqLineLayerSchema`, `QqLineParams` (type), `QqParams` (type), `QuantileLayer` (type), `QuantileLayerInput` (type), `QuantileParams` (type), `RadialGradientPaint` (type), `RadialPaintOptions` (type), `RasterLayer` (type), `RasterLayerInput` (type), `RasterLayerSchema`, `RasterParams` (type), `RecommendedScaleType` (type), `RectLayer` (type), `RectLayerInput` (type), `RectLayerSchema`, `RectParams` (type), `RenderBackend` (type), `RibbonLayer` (type), `RibbonLayerInput` (type), `RibbonLayerSchema`, `RibbonParams` (type), `RugLayer` (type), `RugLayerInput` (type), `RugLayerSchema`, `RugParams` (type), `RuleLayer` (type), `RuleLayerInput` (type), `RuleLayerSchema`, `RuleParams` (type), `RuntimeAblineLayer` (type), `RuntimeAes` (type), `RuntimeAreaLayer` (type), `RuntimeBarLayer` (type), `RuntimeBin2dLayer` (type), `RuntimeBlankLayer` (type), `RuntimeBoxplotLayer` (type), `RuntimeChannelValue` (type), `RuntimeColLayer` (type), `RuntimeContourLayer` (type), `RuntimeCountLayer` (type), `RuntimeCrossbarLayer` (type), `RuntimeCurveLayer` (type), `RuntimeDensity2dFilledLayer` (type), `RuntimeDensity2dLayer` (type), `RuntimeDensityLayer` (type), `RuntimeDotplotLayer` (type), `RuntimeErrorbarLayer` (type), `RuntimeFreqpolyLayer` (type), `RuntimeFunctionLayer` (type), `RuntimeHexLayer` (type), `RuntimeHistogramLayer` (type), `RuntimeHlineLayer` (type), `RuntimeJitterLayer` (type), `RuntimeLabelLayer` (type), `RuntimeLayerSpec` (type), `RuntimeLineLayer` (type), `RuntimeLinerangeLayer` (type), `RuntimeMapLayer` (type), `RuntimePathLayer` (type), `RuntimePointLayer` (type), `RuntimePointrangeLayer` (type), `RuntimePolygonLayer` (type), `RuntimeQqLayer` (type), `RuntimeQqLineLayer` (type), `RuntimeQuantileLayer` (type), `RuntimeRasterLayer` (type), `RuntimeRectLayer` (type), `RuntimeRibbonLayer` (type), `RuntimeRugLayer` (type), `RuntimeRuleLayer` (type), `RuntimeSegmentLayer` (type), `RuntimeSfLabelLayer` (type), `RuntimeSfLayer` (type), `RuntimeSfTextLayer` (type), `RuntimeSmoothLayer` (type), `RuntimeSpec` (type), `RuntimeSpokeLayer` (type), `RuntimeStepLayer` (type), `RuntimeTextLayer` (type), `RuntimeTileLayer` (type), `RuntimeViolinLayer` (type), `RuntimeVlineLayer` (type), `SCALE_CAPABILITIES`, `SCALE_FAMILY_LABELS`, `SCALE_REFERENCE`, `SCHEMA_VERSION`, `SEQUENTIAL_SCHEME_NAMES`, `SHARED_LAYER_PROPS`, `STAT_COLUMNS`, `STAT_REFERENCE`, `STYLE_AESTHETIC_GEOMS`, `STYLE_ORDINAL_SCALE_HELPERS`, `ScaleAesthetic` (type), `ScaleCapability` (type), `ScaleExpansion` (type), `ScaleFamily` (type), `ScaleParamDoc` (type), `ScaleReferenceEntry` (type), `ScaleTypeAesthetic` (type), `Scales` (type), `ScalesSchema`, `SegmentLayer` (type), `SegmentLayerInput` (type), `SegmentLayerSchema`, `SegmentParams` (type), `SequentialColorScaleOptions` (type), `SequentialStyleScaleOptions` (type), `SfLabelLayer` (type), `SfLabelLayerInput` (type), `SfLabelParams` (type), `SfLayer` (type), `SfLayerInput` (type), `SfParams` (type), `SfTextLayer` (type), `SfTextLayerInput` (type), `SfTextParams` (type), `ShapeScaleSpec` (type), `SharedLayerPropDoc` (type), `SizeAreaScaleOptions` (type), `SizeSequentialStyleScaleOptions` (type), `SizeTemporalNumericStyleScaleOptions` (type), `SmoothLayer` (type), `SmoothLayerInput` (type), `SmoothLayerSchema`, `SmoothParams` (type), `SpecAdvisory` (type), `SpecInput` (type), `SpecModule`, `SpokeLayer` (type), `SpokeLayerInput` (type), `SpokeParams` (type), `StackablePosition` (type), `StatName` (type), `StatReferenceEntry` (type), `StepLayer` (type), `StepLayerInput` (type), `StepLayerSchema`, `StepParams` (type), `Steps2ScaleOptions` (type), `StepsScaleOptions` (type), `StepsnScaleOptions` (type), `StyleAesthetic` (type), `SummaryFun` (type), `TEMPORAL_INTERVAL_UNITS`, `TEMPORAL_LABEL_TOKENS`, `TEMPORAL_PARSER_NAMES`, `TEMPORAL_WEEKDAYS`, `THEME_NAMES`, `THEME_NAME_ALIASES`, `TemporalColorScaleOptions` (type), `TemporalDecision` (type), `TemporalDisambiguation` (type), `TemporalFailure` (type), `TemporalInterval` (type), `TemporalIntervalError`, `TemporalIntervalSpec` (type), `TemporalIntervalSpecSchema`, `TemporalIntervalUnit` (type), `TemporalKind` (type), `TemporalLabelSpecSchema`, `TemporalNumericStyleScaleOptions` (type), `TemporalParseError`, `TemporalParseOptions` (type), `TemporalParseResult` (type), `TemporalParserName` (type), `TemporalParserSpec` (type), `TemporalParserSpecSchema`, `TemporalParserSpecSchemaRef`, `TemporalPrecision` (type), `TemporalScaleKind` (type), `TemporalScaleOptions` (type), `TemporalWeekStart` (type), `TemporalWeekStartSchema`, `TextLayer` (type), `TextLayerInput` (type), `TextLayerSchema`, `TextParams` (type), `ThemeName` (type), `ThemeSpec` (type), `TileLayer` (type), `TileLayerInput` (type), `TileLayerSchema`, `TileParams` (type), `TransformedColorScaleOptions` (type), `TransformedPositionScaleOptions` (type), `UnportableSpecError`, `ValidateLimits` (type), `ValidateOptions` (type), `ViolinLayer` (type), `ViolinLayerInput` (type), `ViolinLayerSchema`, `ViolinParams` (type), `ViridisOptionName` (type), `ViridisScaleOptions` (type), `VlineLayer` (type), `VlineLayerInput` (type), `VlineLayerSchema`, `VlineParams` (type), `aes`, `allScaleHelpers`, `assertStructuralGate`, `buildGreyPalette`, `buildHuePalette`, `buildSchemaArtifact`, `builderScaleHelperNames`, `calendarDateFields`, `canonicalMultiScaleChannel`, `canonicalTemporalParserKey`, `componentNameForGeom`, `componentNameForScaleHelper`, `configuredColorScaleType`, `coordEqual`, `coordFixed`, `coordPolar`, `coordRadial`, `coordReferenceList`, `coordSf`, `coordTransform`, `coord_equal`, `coord_fixed`, `coord_polar`, `coord_radial`, `coord_sf`, `coord_transform`, `didYouMean`, `dmy`, `dmy_hm`, `dmy_hms`, `dym`, `dym_hm`, `dym_hms`, `effectiveChannel`, `ensureTemporalPolyfill`, `fillPaintLinear`, `fillPaintRadial`, `fromEpochMilliseconds`, `fromEpochSeconds`, `geomReferenceList`, `gg`, `glow`, `guideAxis`, `guideColorbar`, `guideColorsteps`, `guideLegend`, `guideNone`, `guideReferenceList`, `guide_axis`, `guide_colorbar`, `guide_colorsteps`, `guide_legend`, `guide_none`, `guides`, `hslToHex`, `inferTemporalColumn`, `isPortable`, `knownScaleSlugs`, `levenshtein`, `lintSpec`, `mdy`, `mdy_hm`, `mdy_hms`, `my`, `myd`, `myd_hm`, `myd_hms`, `normalizeChannel`, `parseTemporal`, `parseTemporalColumn`, `parseTemporalFormat`, `parseTemporalInterval`, `portabilityIssues`, `positionReferenceList`, `primaryScaleHelpers`, `scaleAlpha`, `scaleAlphaBinned`, `scaleAlphaContinuous`, `scaleAlphaDate`, `scaleAlphaDatetime`, `scaleAlphaDiscrete`, `scaleAlphaIdentity`, `scaleAlphaManual`, `scaleAlphaOrdinal`, `scaleCapabilityCamelHelpers`, `scaleColorBinned`, `scaleColorBrewer`, `scaleColorContinuous`, `scaleColorDate`, `scaleColorDatetime`, `scaleColorDiscrete`, `scaleColorDistiller`, `scaleColorFermenter`, `scaleColorGradient`, `scaleColorGradient2`, `scaleColorGradientn`, `scaleColorGray`, `scaleColorGrey`, `scaleColorHue`, `scaleColorIdentity`, `scaleColorLog10`, `scaleColorManual`, `scaleColorOrdinal`, `scaleColorSqrt`, `scaleColorSteps`, `scaleColorSteps2`, `scaleColorStepsn`, `scaleColorViridisB`, `scaleColorViridisC`, `scaleColorViridisD`, `scaleColourBinned`, `scaleColourBrewer`, `scaleColourContinuous`, `scaleColourDate`, `scaleColourDatetime`, `scaleColourDiscrete`, `scaleColourDistiller`, `scaleColourFermenter`, `scaleColourGradient`, `scaleColourGradient2`, `scaleColourGradientn`, `scaleColourGray`, `scaleColourGrey`, `scaleColourHue`, `scaleColourIdentity`, `scaleColourLog10`, `scaleColourManual`, `scaleColourOrdinal`, `scaleColourSqrt`, `scaleColourSteps`, `scaleColourSteps2`, `scaleColourStepsn`, `scaleColourViridisB`, `scaleColourViridisC`, `scaleColourViridisD`, `scaleContinuousIdentity`, `scaleDiscreteIdentity`, `scaleDiscreteManual`, `scaleFillBinned`, `scaleFillBrewer`, `scaleFillContinuous`, `scaleFillDate`, `scaleFillDatetime`, `scaleFillDiscrete`, `scaleFillDistiller`, `scaleFillFermenter`, `scaleFillGradient`, `scaleFillGradient2`, `scaleFillGradientn`, `scaleFillGray`, `scaleFillGrey`, `scaleFillHue`, `scaleFillIdentity`, `scaleFillLog10`, `scaleFillManual`, `scaleFillOrdinal`, `scaleFillSqrt`, `scaleFillSteps`, `scaleFillSteps2`, `scaleFillStepsn`, `scaleFillViridisB`, `scaleFillViridisC`, `scaleFillViridisD`, `scaleLinetype`, `scaleLinetypeBinned`, `scaleLinetypeDiscrete`, `scaleLinetypeIdentity`, `scaleLinetypeManual`, `scaleLinewidth`, `scaleLinewidthBinned`, `scaleLinewidthContinuous`, `scaleLinewidthDate`, `scaleLinewidthDatetime`, `scaleLinewidthDiscrete`, `scaleLinewidthIdentity`, `scaleLinewidthManual`, `scaleLinewidthOrdinal`, `scaleRadius`, `scaleReferenceByFamily`, `scaleReferenceList`, `scaleReferencePrimaries`, `scaleShape`, `scaleShapeBinned`, `scaleShapeDiscrete`, `scaleShapeIdentity`, `scaleShapeManual`, `scaleShapeOrdinal`, `scaleSize`, `scaleSizeArea`, `scaleSizeBinned`, `scaleSizeBinnedArea`, `scaleSizeContinuous`, `scaleSizeDate`, `scaleSizeDatetime`, `scaleSizeDiscrete`, `scaleSizeIdentity`, `scaleSizeManual`, `scaleSizeOrdinal`, `scaleType`, `scaleXBinned`, `scaleXContinuous`, `scaleXDate`, `scaleXDatetime`, `scaleXDiscrete`, `scaleXLog10`, `scaleXMonthDay`, `scaleXReverse`, `scaleXSqrt`, `scaleXTime`, `scaleYBinned`, `scaleYContinuous`, `scaleYDate`, `scaleYDatetime`, `scaleYDiscrete`, `scaleYLog10`, `scaleYMonthDay`, `scaleYReverse`, `scaleYSqrt`, `scaleYTime`, `scale_alpha`, `scale_alpha_binned`, `scale_alpha_continuous`, `scale_alpha_date`, `scale_alpha_datetime`, `scale_alpha_discrete`, `scale_alpha_identity`, `scale_alpha_manual`, `scale_alpha_ordinal`, `scale_color_binned`, `scale_color_brewer`, `scale_color_continuous`, `scale_color_date`, `scale_color_datetime`, `scale_color_discrete`, `scale_color_distiller`, `scale_color_fermenter`, `scale_color_gradient`, `scale_color_gradient2`, `scale_color_gradientn`, `scale_color_gray`, `scale_color_grey`, `scale_color_hue`, `scale_color_identity`, `scale_color_log10`, `scale_color_manual`, `scale_color_ordinal`, `scale_color_sqrt`, `scale_color_steps`, `scale_color_steps2`, `scale_color_stepsn`, `scale_color_viridis_b`, `scale_color_viridis_c`, `scale_color_viridis_d`, `scale_colour_binned`, `scale_colour_brewer`, `scale_colour_continuous`, `scale_colour_date`, `scale_colour_datetime`, `scale_colour_discrete`, `scale_colour_distiller`, `scale_colour_fermenter`, `scale_colour_gradient`, `scale_colour_gradient2`, `scale_colour_gradientn`, `scale_colour_gray`, `scale_colour_grey`, `scale_colour_hue`, `scale_colour_identity`, `scale_colour_log10`, `scale_colour_manual`, `scale_colour_ordinal`, `scale_colour_sqrt`, `scale_colour_steps`, `scale_colour_steps2`, `scale_colour_stepsn`, `scale_colour_viridis_b`, `scale_colour_viridis_c`, `scale_colour_viridis_d`, `scale_continuous_identity`, `scale_discrete_identity`, `scale_discrete_manual`, `scale_fill_binned`, `scale_fill_brewer`, `scale_fill_continuous`, `scale_fill_date`, `scale_fill_datetime`, `scale_fill_discrete`, `scale_fill_distiller`, `scale_fill_fermenter`, `scale_fill_gradient`, `scale_fill_gradient2`, `scale_fill_gradientn`, `scale_fill_gray`, `scale_fill_grey`, `scale_fill_hue`, `scale_fill_identity`, `scale_fill_log10`, `scale_fill_manual`, `scale_fill_ordinal`, `scale_fill_sqrt`, `scale_fill_steps`, `scale_fill_steps2`, `scale_fill_stepsn`, `scale_fill_viridis_b`, `scale_fill_viridis_c`, `scale_fill_viridis_d`, `scale_linetype`, `scale_linetype_binned`, `scale_linetype_discrete`, `scale_linetype_identity`, `scale_linetype_manual`, `scale_linewidth`, `scale_linewidth_binned`, `scale_linewidth_continuous`, `scale_linewidth_date`, `scale_linewidth_datetime`, `scale_linewidth_discrete`, `scale_linewidth_identity`, `scale_linewidth_manual`, `scale_linewidth_ordinal`, `scale_radius`, `scale_shape`, `scale_shape_binned`, `scale_shape_discrete`, `scale_shape_identity`, `scale_shape_manual`, `scale_shape_ordinal`, `scale_size`, `scale_size_area`, `scale_size_binned`, `scale_size_binned_area`, `scale_size_continuous`, `scale_size_date`, `scale_size_datetime`, `scale_size_discrete`, `scale_size_identity`, `scale_size_manual`, `scale_size_ordinal`, `scale_type`, `scale_x_binned`, `scale_x_continuous`, `scale_x_date`, `scale_x_datetime`, `scale_x_discrete`, `scale_x_log10`, `scale_x_month_day`, `scale_x_reverse`, `scale_x_sqrt`, `scale_x_time`, `scale_y_binned`, `scale_y_continuous`, `scale_y_date`, `scale_y_datetime`, `scale_y_discrete`, `scale_y_log10`, `scale_y_month_day`, `scale_y_reverse`, `scale_y_sqrt`, `scale_y_time`, `schemaArtifactJSON`, `slugForScaleHelper`, `statReferenceList`, `strokePaintLinear`, `strokePaintRadial`, `structuralGateErrors`, `temporalIntervalTicks`, `temporalLabelConfigurationError`, `temporalLocaleConfigurationError`, `temporalParserConfigurationError`, `toAuthoringDataRef`, `toDataRef`, `toPortable`, `toPortableLossy`, `ydm`, `ydm_hm`, `ydm_hms`, `ym`, `ymd`, `ymd_hm`, `ymd_hms`, `yq`
### stable-intent (8)
`PortableSpec` (type), `SpecError` (type), `SpecErrorCode` (type), `SpecErrorFix` (type), `SpecValidationError`, `ValidateResult` (type), `normalize`, `validate`
## @ggsvelte/spec (./portable)
### experimental (21)
`AesInput` (type), `AuthoringCellValue` (type), `AuthoringColumns` (type), `AuthoringDataRef` (type), `AuthoringRows` (type), `DataInput` (type), `GGBuilder`, `GeomAreaOptions` (type), `GeomBarOptions` (type), `GeomBoxplotOptions` (type), `GeomColOptions` (type), `GeomDensityOptions` (type), `GeomHistogramOptions` (type), `GeomLineOptions` (type), `GeomPointOptions` (type), `GeomSmoothOptions` (type), `GeomTextOptions` (type), `SpecInput` (type), `aes`, `gg`, `normalize`
## @ggsvelte/core
### experimental (388)
`ADVISORY_CATALOG`, `Advisory` (type), `AdvisoryCode` (type), `AesMapping` (type), `AxisEditModel` (type), `AxisGuidePlan` (type), `AxisGuideTick` (type), `AxisResult` (type), `AxisValueFormatter` (type), `BUILTIN_THEMES`, `BandAxisPlan` (type), `BandAxisPlanInput` (type), `BandConfig` (type), `BandGuideConfig` (type), `BandLabelMode` (type), `BandScale` (type), `BatchInteractionMask` (type), `CANVAS_AUTO_THRESHOLD`, `CANVA_PALETTE`, `CATEGORICAL_PALETTE_10`, `CATEGORICAL_SCHEMES`, `CLIDiagnosticCode` (type), `CLIIO` (type), `CLI_DIAGNOSTIC_CATALOG`, `COLORBLIND_PALETTE`, `CandidateBatchFacts` (type), `CandidateBuildFacts` (type), `CandidateDatum` (type), `CandidateDatumColumns` (type), `CandidateFacts` (type), `CandidateGroup` (type), `CandidateInspectMode` (type), `CandidateMatch` (type), `CandidateRange` (type), `CandidateStore` (type), `CandidateStoreOptions` (type), `CandidateStyleColumn` (type), `CanonicalAxisToken` (type), `CellValue` (type), `ClientRect` (type), `ColorScale` (type), `ColorbarGuidePlan` (type), `ColorbarGuideTick` (type), `ColorstepsGuidePlan` (type), `ColorstepsGuideStep` (type), `ColumnTable`, `Columns` (type), `ContinuousConfig` (type), `ContinuousScale` (type), `ContinuousTraining` (type), `CoordAxisProjector` (type), `CoordProjectorInput` (type), `CountStatInput` (type), `CountStatResult` (type), `CreateSemanticViewportInput` (type), `DEFAULT_FONT_STACK`, `DEFAULT_LAYOUT_THEME`, `DeclaredDiscreteness` (type), `DiagnosticCode` (type), `DiscreteGuideEntry` (type), `DiscreteGuidePlan` (type), `DiscreteLegendInput` (type), `DiscreteScaleSpec` (type), `Discreteness` (type), `DodgeInput` (type), `DodgeResult` (type), `Domain` (type), `ECONOMIST_PALETTE`, `EDITION_DEFAULTS`, `EcdfStatInput` (type), `EcdfStatResult` (type), `EditionDefaults` (type), `FEW_DARK_PALETTE`, `FEW_LIGHT_PALETTE`, `FEW_PALETTE`, `FIVETHIRTYEIGHT_PALETTE`, `FLEXOKI_PALETTE`, `FONT_METRICS`, `FacetPanelIdentity` (type), `FacetPanelIdentityInput` (type), `FacetPanelRole` (type), `FacetPanelValueIdentity` (type), `FieldType` (type), `FocusedPrimitive` (type), `GeometryBatch` (type), `GlyphsBatch` (type), `GroupDerivation` (type), `GuidePlan` (type), `HIGH_CARDINALITY_DISCRETE_THRESHOLD`, `INSPECT_GEOM_DIAGNOSTIC_CATALOG`, `INSPECT_INTENT_MODES`, `IPSUM_PALETTE`, `InspectGeomAdvisory` (type), `InspectGeomAdvisoryCode` (type), `InspectIntentMode` (type), `LEGEND_ROW_HEIGHT`, `LINETYPE_DASHES`, `LayerBackend` (type), `LayoutAxisPresentation` (type), `LayoutInput` (type), `LayoutResult` (type), `LayoutTheme` (type), `LegendBlock` (type), `LegendInput` (type), `LegendOrder` (type), `LetterboxRect` (type), `LineageRef` (type), `LineageStore`, `Linetype` (type), `MAX_BINNED_BREAKS`, `MappedField` (type), `Margins` (type), `MetricsTable` (type), `MetricsTableMeasurer`, `NamedData` (type), `NormalizedSpan` (type), `NumberFormatter` (type), `OrdinalColorConfig` (type), `PANDER_PALETTE`, `PANEL_SPACING`, `PIPELINE_ERROR_CATALOG`, `PIPELINE_WARNING_CATALOG`, `POSITION_TRANSFORM_NAMES`, `PTOL_PALETTE`, `PaletteExhaustedError`, `PanelCoordProjector` (type), `PassResult` (type), `PathsBatch` (type), `PipelineError`, `PipelineErrorCatalogEntry` (type), `PipelineErrorCode` (type), `PipelineWarning` (type), `PipelineWarningCode` (type), `PlotRect` (type), `PointShape` (type), `PointShapeGeometry` (type), `PointsBatch` (type), `PolarBBox` (type), `PolarProjector` (type), `PolarProjectorConfig` (type), `PolarReverse` (type), `PolarTheta` (type), `PositionScale` (type), `PositionTransformName` (type), `RAMP_LUT_STEPS`, `RampLegendInput` (type), `RectsBatch` (type), `RenderModel` (type), `ResolvedCandidateInspectMode` (type), `ResolvedColorScale` (type), `ResolvedEdition` (type), `ResolvedGlow` (type), `ResolvedGlyphMark` (type), `ResolvedGradientPaint` (type), `ResolvedPathMark` (type), `ResolvedPointMark` (type), `ResolvedRectMark` (type), `ResolvedSegmentMark` (type), `ResolvedStyleScale` (type), `Rows` (type), `RunOptions` (type), `RuntimeRowFilterClause` (type), `RuntimeRowFilterMode` (type), `RuntimeRowIndexFilter` (type), `SCALE_STATE_VERSION`, `SOLARIZED_PALETTE`, `STATA_PALETTE`, `STRIP_BAND`, `ScaleConfigError`, `ScaleDecision` (type), `ScaleDiagnostic` (type), `ScaleDiagnosticFix` (type), `ScaleDomainSnapshot` (type), `ScaleState` (type), `ScaleTransform` (type), `ScaleWarning` (type), `ScaleWarningCode` (type), `Scene` (type), `SceneAxis` (type), `SceneDiscreteLegend` (type), `SceneLegend` (type), `SceneLegendEntry` (type), `ScenePanel` (type), `SceneRampLegend` (type), `SceneStepsLegend` (type), `SceneTick` (type), `SegmentsBatch` (type), `SemanticCandidateKeys` (type), `SemanticViewport` (type), `SemanticViewportAxisSelection` (type), `SemanticViewportDomains` (type), `SemanticViewportPanel` (type), `SemanticViewportSelection` (type), `SequentialColorScale` (type), `SequentialConfig` (type), `StackInput` (type), `StackResult` (type), `StepsLegendInput` (type), `Stratum` (type), `StyleOutput` (type), `StyleScale` (type), `SumStatInput` (type), `SumStatResult` (type), `SummaryRollingStatInput` (type), `SummaryRollingStatResult` (type), `TABLEAU20_PALETTE`, `TABLEAU_COLORBLIND_PALETTE`, `TABLEAU_HUE_CIRCLE_PALETTE`, `TABLEAU_JEWEL_BRIGHT_PALETTE`, `TABLEAU_SEATTLE_GRAYS_PALETTE`, `TemporalAxisPlanInput` (type), `TemporalLabelFormatOptions` (type), `TemporalTickLabel` (type), `TextMeasurer` (type), `ThemeColorRole` (type), `ThemeRole` (type), `ThemeTokens` (type), `Tick` (type), `TickFormatter` (type), `TimeTicksResult` (type), `TrainMode` (type), `TrainResult` (type), `TrainedScales` (type), `TraversalDirection` (type), `UnknownThemeError`, `VIRIDIS_RAMP_10`, `WSJ_BLACK_GREEN_PALETTE`, `WSJ_DEM_REP_PALETTE`, `WSJ_PALETTE`, `WSJ_RED_GREEN_PALETTE`, `WSJ_RGBY_PALETTE`, `adoptScaleState`, `areaOutlineActive`, `bandKey`, `batchMarkCount`, `buildCandidateStore`, `buildCoordAxisProjector`, `buildInteractionMasks`, `buildLegends`, `buildPanelCoordProjector`, `buildPolarProjector`, `buildPrimitiveInteractionMasks`, `buildRampLut`, `canonicalAxisToken`, `cellToNumber`, `cellsToNumeric`, `collectInspectIntentDiagnostics`, `compileRuntimeRowIndexFilter`, `compileTemporalLabelFormat`, `countMarks`, `createFacetPanelIdentity`, `decodeKey`, `defaultLogTickFormat`, `defaultTickFormat`, `defaultTimeTickFormat`, `deriveGroups`, `disambiguatedLabels`, `discreteColorFillDomainSizes`, `discretenessOf`, `encodeKey`, `finiteExtent`, `fnv1a`, `formatTemporalTickSequence`, `formatTime`, `freshScaleState`, `getScaleTransform`, `groupBatchesByPanel`, `humanizeFieldTitle`, `inferDiscreteness`, `inferFieldType`, `inspectAxisOnBarColDiagnostics`, `inspectAxisOnDistributionDiagnostics`, `inspectHighCardinalityDiagnostics`, `installCandidates`, `installTemporal`, `isISODateString`, `isInspectIntentMode`, `layerGeomsFromSpecLayers`, `layout`, `layoutPass`, `letterboxGutterRects`, `linearTicks`, `linetypeDash`, `linetypeIndex`, `logTicks`, `marginDelta`, `markLinetype`, `niceLinearDomain`, `numberFormatter`, `paintResourceId`, `paletteFingerprint`, `pathData`, `perfMark`, `perfMeasure`, `planBandAxis`, `planStrata`, `planTemporalAxis`, `pointShapeGeometry`, `pointShapeIndex`, `pointShapePathD`, `polarBBox`, `polarProject`, `polarProjectPanelPoint`, `polarUnproject`, `positionDodge`, `positionStack`, `rampColor`, `registerAbline`, `registerAlign`, `registerAll`, `registerAllGeomBatches`, `registerAllStatFrames`, `registerBasic`, `registerBasicAreas`, `registerBasicBars`, `registerBasicGlyphs`, `registerBasicLines`, `registerBasicPoints`, `registerBasicRects`, `registerBasicSegments`, `registerBin`, `registerBin2d`, `registerBoxplot`, `registerConnect`, `registerContour`, `registerCrossbar`, `registerCurve`, `registerDensity`, `registerDensity2d`, `registerDensity2dFilled`, `registerDotplot`, `registerEcdf`, `registerEllipse`, `registerErrorbar`, `registerFunction`, `registerHex`, `registerLinerange`, `registerManual`, `registerMap`, `registerPointrange`, `registerPolygon`, `registerQq`, `registerQqLine`, `registerQuantile`, `registerRaster`, `registerRug`, `registerSf`, `registerSfLabel`, `registerSfText`, `registerSmooth`, `registerSpoke`, `registerSummary`, `registerSummaryBin`, `registerSummaryRolling`, `registerTile`, `registerUnique`, `registerViolin`, `resolveEditionDefaults`, `resolveGlyphMark`, `resolvePathMark`, `resolvePointMark`, `resolveRectMark`, `resolveSegmentMark`, `resolveTheme`, `runCLI`, `runPipeline`, `sampleRampLut`, `sampleSequentialPalette`, `scaleTransform`, `scalesForCoordExpand`, `sceneLabel`, `sceneToSVGString`, `sequentialSchemeRamp`, `serializeScaleState`, `spaceFieldName`, `statCount`, `statEcdf`, `statSum`, `statSummaryRolling`, `themeVar`, `tickStep`, `timeTicks`, `trainBand`, `trainColor`, `trainContinuous`, `trainDiscrete`, `trainLinear`, `trainSequential`
### stable-intent (2)
`RenderSVGOptions` (type), `renderToSVGString`
## @ggsvelte/core (./render)
### experimental (43)
`Advisory` (type), `AxisValueFormatter` (type), `CANVAS_AUTO_THRESHOLD`, `GeometryBatch` (type), `GlyphsBatch` (type), `LayerBackend` (type), `MappedField` (type), `NamedData` (type), `PathsBatch` (type), `PipelineError`, `PipelineWarning` (type), `PointsBatch` (type), `RectsBatch` (type), `RenderModel` (type), `RenderSVGOptions` (type), `ResolvedColorScale` (type), `RunOptions` (type), `ScaleDecision` (type), `ScaleDiagnostic` (type), `ScaleDiagnosticFix` (type), `ScaleDomainSnapshot` (type), `Scene` (type), `SceneAxis` (type), `SceneDiscreteLegend` (type), `SceneLegend` (type), `SceneLegendEntry` (type), `ScenePanel` (type), `SceneRampLegend` (type), `SceneStepsLegend` (type), `SceneTick` (type), `SegmentsBatch` (type), `Stratum` (type), `TrainedScales` (type), `batchMarkCount`, `countMarks`, `pathData`, `planStrata`, `registerGeomBatch`, `registerStatFrame`, `renderToSVGString`, `runPipeline`, `sceneLabel`, `sceneToSVGString`
## @ggsvelte/core (./headless)
### experimental (41)
`Advisory` (type), `AxisValueFormatter` (type), `CANVAS_AUTO_THRESHOLD`, `GeometryBatch` (type), `GlyphsBatch` (type), `LayerBackend` (type), `MappedField` (type), `NamedData` (type), `PathsBatch` (type), `PipelineError`, `PipelineWarning` (type), `PointsBatch` (type), `RectsBatch` (type), `RenderModel` (type), `RenderSVGOptions` (type), `ResolvedColorScale` (type), `RunOptions` (type), `ScaleDecision` (type), `ScaleDiagnostic` (type), `ScaleDiagnosticFix` (type), `ScaleDomainSnapshot` (type), `Scene` (type), `SceneAxis` (type), `SceneDiscreteLegend` (type), `SceneLegend` (type), `SceneLegendEntry` (type), `ScenePanel` (type), `SceneRampLegend` (type), `SceneStepsLegend` (type), `SceneTick` (type), `SegmentsBatch` (type), `Stratum` (type), `TrainedScales` (type), `batchMarkCount`, `countMarks`, `pathData`, `planStrata`, `renderToSVGString`, `runPipeline`, `sceneLabel`, `sceneToSVGString`
## @ggsvelte/core (./headless/register)
### experimental (9)
`registerBasicAreas`, `registerBasicBars`, `registerBasicGlyphs`, `registerBasicLines`, `registerBasicPoints`, `registerBasicRects`, `registerBasicSegments`, `registerGeomBatch`, `registerStatFrame`
## @ggsvelte/core (./temporal)
### experimental (11)
`AxisGuidePlan` (type), `TemporalAxisPlanInput` (type), `TemporalLabelFormatOptions` (type), `TemporalTickLabel` (type), `compileTemporalLabelFormat`, `formatTemporalTickSequence`, `formatTime`, `getTemporalRuntime`, `installTemporal`, `installTemporalRuntime`, `planTemporalAxis`
## @ggsvelte/core (./dom)
### experimental (9)
`CanvasFocusPresentation` (type), `ColorResolver` (type), `PrimitiveFocusMask` (type), `StaticQuadtree`, `cssColorResolver`, `drawBatch`, `drawClippedToPanel`, `drawStratum`, `sizeCanvasForDpr`
## @ggsvelte/svelte
### experimental (526)
`A11yMode` (type), `Advisory` (type), `Aes` (type), `AesInput` (type), `AlphaScaleSpec` (type), `AreaMode` (type), `AuthoringCellValue` (type), `AuthoringColumns` (type), `AuthoringDataRef` (type), `AuthoringRows` (type), `AxisGuideOptions` (type), `AxisGuidePlan` (type), `AxisGuideSpec` (type), `AxisGuideTick` (type), `BinnedColorScaleOptions` (type), `BinnedFiniteStyleScaleOptions` (type), `BoxplotParams` (type), `BrushSelection` (type), `COMPOSITION_DIAGNOSTIC_CATALOG`, `ChannelValue` (type), `ColorScaleOptions` (type), `ColorScaleSpec` (type), `ColorbarGuideOptions` (type), `ColorbarGuidePlan` (type), `ColorbarGuideSpec` (type), `ColorbarGuideTick` (type), `ColorstepsGuideOptions` (type), `ColorstepsGuidePlan` (type), `ColorstepsGuideSpec` (type), `ColorstepsGuideStep` (type), `CompositionDiagnostic` (type), `CompositionDiagnosticCode` (type), `ContinuousPositionScaleOptions` (type), `ControllerDatumIdentity` (type), `CoordFixedOptions` (type), `CoordFixedSpec` (type), `CoordPolar`, `CoordPolarOptions` (type), `CoordRadial`, `CoordRadialOptions` (type), `CoordRadialReverse` (type), `CoordRadialSpec` (type), `CoordRadialTheta` (type), `CoordSf`, `CoordSfOptions` (type), `CoordSfSpec` (type), `CoordSpec` (type), `CoordTransformAxisOptions` (type), `CoordTransformAxisSpec` (type), `CoordTransformName` (type), `CoordTransformOptions` (type), `CoordTransformSpec` (type), `CreatePlotInteractionOptions` (type), `DEPRECATION_DIAGNOSTIC_CATALOG`, `DataInput` (type), `DataProfile` (type), `DataRef` (type), `DensityParams` (type), `DeprecationDiagnostic` (type), `DeprecationDiagnosticCode` (type), `DiscreteColorScaleOptions` (type), `DiscreteFiniteStyleScaleOptions` (type), `DiscreteGuideEntry` (type), `DiscreteGuidePlan` (type), `DiscreteNumericStyleScaleOptions` (type), `DiscretePositionScaleOptions` (type), `DuplicateMergeKeyDiagnostic` (type), `DuplicateMergeKeyKind` (type), `DuplicatePlotLayerDiagnostic` (type), `DuplicatePlotLayerKind` (type), `DuplicateScaleChannelDiagnostic` (type), `ErrorbarParams` (type), `FacetInput` (type), `FacetIntervalPreset` (type), `FacetScales` (type), `FacetSpec` (type), `FiniteStyleScaleOptions` (type), `GGBuilder`, `GeomProps` (type), `GuidePlan` (type), `GuideSpec` (type), `GuideThemeSpec` (type), `GuidesSpec` (type), `INTERACTION_DIAGNOSTIC_CATALOG`, `IdentityColorScaleOptions` (type), `IdentityFiniteStyleScaleOptions` (type), `IdentityNumericStyleScaleOptions` (type), `Inspect`, `InspectInput` (type), `InspectMode` (type), `InspectOptions` (type), `InteractionDiagnostic` (type), `InteractionDiagnosticCode` (type), `InteractionSource` (type), `InteractionTool` (type), `IntervalSelection` (type), `LINETYPE_NAMES`, `LabsSpec` (type), `Layer` (type), `LayerBackend` (type), `LayerInput` (type), `LayerRegistry` (type), `LayerSpec` (type), `LegendFilterClause` (type), `LegendFilterEvent` (type), `LegendFilterInput` (type), `LegendFilterOptions` (type), `LegendFocusChange` (type), `LegendFocusClear` (type), `LegendFocusEvent` (type), `LegendFocusInput` (type), `LegendFocusOptions` (type), `LegendGuideOptions` (type), `LegendGuideSpec` (type), `LegendSpec` (type), `Linetype` (type), `LinetypeName` (type), `LinetypeScaleSpec` (type), `MAX_TEMPORAL_CANDIDATES`, `MAX_TEMPORAL_MAJOR_TICKS`, `MAX_TEMPORAL_MINOR_TICKS`, `MIN_TEMPORAL_LABEL_GAP_PX`, `ManualColorScaleOptions` (type), `ManualFiniteStyleScaleOptions` (type), `ManualNumericStyleScaleOptions` (type), `MappedField` (type), `MarkLayerDescriptor` (type), `MultiIdentityScaleOptions` (type), `MultiManualScaleOptions` (type), `MultiScaleAesthetic` (type), `MultiScaleChannel` (type), `NonEmptyReadonlyArray` (type), `NoneGuideSpec` (type), `NumericStyleScaleOptions` (type), `POINT_SHAPE_NAMES`, `PipelineError`, `PipelineWarning` (type), `PlotDatum` (type), `PlotDiagnostic` (type), `PlotInspection` (type), `PlotInspectionChange` (type), `PlotInspectionClear` (type), `PlotInteractionChange` (type), `PlotInteractionController` (type), `PlotInteractionEvent` (type), `PlotInteractionInterval` (type), `PlotInteractionMutationOptions` (type), `PlotInteractionScope` (type), `PlotInteractionSnapshot` (type), `PlotInteractionTransition` (type), `PlotInteractionZoomOptions` (type), `PlotSelection` (type), `PointPosition` (type), `PointSelection` (type), `PointShape` (type), `PointShapeName` (type), `PositionParams` (type), `PositionScaleSpec` (type), `PositiveStyleScaleSpec` (type), `ReadonlyIntervalDomains` (type), `ReadonlyZoomDomains` (type), `RecommendedScaleType` (type), `RenderBackend` (type), `RenderModel` (type), `RenderSVGOptions` (type), `ResolvedColorScale` (type), `ResolvedInspectMode` (type), `ResolvedInteractionConfig` (type), `ResolvedStyleScale` (type), `RunOptions` (type), `RuntimeSpec` (type), `SCALE_CAPABILITIES`, `STYLE_AESTHETIC_GEOMS`, `ScaleCapability` (type), `ScaleDecision` (type), `ScaleDiagnostic` (type), `ScaleDiagnosticFix` (type), `ScaleExpansion` (type), `ScaleState` (type), `ScaleTypeAesthetic` (type), `Scales` (type), `Scene` (type), `ScopedInteractionDomain` (type), `ScopedInteractionInterval` (type), `ScopedInteractionKeys` (type), `SelectInput` (type), `SelectOptions` (type), `SemanticIntervalAxis` (type), `SequentialColorScaleOptions` (type), `SequentialStyleScaleOptions` (type), `ShapeScaleSpec` (type), `SmoothParams` (type), `SpecAdvisory` (type), `SpecError` (type), `SpecInput` (type), `StackablePosition` (type), `Stratum` (type), `StyleAesthetic` (type), `TEMPORAL_INTERVAL_UNITS`, `TEMPORAL_LABEL_TOKENS`, `TEMPORAL_WEEKDAYS`, `THEME_NAMES`, `TemporalColorScaleOptions` (type), `TemporalDecision` (type), `TemporalDisambiguation` (type), `TemporalInterval` (type), `TemporalIntervalSpec` (type), `TemporalIntervalUnit` (type), `TemporalKind` (type), `TemporalNumericStyleScaleOptions` (type), `TemporalParserName` (type), `TemporalParserSpec` (type), `TemporalPrecision` (type), `TemporalScaleOptions` (type), `TemporalWeekStart` (type), `ThemeName` (type), `ThemeSpec` (type), `ThemeTokens` (type), `Tooltip`, `TooltipContext` (type), `TooltipField` (type), `TransformedColorScaleOptions` (type), `TransformedPositionScaleOptions` (type), `ValidateResult` (type), `ViridisOptionName` (type), `ViridisScaleOptions` (type), `ZoomDomains` (type), `ZoomEvent` (type), `ZoomInput` (type), `ZoomOptions` (type), `aes`, `coordEqual`, `coordFixed`, `coordPolar`, `coordRadial`, `coordSf`, `coordTransform`, `coord_equal`, `coord_fixed`, `coord_polar`, `coord_radial`, `coord_sf`, `coord_transform`, `createGeomLayer`, `createPlotInteraction`, `deprecatedPropDiagnostic`, `dmy`, `dmy_hm`, `dmy_hms`, `duplicateMergeKeyDiagnostic`, `duplicatePlotLayerDiagnostic`, `duplicateScaleChannelDiagnostic`, `dym`, `dym_hm`, `dym_hms`, `fromEpochMilliseconds`, `fromEpochSeconds`, `gg`, `guideAxis`, `guideColorbar`, `guideColorsteps`, `guideLegend`, `guideNone`, `guide_axis`, `guide_colorbar`, `guide_colorsteps`, `guide_legend`, `guide_none`, `guides`, `isCompositionDiagnostic`, `isDuplicateMergeKeyDiagnostic`, `isDuplicatePlotLayerDiagnostic`, `isDuplicateScaleChannelDiagnostic`, `isPortable`, `lintSpec`, `mdy`, `mdy_hm`, `mdy_hms`, `my`, `myd`, `myd_hm`, `myd_hms`, `normalizeInteractionConfig`, `parseTemporalFormat`, `parseTemporalInterval`, `planStrata`, `registerAbline`, `registerAlign`, `registerAll`, `registerBasic`, `registerBin`, `registerBin2d`, `registerBoxplot`, `registerConnect`, `registerContour`, `registerCrossbar`, `registerCurve`, `registerDensity`, `registerDensity2d`, `registerDensity2dFilled`, `registerDotplot`, `registerEcdf`, `registerEllipse`, `registerErrorbar`, `registerFunction`, `registerHex`, `registerLayer`, `registerLinerange`, `registerManual`, `registerMap`, `registerPlotLayer`, `registerPointrange`, `registerPolygon`, `registerQq`, `registerQqLine`, `registerQuantile`, `registerRaster`, `registerRug`, `registerSf`, `registerSfLabel`, `registerSfText`, `registerSmooth`, `registerSpoke`, `registerSummary`, `registerSummaryBin`, `registerSummaryRolling`, `registerTile`, `registerUnique`, `registerViolin`, `runPipeline`, `scaleAlpha`, `scaleAlphaBinned`, `scaleAlphaContinuous`, `scaleAlphaDate`, `scaleAlphaDatetime`, `scaleAlphaDiscrete`, `scaleAlphaIdentity`, `scaleAlphaManual`, `scaleColorBinned`, `scaleColorContinuous`, `scaleColorDate`, `scaleColorDatetime`, `scaleColorDiscrete`, `scaleColorIdentity`, `scaleColorLog10`, `scaleColorManual`, `scaleColorSqrt`, `scaleColorViridisB`, `scaleColorViridisC`, `scaleColorViridisD`, `scaleColourBinned`, `scaleColourContinuous`, `scaleColourDate`, `scaleColourDatetime`, `scaleColourDiscrete`, `scaleColourIdentity`, `scaleColourLog10`, `scaleColourManual`, `scaleColourSqrt`, `scaleColourViridisB`, `scaleColourViridisC`, `scaleColourViridisD`, `scaleContinuousIdentity`, `scaleDiscreteIdentity`, `scaleDiscreteManual`, `scaleFillBinned`, `scaleFillContinuous`, `scaleFillDate`, `scaleFillDatetime`, `scaleFillDiscrete`, `scaleFillIdentity`, `scaleFillLog10`, `scaleFillManual`, `scaleFillSqrt`, `scaleFillViridisB`, `scaleFillViridisC`, `scaleFillViridisD`, `scaleLinetype`, `scaleLinetypeBinned`, `scaleLinetypeDiscrete`, `scaleLinetypeIdentity`, `scaleLinetypeManual`, `scaleLinewidth`, `scaleLinewidthBinned`, `scaleLinewidthContinuous`, `scaleLinewidthDate`, `scaleLinewidthDatetime`, `scaleLinewidthDiscrete`, `scaleLinewidthIdentity`, `scaleLinewidthManual`, `scaleShape`, `scaleShapeBinned`, `scaleShapeDiscrete`, `scaleShapeIdentity`, `scaleShapeManual`, `scaleSize`, `scaleSizeBinned`, `scaleSizeContinuous`, `scaleSizeDate`, `scaleSizeDatetime`, `scaleSizeDiscrete`, `scaleSizeIdentity`, `scaleSizeManual`, `scaleType`, `scaleXBinned`, `scaleXContinuous`, `scaleXDate`, `scaleXDatetime`, `scaleXDiscrete`, `scaleXLog10`, `scaleXMonthDay`, `scaleXReverse`, `scaleXSqrt`, `scaleXTime`, `scaleYBinned`, `scaleYContinuous`, `scaleYDate`, `scaleYDatetime`, `scaleYDiscrete`, `scaleYLog10`, `scaleYMonthDay`, `scaleYReverse`, `scaleYSqrt`, `scaleYTime`, `scale_alpha_binned`, `scale_alpha_continuous`, `scale_alpha_date`, `scale_alpha_datetime`, `scale_alpha_discrete`, `scale_alpha_identity`, `scale_alpha_manual`, `scale_color_binned`, `scale_color_continuous`, `scale_color_date`, `scale_color_datetime`, `scale_color_discrete`, `scale_color_identity`, `scale_color_log10`, `scale_color_manual`, `scale_color_sqrt`, `scale_color_viridis_b`, `scale_color_viridis_c`, `scale_color_viridis_d`, `scale_colour_binned`, `scale_colour_continuous`, `scale_colour_date`, `scale_colour_datetime`, `scale_colour_discrete`, `scale_colour_identity`, `scale_colour_log10`, `scale_colour_manual`, `scale_colour_sqrt`, `scale_colour_viridis_b`, `scale_colour_viridis_c`, `scale_colour_viridis_d`, `scale_continuous_identity`, `scale_discrete_identity`, `scale_discrete_manual`, `scale_fill_binned`, `scale_fill_continuous`, `scale_fill_date`, `scale_fill_datetime`, `scale_fill_discrete`, `scale_fill_identity`, `scale_fill_log10`, `scale_fill_manual`, `scale_fill_sqrt`, `scale_fill_viridis_b`, `scale_fill_viridis_c`, `scale_fill_viridis_d`, `scale_linetype`, `scale_linetype_binned`, `scale_linetype_discrete`, `scale_linetype_identity`, `scale_linetype_manual`, `scale_linewidth_binned`, `scale_linewidth_continuous`, `scale_linewidth_date`, `scale_linewidth_datetime`, `scale_linewidth_discrete`, `scale_linewidth_identity`, `scale_linewidth_manual`, `scale_shape`, `scale_shape_binned`, `scale_shape_discrete`, `scale_shape_identity`, `scale_shape_manual`, `scale_size_binned`, `scale_size_continuous`, `scale_size_date`, `scale_size_datetime`, `scale_size_discrete`, `scale_size_identity`, `scale_size_manual`, `scale_type`, `scale_x_binned`, `scale_x_continuous`, `scale_x_date`, `scale_x_datetime`, `scale_x_discrete`, `scale_x_log10`, `scale_x_month_day`, `scale_x_reverse`, `scale_x_sqrt`, `scale_x_time`, `scale_y_binned`, `scale_y_continuous`, `scale_y_date`, `scale_y_datetime`, `scale_y_discrete`, `scale_y_log10`, `scale_y_month_day`, `scale_y_reverse`, `scale_y_sqrt`, `scale_y_time`, `temporalIntervalTicks`, `toPortable`, `toPortableLossy`, `ydm`, `ydm_hm`, `ydm_hms`, `ym`, `ymd`, `ymd_hm`, `ymd_hms`, `yq`
### stable-intent (238)
`Coord`, `CoordCartesian`, `CoordEqual`, `CoordFixed`, `CoordFlip`, `CoordTransform`, `Facet`, `FacetGrid`, `FacetWrap`, `GGPlot`, `GeomAbline`, `GeomArea`, `GeomBar`, `GeomBin2d`, `GeomBlank`, `GeomBoxplot`, `GeomCol`, `GeomContour`, `GeomCount`, `GeomCrossbar`, `GeomCurve`, `GeomDensity`, `GeomDensity2d`, `GeomDensity2dFilled`, `GeomDotplot`, `GeomErrorbar`, `GeomFreqpoly`, `GeomFunction`, `GeomHex`, `GeomHistogram`, `GeomHline`, `GeomJitter`, `GeomLabel`, `GeomLine`, `GeomLinerange`, `GeomMap`, `GeomPath`, `GeomPoint`, `GeomPointrange`, `GeomPolygon`, `GeomQq`, `GeomQqLine`, `GeomQuantile`, `GeomRaster`, `GeomRect`, `GeomRibbon`, `GeomRug`, `GeomRule`, `GeomSegment`, `GeomSf`, `GeomSfLabel`, `GeomSfText`, `GeomSmooth`, `GeomSpoke`, `GeomStep`, `GeomText`, `GeomTile`, `GeomViolin`, `GeomVline`, `GuideAxis`, `GuideChannel` (type), `GuideColorbar`, `GuideColorsteps`, `GuideLegend`, `GuideNone`, `Guides`, `Labs`, `Legend`, `NonPositionGuideChannel` (type), `PortableSpec` (type), `PositionGuideChannel` (type), `Scale`, `ScaleAlphaBinned`, `ScaleAlphaContinuous`, `ScaleAlphaDate`, `ScaleAlphaDatetime`, `ScaleAlphaDiscrete`, `ScaleAlphaIdentity`, `ScaleAlphaManual`, `ScaleAlphaOrdinal`, `ScaleColorBinned`, `ScaleColorBrewer`, `ScaleColorContinuous`, `ScaleColorDate`, `ScaleColorDatetime`, `ScaleColorDiscrete`, `ScaleColorDistiller`, `ScaleColorFermenter`, `ScaleColorGradient`, `ScaleColorGradient2`, `ScaleColorGradientn`, `ScaleColorGrey`, `ScaleColorHue`, `ScaleColorIdentity`, `ScaleColorLog10`, `ScaleColorManual`, `ScaleColorOrdinal`, `ScaleColorSqrt`, `ScaleColorSteps`, `ScaleColorSteps2`, `ScaleColorStepsn`, `ScaleColorViridisB`, `ScaleColorViridisC`, `ScaleColorViridisD`, `ScaleColourBinned`, `ScaleColourBrewer`, `ScaleColourContinuous`, `ScaleColourDate`, `ScaleColourDatetime`, `ScaleColourDiscrete`, `ScaleColourDistiller`, `ScaleColourFermenter`, `ScaleColourGradient`, `ScaleColourGradient2`, `ScaleColourGradientn`, `ScaleColourGrey`, `ScaleColourHue`, `ScaleColourIdentity`, `ScaleColourLog10`, `ScaleColourManual`, `ScaleColourOrdinal`, `ScaleColourSqrt`, `ScaleColourSteps`, `ScaleColourSteps2`, `ScaleColourStepsn`, `ScaleColourViridisB`, `ScaleColourViridisC`, `ScaleColourViridisD`, `ScaleFillBinned`, `ScaleFillBrewer`, `ScaleFillContinuous`, `ScaleFillDate`, `ScaleFillDatetime`, `ScaleFillDiscrete`, `ScaleFillDistiller`, `ScaleFillFermenter`, `ScaleFillGradient`, `ScaleFillGradient2`, `ScaleFillGradientn`, `ScaleFillGrey`, `ScaleFillHue`, `ScaleFillIdentity`, `ScaleFillLog10`, `ScaleFillManual`, `ScaleFillOrdinal`, `ScaleFillSqrt`, `ScaleFillSteps`, `ScaleFillSteps2`, `ScaleFillStepsn`, `ScaleFillViridisB`, `ScaleFillViridisC`, `ScaleFillViridisD`, `ScaleLinetypeBinned`, `ScaleLinetypeDiscrete`, `ScaleLinetypeIdentity`, `ScaleLinetypeManual`, `ScaleLinewidthBinned`, `ScaleLinewidthContinuous`, `ScaleLinewidthDate`, `ScaleLinewidthDatetime`, `ScaleLinewidthDiscrete`, `ScaleLinewidthIdentity`, `ScaleLinewidthManual`, `ScaleLinewidthOrdinal`, `ScaleRadius`, `ScaleShapeBinned`, `ScaleShapeDiscrete`, `ScaleShapeIdentity`, `ScaleShapeManual`, `ScaleShapeOrdinal`, `ScaleSizeArea`, `ScaleSizeBinned`, `ScaleSizeBinnedArea`, `ScaleSizeContinuous`, `ScaleSizeDate`, `ScaleSizeDatetime`, `ScaleSizeDiscrete`, `ScaleSizeIdentity`, `ScaleSizeManual`, `ScaleSizeOrdinal`, `ScaleXBinned`, `ScaleXContinuous`, `ScaleXDate`, `ScaleXDatetime`, `ScaleXDiscrete`, `ScaleXLog10`, `ScaleXMonthDay`, `ScaleXReverse`, `ScaleXSqrt`, `ScaleXTime`, `ScaleYBinned`, `ScaleYContinuous`, `ScaleYDate`, `ScaleYDatetime`, `ScaleYDiscrete`, `ScaleYLog10`, `ScaleYMonthDay`, `ScaleYReverse`, `ScaleYSqrt`, `ScaleYTime`, `SpecValidationError`, `Theme`, `ThemeBase`, `ThemeBw`, `ThemeClassic`, `ThemeClean`, `ThemeDark`, `ThemeDefault`, `ThemeEconomist`, `ThemeEconomistwhite`, `ThemeFew`, `ThemeFivethirtyeight`, `ThemeGgplot2`, `ThemeGray`, `ThemeGrey`, `ThemeHc`, `ThemeHcdark`, `ThemeHrbr`, `ThemeIgray`, `ThemeLight`, `ThemeLinedraw`, `ThemeMap`, `ThemeMinimal`, `ThemePander`, `ThemeSolarized`, `ThemeSolarized2`, `ThemeSolarized2dark`, `ThemeSolarizeddark`, `ThemeSolid`, `ThemeStata`, `ThemeStatas1color`, `ThemeTest`, `ThemeTufte`, `ThemeVoid`, `ThemeWsj`, `normalize`, `renderToSVGString`, `validate`
## @ggsvelte/cli
### experimental (2)
`CLIIO` (type), `runCLI`
---
# Upgrade guide
One section per released 0.x transition, newest first. Each heading is a
stable anchor that changesets and release notes link to. Pre-1.0, breaking
changes ride minor releases; every deprecation or removal ships with a
migration note here.
## Five-minute path
- Check that linked `@ggsvelte/*` packages (`svelte`, `spec`, `core`, `cli`, `skill`) resolve to one compatible release.
- Read only the adjacent transition sections needed for the installed version.
- Apply the before/after source change backed by the migration fixtures.
- Run strict type, build, render, and visual checks before deploying.
- Follow a stable diagnostic anchor if blocked; roll package versions back together if needed.
The accepted lifecycle and deprecation policy remains in
[Lifecycle and editions](https://ggsvelte.sh/guide/lifecycle#lifecycle-tags); this page applies it
rather than creating a second policy.
## 0.28 to 0.29
### Removed Tableau 10, Summer, Winter, and stone schemes
Six categorical `scheme` names (and matching public `*_PALETTE` constants)
are gone:
- `tableau10`
- `tableau_summer`, `tableau_winter`
- `tableau_miller_stone`, `tableau_superfishel_stone`,
`tableau_nuriel_stone`
Prefer `observable10`, `colorblind`, `Dark2`, `pander`, or another
remaining Tableau scheme (`tableau20`, `tableau_colorblind`,
`tableau_jewel_bright`, …), or pass an explicit `range`.
```json fragment
// Before
{
"scales": { "color": { "type": "ordinal", "scheme": "tableau10" } }
}
```
```json fragment
// After
{
"scales": { "color": { "type": "ordinal", "scheme": "observable10" } }
}
```
## 0.27 to 0.28
### Removed spreadsheet, Highcharts, and extra Stata schemes and themes
Nine categorical `scheme` names (and the matching public `*_PALETTE` constants
from `@ggsvelte/core`) are gone:
- `stata_s1color`, `stata_s1rcolor`, `stata_mono`
- `hc`, `hc_dark`
- `calc`, `excel`, `excel_fill`, `excel_new`
A PortableSpec that still names one of those schemes fails validation. Switch
to a remaining scheme — `stata`, `observable10`, `Dark2`, and `pander` are
the usual replacements — or pass an explicit `range` of hex color stops.
Four chart **themes** are also gone: `stata_mono`, `calc`, `excel`, and
`excel_new` (and their Svelte shells `ThemeStatamono`, `ThemeCalc`,
`ThemeExcel`, `ThemeExcelnew`). Prefer `stata`, `stata_s1color`, `bw`,
`classic`, or `minimal`.
```json fragment
// Before: scheme / theme names that no longer validate
{
"theme": "excel_new",
"scales": { "color": { "type": "ordinal", "scheme": "excel_new" } }
}
```
```json fragment
// After: pick remaining theme + scheme (or an explicit color range)
{
"theme": "minimal",
"scales": { "color": { "type": "ordinal", "scheme": "observable10" } }
}
```
### Removed Accent, Paired, Grey, Google Docs, and Tableau multi-hue schemes
Eight more categorical `scheme` names (and matching public `*_PALETTE`
constants where they existed) are gone:
- `Accent`, `Paired`
- `grey`, `gray`
- `gdocs`
- `tableau_green_orange_teal`, `tableau_red_blue_brown`,
`tableau_purple_pink_gray`
Theme `gdocs` (and Svelte shell `ThemeGdocs`) is also gone. Prefer
`minimal`, `classic`, or `bw`.
`scaleColorGrey()` / `` still work: they bake an explicit
greyscale `range` (optional `start`/`end`). They no longer emit
`scheme: "grey"`.
```json fragment
// Before
{
"theme": "gdocs",
"scales": { "color": { "type": "ordinal", "scheme": "Accent" } }
}
```
```json fragment
// After
{
"theme": "minimal",
"scales": { "color": { "type": "ordinal", "scheme": "Dark2" } }
}
```
## 0.26 to 0.27
### Explicit registration for spec-driven charts
Apps that declare layers with components (``, ``, …)
need **no change**: each component now registers its own geom batch and
default stat on import, and GGPlot bundles only the geoms and stats a chart
declares. Identity charts (point, line, path, col, bar, area, rule, hline,
vline, text, label, rect, ribbon, segment, count, blank, jitter, step) work
out of the box as before.
Apps that drive GGPlot with a `layers` prop or a `spec`, or call
`runPipeline` / `renderToSVGString` directly, must register specialty
geoms/stats (smooth, boxplot, violin, hex, contour, density_2d, sf, qq, …)
explicitly. A missing registration fails loudly: `Geom "smooth" is not
registered in this build. Call registerAll() …`.
```svelte fragment
```
```svelte fragment
```
- Prefer one `registerAll()` at app startup for the pre-0.27 "full grammar"
behavior — grammar + Temporal + interaction candidates (also re-exported
from `@ggsvelte/svelte`).
- Prefer a per-family call (`registerSmooth()`, `registerBoxplot()`, …, from
`@ggsvelte/core`) for granular opt-in without the full grammar.
- Overriding `stat` to a specialty stat (e.g.
``) needs that stat's register call too —
the component registers only its default stat.
- Direct `@ggsvelte/core` barrel importers: the barrel is side-effect-free
now — `registerAll()` restores pre-0.27 import-time registration. The lean
`@ggsvelte/core/render` entry is unchanged (basic registration on import).
### Skill moved to @ggsvelte/skill
The agent skill (`SKILL.md` + `references/`) no longer ships inside
`@ggsvelte/svelte`. It is its own package, `@ggsvelte/skill`, versioned in
lock-step with the rest of ggsvelte — the package root IS the skill directory:
```sh fragment
npm install --save-dev @ggsvelte/skill
# then copy or symlink it into your agent's skills directory:
cp -R node_modules/@ggsvelte/skill .claude/skills/ggsvelte
```
Or point agents at the stable path
`node_modules/@ggsvelte/skill/SKILL.md` directly. Re-copy on every version
bump; dependabot (or npm-check-updates) surfaces those bumps now. Any checkout
that previously read `node_modules/@ggsvelte/svelte/skills/ggsvelte/` must
switch — that directory is gone.
## 0.22 to 0.23
### CLI moved to @ggsvelte/cli
The `ggsvelte-render` bin no longer ships with `@ggsvelte/svelte`. It is
its own package, `@ggsvelte/cli`, with no Svelte dependency — install it
wherever the command runs (agent sandboxes above all):
```sh fragment
npm install -g @ggsvelte/cli
# or add @ggsvelte/cli as a dependency of the project that invokes it
```
The command name, flags, exit codes, and JSONL diagnostics are unchanged.
`ggsvelte-codemod` still ships with `@ggsvelte/svelte`. If a sandbox image
or CI step ran `ggsvelte-render` via the Svelte package's bin, add
`@ggsvelte/cli` there before upgrading `@ggsvelte/svelte`.
## 0.20 to 0.21
### Row identity on interaction
Durable row identity no longer belongs on the grammar root. Ordinary charts
omit identity entirely: the engine uses an `id` column when present, otherwise
the **row index** (order-stable only — not reorder-safe across data refresh).
Custom durable identity (non-`id` natural keys, composite accessors, pin
rebind across reorder) lives on interaction surfaces:
```svelte fragment
```
```svelte fragment
```
- Prefer `` or `inspect={{ identity: "…" }}` when
inspect is enabled.
- Prefer `select={{ type: "point", identity: "…" }}` (or interval) when
selection owns the key without inspect.
- Prefer `createPlotInteraction({ identity: "…" })` when linked plots share
one controller and the same identity field.
- Resolution order: Inspect → Select → controller → deprecated `key` →
auto `id` → row index.
- `` still dual-reads through 0.21.x and emits
`DEPRECATED_PLOT_PROP`; it is removed in 0.22.0.
## 0.18 to 0.19
### Legend focus on GuideLegend
Discrete legend focus is no longer a plot-host capability prop. Opt in on the
guide child that owns the aesthetic:
```svelte fragment
```
```svelte fragment
```
- `focus` accepts `true` or `{ preview?: boolean }` (same shape as the old
plot prop). It is host-only — not a PortableSpec / `guideLegend()` field.
- Only channels with an active `` get interactive legend
targets. Enable multiple aesthetics with multiple GuideLegend children.
- A focus-only GuideLegend (no presentation options) does not force
`type: "legend"`, so continuous colour scales keep their colorbar.
- `` still works plot-wide through 0.19.x and emits
`DEPRECATED_PLOT_PROP`; it is removed in 0.20.0.
- Handlers stay plot-level: `onlegendfocus`, `oninteraction`, and `key`.
### Legend filter on GuideLegend
Discrete legend filter is no longer a plot-host capability prop. Opt in on the
guide child that owns the aesthetic:
```svelte fragment
```
```svelte fragment
```
- `filter` accepts `true` or `{ mode?, multiple? }` (same shape as the old
plot prop). It is host-only — not a PortableSpec / `guideLegend()` field.
- Only channels with an active `` get filter checkboxes.
Enable multiple aesthetics with multiple GuideLegend children.
- A filter-only GuideLegend (no presentation options) does not force
`type: "legend"`, so continuous colour scales keep their colorbar.
- `` still works plot-wide through 0.19.x and emits
`DEPRECATED_PLOT_PROP`; it is removed in 0.20.0.
- Handlers stay plot-level: `onlegendfilter`, `oninteraction`, and `key`.
- Focus and filter coexist on one GuideLegend:
``.
## 0.11 to 0.12
### Manual color domain/range diagnostic code
Validation used to emit the code `scale-manual-domain-range` when a manual
color/fill scale had mismatched domain and range lengths. It now emits
`color-manual-domain-range` — the same string the pipeline already used —
so agents and the error-reference page have one name for that fault.
If your tooling matches `SpecError.code` or docs anchors by string, update:
- code: `scale-manual-domain-range` → `color-manual-domain-range`
- docs anchor: `#scale-manual-domain-range` → `#color-manual-domain-range`
(pipeline entry is now `#color-manual-domain-range-pipeline` when both
sources appear on the page)
Pipeline-only and validation-only catalogs remain separate objects, but dual
codes share one prose source in `@ggsvelte/spec`. `PIPELINE_ERROR_CATALOG`
is also exported from `@ggsvelte/spec` (and still re-exported from
`@ggsvelte/core`).
## 0.12 to 0.13
### Grammar props removed from ``
The seven grammar props deprecated in 0.11.0 — `theme`, `scales`, `coord`,
`facet`, `labs`, `guides`, and `legend` — are **removed** from
`` in 0.13.0. Compose them only as declaration-only children. The
`ggsvelte-codemod` still rewrites old source that uses the prop form.
`LayerDescriptor` is removed; use `MarkLayerDescriptor`.
### `normalize()` returns the post-normalize geom union
`normalize()` rewrites five convenience geoms to a canonical name —
`histogram` to `bar`, `freqpoly` to `line`, `jitter` to `point`,
`hline` and `vline` to `rule`. Its declared return type used to name all
49 geoms anyway, so nothing could tell which 44 actually reach the pipeline.
It now returns `NormalizedSpec`, whose layers are `NormalizedLayerSpec` —
the same shape, minus the five names normalize has already removed. Alongside
it, `@ggsvelte/spec` exports `ALIAS_GEOMS`, `GEOM_ALIASES`,
`AliasGeomName` and `NormalizedGeomName`.
Authored specs are unaffected: `PortableSpec` and the published JSON Schema
still accept every one of the 49 names, and `geom: "histogram"` works exactly
as before.
One kind of caller changes. Code that reads geoms back off a normalized spec
and expects all 49 now sees 44:
```ts fragment
// Before — the "histogram" arm was reachable in the type, never at runtime.
const spec: PortableSpec = normalize(input);
for (const layer of spec.layers) {
if (layer.geom === "histogram") { /* dead branch */ }
}
// After — narrow before normalize, or drop the branch.
const spec = normalize(input); // NormalizedSpec
for (const layer of spec.layers) {
if (layer.geom === "bar") { /* what histogram became */ }
}
```
Annotating the result as `PortableSpec` still compiles, so passing a
normalized spec on to anything that takes one needs no change.
## 0.10 to 0.11
### Compose the theme as a child layer
The `theme` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Compose the theme as a declaration-only child — named shells
for every built-in theme, or the generic `` escape hatch for dynamic
names and role overrides.
Before:
```svelte fragment
```
After:
```svelte fragment
```
`LayerDescriptor` was renamed to `MarkLayerDescriptor` in 0.11.0 and the
alias was removed in 0.13.0.
### Compose scales as child layers
The `scales` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Compose scales as declaration-only children — named shells
for every color/fill helper (``, ``,
British `Colour` aliases, …), or the generic `` escape hatch
for raw fragments and computed scales. Two children on one channel emit a
`DUPLICATE_SCALE_CHANNEL` advisory (last child still wins).
Named shells route through the matching helpers, so migrating a raw fragment
like `scales={{color:{scheme:"colorblind"}}}` to
`` adds `type:"ordinal"` to the
PortableSpec (rendering is unchanged). Use `` when you need
byte-identical PortableSpec.
Before:
```svelte fragment
```
After:
```svelte fragment
```
`PlotDiagnostic` also widens to include `CompositionDiagnostic`
(`DUPLICATE_SCALE_CHANNEL`, `DUPLICATE_PLOT_LAYER`). Exhaustive `switch` on
`.code` needs new arms; handlers annotated `PlotDiagnostic` keep compiling.
### Compose coord as a child layer
The `coord` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Compose the coordinate system as a declaration-only child —
``, `` / ``, ``,
``, or the generic `` escape hatch. Two
coord children emit a `DUPLICATE_PLOT_LAYER` advisory (last child still wins).
### Compose facet as a child layer
The `facet` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Compose facets as declaration-only children — ``, ``, or the complete
`` surface. Keep `strip` nested
(`strip={{position,show}}`). Two facet children emit a
`DUPLICATE_PLOT_LAYER` advisory (last child still wins). Bare ``
with no wrap/rows/cols fails validation (`facet-form-missing`).
### Compose labs as a child layer
The `labs` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Compose labels as a declaration-only child —
``. There is
no `` escape hatch because Labs is a flat bag of strings:
`` already covers the computed case.
labs is a MERGE family: two `` children setting different keys both
survive. Two children setting the SAME key emit a `DUPLICATE_MERGE_KEY`
advisory and the later one wins.
### Compose guides as child layers
The `guides` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Guides are keyed by aesthetic, so the child form is one shell per
guide TYPE taking a `channel` prop — the aesthetic is a key, never part of the
component name: ``,
``,
``, ``,
``, plus `` for raw or computed
guide bags.
guides is a MERGE family keyed by channel, but the value AT a channel is
replaced whole. Two guide children on one channel emit a
`DUPLICATE_MERGE_KEY` advisory (last child still wins). A top-level guide
child still wins over a scale-local `guide` on the same channel.
The shells carry no scale knowledge and do not guess: `` over
a discrete color scale fails loudly rather than silently degrading to a legend.
### Compose legend as a child layer
The `legend` prop on `` was deprecated in 0.11.0 and **removed in
0.13.0**. Compose it as ``.
`