Line charts
Render lines, steps, ranges, points, bars, and stacked areas at scale.
Framework quickstart
Render the same line chart six ways
Choose the imperative TypeScript API or a thin framework adapter. Every tab uses the same typed-array data and chart options.@sixtyfold/lineimport { LineChart } from "@sixtyfold/line";
const data = {
x: new Float64Array([0, 1, 2, 3]),
y: new Float64Array([3, 7, 4, 9]),
length: 4,
};
const canvas = document.querySelector<HTMLCanvasElement>("#chart")!;
const chart = new LineChart(canvas, {
renderMode: "auto",
axis: { bottom: { format: "time" } },
series: [{ name: "Signal", color: "#4ecca3" }],
});
await chart.initialize();
chart.setData(data);
window.addEventListener("pagehide", () => chart.destroy(), { once: true });@sixtyfold/line renders multiple series against one ordered X column. Series may independently use line, step, range, scatter, bar, or stacked-area geometry while sharing axes, interaction, and tooltips.
Exact configuration and method signatures live in the generated Line options, LineChart methods, and line data types reference.
Series geometry
SeriesOptions contains common name, color, width, unit, fill, and marker fields. Geometry-specific options live under band, point, bar, and stack so unrelated settings do not become ambiguous.
Range data
chart.setMultiSeriesData({
x,
series: [
{ low: temperatureMin, high: temperatureMax },
temperatureMean,
],
length: x.length,
seriesCount: 2,
});Use an explicit mean series when the true aggregate is not (low + high) / 2. Suppress the range center stroke with a zero series width and disable boundaries with band.borderWidth: 0 when the envelope alone conveys the intended information.
Level of detail (LOD)
LOD means level of detail. It lets the chart draw a screen-sized
representation of a much larger dataset, then reveal finer detail as you zoom.
The default adaptive policy preserves ordered endpoints, extrema, and real
NaN gaps. Most applications should keep the defaults.
The adaptive grid remains stable through animation and unrelated redraws. It changes only after continued zoom moves far enough beyond the current detail level.
const chart = new LineChart(canvas, {
lod: {
mode: "adaptive",
density: 0.75,
rebaseRatio: 1.25,
quantizationStep: 0.25,
},
});Tune rebaseRatio and quantizationStep together. For smoother changes, start near 1 + quantizationStep, such as 1.10–1.12 with 0.10. A visually sensitive multi-pass range band may benefit from 0.05 and 1.06–1.08; measure the cost on target browsers and device-pixel ratios.
Patch the policy without reconstructing the chart or rebuilding its hierarchy:
chart.setLODOptions({ density: 0.75, rebaseRatio: 1.12, quantizationStep: 0.1 });mode: "pyramid" selects among prebuilt global min/max levels. Stacked areas always use this path because independently reducing each input would change cumulative geometry.
Visibility and appearance
chart.setSeriesVisible(2, false);
chart.setVisibleSeries([0, 1]);
chart.updateSeriesAppearance(0, { color: "#ffe47a", width: 2 });
chart.setSeriesVisibilityCallback((event) => {
console.log(event.source, event.visibility);
});Visibility callbacks identify changes originating from initialization, the API, or an interactive legend. legend.allowHideAll controls whether the built-in legend can hide the final visible series.
Streaming
After initialize(), create a fixed-capacity stream with positive integer
dimensions:
chart.initStreaming(2, 1_000_000);
chart.addVector(timestamp, [phaseL1, phaseL2]);addVector requires a finite timestamp and one value per configured series.
It copies the scalar values before queuing them, so the caller can reuse that
array immediately. Keep timestamps ascending; use NaN for a missing Y value,
not for a timestamp.
Use addVectors(timestamps, valuesBySeries) for existing Float64Array
columns. Supply one column per configured series, each matching the timestamp
length, and finite timestamps. Validation finishes before queued
scalar samples are flushed or buffers are transferred. A validation failure
therefore leaves the queue unchanged and caller buffers attached.
Valid scalar and bulk appends retain their call order. The ring buffer
maintains chronological display after it wraps, and LOD construction can
complete while appends continue. Calling initStreaming again discards queued
samples from the old stream. Resetting streaming or replacing data also
cancels the old dataset's pending viewport animation.
Animated replacement
setData and setMultiSeriesData reveal new series from left to right when animation is enabled. preservePreviousFrame: true keeps the previous plot ahead of the new reveal boundary. Use it only after the preceding reveal has completed, and restore the viewport immediately when replacing a preview with its full dataset.