| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| semiotic-3.12.0.provenance.json | 2026-10-01 | 1.6 kB | |
| semiotic-3.12.0.sbom.cdx.json | 2026-10-01 | 80.6 kB | |
| semiotic-3.12.0.tgz | 2026-10-01 | 6.0 MB | |
| semiotic-3.12.0.tgz.sha512 | 2026-10-01 | 150 Bytes | |
| README.md | 2026-10-01 | 12.4 kB | |
| Semiotic v3.12.0 source code.tar.gz | 2026-10-01 | 81.9 MB | |
| Semiotic v3.12.0 source code.zip | 2026-10-01 | 85.0 MB | |
| Totals: 7 Items | 173.0 MB | 0 | |
Added
- XY and ordinal frames take
interactiveGraphics(throughframePropson any HOC): focusable SVG controls drawn in plot coordinates, in a labelledrole="group"layer outside the chart'srole="img"overlay, so sliders stay exposed to assistive technology. The function form receives{ size, margin, scales, pointerToPlot };interactiveGraphicsLabelnames the group. Client-only. DirectManipulationMarkers(semiotic/controls): ordered draggable handles, such as a baseline and a max, each a slider bounded by its neighbors. Coincident handles resolve by drag direction, so neither can trap the other.pointerToLocalPointmaps a pointer into an SVG element's coordinate space.DirectManipulationControltakespointToValue(the pointer already in the handle's coordinate space, so(point) => scales.y.invert(point.y)replaces hand-rolled screen-matrix math),stepOrigin, andariaRoleDescription, and handles PageUp/PageDown.diagnoseConfig/--doctorwarn withANNOTATION_UNKNOWN_FIELDwhen an annotation key looks like a misspelled field (fil→fill); keys naming a data field or accessor are coordinates and are never flagged.perspectiveon every network chart (ForceDirectedGraph, SankeyDiagram, ProcessSankey, ChordDiagram, TreeDiagram, Treemap, CirclePack, OrbitDiagram, NetworkCustomChart, and StreamNetworkFrame) draws the finished layout in a parallel projection:"isometric"(true 30°),"pixel"(2:1),"dimetric","military", or"cabinet". Every piece hasthickness(6 layout px by default;0draws flat pieces): circles and symbols become tokens lying on the ground at their pixel size with a shaded rim; rects, chord arcs, and circle-pack circles become slabs with side walls; Treemap and CirclePack levels stack on their parents; edges and bands ride one thickness above their surface and cast a soft shadow (edgeShadow).marks: "billboard"keeps upright point marks. Standing marks paint back to front. Layout coordinates do not change, and hover, tooltips, keyboard focus, annotations, the accessible table, the zoom camera, component SSR, andrenderToStaticSVGfollow the projected marks.- The object form adds
elevation(a field, constant, or callback, with drop lines and ground shadows),marks: "extrude"prisms for leaf rects,ground.gridandground.plate,regions(labelled plates under node ids that seat their members; plates and regions default to the piece thickness), orthogonal ground routing (edges.route), ground-aligned labels, pictogramglyphs, and an animatedtransition. Grid, plates, regions, routing, and extrusion load on demand in browsers;preloadNetworkPerspectiveExtras()loads them before hydration. semiotic/network/perspective:isometricGlyphs(box, server, database, cylinder, tile, cloud, pin), builders (isoBox,isoStack,isoCylinder,isoTile,isoCloud,isoPin), and an accessiblePerspectiveToggle.semiotic/networkexportsresolveNetworkPerspective,createNetworkPerspectiveFrame,projectNetworkScene, anduseNetworkPerspective()(the fitted projection for custom-layout overlays). Custom layouts readctx.perspectiveand can setperspective: "ground"on their result to laybackgrounds/overlayson the projected ground, or place individual decorations withNetworkPerspectiveGround(flat geometry, optionally at piece height) andNetworkPerspectiveBillboard(upright content that follows its anchor, or lies flat at pixel size withonGround). Layouts list decorations that reach past their marks inperspectiveBoundsso the projection's fit keeps them in the plot. A development warning fires when a projected layout leaves decorations in plot space. All built-in network recipes place their hulls, arrowheads, node cards, headers and badges this way;mermaidDagLayoutemits solid shaped pieces and real edges under a perspective.diagnoseConfigwarns when a ProcessSankey (a time axis) is projected and when a network chart is given the geo-onlyprojectionprop.- Threshold (
y-threshold,x-threshold),band, andx-bandannotations acceptlabelColorfor the label text, which otherwise uses the annotationcolor. WithlabelBackground: { type: "box", fill }it draws a light-on-dark label chip on a colored line, in the browser and inrenderChartSVG. RealtimeHistogramandTemporalHistogramacceptvalueBands([{ upTo?, fill }], wherefillis a color orHatchFill) to split each unstacked bar's fill at value edges, e.g. solid up to 5, hatched up to 10, a warning hatch above. Each bar stays one mark with its bin datum, so hover, selection,hoverHighlight, tooltips, andgetSourceRowsare unchanged. Stacked (categoryAccessor) bins ignore it.- The tooltip wrapper (
.stream-frame-tooltip) reports its placement asdata-placement("pending", then"placed") anddata-flip-x/data-flip-y. A CSStransitiononleft/topnow eases only same-side moves: the first placement and each flip set an inlinetransition: none, so the tooltip no longer glides in from the pointer or swings across it. validateProps,diagnoseConfig, andnpx semiotic-ai --doctorreport axis config keys that no renderer reads, inframeProps.axesand the histograms' top-levelaxes, with a "Did you mean" suggestion (for exampletickCont→tickCount, the alias ofticks). The check stays out of the chart bundles, like the rest of prop validation.GradientConfigacceptsextent: "domain"for area fills, which anchors the stops to the y-domain instead of each area's own top-to-baseline span.
Changed
DirectManipulationControlfiresonChangeStart/onChangeEnd(and the matching observations) for each keyboard change, not only for pointer drags, so a consumer that commits on release also hears keyboard users. It no longer setsaria-roledescription="visualization control"by default, so screen readers announce the standard "slider" role.- Importing one chart no longer ships its neighbors. Published chunks merge
many modules, and module-scope side effects (
displayNameassignments, top-level plugin/layout registration, un-annotatedforwardRef/memo/createContext/lazycalls, a prototype mixin on the pipeline stores) forced consumer bundlers to keep every chart that shared a chunk. Components are now pure initializers (withDisplayName(forwardRef(...), "Name"), so DevTools names survive minification), charts register their plugins when they render, and the build drops esbuild's side-effect-only cross-chunk imports when their targets are inert. Initial-load gzip for one named import in a Vite (Rolldown) app, before → after:semiotic/aisuggestCharts227 → 40 KiB,MotifBraidChart164 → 101,GaltonBoardChart145 → 85,SankeyDiagram159 → 125,Scatterplot150 → 123,RealtimeLineChart130 → 114,BarChart116 → 100,ChoroplethMap112 → 103,LineChart120 → 117. esbuild consumers see similar reductions. - XY transition interpolation (
animate/transition) loads on demand. An animated chart holds its first paint until the engine arrives, which is invisible because the intro starts from a blank frame;renderChart, SSR, and the animated GIF renderer are unchanged. - A bare
<StreamNetworkFrame chartType="force" />(no chart component and noregisterBuiltInNetworkLayouts()call) now restores its built-in layout on the client from a split chunk instead of rendering an empty scene. Server rendering still requires the explicit registration and warns without it. -
The README cold-consumer table bundles each named import with code splitting through Rolldown (Vite's bundler, resolved from the
vitedevDependency) and reports initial load and on demand gzip separately (benchmarks/setup/cold-consumer-imports.jsonschema 2). The previous table inlined lazily loaded code into every row.npm run sizeaddscheck:treeshake-isolation, which fails when a representative named import retains an unrelated chart, and the newsemiotic/no-module-side-effectscustom lint keeps library module scope inert (npm run lint:custom:adopt-rulerecords a new rule's baseline cursor). -
HatchFillandcreateHatchPatterndraw the same hatch on canvas and in SVG. Positive angles turn clockwise from horizontal on both, soangle: 45draws\and-45draws/(SVG used to draw them mirrored), andspacingis the perpendicular gap between lines at every angle. Canvas hatches at ±45° used to sitspacing ÷ √2apart, so they now read about 1.4× sparser; dividespacingby 1.41 to keep the old density. Canvas also honorslineOpacity, bakes the tile at device resolution, and tiles without seams at any angle. Bar-funnel dropoff hatches use one pattern on both backends. The recipe kit's SVGhatchFillhelper keeps its own convention (angle measured from vertical, matchinglegendSwatches).
Fixed
- Update the development dependency lockfile to patched
brace-expansion,fast-uri, andmarkdown-itreleases, clearing the release security audit. - The "Skip to data table" link and the collapsed "View data summary" trigger are visible while keyboard-focused (they stayed clipped to 1px, hiding the focus indicator).
- Component SSR with
animateserialized the first frame of the intro animation: Scatterplot and BubbleChart points atr="0", zero-height WaterfallChart and BarChart bars, zero-sweep PieChart slices, and SankeyDiagram, Treemap, and CirclePack with no marks at all. The server render and the hydration pass that must match it now paint the final state; client-only mounts still animate their intro. renderToStaticSVG/renderChartpaintframeProps.background, as the live chart does; an undefined top-levelbackgroundno longer erases it.- Static ForceDirectedGraph
colorBycolors follow category order, matching the live chart and the static legend, instead of hashing categories into a different palette. - Filled
curvednetwork edges honorfillOpacityin SVG output (default 0.1, as on canvas); they previously rendered opaque in SSR. - AreaChart
semanticGradientfills anchor their stops to the y-domain, the same span the semantic line bands use. When the data maximum sat below the domain maximum (for exampleyExtent: [0, 100]with data topping out at 60), the fill stretched its stops over the area's own extent and changed color at different values than the line. Below the lowest stop, the fill and the line both keep that stop's color. StreamGeoFramesizes its interaction canvas on mount, so a map that is never hovered no longer keeps the native 300×150 canvas box. XY and geo canvases take their CSS size from the frame at commit, so a chart mountedpausedor in a hidden tab lays out at its real size before its first paint.- A top legend in a compact frame keeps its capped reservation in the
browser. The frame used to raise the top margin back to the 34px
top-legend floor after the chart had capped it, collapsing the plot to 1px
where
renderChartkept it. The physics static renderer had the same floor. renderChart("ProcessSankey")caps its legend reservation to the frame like the browser chart. A compact frame no longer computes a negative plot height, which drew the grid upward from the axis and a zero-thickness ribbon. Animated GIF frames keep a plot of at least 1px.- Static SVG no longer writes CSS variables that standalone renderers can't
resolve: a
var()box-backgroundfillorstrokebecomes its literal fallback, andenclose/rect-enclosedefault to the theme's secondary text color. In the browser, avar()box-background paint goes throughstyle(like the halo), with its fallback kept as the attribute. renderChartbandandx-bandannotations withoutfillorcolordefault to the theme primary for the fill and the label, like the browser chart, instead of the annotation text color.layer: "under"bands follow suit.- AreaChart and the chart specs no longer describe the semantic line as ignoring stop opacity; each band takes its stop's color and opacity.