Skip to content

Foldkit Viz: visx parity and chart excellence

Date: 2026-10-05. Local source baseline: e28304a, managed promo worktree, branch codex/foldkit-0-166-0.

This is a source-grounded assessment and proposed roadmap, not an implementation plan or release claim. The latest bar/cloud APIs are committed locally and documented as unreleased. Public npm and Pages availability must be verified separately.

Intended outcome and recommendation

A developer should be able to compose a trustworthy instrument for investigating a system, or an expressive visualisation that invites useful exploration, using the same pure geometry and explicit Foldkit state. First useful success: load caller-owned records, compare two views, inspect an exact observation and explain what is selected, missing or uncertain.

Pursue a shared foundation with two visual directions. Precision and delight should share data identities, scales, selection, measurement, accessibility and provenance. Presentation can vary substantially. Precision means that a visual claim is traceable and testable; delight means that a surprising interaction makes a pattern easier to discover or understand.

Observed: the repository has broad geometry, application-level chart examples, reusable Cartesian adapters, six live promo explorers and an eighteen-chart promo gallery. Inferred: interaction composition and qualification offer more immediate value than adding another broad batch of chart types. Unknown: customer demand, operating contexts, adoption and real-task performance. A competitor checklist does not establish those.

Assumed first contexts: engineering telemetry and analytical data exploration. These are design fixtures, not claims that a critical-system deployment has been validated. No commercial, regulatory or operational suitability claim follows from this roadmap.

Three routes considered:

RouteBenefitTradeoffRecommendation
Copy every visx example firstClear breadth and familiar demonstrationsRisks expanding the gallery faster than the shared APIs and evidenceUse as an inventory, not the delivery order
Build a shared interaction foundation and two reference experiencesReuse is visible; precision and expressiveness can be tested togetherFewer new thumbnails initiallyRecommended
Keep existing primitives and document app recipes onlyLowest package scope and migration costConsumers continue owning repeated plumbingRetain for specialised recipes until reusable demand is demonstrated

Evidence and interpretation

Compared the rendered visx gallery on 2026-10-05: 47 example links. Also inspected the public package inventory, tooltip API, annotation API and XYChart source. This is a gallery map plus selected capability comparison, not an exhaustive method-by-method audit of all visx packages.

Local evidence:

Status vocabulary:

  • Public: a corresponding exported primitive/adapter exists. This does not establish complete visx semantics or native acceptance.
  • Partial: public support covers only part of the behaviour.
  • App: an implementation exists in the demo/application; a reusable package contract is absent or narrower.
  • Build: no dedicated corresponding primitive/recipe was found in the audited source.
  • Promo Live means a dedicated explorer; Tile means a gallery rendering; Indirect means another explorer demonstrates the capability; Absent means no dedicated promo presentation.

Priorities are proposed: P1 composition and dependable inspection; P2 analytical breadth and expressive presentation; P3 specialised parity after a concrete use case. Do not infer a percentage parity score from unlike units.

Paths in the first column are visx gallery routes. Local paths in the evidence column are relative to packages/foldkit-viz/src/ unless prefixed web:; web: means apps/web/src/ui/.

