core
The backend-agnostic scene model: a retained Scene that records vector geometry through a PathContext, flattens curves, groups rings, tessellates fills, expands strokes, and packs everything into GPU-ready buffers with per-drawable color/flag side-tables. HitIndex provides CPU hit-testing over the same data.
import { Scene } from "@mapequation/d3gl";
const scene = new Scene(0.5);scene.group("shapes", (g) => g.drawable("a", (ctx) => { ctx.rect(0, 0, 10, 10); }));scene.setFill("shapes", "a", "#3366cc");const buffers = scene.buffers("shapes"); // GPU-ready typed arraysClasses
Section titled “Classes”| Class | Description |
|---|---|
| HitIndex | - |
| PathRecorder | Records PathContext drawing calls into flattened polylines (subpaths). This is the retained-mode capture used by GPU backends: call a d3 generator into a PathRecorder once, then hand the subpaths to the tessellator. |
| Scene | - |
Interfaces
Section titled “Interfaces”| Interface | Description |
|---|---|
| Backend | A renderer for a Scene, implemented per target (WebGL / Canvas / SVG). |
| DeclutterScratch | Reusable grid scratch so a per-frame caller (geo declutter runs on every zoom) allocates nothing. |
| DrawableOpts | - |
| DrawableRange | Contiguous slice a drawable occupies within a group’s shared buffers. |
| DrawableVector | - |
| DrawBatch | Generalized transient pass-through payload (built per repaint, discarded). |
| FillGeometry | - |
| GroupBufferDelta | Buffers for an appended TAIL of a group (see Scene.appendedBuffers). Same arrays as GroupBuffers but each holds only the newly-appended data; index values are group-absolute. drawableCount is the total after the append, fromDrawable the index where the new range begins. Point count = pointCenters/4. |
| GroupBuffers | GPU-ready typed arrays for one group. Vertices are [x, y, drawableId]. |
| GroupBuilder | - |
| HalfLinkGeometry | The resolved anchor + control points of a half-arrow link (the vertices its outline visits). |
| HalfLinkParams | Inputs for one directed half-arrow link (world coordinates/units). |
| InstancedArrowsData | SoA for a batch of instanced triangle arrowheads (directed-link tips). |
| InstancedCirclesData | SoA for a batch of instanced circles (e.g. network nodes). Plain typed arrays. |
| InstancedHalfArrowsData | SoA for a batch of instanced half-arrow links (#104 N6) — the “map of networks” directed-link glyph: one filled shape per link, pinched to the source centre and ending in a barbed arrowhead on the target boundary, bowed around a shared centre curve (see network/half-link.ts). All world units. |
| InstancedHighlight | Shader-driven highlight state for an instanced layer (#162). Passed to Backend.styleInstancedLayer, it maps to vertex-shader uniforms so hover/selection restyle costs no geometry rebuild: - hoverGroup — the hovered node’s group id (matched against each instance’s groups); -1 = none. - dimActive / dimOpacity — fade every non-highlighted instance’s alpha by dimOpacity when active. - recolor — RGB (0..1) a highlighted instance is tinted toward, preserving luminance (so a weight- encoded link keeps its weight); null/absent ⇒ highlighted instances keep their colour (e.g. nodes). - selected — optional per-instance flag buffer (0/1) to upload in place (a selection change), instead of re-emitting the layer. Length must equal the layer’s instance count. |
| InstancedLinesData | SoA for a batch of instanced lines (e.g. network links); straight, or bent via bends. |
| InstancedPieData | SoA for a batch of instanced pie wedges (#171) — the physical-view glyph for a state network’s overlapping module membership. One instance per wedge (not per pie): a wedge is an angular [startFrac, endFrac] sector of a disc, so a physical node spanning w modules contributes w wedge instances sharing a centre/radius. Reuses the circle’s quad+SDF-disc positioning; the fragment discards outside the disc and outside the wedge’s angular range, so there is no per-fragment loop and no wedge texture — it draws in one instanced call and updates in place like InstancedCirclesData. (Single-module physical nodes stay on the InstancedCirclesData lane as solid discs.) |
| PassThroughLayer | Identifies a pass-through layer to a backend (no retained geometry). |
| PathContext | PathContext is the seam of d3gl: the subset of CanvasRenderingContext2D’s path API that d3 path-emitting generators (d3-geo geoPath, d3-shape, d3-chord, d3-hierarchy links) actually call. Implement this once per backend and any of those generators can render to that backend unchanged. |
| PathSink | A minimal 2-D path sink (matches the subset of CanvasRenderingContext2D / d3gl’s PathContext we use). |
| PointBatch | Transient, GPU/Canvas-ready point data. Owned by no one — built per repaint and discarded. |
| ProjectedPath | One projected path feature, ready to draw. Canvas draws natively; WebGL tessellates per frame. |
| RenderDelta | An incremental append for one layer: only the drawables added at/after buffers.fromDrawable. buffers are the delta GPU buffers (for WebGL), drawables the matching new vector views (for Canvas/SVG draw-on-top). Index values in buffers are group-absolute, so a backend whose buffers mirror the group appends verbatim. clipTo/sizeMode mirror the layer’s current settings. |
| RenderLayer | One named layer handed to a backend: GPU buffers + the vector view + optional clip. |
| RingGroup | One filled polygon: an outer ring plus zero or more hole rings. |
| StrokeGeometry | - |
| StrokeOptions | - |
| StyleTables | Just the per-drawable style tables (colors + flags), for styles-only backend updates — never the O(total-vertices) Scene.buffers rebuild: geometry hasn’t changed, only how it’s painted. LIVE views of the Scene’s typed storage (#207) — zero copies/allocation per call; see Scene.styleTables. |
| Subpath | A flattened subpath: a polyline plus whether it was closed. |
| TextData | One backend-rendered text label (#105 N7b-2). Positioned in screen pixels (the caller projects the world anchor and applies the view transform) and drawn at a constant pixel font, so labels stay readable at any zoom — re-pushed each setTransform, like the HTML overlay it mirrors. Drawn live by the SVG (<text>) and Canvas (fillText) backends; the WebGL backend keeps the HTML overlay on screen (GPU/MSDF text is #69) but retains the set for export (#219), so labels survive toSVG()/toPNG() on all three backends. |
| VectorLayer | A named layer’s vector view — everything a CPU rasterizer or serializer needs, with no GPU buffers. RenderLayer is this plus the buffers; the export-only stash a backend keeps for toSVG() (Backend.setExportLayers, #200) is this alone, since instanced-lane content is never uploaded as Scene geometry. |
| ViewTransform | View transform applied on top of project-once geometry: scale k, translate (x, y). |
Type Aliases
Section titled “Type Aliases”| Type Alias | Description |
|---|---|
| DrawItem | What a PassThroughSpec yields per datum (generalizes the point-only project()). |
| InstancedLayer | A named GPU-instanced primitive layer — the network rendering lane (#100). |
| LineCap | Open-subpath end-cap style. |
| LineJoin | Stroke join style. |
Variables
Section titled “Variables”| Variable | Description |
|---|---|
| DEFAULT_CURVE_TOLERANCE | Default flattening tolerance, in world units — the max deviation between a curve and the polyline it is baked to. Every curve is baked ONCE, at build time, and the view transform only scales the result, so a facet of t world units is t·k screen px at zoom k (#45). Engines expose this as curveTolerance; set it to 0.25 / kMax for a chart that needs sub-pixel curves at zoom kMax. |
| DEFAULT_MITER_LIMIT | Defaults match the Canvas 2D defaults and are pinned identically on Canvas/SVG so the three backends agree. (SVG’s own default miter limit is 4, so it must be set explicitly.) |
| version | The d3gl package version, injected at build time from package.json. |
Functions
Section titled “Functions”| Function | Description |
|---|---|
| arrowsToDrawables | Instanced arrowheads → one filled triangle per arrow, tip set back to the target node’s boundary. bake mirrors the Scene twin’s screen-sizeMode trick: solve in pixel space (×k) and emit ÷k, so the world-coordinate output reproduces the constant-pixel GPU render under the view’s ×k transform. |
| bentEndTangent | Unit end-tangent of a bent link at the target — matches the arrow shader’s bezier t=1 tangent. |
| bezierControl | Quadratic-bezier control point for a bent link: chord midpoint offset ⟂ by bend· |
| circlesToDrawables | Instanced circles → one drawable per instance. |
| declutterMembers | Enumerate the glyphs a kept survivor represents from a declutterScreen winners array: every glyph mapped to kept (including kept itself, which maps to itself). O(count) inverse scan — run lazily on a hit (members()), never per frame. Returns indices in source order. |
| declutterScratch | A fresh, empty scratch (grown lazily on first use). Hold one per engine and pass it in to reuse it. |
| declutterScreen | Greedy screen-space declutter. Visits glyphs in order (importance descending; omitted ⇒ index order) and keeps each unless its centre is within spacing·(rᵢ + rⱼ) of an already-kept glyph — so the drawn circles don’t overlap and the most important glyph in a cluster survives. A glyph whose centre is off-screen is always kept and never occludes others (so panning never culls what’s barely out of view). O(n) via a uniform grid sized to the largest exclusion radius, so any overlapping pair falls in the 3×3 cell neighbourhood. |
| expandStroke | Expand a polyline into fill triangles for a stroke of the given width. |
| flattenArc | Circular arc, matching CanvasRenderingContext2D.arc semantics. |
| flattenArcTo | Tangent arc, matching CanvasRenderingContext2D.arcTo(x1, y1, x2, y2, radius) — the rounded-corner primitive (rounded rects/bars, CSS-style shapes). (x0, y0) is the current point; (x1, y1) the corner; (x2, y2) the point the outgoing segment heads towards. The arc is tangent to BOTH half-infinite lines (x1,y1)→(x0,y0) and (x1,y1)→(x2,y2), so the tangent points may lie beyond (x0,y0)/(x2,y2) — that is the spec, not a bug. |
| flattenCubic | Cubic bezier from (x0,y0) to (x3,y3) with control points (x1,y1),(x2,y2). |
| flattenQuadratic | Quadratic bezier: elevate to cubic and reuse the cubic flattener. |
| groupRings | Group a flat list of closed rings into filled polygons with holes, at ARBITRARY nesting depth (issue #73 — an island in a lake in land, and deeper). |
| halfArrowsToDrawables | Instanced half-arrows → one filled “map of networks” link shape per instance, via the shared halfLinkGeometry reference path. Same bake trick as arrowsToDrawables. |
| halfLinkGeometry | Resolve the half-arrow link’s outline vertices, or null when the link should be skipped (the nodes overlap and the bend is too small to route around them — matches the reference’s guard). |
| halfLinkPathString | The reference SVG path string for a half-arrow link (or "" when skipped) — same command sequence and number formatting as mapequation’s network-rendering, so it is golden-tested against its example.svg. |
| instancedVectorLayers | One emit of the instanced lanes → the export-only vector layers a serializer can draw (#200). |
| linesToDrawables | Instanced lines → one stroked path per line (straight, or a quadratic bow for bends). World endpoints with a per-line width, so screen sizeMode needs no bake (the width alone is in px). |
| pieToDrawables | Instanced pie wedges → one filled arc sector per wedge. Screen sizeMode pins the sector at a constant pixel size around its (projected) centre via the drawable anchor, as tracePieWedges does. |
| pointInRing | Ray-casting point-in-polygon test against a ring (interleaved x,y). |
| scaleHalfLink | Uniformly scale a resolved half-arrow geometry’s coordinates by s (about the origin). Used to “bake” a screen-space shape for the retained SVG/Canvas path: the shape is solved in pixel space (node centres × k, sizes in px) — because the tip length (width^⅓), tip width (width^½) and outer bend (^0.4) are not linear in size, so they can’t be reproduced by pre-dividing the sizes — and the result is scaled by 1/k, so the Scene’s ×k view transform reproduces the exact pixel shape. |
| signedArea | Shoelace signed area of a ring (interleaved x,y). Positive for counter-clockwise winding, negative for clockwise. Magnitude is the area. |
| straightUnit | Unit chord direction source→target (1,0 if degenerate). Used by the Scene/SVG arrow emitters. |
| tessellateFill | Triangulate filled (closed) subpaths into triangles via earcut. |
| traceHalfLink | Trace a resolved half-arrow link onto a PathSink (Canvas/SVG export), as the reference does: inner-start → source centre → foot → outer edge (quadratic via cp2) → barb → tip → inner base → inner edge (quadratic via cp1) → close. |