JSPM

  • Created
  • Published
  • Downloads 56
  • Score
    100M100P100Q63695F
  • License MIT

Real-time LOD time series rendering engine for the browser.

Package Exports

  • blazeplot
  • blazeplot/package.json

Readme

BlazePlot

npm version npm downloads license build

Fast WebGL2 plotting engine for the browser 🔥

GPU-native, zero DOM. Built on WebGL2 + regl. No Canvas2D, no SVG, no layout thrashing.

Installation

bun install blazeplot

Quick start

<canvas id="chart" style="width:100%;height:400px"></canvas>
import { Chart } from "blazeplot";

const canvas = document.getElementById("chart");
const chart = new Chart(canvas);

const series = chart.addSeries(
  { mode: "line", capacity: 1_000_000, downsample: "minmax" },
  { color: [0.3, 0.6, 1.0, 1.0] },
);

chart.setViewport({ xMin: 0, xMax: 1000, yMin: -2, yMax: 2 });
chart.start();

const xs = new Float64Array(256);
const ys = new Float32Array(256);
let t = 0;

function push() {
  for (let i = 0; i < 256; i++) {
    xs[i] = t++;
    ys[i] = Math.sin(t * 0.01) * 0.5 + Math.random() * 0.01;
  }
  series.append(xs, ys);
  requestAnimationFrame(push);
}
push();

Features

WebGL2 rendering GPU-accelerated from the ground up. No Canvas2D fallback, no DOM text nodes.
Flexible data model Streaming ring buffer or static arrays. Bring your own data shape.
LOD downsampling Min/max pyramid for efficient line rendering at any zoom level — sparse views show raw points, dense views show vertical segments.
Pan & zoom Pointer/touch pan and wheel zoom via Camera2D. Customizable viewport policies.
Grid lines Data-anchored grid rendered as WebGL line lists.
Multi-series Independent buffers, styles, and visibility per series.
Benchmark overlay Built-in fps, frame time, vertex count, draw calls.
ResizeObserver Automatic DPR-aware canvas sizing.

API

Chart

Signature Description
new Chart(canvas, options?) Create a chart from an HTML canvas element.
chart.addSeries(config, style?) Add a data series. Returns SeriesStore.
chart.removeSeries(series) Remove a previously added series.
chart.setViewport({ xMin, xMax, yMin, yMax }) Set the visible data range.
chart.resize(dpr?) Resize the canvas to match its CSS size × DPR.
chart.start() Start the render loop (rAF).
chart.stop() Stop the render loop.
chart.getFrameStats(target?) Copy per-frame benchmark counters into a reusable object.
chart.dispose() Dispose GPU resources, observers, and input handlers.

ChartOptions

Property Default Description
viewportPolicy? Custom pan/zoom/viewport behavior hooks.
grid? true Show grid lines.
gridStyle? { color: [0.22,0.30,0.44,0.45] } Grid line color and width.

ChartFrameStats

Field Description
fps Instantaneous render-loop FPS.
frameMs Milliseconds spent in render().
pointsRendered Number of vertices drawn this frame.
drawCalls Number of GPU draw calls this frame.
uploadBytes Bytes uploaded to GPU this frame.
renderMode "none" / "raw" / "minmax" / "mixed".

SeriesStore

Signature Description
series.append(xs, ys) Append typed arrays of X and Y values (streaming).
series.clear() Clear all data and reset.
series.setVisible(v) Toggle visibility.
series.visible Current visibility state.
series.length Number of samples buffered.

SeriesConfig

Property Description
mode "line" / "envelope" / "scatter" (envelope and scatter roadmap-only).
capacity Ring buffer capacity (samples).
downsample "minmax" (LOD for line rendering).

SeriesStyle

Property Default Description
color [0.3, 0.6, 1.0, 1.0] RGBA float color.
lineWidth 1 Line width in pixels.

ViewportPolicy

interface ViewportPolicy {
  beforePan?(camera: Camera2D, intent: PanIntent): PanIntent | null;
  beforeZoom?(camera: Camera2D, intent: ZoomIntent): ZoomIntent | null;
  beforeRender?(camera: Camera2D): void;
}

Lower-level primitives

Camera2D, RingBuffer, MinMaxPyramid, AxisController are exported for advanced use cases.

Architecture

src/
  core/          # Data model — series, datasets, LOD
  render/        # GPU abstraction + regl backend
  interaction/   # Camera, input, axis ticks
  ui/            # Orchestrator (Chart)

Development

bun install
bun run dev          # Vite dev server → preview/
bun run build        # Package build (JS + declarations)
bun run build:js     # JS-only build
bun test             # Tests
bun run typecheck    # TypeScript strict check

Package build

bun run build

Output:

dist/index.js        ES module
dist/index.d.ts      TypeScript declarations

Why WebGL2?

Canvas2D and SVG are CPU-bound — every point becomes a draw call or a DOM node. BlazePlot keeps data on the GPU, streams only visible vertices, and avoids DOM entirely. For dense line plots (millions of points), interactive scatter, or real-time streaming, the difference is orders of magnitude.