#visx example / routeLocal evidence and capability statusPromo exposureRemaining work / priority
01Bars /barsPublic: chart/bars.ts, math/scale.tsLive: barsMaintain signed/sparse/orientation acceptance; P1
02Dots /dotsPublic: scatter geometry + point adapterLive: scatter; TileExpose dense point inspection recipe; P1
03Patterns /patternsPartial: foldkit/paint.ts dots and hatchLive: barsPattern sampler; line/image/custom patterns remain caller SVG; P2
04AreaClosed /areasPublic: shape/area.ts; web: area-chartTileLive baseline and missing-data controls; P2
05Treemap /treemapPublic: hierarchy treemap; web: treemap-chartTileDrill-down and label-budget recipe; P2
06Zoom /zoom-iPartial/Public math: math/zoom.ts; App gesture wiring in zoomable-line-chartAbsentControlled zoom/pan with actual local coordinates and touch tests; P1
07Stacked Areas /stacked-areasPublic: shape/stack.ts + shape/area.tsIndirect: streamgraph tileExplicit stacked-area recipe and common-baseline mode; P2
08Axes & scales /axisPublic: foldkit/axes.ts, math/scale.tsIndirect: live Cartesian explorersScale laboratory, time/log edge cases, collision policy; P1
09Chord /chordPublic: shape/chord.ts; web: chord-chartTileLive matrix editing and retained relation inspection; P2
10Streamgraph /streamgraphPublic: stack + area; web: streamgraph-chartTileOffset/order controls and exact values; P2
11Legends /legendsPartial: categorical foldkit/accessibility.tsIndirect: line/scatter/barsContinuous and threshold legends; controlled visibility recipe; P1
12Curves /curvesPublic: shape/line.ts; web: curve-comparison-chartLive: line; Tile controlsDifferential audit of each supported curve; P1
13Area difference /thresholdBuild: threshold scale exists, but no crossing-aware difference-area helperAbsentSplit fills at curve crossings, including exact roots; P2
14Annotation /annotationPartial: foldkit/annotations.ts reference linesIndirect: lineCallouts, connectors, subject regions and placement policy; P1
15Radial Lines /lineradialPublic: shape/lineRadial.tsIndirect: radar tilePolar coordinate/curve recipe; P2
16Drag i /drag-iApp: drag/pan handling in zoomable-line-chart; no general drag moduleAbsentPure drag state + controlled Foldkit wiring; P1
17Bar Group /bargroupPublic: chart/bars.ts, grouped verticalLive: bars; TileCovered within documented scope
18Bar Group Horizontal /bargrouphorizontalPublic: chart/bars.ts, grouped horizontalLive: barsCovered within documented scope
19Pies & donuts /piesPublic: shape/pie.ts, shape/arc.ts; web: donut-chartTileLive sorting/padding/selection controls; P2
20Brush /brushPartial: math/brush.ts interval; interaction/selection.ts; web histogram-brush and linked-charts appsIndirect: dataset explorer selectionReusable interval and rectangle selection, handles and keyboard wiring; P1
21Bar Stack /barstackPublic: chart/bars.ts, signed vertical stackLive: barsCovered within documented scope
22Bar Stack Horizontal /barstackhorizontalPublic: chart/bars.ts, signed horizontal stackLive: bars; TileCovered within documented scope
23Delaunay Triangulation /delaunay-triangulationPublic: math/delaunay.ts; web: voronoi-chart uses triangulationAbsentDedicated triangulation tile and nearest-point recipe; P2
24Voronoi Overlay /delaunay-voronoiPublic: Voronoi cells and paths; App: voronoi-chartAbsentReusable nearest-hit inspection overlay and empty/duplicate tests; P1
25Dendrograms /dendrogramsPublic: hierarchy clusterLayout; web: radial-tree-chartAbsentAdd Cartesian/radial cluster recipe; P2
26Drag ii /drag-iiApp: related drag wiring, no multi-object drag contractAbsentKeyed draggable marks, bounds, cancellation and retained identity; P2
27XYChart /xychartPartial: Cartesian layout, series, axes, theme, legend, tooltip adaptersLive examples assembled explicitlyMulti-series registration/domain/inspection composition without hidden state; P1
28Custom Projection /geo-customPublic: callable Projection accepted by shape/geo.tsIndirect: map tileCustom projection recipe; geographic limitations remain; P3
29AlbersUsa /geo-albers-usaPartial: geoAlbersUsa; web: map-projections-chartAbsentCompare projection behaviour and inset geometry to reference fixtures; P3
30Mercator /geo-mercatorPartial: geoMercator; web projection/choropleth appsIndirect: map tileAntimeridian, rotation and resampling are separate missing capabilities; P3
31Glyphs /glyphsPublic: shape/symbol.ts; web: symbol-scatter-chartIndirect: live scatter symbolsGlyph sampler and hit-target recipe; P2
32Gradients /gradientsPublic: linear/radial foldkit/paint.tsLive: bars linearDedicated gradient sampler and radial use; P2
33Heatmaps /heatmapsPublic scales; App: heatmap-chart; tile renders cellsTile: rectangularRect/circle renderer recipe and quantitative colour legend; P2
34Link Types /linktypesPublic: shape/link.tsIndirect: hierarchy tilesLink sampler and explicit direction markers; P2
35Network /networkPublic: simulation and forces; App: force-graphAbsentSeeded network explorer, bounded simulation and node inspection; P2
36Pack /packPublic: hierarchy pack; web: packed-circles-chartTileDrill-down, group emphasis and measured labels; P2
37Polygons /polygonsPublic low-level path builder; standard SVG polygonAbsentRecipe sufficient unless reusable polygon operations are required; P3
38Radar /radarPublic radial line; App: radar-chartTileExplicit common scale, ordering and comparison limits; P2
39Radial Bars /radial-barsPublic arc geometry; App: wind-rose-chartAbsentDedicated radial-bar recipe; preserve area interpretation; P2
40Responsive /responsiveApp: shared promo measurement, ResizeObserver Mount streamsAll live explorers responsiveOptional reusable measurement adapter and hidden-container tests; P1
41Sankey /sankeyPublic: shape/sankey.ts; web: sankey-chartTileLive flow inspection, units and conservation diagnostics; P2
42SplitLinePath /splitlinepathBuild: line geometry exists; no dedicated styled segment helperAbsentSegment at meaningful boundaries without curve discontinuities; P2
43Stats Plots /statsplotPublic: math/stats.ts; App: box/violin renderersTilesReusable statistics geometry with explicit method/sample size; P2
44Text /textPartial: layout/text.ts measured wrappingIndirect: source/API onlyLabel layout, truncation, rotation, anchoring and fit recipe; P1
45Tooltip /tooltipPartial: SVG default and caller renderer in foldkit/annotations.tsLive: scatterMeasured bounds, flip/clamp policy and optional HTML overlay; P1
46Trees /treesPublic: hierarchy tree + links; App: tidy-tree-chartTileRetained tree navigation and collapsed-branch recipe; P2
47Wordcloud /wordcloudPartial: layout/wordcloud.ts, deterministic rectangle collisionsLive: wordcloudPixel-mask packing only if density is a demonstrated need; P3

