Download Latest Version Semiotic v3.5.2 source code.tar.gz (15.7 MB)
Email in envelope

Get an email when there's a new version of Semiotic

Home / v3.5.2
Name Modified Size InfoDownloads / Week
Parent folder
README.md 2026-05-12 9.7 kB
Semiotic v3.5.2 source code.tar.gz 2026-05-12 15.7 MB
Semiotic v3.5.2 source code.zip 2026-05-12 16.7 MB
Totals: 3 Items   32.5 MB 0

Added

  • useSeriesFeatures hookforecast + anomaly props are now first-class on AreaChart, Scatterplot, and ConnectedScatterplot (previously LineChart-only). Each consumer collapses from ~85 LOC of synthetic-key + lazy-load + state-management boilerplate to ~10 lines via the shared hook. series-features, forecast, and anomaly capability tags surface through chartSpecs.ts / ai/capabilities.json for agent discovery.
  • useEncodingDomain hook — generic [min, max] tracker over bounded data + push-mode values, extracted from BubbleChart's sizeBy logic. Scatterplot's sizeBy now picks up correctly-scaled radii in push mode (previously a latent bug that returned the raw sizeBy value as the pixel radius). String-field accessors hitting numeric-string values ("5", "12") coerce cleanly instead of leaking strings into downstream math.
  • useStreamStatus hook — user-facing observer for push-API charts. Wraps a ref, intercepts push/pushMany, and exposes a reactive status enum ("idle" | "active" | "stale") plus lastPushTime. Surfaced via semiotic/utils and semiotic/realtime. Wrap-once symbol guard prevents StrictMode double-wrap.
  • useXYLineStyle hook (Phase 2 step 5 of the HOC/Frame audit) — the line-side analogue of useXYPointStyle. LineChart, MultiAxisLineChart, and MinimapChart (both main + overview lines) all collapse to a single hook call covering the five-step recipe: base stroke width → color resolution → optional group-aware fill → mergeShapeStyle primitives overlay → wrapStyleWithSelection. A resolveStroke(d, group?) override absorbs MultiAxisLineChart's per-series colorMap; unset selection-hook / primitives args keep MinimapChart's main + overview paths intact (no-ops on the wraps preserve referential identity). LineChart's forecast/anomaly segment-aware wrap stays HOC-side as a post-pass over the hook's output — the lazy-load + state-management contract has no counterpart in the other two consumers. Net ~65 LOC removed across the three HOCs. 15 unit tests pin the recipe.
  • Bundle-size truth sourcescripts/sync-bundle-sizes.mjs reads package.json#exports, gzips each *.module.min.js, and upserts marker-block sections in README.md, CLAUDE.md, and ai/system-prompt.md (the synced .cursorrules / .windsurfrules / .github/copilot-instructions.md / .clinerules / docs/public/llms-full.txt follow from CLAUDE.md). check:bundle-sizes is wired into release:check, prepublishOnly, and the CI workflow alongside the other doc-correctness gates, so dependency bumps that nudge a bundle past its rounded KB boundary now fail CI when the docs haven't been regenerated. Drops the stale // 200 KB gzip hero comment in the README — the autogenerated table is the only source of truth.
  • radialGeometry helperssweepToAngles, valueToAngle, computeArcBoundingBox extracted from GaugeChart into a shared module, exposed via semiotic/utils. Custom radial-chart authors (XYCustomChart, bespoke layouts) no longer have to re-derive the gauge sweep math.
  • ProcessSankey temporal validatorsvalidateProcessSankey and formatProcessSankeyIssue exported from semiotic and semiotic/network. External code (data pipelines, AI agents, server-side validators) can pre-check graphs against the same value-conservation + endpoint-resolution rules the chart enforces.
  • regression prop on Scatterplot, BubbleChart, ConnectedScatterplot, BarChart, DotPlot — sugar over the trend annotation. Accepts true | method string ("linear" | "polynomial" | "loess") | full RegressionConfig. Ordinal charts treat categories as integer indices and project the regression line through the band scale (with linear interpolation between band centers for LOESS fractional indices).
  • FlowMap push API — joined the realtime-capable HOC family. The frame gained a geo-lines variant on useFrameImperativeHandle plus pushLine / pushManyLines / removeLine / getLines / lineIdAccessor on GeoPipelineStore. supportsPush: true in capabilities; docs streaming demo flipped from setState(flows) to ref.current.push(flow).
  • Capability matrix at ai/capabilities.json — 44 charts indexed across 5 categories with renderModes / supportsPush / supportsSSR / supportsLegend / supportsSelection / supportsLinkedHover / colorModel / layoutMode / specialFeatures fields. Generated alongside docs/capabilities.md by npm run docs:capabilities; locked against chartSpecs.ts by check:capabilities. suggestCharts({ capabilities }) accepts push/linkedHover/ssr/selection/legend constraints and surfaces a filteredOut list with reasons. New /features/capabilities website page renders an interactive filterable matrix.

