Line chart
Sand scatters within a ribbon along each series, then resolves into a solid line —
straight or a smooth Catmull-Rom spline — with an optional area fill. The config surface mirrors
the bar chart; a line block replaces the bar's border.
axes,
legend (including click-to-isolate), currentValue, fps,
interaction.hover and interaction.dim interfaces as the bar chart. This
page documents only what differs; see the bar chart for those
shared blocks.
Constructor
new LineChart(host: HTMLElement, config: LineChartConfig)
Mounts a canvas into host and boots the best backend (WebGPU → Canvas2D). Only
data is required.
Config — top level
Identical to the bar chart except for lineThickness (new) and line
(replaces bars).
| Property | Type | Default | Description |
|---|---|---|---|
data required | DataSet | — | Points to render. See Data model. |
lineThickness | number | 0.03 | New for line charts. Ribbon thickness the sand scatters within, in layout units. |
grainDensity | number | 0.6 | Grains per unit area of the line ribbon. |
maxGrains | number | 100000 | Hard grain ceiling. Grains scale with the line's ribbon area (path length × thickness), not the point count, and never exceed this — so grain cost stays bounded even at thousands of points. |
colors | string[] | DEFAULT_PALETTE | Series colors (CSS), cycled per series. |
background | string | transparent | Canvas clear color. |
grain | object | — | Grain appearance. See below. |
animation | object | — | Timing. See below. |
interaction | object | — | Hover + legend-dim tuning. Same as bar chart. |
axes | { x?, y? } | off | Same as bar chart. |
legend | LegendConfig | off | Same as bar chart, including click-to-isolate (interactive). |
currentValue | object | off | Same as bar chart. |
line | LineStyleConfig | off | Solid line + area fill. See below. |
fps | FpsConfig | off | Same as bar chart. |
panZoom | PanZoomConfig | off | Drag to pan, wheel/UI to zoom. Shared pan & zoom. |
backend | 'auto' | 'webgpu' | 'webgl2' | 'canvas2d' | 'auto' | Force a rendering backend. |
grain
Identical to the bar chart: sizePx (3), shape ('disc'),
jitter (0.6), settleJitter (0.004). See
bar chart → grain.
animation
duration, stagger and
morphDuration are in milliseconds.Same as the bar chart, with two line-specific twists in the enum values:
| Property | Type | Default | Description |
|---|---|---|---|
duration | number (ms) | 900 | Per-grain travel time. |
stagger | number (ms) | 500 | Spread of pour start times. |
ease | 'linear' | 'easeOutCubic' | 'easeOutQuint' | 'easeOutCubic' | Grain travel easing. |
morphDuration | number (ms) | duration + stagger | Transition window for live changes (line tween + grain fade). |
reflow | 'translate' | 'reshuffle' | 'withLine' | 'translate' | How grains of an unchanged part of the line move. withLine (vs. the bar's withBar) locks them rigidly to the line — no delay, no fade flash. |
morphGrains | boolean | true | Animate the sand during an update/add/remove morph. false snaps every grain straight to its new position (added grains just appear, removed just vanish) so only the solid line tweens on a data change. Ignored for the initial pour-in. |
enter | 'pour' | 'rise' | 'continue' | 'pour' | How an added point's grains appear. continue (line-only) skips the emergence entirely — the vertex appears settled and the line just extends to it. Best for continuous streaming. |
exit | 'fall' | 'vanish' | 'fall' | How a removed point's grains leave. |
line — solid line + area fill LineStyleConfig
The line-chart analogue of the bar chart's fill + border. Off by default; a config without
line renders as pure sand. Line and fill always use the series color.
| Property | Type | Default | Description |
|---|---|---|---|
stack | boolean | false | Stack the series into a stacked area chart: each series sits on the cumulative total of the series below it (at every x), and the value axis spans the stack total. Best paired with a visible fill. Stacked bands use straight edges so they tile gap-free (spline is applied only to un-stacked areas). |
line.line — the connecting line
| Property | Type | Default | Description |
|---|---|---|---|
style | 'none' | 'straight' | 'spline' | 'straight'* | none = sand only, no line; straight = segments between points; spline = smooth Catmull-Rom curve. *Default when a line block is present. |
width | number | 1 | Stroke width in CSS px. |
opacity | number (0..1) | 1 | Stroke opacity. |
line.fill — area under the line
| Property | Type | Default | Description |
|---|---|---|---|
opacity | number (0..1) | 1 | Area fill opacity. Omit the fill block for no area. |
line.reveal — particle→line crossfade
| Property | Type | Default | Description |
|---|---|---|---|
start | 'afterPour' | number | 'afterPour' | When the fade begins. A number = absolute seconds from start. |
duration | number (ms) | 500 | Fade window length. |
ease | Easing | 'easeOutCubic' | Fade easing. |
grainsTo | number (0..1) | 0 | Grain end-opacity after the fade. |
Shared blocks
axes, legend, currentValue, fps,
interaction.hover and interaction.dim are the same interfaces the bar chart
uses — including currentValue's cursor-line (guide: horizontal / vertical /
crosshair), axis value markers, the mode: 'axis' (On axes)
readout, and legend.interactive click-to-isolate. Full property tables:
axes ·
legend ·
currentValue ·
fps ·
interaction.hover / interaction.dim.
Methods
Same surface as the bar chart: whenReady(), get backend,
on('hover', fn), on('seriesFocus', fn), focusSeries(index),
getFocusedSeries(), update(data | patches), add(points),
remove(refs), repour(), getData(), dispose().
See bar chart → Methods.
It also implements the shared PanZoomable
interface: getView(), setView(v), panBy(),
panTo(), zoomBy(), zoomTo(), resetView(),
isPanZoomEnabled().
Events
The hover event carries { point: LineMeta | null } — note it's
point (a line vertex), where the bar chart uses bar.
// LineMeta — metadata for one line vertex (data point)
{
pointId: number;
seriesIndex: number;
seriesKey: Scalar | undefined;
xValue: Scalar;
yValue: number;
pos: number; // layout-space x center [0,1]
height: number; // layout-space y (top of the band when stacked)
baseHeight: number; // layout-space y of the stack floor (0 when un-stacked)
color: RGBA;
}
seriesFocus carries { index: number | null } — same shape as the bar chart's.
See bar chart → Events.
Examples
Spline line with area fill
new LineChart(el, {
data,
lineThickness: 0.04,
line: {
line: { style: 'spline', width: 2 },
fill: { opacity: 0.18 },
reveal: { duration: 700, grainsTo: 0.1 },
},
axes: { x: { show: true }, y: { show: true, gridLines: true } },
});
Stacked area chart
new LineChart(el, {
data,
line: {
stack: true, // each series stacks on the ones below
fill: { opacity: 0.6 },
line: { style: 'straight', width: 1.5 },
},
axes: { x: { show: true }, y: { show: true } },
});
Line-only transition (grains don't move on a data change)
new LineChart(el, {
data,
line: { line: { style: 'spline' }, fill: { opacity: 0.15 } },
animation: { morphGrains: false }, // update/add/remove: only the line tweens
});
Crosshair cursor with values on the axes
new LineChart(el, {
data,
axes: { x: { show: true }, y: { show: true } },
currentValue: { show: true, mode: 'axis', guide: 'both' },
});
Streaming: append points that just extend the line
const chart = new LineChart(el, {
data,
line: { line: { style: 'straight' } },
animation: { enter: 'continue' }, // no pour — vertex appears settled
});
setInterval(() => {
chart.add({ x: Date.now(), y: nextSample() });
}, 1000);
Sand only (no resolved line)
new LineChart(el, {
data,
line: { line: { style: 'none' } }, // grains never resolve into a stroke
});
Hover
chart.on('hover', ({ point }) => {
if (point) label.textContent = `${point.xValue} → ${point.yValue}`;
});
Series dimming — click a legend entry to isolate it
new LineChart(el, {
data,
legend: { show: true, interactive: true },
interaction: { dim: { opacity: 0.15 } },
});
© 2026 · License · Data model →