Covered rows mean a corresponding composition exists, not that every prop, algorithm or interaction matches visx. No new chart should be added merely to move a row from absent to present.

IDGapExisting foundationConcrete exit criteria
F1Shared coordinate conversion and measurementApp measurement Commands/Mount streams; frame geometryCSS-scaled/nested SVG, viewBox offsets, scrolling, resize, initially hidden containers and teardown produce correct local coordinates; no view/update DOM mutation
F2Controlled interaction contractsSelection union, interval brush, zoom matricesInterval/rectangle/key selection, translate/resize handles, drag cancellation, touch/pointer and keyboard work with parent-owned state; selection stays meaningful across resize/filter/reordering
F3Inspection and tooltip placementProjected datum identity; custom SVG tooltipNearest datum and shared-X inspection are explicit policies; ties deterministic; transformed inputs accurate; measured tooltip stays inside declared bounds and exposes the same record through keyboard/data table
F4Composable multi-series viewFrame, series, grid, axes, themeLine/point/bar/area layers share declared domains and units; visibility and selection are controlled; data identity survives layer changes; no package-owned data loading or hidden registry state
F5Rich legends and annotationsCategorical legend and reference lineThreshold boundaries and continuous ramp labels match actual scale; anchored callouts avoid plot clipping; threshold and region meanings available without colour
F6Segment/difference geometryExisting line/area/curve primitivesReturned segments retain source references; crossings split correctly; equal runs, repeated X, missing observations and supported curves have reference fixtures; fill never connects across a declared gap
F7Text, paint and SVG utility recipesMeasured wrapping; four paint helpers; native SVGStable caller IDs; collision/truncation policy explicit; theme-safe text contrast; marker/clip recipes work across multiple charts; generic group/polygon wrappers only if they remove real friction
F8Deeper math parityVendored D3; existing geometry checksPer-algorithm reference fixtures, documented tolerance and failure domain; audit known RGB-basis interpolation and geographic omissions; no aggregate claim of D3 parity

Direct equivalents for React context, hooks or portals are not required. Preserve Foldkit composition through Model → view → Message → update → Model; browser effects stay in Commands/Mount/Subscriptions. Pure geometry remains independent of Foldkit, Effect and DOM. Optional render adapters consume the render-scoped HtmlBuilder. Data, keys, colours, units, fonts and themes stay caller-configurable.

Stretch goals: precision instruments

These are proposed capabilities beyond a gallery checklist. Acceptance means the stated evidence is obtained, not that the system is certified for any operational domain.