Changed

  • ProcessSankey particles unified with SankeyDiagram — particles now ride the canvas + ParticlePool path. The HOC writes pre-computed cubic bezier control points onto each ribbon spec; NetworkPipelineStore's particle-pool gate broadened from chartType === "sankey" to also accept customNetworkLayout. SVG particle overlay deleted (~80 LOC, including the <circle>-per-particle allocation per frame). Prop surface aligned: showParticles + particleStyle (same ParticleStyle shape as SankeyDiagram). Individual particleRadius / particleDuration / particleDensity / particleMaxPerEdge props removed. Particles inherit source-band colors via nodeColorMap binding through invisible color-binding scene nodes.
  • Ribbon geometry unified — new src/components/geometry/ribbonGeometry.ts is the single source of truth for the M-C-L-C-Z ribbon path emission. SankeyDiagram passes cp1X = xi(curvature), cp2X = xi(1-curvature) (d3-sankey S-curve); ProcessSankey passes cp1X = cp2X = cx (lane-aware single-point bend). Both buildScenes.ts (SSR) and the HOCs (CSR) call the same helper.
  • algorithm.jsalgorithm.ts — last JS file in the chart source tree migrated to TypeScript with all types inlined as the canonical source (algorithm.d.ts deleted). 7 import sites updated to drop the .js extension; test file converted with type-annotated fixtures.
  • getSize clamps to sizeRange — normalized position is now clamped to [0, 1] before mapping into the size range, so a pushed point whose sizeBy value falls outside the running domain (most common in push-mode initial state) renders at the boundary radius instead of producing an arbitrarily large pixel value.
  • Push-mode bezier carry-throughNetworkPipelineStore.ingestBounded now copies pre-computed bezier from raw edges onto internal RealtimeEdge records, validated against the BezierCache shape (object + circular: boolean + 4-point or non-empty-segments + finite halfWidth). Malformed shapes are silently dropped instead of crashing the particle pipeline.
  • Edge value preservation — bounded ingestion now uses Number.isFinite(numValue) ? numValue : 1 instead of Number(v) || 1, so a legitimate value: 0 edge survives end-to-end (e.g. suppressed-flow markers in particle pipelines).
  • Particle CSS variable resolutionnetworkParticleRenderer runs all colors through resolveCSSColor so particleStyle.color="var(--semiotic-primary)" and theme-token-returning edgeColorFn results paint correctly (canvas's fillStyle silently rejects CSS custom properties otherwise).
  • Particle color resolution moved out of the renderer — functional particleStyle.color is now invoked in getParticleColor with a resolveEdgeEndpoint-resolved RealtimeNode. Custom-layout charts (ProcessSankey) where edge.source is a string id now correctly invoke the user's color function instead of falling back to a hardcoded default.
  • Keyboard nav skips invisible scene nodesextractNetworkNavPoints skips r <= 0 circles and w <= 0 || h <= 0 rects (matching the canvas renderer's own skip gates). Keyboard focus on ProcessSankey now lands on a real band/ribbon instead of an off-canvas color-binding placeholder.
  • Bundle countssemiotic/ai covers 40 HOCs (XY + ordinal + network + realtime); semiotic/recipes added to the table; full schema covers 44 charts.
  • Documentation refreshed — README, CLAUDE.md, ai/system-prompt.md, and the synced .cursorrules / .windsurfrules / .github/copilot-instructions.md / .clinerules / docs/public/llms-full.txt all carry current bundle sizes, chart counts, and entry-point inventory.
  • Bundle-size docs corrected — earlier in this release cycle the README/CLAUDE.md/ai/system-prompt.md bundle table briefly carried inflated numbers because npm run dist (no --production) writes non-minified output to dist/*.module.min.js. The published artifacts come from npm run dist:prod, which terser-minifies. Both scripts/sync-bundle-sizes.mjs and size-limit read dist/*.module.min.js directly, so a local dist build silently substituted unminified bytes into the docs. The corrected numbers (xy 81 KB gz, ordinal 66 KB, network 62 KB, etc.) now reflect actual published artifacts. The bundle-size check tolerates ±3 KB build-machine variance so local↔CI minor differences don't fail without real growth.

Fixed

  • Fixed ProcessSankey particles not flowing when showParticles was toggled on (root cause: customNetworkLayout charts skipped finalizeLayout, so pre-computed bezier never reached store.edges).
  • Fixed ProcessSankey particles rendering as light grey instead of inheriting source-node category color.
  • Fixed Number.isFinite coercion in useEncodingDomain so the running domain is always numeric.
Source: README.md, updated 2026-05-12