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.4.2
Name Modified Size InfoDownloads / 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

  • gradientFill on BarChart — same API as AreaChart.gradientFill: true for 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 with roundedEdge unconditionally (previously only when roundedTop > 0) so gradient direction resolves without requiring rounded corners. New buildBarGradient helper in barCanvasRenderer.ts builds the CanvasGradient per bar; StackedBarChart / GroupedBarChart get it for free via the shared scene + renderer.
  • SVG / SSR rendering for bar gradientsordinalSceneNodeToSVG in SceneToSVG.tsx emits <defs><linearGradient> + fill="url(#id)" for rect nodes carrying fillGradient. Works through both renderToStaticSVG (server) and animatedGif (GIF export) automatically since both delegate to the shared scene-to-SVG converter. Uses gradientUnits="userSpaceOnUse" with absolute coords so each bar's gradient tracks its own rect. New safeSvgId helper coerces category names containing spaces/punctuation to a legal SVG id charset before embedding them in the gradient's id and url(#...) reference.
  • renderers/colorUtils.ts — shared parseCanvasColor(ctx, color) used by both barCanvasRenderer and areaCanvasRenderer. Resolves any valid CSS color (named like "steelblue", hsl(), rgb(), hex short/long) to an [r, g, b] tuple via a ctx.fillStyle round-trip that the browser normalizes. Uses a sentinel-probe pattern so silently-rejected invalid colors (canvas ignores them and leaves fillStyle at the previous value) fall back safely instead of being mis-parsed as the prior color. Unified the two previously-duplicated local parseColor helpers. Bar-gradient dev demos on /charts/bar-chart cover three shapes: opacity fade, multi-color stops, and horizontal bars.

Changed

  • JSX transform flipped to the automatic runtime. tsconfig.json and tsconfig.mcp.json now use "jsx": "react-jsx" instead of the classic "jsx": "react". JSX compiles to imports from react/jsx-runtime rather than React.createElement(...), matching React 17+ guidance and removing the "outdated JSX transform" runtime warning that was peppering test output. ESLint flat config layers reactPlugin.configs["jsx-runtime"].rules on top of recommended to disable react/react-in-jsx-scope and react/jsx-uses-react (both obsolete under the new runtime). 17 test files lost their now-redundant import React from "react" imports; the 51 files that reference React.X types kept theirs. Rollup's external predicate in scripts/build.mjs extended to cover the react/jsx-runtime and react/jsx-dev-runtime subpaths alongside the existing react-dom/server entry (auto-external marks package roots external but not subpaths).
  • Empty legends no longer reserve margin. useChartLegendAndMargin previously returned a truthy legend object with legendGroups: [{ items: [], label: "" }] when mounted with no data (push-API pattern) plus colorBy — that reserved 110px of right margin and rendered only the legend's header neatline. Zero-item legends now resolve to undefined, 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-router and marked-gfm-heading-id moved from dependenciesdevDependencies (both are docs-only — never imported by anything under src/). Removed tslib as an explicit dev dep (no importHelpers: true in either tsconfig, so TypeScript never emits tslib references). @testing-library/dom now an explicit devDependency (was a transitive peer of @testing-library/react@16+; missing on npm install --legacy-peer-deps and 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.js returns 0.

Fixed

  • Publish workflow OOM in prepublishOnly. Four of the five node scripts/build.mjs invocations across package.json scripts were missing the --max-old-space-size=8192 flag that dist and dist:prod carry; 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 through npm run dist:prod so there's one source of truth for how to invoke the build.
  • parseCanvasColor detects silently-rejected invalid colors. The browser ignores invalid CSS color assignments without throwing — fillStyle stays 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 #010203 before 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-string fillStyle case (CanvasGradient / CanvasPattern).
  • buildBarGradient / buildRectSVGGradient: < 2 valid stops falls back to solid. Both previously checked fg.colorStops.length >= 2 but then filtered out NaN offsets inside the loop — a configured list of 2 stops with one NaN produced a single-stop gradient (flat color) or, on the SVG path, emitted offset="NaN" which invalidates the whole gradient. Now both filter for finite offsets first, clamp, then require ≥2 valid survivors before building.
  • Bar renderer preserves CanvasPattern fills when fillGradient is set. The opacity branch of buildBarGradient used a hardcoded "#4e79a7" fallback when the resolved fill wasn't a string, silently replacing a CanvasPattern fill 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. snapshotPositions now captures node.bodyWidth into prev.w so the candlestick exit node reads the pre-transition width instead of falling through to the 6px default on the final frame. getNodeIdentity prefers an existing _transitionKey over the datum-derived key so exit stubs stay stable across overlapping transitions (affects all exit-node types, not just candlestick).
  • CandlestickChart OHLC validation gap. When the user asks for OHLC mode but the data is missing open/close fields, warnMissingField and validateArrayData now 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 under src/components/ and src/__tests__/scenarios/ had bare import React from "react" imports that existed only to satisfy the classic JSX transform. Removed with the transform flip. The 51 files that use React.SomeType / React.ComponentProps<> kept their imports.
  • 3246 unit tests pass (was 3216 in 3.4.1). Net adds: 9 buildBarGradient tests + 6 SVG gradientFill tests in SceneToSVG.test.tsx + 1 BarChart empty-legend suppression test + 8 parseCanvasColor tests covering hex normalization, named colors, invalid-with-string-prev, invalid-with-non-string-prev, and the sentinel-self edge case + 2 ordinalSceneBuilders tests 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 (no Math.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 onCategoriesChange callback on StreamOrdinalFrame + StreamXYFrame threading through useChartSetup state into useChartLegendAndMargin's existing categories param), known landmines (first-ingest timing, sorted-array dedupe, XY's groupAccessor variant, LinkedCharts + CategoryColorProvider interaction), and an estimated ~150 LOC surface across 5 files.
Source: README.md, updated 2026-04-23