LayerCake Svelte Graphics Framework
LayerCake is a lightweight, opinionated graphics framework designed for building highly customizable and reusable data visualizations with Svelte. It emphasizes a clear separation between the data layering, scaling, and rendering logic, allowing developers to bring their own Svelte components for charts and annotations. The current stable version is 10.0.2, with major versions released somewhat frequently to align with Svelte's evolution (e.g., Svelte 5 'Runes' support in v9/v10). Key differentiators include its Svelte-native component approach, making it highly composable and performant within a Svelte application, and its flexibility in rendering to SVG, HTML, or Canvas elements without dictating visual styles.
Common errors
-
Error: 'Component' is not a constructor (when importing LayerCake components in a Svelte 3/4 project with LayerCake v9+)
cause Attempting to use LayerCake v9.0.0 or higher with Svelte 3 or Svelte 4. LayerCake v9+ uses Svelte 5 Runes, which are incompatible with older Svelte versions.fixDowngrade LayerCake to `8.4.4` to maintain compatibility with Svelte 3/4: `npm install layercake@8.4.4`. -
TypeError: Cannot read properties of undefined (reading 'xScale') in a custom chart component.
cause A custom chart component is trying to access `xScale` from LayerCake's context, but it's not being provided, likely due to incorrect placement or missing `let:` slot prop definitions.fixEnsure your custom component is nested within a LayerCake layout component (`<Svg>`, `<Html>`, `<Canvas>`) and that you are correctly receiving context values via `getContext` or using `let:xScale` on the slot if it's exposed that way, as shown in the LayerCake examples. -
SyntaxError: Unexpected token 'export' (when trying to `require('layercake')` in a CommonJS environment)cause LayerCake is published as an ESM-first package, and directly `require()`ing it in a pure CommonJS environment might fail without proper transpilation or configuration.fixPrefer ESM `import { ... } from 'layercake';` syntax. If you are forced to use CommonJS, ensure your build setup correctly handles ESM imports (e.g., Babel or Webpack configured with `esm` support or consider dynamic `import('layercake')`).
Warnings
- breaking LayerCake v10.0.0 removed the `innerElement` binding from the `Svg` component. If you were relying on this binding, your code will break.
- breaking LayerCake v9.0.0 introduced breaking changes related to sorting domains and updated layout components to use Svelte 5 'Runes' syntax. This may require updates to custom layout components and how domains are handled.
- breaking LayerCake v8.0.0 changed default behavior for ordinal domains, sorting them by default. This was later made optional in v8.1.0.
- gotcha LayerCake versions 9.0.0 and above are primarily designed for Svelte 5 and utilize Svelte's 'Runes' syntax. Earlier versions (up to 8.4.4) are compatible with Svelte 3 and Svelte 4.
- gotcha LayerCake relies heavily on Svelte's context API and slot props for component composition. Understanding these Svelte features is crucial for effective use.
Install
-
npm install layercake -
yarn add layercake -
pnpm add layercake
Imports
- LayerCake
import LayerCake from 'layercake';
import { LayerCake } from 'layercake'; - Svg
const Svg = require('layercake').Svg;import { Svg } from 'layercake'; - Html
import { HtmlComponent } from 'layercake';import { Html } from 'layercake';
Quickstart
<script lang="ts">
import { LayerCake, Svg, Html, Canvas } from 'layercake';
import AxisX from './components/AxisX.svelte';
import AxisY from './components/AxisY.svelte';
import Line from './components/Line.svelte';
import Scatter from './components/Scatter.svelte';
import Labels from './components/Labels.svelte';
const data = [
{ x: 0, y: 1, label: 'Point A' },
{ x: 1, y: 2, label: 'Point B' },
{ x: 2, y: 3, label: 'Point C' }
];
// Example of how you might pass context values as slot props
// If you define 'x' and 'y' props on LayerCake, these will be available
// to descendant components via context or slot props.
function getX(d: typeof data[0]) { return d.x; }
function getY(d: typeof data[0]) { return d.y; }
</script>
<style>
.chart-container {
width: 100%;
max-width: 800px;
height: 500px;
border: 1px solid #eee;
margin: 20px auto;
}
</style>
<div class="chart-container">
<LayerCake
x={getX}
y={getY}
{data}
>
<Svg let:x let:y let:width let:height>
<!-- Svg provides scales and dimensions via slot props -->
<AxisX/>
<AxisY/>
<Line color='#f0c'/>
</Svg>
<Canvas let:xScale let:yScale let:data>
<!-- Canvas components draw to a canvas element -->
<Scatter color='#0fc'/>
</Canvas>
<Html>
<!-- Html components render standard HTML elements -->
<Labels/>
</Html>
</LayerCake>
</div>