IDGoal and useful experienceFirst bounded deliverableAcceptance evidence
P1Truthful signal rendering. Distinguish missing, invalid, stale, estimated and observed data instead of drawing one confident lineExplicit quality metadata and gap-aware line/band recipeNull/non-finite values do not become zero; declared gaps are not interpolated; stale and estimated samples have non-colour cues; inspected raw values, units, timestamps and quality agree with table/export
P2Uncertainty as geometry. Show ranges and sample support beside an estimateInterval band and error-bar geometry with caller-supplied bounds and metadataInterval semantics labelled; inverted/invalid bounds rejected; low sample support shown; rescale/selection preserve bounds; no statistical inference manufactured by the renderer
P3Instrument-grade axes. Inspect small changes without losing unit or time contextUnit-aware formatting recipe, visible domain controls and pinned comparison baselineUnits/time zone explicit; repeated/irregular times, narrow domains, negative values and DST cases tested; formatting does not hide a decision-relevant difference; domain changes visible; no automatic misleading dual-axis comparison
P4Event correlation and replay. Freeze an incident and compare related signals at the same instantShared cursor, interval brush, event lane, pause/live indicator and deterministic app-owned replayFreeze stops the inspected snapshot changing; late/out-of-order data policy visible; selections survive replay; timestamps align across charts; refresh/cancellation failures and retained stale data are testable
P5Dense data without hiding the event. Overview and detail remain faithful when records outnumber pixelsViewport-aware line reduction with extrema preservation and declared aggregationProposed fixtures: 10k/100k/1m records; spikes, gaps and boundary samples preserved; inspector retrieves exact raw record; downsampling indicated; compare reference output and record memory/update timings on named hardware/browser
P6Reproducible evidence views. Hand a colleague the exact chart state and supporting dataSerializable app-owned view specification plus static SVG/PNG and raw-data export recipeDataset revision, filters, domains, units, selected keys, quality policy and theme recorded; replay gives equivalent semantic output; export includes title, legend, provenance and a full table; publication/release evidence remains separate

Proposed performance budgets for P5, to be confirmed on recorded reference devices: geometry/interaction computation p95 ≤16ms, complete visible update p95 ≤33ms, and a configurable default ceiling of 2,000 rendered marks. This ceiling applies to overview rendering, not discarded source records. Measure initial load separately. A missed budget changes representation or scope; it must not silently remove anomalies. GPU/Canvas is a later adapter decision backed by these measurements.

Stretch goals: expressive exploration

IDGoal and analytical purposeFirst bounded deliverableAcceptance evidence
J1A chart that unfolds. Turn an overview into aligned small multiples while retaining the selected observationOne dataset switches between aggregate, grouped and per-series panelsPosition/identity continuity explains the transition; units and raw values persist; interruption lands in a valid model; reduced motion performs the same operation immediately
J2Beautiful distribution anatomy. Reveal the observations underneath a summaryRaincloud composition: density + box summary + seeded jittered observationsSame source records drive all layers; sample size, bandwidth and quartile method explicit; jitter never changes encoded measurement; inspect an individual record and compare groups on a common scale
J3Flow with character. Dotted, hatched or gently moving flow traces explain direction and magnitudeSankey/stateflow styling recipe with an explicit direction layer and selected pathMovement encodes declared direction only; widths encode quantities; conservation issues visible; selected edges are legible in both themes and static export; motion can stop without losing meaning
J4Unexpected but readable time. Discover cycles without concealing the exact sequenceCalendar/spiral comparison with an aligned linear referencePeriod and projection labelled; gaps/overlaps visible; exact timestamps inspectable; switching forms retains selection; a linear view remains available for precise comparison
J5Typography that earns its space. Labels and direct annotations form part of the compositionMeasured label allocator with priority, collision and truncation policiesNo unexpected overlap/clipping across target widths, fonts and long labels; rejected labels explicitly available through inspection/table; layout deterministic after font measurement
J6A personal visual voice. Change colour, ink, texture and rhythm while keeping the chart honestTheme recipes: daylight scientific, dark instrument, vivid editorial and quiet printFour recipes use the same data/geometry; labels and meaningful boundaries meet declared contrast targets; colour is reinforced by shape/pattern; fonts and SVG IDs configurable; print and reduced-motion forms retain the claim

