Repository navigation
v4.9.0
4.9 is a maintenance release that makes d3plus lighter to install and cleans up its API. @d3plus/core installs at a third of its former size, its minified bundle is a third smaller, several dependencies are gone, and the es/ builds are modern ES2022. A few methods that did nothing are removed, and Geomap accepts only its built-in projection names. Behind the scenes, tests run on Vitest, the docs site on Vite, Prettier formats the repo, and releases publish to npm from CI. Most charts need no changes; see the breaking changes.
Added
colorGrayin@d3plus/color: the gray scale d3plus uses for neutral ink, keyed 50–900. (#988)finite,clamp, andpathCommandsin@d3plus/math,colorGrayscalein@d3plus/color, andsoftHyphenin@d3plus/text. (#989) finite ↗ · clamp ↗ · pathCommands ↗ · colorGrayscale ↗ · softHyphen ↗
Changed
- Smaller installs. Published packages no longer include source maps, and each package's README links to its full API reference (
API.mdon GitHub) instead of embedding it.@d3plus/coredrops from ~8.3 MB to ~2.8 MB gzipped. The CDN entry (jsdelivr/unpkg) now serves the minified.full.min.jsbundle; thebrowserfield is gone. (#988) - Smaller minified bundles. The
.min.jsbundles keep license comments only:d3plus-core.full.min.jsgoes from 2.19 MB to 1.38 MB (425 KB gzipped). (#988) - ES2022 modules. The
es/builds are compiled to ES2022 instead of ES5, so they keep classes,?.and??as written instead of shipping down-leveled helpers. The UMD bundles were already modern. (#987) - Fewer dependencies.
open-color,file-saver,d3-sankey, andundiciare no longer dependencies, and@d3plus/data,@d3plus/render, and@d3plus/textdrop dependencies they didn't use.@d3plus/exportloadshtml-to-imageonly when saving an HTML element.@d3plus/typesre-exports types only. (#988) - Text no longer breaks after
/before a letter (USA/Canada,and/or), matching Chrome and Safari.@d3plus/domand@d3plus/textmeasure and segment text with@chenglou/pretext1.0. (#999) - Sankey lays out with a TypeScript port of d3-sankey, so
d3-sankeyand its older copies ofd3-array,d3-shape, andd3-pathare no longer installed. Layouts are identical; link paths are written with 3 decimal places, like every other d3plus shape. (#988) findLocaleresolves from a 122-entry table instead of the full LCID and ISO 639 lists (~8,400 lines). Chechen (ce) now resolves toce-RU. (#988)stripkeeps the base letter of any accented letter (Č→C,ğ→g); it used to drop letters outside Latin-1. Its output for Latin-1 is unchanged. (#988)uniquekeeps oneNaNinstead of dropping everyNaN. (#988)@d3plus/ssrfetches map tiles with Node'shttp/httpsmodules instead ofundici. Private and loopback addresses are still refused at connect time. (#988)- No Node
enginesrequirement on the browser packages. Only@d3plus/ssr, which runs in Node, declaresnode >= 22. (#990) @d3plus/coreusesd3-composite-projections2 (same projections, now with TypeScript types). (#999)
Fixed
- The standalone (non-
.full) UMD bundles read their dependencies from the globals those libraries define (d3for thed3-*modules,d3plusfor@d3plus/*,topojson,FloatingUIDOM, …). They looked for names liked3Colorthat nothing defines. (#987) - A Plot too small for its title, timeline, axes, or facet panels no longer draws bars, hover areas, and forecast regions with negative sizes. (#993)
- Shape background images in a Plot stay above the circles they belong to; clipping them to the plot area had moved them below. (#993)
flattenPathin@d3plus/renderreads compact arc flags (a1 1 0 011 1) as two flags instead of one number. (#989)
Documentation
- API.md documents every class's generated config accessors in a "Config accessors" table with type, default, and description, including the 26 Viz accessors (
duration,width,zoomFactor, …) and the shape and component accessors it didn't list before. Storybook args show their real defaults, including ones set in a constructor's helpers. (#989, #994, #1001) - The Area, Line, and TextBox examples that set
fill,stroke, orcolorto an accessor function render again. (#993) - The Geomap, Matrix, RadialMatrix, and shape-background-image examples load their data again: oec.world now blocks scripted requests, so their data is inline and the world map is served with the site. (#993)
Developer & tooling
- Tests run on Vitest.
pnpm testlints, then runs every package's tests in one Vitest run against the TypeScript source, so nothing is built first. Core's browser tests run in Vitest browser mode (Playwright Chromium), and node tests measure text with@napi-rs/canvasinstead of node-canvas.pnpm test:builtchecks the builtes/output, and the release script runs it. Duplicated tests are merged and table-driven, and the visual-regression suite fingerprints the charts added since 4.0. (#991, #992) - Pull requests test only what they affect. CI runs the tests and coverage of the packages a pull request changes plus their dependents, or of every package when it changes shared config, test helpers, scripts, or the lockfile. Pushes to
maintest everything. Node 22, 24, and 26 all gate merges, and.nvmrcpins 26. (#1000, #1002) - Releases publish from CI. Publishing a GitHub release runs the "Publish to npm" workflow, which publishes every package through npm trusted publishing (OIDC, no npm token) with provenance, dependencies first, and prereleases under the
nextdist-tag.pnpm run releaseno longer publishes or needs an npm login: it checks thatmainis clean and in sync with origin and thatghis logged in, validates the version, always rebuilds, prints one line per step (a failing step prints its output), titles this file'sUnreleasedsection with the new version and uses it as the release notes, and restores the working tree when it stops before the commit. (#987, #1003) - Prettier formats the repo.
pnpm formatrewrites andpnpm format:check(run in CI) verifies; the docs generator formats what it writes..git-blame-ignore-revsletsgit blameskip the formatting commit (git config blame.ignoreRevsFile .git-blame-ignore-revs). The files and functions Prettier's wrapping took past ESLint'smax-lineslimits are split into smaller modules and steps. (#1001) - Storybook runs on Vite (
@storybook/react-viteinstead of@storybook/nextjs), which drops Next.js and webpack from the install. Shared dependency ranges live in a pnpm catalog. ESLint 10 runs once over the repo (pnpm lint, includingscripts/), on TypeScript 6 and Vite 8. Dependabot opens grouped monthly updates; TypeScript 7 waits until typescript-eslint and TypeDoc support it. (#990, #998) - The dev server runs on Vite.
pnpm --filter @d3plus/<pkg> run devserves a package'sdev/pages through Vite instead of a hand-written HTTP server, and reloads through Vite's client instead of an injected Server-Sent Events snippet. URLs, port (DEV_PORT), the generated index, and per-page reloads are unchanged;chokidaris no longer a dependency. (#1004) - Quieter scripts. Builds print one line per package under
pnpm -ror CI (VERBOSE=1prints every file), and the docs generator prints TypeDoc warnings only and fails when a package fails. (#987) - The
.fullUMD bundles compile sibling packages from source, and a package with no dependencies (@d3plus/locales) writes its.fullbundles as copies of the standalone ones instead of building them twice. (#990, #1002) - Viz's config accessors are generated from
charts/viz/vizFields.tsinstead of hand-written: the 42 that store their value as given (zoomControlStyle,detectResize,attribution, …) and the 36 const-wrapped and deep-merged ones (title,legend,tooltip,tooltipConfig,legendConfig, …).VizBaseConfigfolds intoVizBase, which keeps only the setters with real logic. The generated accessors are typed fromD3plusConfig(they wereany), with their descriptions on it.D3plusConfiggains the keys it was missing: 22 of the plain accessors' keys, pluscolor,shape,messageStyle,subtitleConfig,timelineConfig, andtotalConfig, and it types Axis and TextBoxshape. (#989, #994) @d3plus/renderexportsarcPathandFULL_TURN, and draws motion-trail hulls withd3-polygon.@d3plus/core/internaladdsrowLegend,shareRow, and theVizDrawResulttype;vizDrawreturns the margin it claimed and its panels. (#989, #1002)@d3plus/core/internaldropscreateFluentandFluentInstance(useinstallFluent),vizPreDrawPureandvizDrawPure(usevizPreDrawandvizDraw),polarLegend(userowLegend), ParallelCoordinates'grayscale(usecolorGrayscale), andsunburstShadeAmount(usepartitionShadeAmount). ItsVizContexttype is the pipeline stage context.ChartDefinitiondrops its unreadfeaturesfield. (#989)
Breaking changes
Most charts upgrade with no code changes. These affect code that calls the removed methods, Geomap projections set by name, bundlers that target older browsers, and tests that compare exact output.
renderScene()andrenderMode()are removed from every chart. Useselect(target).renderer("svg" | "canvas").render(callback)instead. (#989)backConfig()is removed. It had no effect; passing it toconfig()now logs an unknown-property warning. Style the Back button withbackControlStyleandbackControlClassName. (#989)domToSceneis removed from@d3plus/render. (#989)- Geomap
projectionaccepts only built-in names: the d3-geo projections plusgeoAlbersUsaTerritories,geoMiller,geoRobinson, andgeoWinkel3. Pass any other projection as a function (e.g..projection(geoBertin1953())). An unknown name warns and falls back to Mercator. (#988) - The
es/builds are ES2022. A bundler that targets older browsers must transpile@d3plus/*. (#987) - Package contents change: source maps are no longer published, the
browserfield is gone (bundlers resolve throughexports), and the bare CDN URL serves.full.min.jsinstead of.full.js. (#988) - Output shifts: text no longer breaks after
/before a letter, Sankey link paths are rounded to 3 decimal places,stripkeeps base letters outside Latin-1,uniquekeeps oneNaN, andfindLocale("ce")returnsce-RU. Visual-regression snapshots with wrapped slashes or Sankey links will change. (#988, #999)