Skip to content

Getting started

d3’s generators (d3-geo’s geoPath, d3-shape, d3-hierarchy links) don’t draw; they emit path commands to a context. d3gl implements that same context across SVG / Canvas2D / WebGL2, so any context-driven d3 generator can render on the GPU unchanged. Geometry is projected & tessellated once; pan/zoom is one transform-matrix uniform and recolor/show-hide is one texture write.

Terminal window
npm i @mapequation/d3gl
# React components also need: npm i react react-dom (optional peer deps)

@mapequation/d3gl is one package with subpath exports; the root entry is core.

  • core (root)Scene, PathContext, tessellation, stroke expansion, hit-testing
  • /canvas — Canvas2D backend
  • /webgl — luma.gl v9 WebGL2 backend (palette-texture color, GPU picking, PNG export)
  • /svg — SVG backend + vector export
  • /geo — projection + GeoJSON project-once helpers, inverse projection
  • /labels — HTML label overlay with culling
  • /mapgeoMap + plot engines with d3-zoom wiring
  • /react — headless MapController + <D3GL> component
import { plot } from "@mapequation/d3gl/map";
import { line } from "d3-shape";
const points: [number, number][] = [[0, 0], [100, 80], [200, 40], [320, 160], [440, 90]];
const chart = plot(document.querySelector("#chart")!, { width: 640, height: 400, backend: "webgl" });
const gen = line<[number, number]>().x((d) => d[0]).y((d) => d[1]);
chart.layer("series", [points], { draw: (ctx, d) => { gen.context(ctx); gen(d); }, stroke: "#1a73e8", lineWidth: 1.5 });
chart.enableZoom();

Generators that emit coordinates around the origin (radial trees, chords) place with the canonical canvas idiom — call ctx.translate(cx, cy) once, then run the generator unchanged:

chart.layer("links", links, { draw: (ctx, l) => { ctx.translate(cx, cy); gen.context(ctx); gen(l); } });

translate is the one transform in the context (no rotate/scale/save/restore); it accumulates like Canvas2D and applies only within that drawable’s draw callback.

Every engine renders through a backend — "webgl" (default), "canvas", "svg", or "auto" (instant canvas first paint, then a transparent upgrade to WebGL). Pass it via the backend option, or switch at runtime with setBackend(...). See Rendering backends for how to choose and how auto works.

See the Examples for full, runnable demos, and the Reference for the API of each module.