Originality is a hypothesis about comprehension and satisfaction. Each expressive recipe must answer a real question before adding ornament. Avoid decorative motion that suggests data changes, overshoot that implies false values, and a novel projection that makes a required comparison harder.

Two reference experiences

Signal desk: an incident investigation instrument

Use synthetic, explicitly labelled system telemetry with timestamp, signal, value, unit, quality, source revision and optional caller-supplied interval. Compose an overview, a precise detail chart, an event lane and a record table. Brush a period, zoom into a spike, compare related signals, freeze a cursor and inspect provenance. Include empty/loading/stale/error fixtures and a late-arriving sample.

First slice: interval brush + zoom + linked cursor + table, using F1–F3. Subsequent precision work adds quality and uncertainty only after that composition is stable. Alarm thresholds are application inputs, never conclusions generated by Viz.

Foldout atlas: an expressive comparison explorer

Use illustrative community activity records with dates, groups and distributions. Unfold a compact overview into small multiples; change the view to a raincloud; follow one group through a flow view. Keep one selected record/group and the same units visible throughout. Use saturated colour, crisp rules, measured type and restrained patterned ink. Offer daylight/dark/print recipes.

First slice: J1 using existing bars and parent-owned selection. J2 adds a second analytical perspective. Novel time layouts and flow motion are optional later recipes, contingent on comprehension evidence.

Delivery sequence and decision gates

The cross-package roadmap remains docs/roadmap.md. This table proposes slices, not dates or approved implementation work. Keep each slice independently reviewable and separately released when appropriate.

SliceScopeResult worth reviewingGate / scope cut
M0 — baseline mapThis document, source pointers and current evidenceShared inventory with explicit status and gapsComplete as a planning artifact; refresh when code or upstream changes
M1 — controlled explorationF1–F3; one Signal desk route; reuse existing geometryBrush/zoom/shared inspection between two charts and tableNumeric and state tests, touch/keyboard/browser acceptance and an external consumer; cut rectangle handles before weakening interval selection or cancellation
M2 — trustworthy signalsP1–P3, F5; quality/uncertainty fixturesGaps, stale data, units and bounds remain explicit at every scaleAdversarial fixtures and exact-value inspection; no broad critical-system suitability claim
M3 — expressive compositionJ1–J2, J5–J6; develop only the F4 composition needed by the examplesFoldout and raincloud experiences with retained identityComprehension task, motion interruption, label layout and accessible fallback; cut novel forms that obscure comparison
M4 — scale and reproducibilityP4–P6; measured F8 work required by these casesReplayed/exported incident with a faithful dense overviewDevice-labelled performance and semantic export fixtures; choose alternative rendering only when measurements justify it
M5 — specialised depthF6, geographic omissions, cloud masks, advanced network/time recipesOne evidenced use case per capabilitySeparate algorithm/spec/qualification slice; no blanket visx clone

Proposed learning appetite: four focused engineering days for M1, including qualification and a comprehension check; this is a suggested cap, not an estimate or accepted budget. Allocate two days to coordinate/interaction contracts, one to the reference composition, and one to fixtures/native checks and task review. If the first two days show incompatible ownership contracts, reduce to one interval brush and shared cursor and document the remaining gap. Later slices require their own scope and budget decisions.

Proposed learning tasks with three representative developers/analysts, recruited only through separately authorised activity: identify a spike and its raw value, isolate its interval, distinguish missing from zero, compare a related signal, and explain the chosen view. Primary measure: unassisted correct task completion; baseline unknown. Proposed threshold: all three distinguish missing/zero and retrieve the exact record, and at least two complete the linked selection without guidance. Small qualitative results indicate friction, not population success rates or market demand. Incorrect interpretation caused by an expressive form blocks that form; repeated interaction confusion reshapes M1. Inconclusive results extend neither scope nor budget automatically. If representative participants are unavailable within the learning window, finish the technical evidence and record comprehension as untested; do not substitute engineering acceptance for that evidence.

Definition of chart excellence

