| Name | Modified | Size | Downloads / Week |
|---|---|---|---|
| Parent folder | |||
| README.md | 2026-04-23 | 8.8 kB | |
| Semiotic v3.4.2 source code.tar.gz | 2026-04-23 | 7.5 MB | |
| Semiotic v3.4.2 source code.zip | 2026-04-23 | 8.1 MB | |
| Totals: 3 Items | 15.6 MB | 0 | |
Added
gradientFillonBarChart— same API asAreaChart.gradientFill:truefor a default 80%→5% opacity fade on the resolved bar color,{ topOpacity, bottomOpacity }for explicit opacity stops, or{ colorStops: [{offset, color}, ...] }for arbitrary multi-color gradients. Direction always runs from each bar's tip (opposite the baseline) toward its base, so positive/negative and vertical/horizontal orientations all do the right thing. The scene builder now tags every rect withroundedEdgeunconditionally (previously only whenroundedTop > 0) so gradient direction resolves without requiring rounded corners. NewbuildBarGradienthelper inbarCanvasRenderer.tsbuilds theCanvasGradientper bar;StackedBarChart/GroupedBarChartget it for free via the shared scene + renderer.- SVG / SSR rendering for bar gradients —
ordinalSceneNodeToSVGinSceneToSVG.tsxemits<defs><linearGradient>+fill="url(#id)"for rect nodes carryingfillGradient. Works through bothrenderToStaticSVG(server) andanimatedGif(GIF export) automatically since both delegate to the shared scene-to-SVG converter. UsesgradientUnits="userSpaceOnUse"with absolute coords so each bar's gradient tracks its own rect. NewsafeSvgIdhelper coerces category names containing spaces/punctuation to a legal SVG id charset before embedding them in the gradient'sidandurl(#...)reference. renderers/colorUtils.ts— sharedparseCanvasColor(ctx, color)used by bothbarCanvasRendererandareaCanvasRenderer. Resolves any valid CSS color (named like"steelblue",hsl(),rgb(), hex short/long) to an[r, g, b]tuple via actx.fillStyleround-trip that the browser normalizes. Uses a sentinel-probe pattern so silently-rejected invalid colors (canvas ignores them and leavesfillStyleat the previous value) fall back safely instead of being mis-parsed as the prior color. Unified the two previously-duplicated localparseColorhelpers. Bar-gradient dev demos on/charts/bar-chartcover three shapes: opacity fade, multi-color stops, and horizontal bars.
Changed
- JSX transform flipped to the automatic runtime.
tsconfig.jsonandtsconfig.mcp.jsonnow use"jsx": "react-jsx"instead of the classic"jsx": "react". JSX compiles to imports fromreact/jsx-runtimerather thanReact.createElement(...), matching React 17+ guidance and removing the "outdated JSX transform" runtime warning that was peppering test output. ESLint flat config layersreactPlugin.configs["jsx-runtime"].ruleson top ofrecommendedto disablereact/react-in-jsx-scopeandreact/jsx-uses-react(both obsolete under the new runtime). 17 test files lost their now-redundantimport React from "react"imports; the 51 files that referenceReact.Xtypes kept theirs. Rollup'sexternalpredicate inscripts/build.mjsextended to cover thereact/jsx-runtimeandreact/jsx-dev-runtimesubpaths alongside the existingreact-dom/serverentry (auto-external marks package roots external but not subpaths). - Empty legends no longer reserve margin.
useChartLegendAndMarginpreviously returned a truthy legend object withlegendGroups: [{ items: [], label: "" }]when mounted with nodata(push-API pattern) pluscolorBy— that reserved 110px of right margin and rendered only the legend's header neatline. Zero-item legends now resolve toundefined, so no margin is reserved and the chart uses the full width until categories arrive. Surfaced by the "Update: Bar Chart" demo on/features/push-api. - Dependency hygiene.
react-routerandmarked-gfm-heading-idmoved fromdependencies→devDependencies(both are docs-only — never imported by anything undersrc/). Removedtslibas an explicit dev dep (noimportHelpers: truein either tsconfig, so TypeScript never emits tslib references).@testing-library/domnow an explicitdevDependency(was a transitive peer of@testing-library/react@16+; missing onnpm install --legacy-peer-depsand broke 79 test files on the publish workflow). Net: Cloud consumers installing the library get 19 runtime deps instead of the 22 they were getting before.grep -c "react-router\|marked-gfm-heading-id\|tslib" dist/semiotic.module.min.jsreturns 0.
Fixed
- Publish workflow OOM in
prepublishOnly. Four of the fivenode scripts/build.mjsinvocations across package.json scripts were missing the--max-old-space-size=8192flag thatdistanddist:prodcarry; the one that ran on publish hit Node's 4GB default heap ceiling and died during rollup minification with a mark-compact GC failure (exit 134). All five invocations (build:analyze,build:prod,pretest:dist,release:check,prepublishOnly) now share the heap bump, and the last two route throughnpm run dist:prodso there's one source of truth for how to invoke the build. parseCanvasColordetects silently-rejected invalid colors. The browser ignores invalid CSS color assignments without throwing —fillStylestays at whatever was set before. Without a probe, feeding an invalid color to the parser would mis-read the previous color as the caller's input. Added a sentinel-set-first pattern: assign#010203before the user's color, then compare; if the sentinel is still there (and the input wasn't literally the sentinel), return the fallback tuple. Also guards the non-stringfillStylecase (CanvasGradient/CanvasPattern).buildBarGradient/buildRectSVGGradient: < 2 valid stops falls back to solid. Both previously checkedfg.colorStops.length >= 2but then filtered outNaNoffsets inside the loop — a configured list of 2 stops with one NaN produced a single-stop gradient (flat color) or, on the SVG path, emittedoffset="NaN"which invalidates the whole gradient. Now both filter for finite offsets first, clamp, then require ≥2 valid survivors before building.- Bar renderer preserves
CanvasPatternfills whenfillGradientis set. The opacity branch ofbuildBarGradientused a hardcoded"#4e79a7"fallback when the resolved fill wasn't a string, silently replacing aCanvasPatternfill with a grey gradient. Now guards: if the resolved fill isn't a string, the gradient is skipped entirely and the pattern fill renders as intended. - Candlestick transition exit stubs preserve bodyWidth.
snapshotPositionsnow capturesnode.bodyWidthintoprev.wso the candlestick exit node reads the pre-transition width instead of falling through to the 6px default on the final frame.getNodeIdentityprefers an existing_transitionKeyover the datum-derived key so exit stubs stay stable across overlapping transitions (affects all exit-node types, not just candlestick). CandlestickChartOHLC validation gap. When the user asks for OHLC mode but the data is missingopen/closefields,warnMissingFieldandvalidateArrayDatanow cover all four accessors. Previously the scene builder silently dropped bars and the chart rendered blank with no feedback.
Tooling
noUnusedLocals/ ESLint cleanup pass. 17 test files undersrc/components/andsrc/__tests__/scenarios/had bareimport React from "react"imports that existed only to satisfy the classic JSX transform. Removed with the transform flip. The 51 files that useReact.SomeType/React.ComponentProps<>kept their imports.- 3246 unit tests pass (was 3216 in 3.4.1). Net adds: 9
buildBarGradienttests + 6 SVGgradientFilltests inSceneToSVG.test.tsx+ 1BarChartempty-legend suppression test + 8parseCanvasColortests covering hex normalization, named colors, invalid-with-string-prev, invalid-with-non-string-prev, and the sentinel-self edge case + 2ordinalSceneBuilderstests for roundedEdge tagging and fillGradient attachment + 2 NaN-stop fallback tests.
Docs
/charts/bar-chart— new "Gradient Fill" section under Examples with three live demos (default opacity fade, multi-color colorStops, horizontal direction flip) and a props-table row. Generator seeds match the page's existing deterministic pattern (noMath.random()at module scope).- OUTSTANDING_WORK.md — added "Legend auto-population from pushed categories [YELLOW]" under the Push API section. Captures the 3.4.2 short-circuit (empty legends don't reserve margin), the real design (an
onCategoriesChangecallback on StreamOrdinalFrame + StreamXYFrame threading throughuseChartSetupstate intouseChartLegendAndMargin's existingcategoriesparam), known landmines (first-ingest timing, sorted-array dedupe, XY'sgroupAccessorvariant,LinkedCharts+CategoryColorProviderinteraction), and an estimated ~150 LOC surface across 5 files.