Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
d301e39
rework main lib with dynamic dimension calculations
mhkeller Aug 1, 2026
11bc4ee
mass edit of examples
mhkeller Aug 1, 2026
64b9550
more component and example updates
mhkeller Aug 1, 2026
780e696
doc updates
mhkeller Aug 1, 2026
1b26f7d
try a new strategy for types
mhkeller Aug 1, 2026
bb85efd
update docs
mhkeller Aug 1, 2026
9daecfe
some more type stuff
mhkeller Aug 1, 2026
d2d96f0
fix for vite8
mhkeller Aug 1, 2026
91144a2
fix axisx baseline dupe
mhkeller Aug 1, 2026
f39f021
more axis fixes
mhkeller Aug 1, 2026
870430b
voronoi a11y improvement
mhkeller Aug 1, 2026
0d969da
beeswarm fixes
mhkeller Aug 1, 2026
c837ec6
remove useless width/height props
mhkeller Aug 1, 2026
33f10c4
fix nested scales and percentRange. also make {d}Range props trigger …
mhkeller Aug 1, 2026
c57000c
update docs
mhkeller Aug 1, 2026
e5c13f3
anotehr test
mhkeller Aug 1, 2026
309dabe
updates to grouped bar/column charts
mhkeller Aug 2, 2026
7d65341
fix comments
mhkeller Aug 2, 2026
9a4ecd4
rename {n}1 to {n}2
mhkeller Aug 2, 2026
36d2bb8
c. -> cake.
mhkeller Aug 2, 2026
2aba31e
one more
mhkeller Aug 2, 2026
7c08aad
a11y notice and document svelte bug
mhkeller Aug 2, 2026
c0e921d
draft changelog
mhkeller Aug 2, 2026
1c16d90
regen our aria snapshots
mhkeller Aug 2, 2026
524ab41
add diverging bar examples; fix doc over-rendering in dev
mhkeller Aug 2, 2026
ca93bda
Potential fix for pull request finding
mhkeller Aug 2, 2026
928e49d
update docs build
mhkeller Aug 2, 2026
535b54c
fix filterObject jsdocs
mhkeller Aug 2, 2026
531b6eb
fix weird 404/500 docs site mismatch
mhkeller Aug 2, 2026
c54b6fa
cake -> k
mhkeller Aug 22, 2026
ce170f2
cake -> k
mhkeller Aug 22, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ node_modules
.vercel
.output
stashed
/.claude

# Playwright
/test-results/
Expand Down
95 changes: 88 additions & 7 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,86 @@
# Changelog

# 11.0.0

> DRAFT – date TBD