Every accepted chart/recipe should carry a small evidence record:

  1. Analytical claim: what question it answers, quantities/units, scale/domain, aggregation and meaningful omissions.
  2. Geometry: finite output, declared invalid-input policy, supported boundary conditions and per-algorithm reference/property tests. Extreme magnitude, cancellation, degenerate domains, repeated keys and sparse data are deliberate fixtures.
  3. State: controlled keys and selection; stale async completions cannot replace current data; identity persists across sorting/filtering/resize; side effects occur only at runtime boundaries.
  4. Perception: measured label layout, explicit baseline, distinguishable series without colour alone, legible light/dark/print output, and no texture that masks a critical boundary.
  5. Interaction: local coordinates, keyboard and touch, focus retention, cancellation, stable inspection and observable recovery.
  6. Performance: recorded dataset, render density, device/browser and p50/p95 update/memory measurements. No performance claim from a thumbnail or unit test.
  7. Evidence: focused tests, external consumer, native browser checks, static export comparisons and any publication proof recorded separately. Native accessibility task acceptance is distinct from generated ARIA markup.

For proposed accessibility targets, use WCAG 2.2 contrast guidance: 4.5:1 for ordinary text, 3:1 for qualifying large text; use non-text contrast guidance for meaningful graphical objects. Meeting these targets alone does not establish overall accessibility conformance.

Deliberate deferrals

  • No rewrite of Foldkit into React-like context/hooks or a second state runtime.
  • No full React API compatibility or exact package-count target.
  • No automatic statistical conclusions, forecasting, alarm policy or domain certification.
  • No 3D, ambient sound, generative chart choice or GPU rewrite without a task that needs it.
  • No pixel-mask cloud or globe projection overhaul before a use case demonstrates the current limit.
  • No migration of every existing web chart in one release; qualify representative contracts first.

Next proposed action: specify M1 as a bounded interaction/composition project, with exact public contracts and regression fixtures. The roadmap does not authorise that implementation.

M1 implementation evidence — 2026-10-05

The local Signal desk qualification records pure coordinate/domain/nearest-record APIs, typed SVG Mount composition, parent-owned interval brush/pan/zoom/pin state and the native /examples/signals/ route.

F1 now has general affine conversion, scoped measurement/readiness and transformed/hidden SVG evidence. F2 has controlled interval selection, navigation/cancellation and keyboard/range alternatives. F3 has deterministic nearest-X inspection linked to exact readout/raw table, including pinned outside-view notices. These are bounded advances: native touch remains unperformed because the browser input capability rejects touch delivery; rectangle/key brushes, resize handles, pinch and measured HTML tooltip placement remain gaps. No complete F1–F3 parity or production-critical suitability is claimed.

Recommended next: specify M2 quality and uncertainty, beginning with explicit missing/invalid/stale data and caller-owned thresholds. Keep representative-user comprehension and native touch acceptance separate from engineering test success.

M2 implementation evidence — 2026-10-05

The M2 qualification record records pure run/band APIs, validated metric quality and source freshness, gap-aware clipped rendering and exact interval/support/reference disclosures. This advances partial P1, interval-band P2 and units/domain/reference portions of P3/F5. Automated qualification and one independent review/fix pass are complete; native Firefox mouse/keyboard and390/1280 light/dark observations are recorded. Held-pointer and hardware touch acceptance remain open. Error bars and a pinned comparison baseline remain gaps. No full parity, statistical inference or critical-system suitability is claimed.

Captured comparison follow-up — 2026-10-05

P2 now includes exported, packed-consumer-qualified error-bar segment geometry for both axes. P3 now includes independent native Foldkit baseline capture, exact current-minus-baseline differences and captured provenance. The Signal desk composes selected error bars and clipped baseline references without changing supplied bounds or full-data domains. See local qualification: 523 workspace tests pass, with post-review browser evidence for responsive themes, off-screen baseline, table/source and held Capture/Clear/Escape interactions. Independent capture loss, hardware touch and assistive-technology acceptance remain open. This advances those bounded portions, not full P2/P3 or visx parity.

Event-lane design follow-up — 2026-10-05

A approved written design addresses only the event-lane portion of P4: an optional caller feed with independent provenance, exact event selection, aligned guides and retained raw event evidence. It reuses existing geometry and keeps events outside measured values/domains. The implementation plan is executed locally with qualification evidence. Only the event-lane portion of P4 is delivered; replay/live transport, device and assistive-technology acceptance remain open. Next: direct accessibility and device acceptance of these interactions.