A full Svelte 5 rewrite. Stores are gone: the context is a reactive getter object, and dimensions are defined as data in a registry that drives props, scales, context keys and types. See the [migration notes](#migrating-from-10x) below.

**Breaking changes**

- The context is accessed with `getLayerCakeContext()` instead of `getContext('LayerCake')`, and its values are plain reactive values, not stores: `$xGet(d)` becomes `k.xGet(d)` after `const k = getLayerCakeContext()`. Property reads are reactive – destructuring outside of `$derived` captures a stale snapshot. The variable name is up to you. The docs and examples call it `k`.
- Requires `svelte@5.40` or newer (the library uses `createContext`).
- The `children` snippet receives the context object as its single argument. Svelte 4 `let:` directives no longer apply.
- Scales are only created for dimensions you configure (via the accessor, `[name]Domain`, `[name]Scale` or `[name]Range` prop). Unconfigured dimensions return `undefined` from the context, where previous versions always created default `x`/`y`/`z`/`r` scales. Components that read another dimension's values should guard, e.g. `k.yRange ? Math.max(...k.yRange) : k.height`.
- The `width` and `height` props are gone. They only ever set the size the chart drew at before the container was measured, which is the same 100 the component now uses on its own, and the name implied an override that never existed. For a server-side render, set the coordinate system with [`percentRange`](https://layercake.graphics/guide#percentrange) instead. Passing either one now logs `[LayerCake] Unknown prop 'width'. Ignoring...`.
- The domains passed to the `children` snippet are now read back off the scale after `.nice()` and `[name]Padding` are applied, matching what the context reports. Previously the snippet received the pre-nice domain.
- Passing an uninstantiated scale factory (`xScale={scaleLinear}` instead of `xScale={scaleLinear()}`) now throws a clear error. It was never documented behavior.
- A function passed as `[name]Range` receives `({ width, height, scales })` and only re-runs when the values it actually reads change.
- `debug` no longer prints during server-side rendering; it prints in the browser after hydration.
- Unknown props are reported with a console warning unless `verbose={false}`.
- A range you customized on a passed-in scale is now preserved instead of being overwritten with the dimension's default – so `zScale={scaleOrdinal(schemeCategory10)}` keeps its colors. Layer Cake still manages the range of pristine scales, and an explicit `[name]Range` prop always wins. Per [#364](https://github.com/mhkeller/layercake/issues/364).

**New features**

- Two nested dimensions, `x2` and `y2`, for grouped column and bar charts. They default to a `scaleBand()` whose range is the parent scale's bandwidth, so a grouped column chart is just `x="year" xScale={scaleBand()} x2="fruit" y="value"`. See the new [ColumnGrouped example](https://layercake.graphics/example/ColumnGrouped).
- Two color dimensions, `c` and `c2` (e.g. for opacity). Their domains are computed from your data like any other dimension. `c` defaults to an ordinal scale with a ten-color categorical palette (d3's `schemeCategory10`, no new dependency) and `c2` to a linear scale with a `[0, 1]` range – override with `cRange`/`c2Range`, or pass a preconfigured scale like `cScale={scaleOrdinal(schemeCategory10)}`, whose customized range is preserved. Per [#364](https://github.com/mhkeller/layercake/issues/364).
- `[name]Range` functions receive the computed sibling scales, e.g. `x2Range={({ scales }) => [0, scales.x.bandwidth() / 2]}`.
- New `x2DomainSort`, `y2DomainSort`, `cDomainSort` and `c2DomainSort` props.
- The context exposes `element`, the `.layercake-container` div.
- Dimensions are defined as data in a registry (`settings/dimensions.js`); prop handling, scale creation, context keys and TypeScript definitions are all generated from it.

**Performance**

- Scales, domains and getters are only computed for dimensions you actually configure. Previous versions always built all four.
- The reactive graph is pull-based and fine-grained. Scales only depend on the values their range reads, so color and ordinal scales no longer rebuild on every resize tick, and a `percentRange` chart doesn't rebuild any scales while resizing.
- Extents only depend on the dimensions that contribute data, so changing a prop of an unused dimension no longer rescans your data.
- Child components read one shared context object through getters instead of subscribing to ~50 derived stores each.

**Types**

- `getLayerCakeContext()` returns a fully typed context: every key autocompletes with hover documentation, and typos like `k.xGett` are compile errors.
- Component props are fully typed. The per-dimension halves of both typedefs are generated from the registry (`npm run generate:dims`) and enforced by tests, so types, docs and runtime behavior can't drift apart.

**Fixes**

- A dimension configured only through its `[name]Scale` prop keeps the scale's preconfigured domain instead of having it overwritten with an empty array.
- The zero-width/zero-height container warning now always fires when the container is unsized, not only when a child happens to read a size-dependent value.
- Axis components fall back gracefully on charts that don't configure the opposite dimension.
- The declared svelte peer dependency now matches the version the library actually requires.

## Migrating from 10.x

| 10.x | 11.0 |
| ------------------------------------------------ | ------------------------------------------------------------------ |
| `const { data, xGet } = getContext('LayerCake')` | `const k = getLayerCakeContext()` |
| `$xGet(d)`, `$yScale.ticks()`, `$width` | `k.xGet(d)`, `k.yScale.ticks()`, `k.width` |
| `<LayerCake let:width>` | `{#snippet children(k)}...{/snippet}` or read `k.width` in a child |
| Color via `z` | Still works, but `c` is now the dedicated color dimension |
| `getContext('canvas')` store | `getContext('canvas').ctx` getter object (same for `'gl'`) |

# 10.0.3

> 2026-07-11

Upgrade deps and GH actions. Fixes to docs and type annotations.

- [PR#413](https://github.com/mhkeller/layercake/pull/413)
- [PR#414](https://github.com/mhkeller/layercake/pull/414)

# 10.0.2

> 2025-09-23

- Removes the npm version constraint from package.json because it was causing issues and is not really needed
- [PR#345](https://github.com/mhkeller/layercake/pull/345)

# 10.0.1

> 2025-08-24

- Updates the Svelte peer dependency to version 5 or greater. This should have been included with `v9.0.0` so putting it in now as a patch release. Users needing Svelte 3 (probably no one) or Svelte 4 (very few) support should use version 8.4.4.
- [PR#332](https://github.com/mhkeller/layercake/pull/332)

# 10.0.0

> 2025-08-18
Expand All @@ -14,20 +95,20 @@
- Converts most of the codebase to Svelte 5's runes and incorporates some longstanding pending breaking changes.

**Breaking changes**
- The `title` prop on `Svg` and `ScaledSvg` layout components is renamed to `titleText` to avoid conflicting with the `title` snippet namespace. https://github.com/mhkeller/layercake/pull/271
- The `title` snippet for those components now creates the outer `<title>` tag for you. Previously, the slot was blank and you had to write your own `<title>` wrapper. https://github.com/mhkeller/layercake/pull/271
- The `fallback` slot on `Canvas` and `Webgl` layout components was removed. The `fallback` text prop is sufficient. https://github.com/mhkeller/layercake/pull/271
- The `extents` prop is deprecated https://github.com/mhkeller/layercake/pull/243
- Domains for ordinal scales are no longer sorted by default https://github.com/mhkeller/layercake/pull/241

- The `title` prop on `Svg` and `ScaledSvg` layout components is renamed to `titleText` to avoid conflicting with the `title` snippet namespace. https://github.com/mhkeller/layercake/pull/271
- The `title` snippet for those components now creates the outer `<title>` tag for you. Previously, the slot was blank and you had to write your own `<title>` wrapper. https://github.com/mhkeller/layercake/pull/271
- The `fallback` slot on `Canvas` and `Webgl` layout components was removed. The `fallback` text prop is sufficient. https://github.com/mhkeller/layercake/pull/271
- The `extents` prop is deprecated https://github.com/mhkeller/layercake/pull/243
- Domains for ordinal scales are no longer sorted by default https://github.com/mhkeller/layercake/pull/241

# 8.4.4

> 2025-07-24

* Remove `$:` from context setting.
- Remove `$:` from context setting.
- [PR#302](https://github.com/mhkeller/layercake/pull/302)


# 8.4.3

> 2025-03-20
Expand Down
Loading