diff --git a/.changeset/pre.json b/.changeset/pre.json index 74763b399..75d589340 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -14,6 +14,7 @@ }, "changesets": [ "add-boxplot-component", + "add-dodge-component", "add-geoclippath-component", "add-georaster-component", "add-smart-label-placement", @@ -54,6 +55,7 @@ "canvas-group-opacity", "chart-data-precedence", "chart-props-no-spread", + "chart-resolve-domain-series-metadata", "chatty-flies-bet", "chatty-shirts-rule", "chilly-games-hide", @@ -110,6 +112,7 @@ "fix-arclabel-canvas-rotation", "fix-area-all-zero", "fix-barchart-diverging-edge-rounding", + "fix-canvas-currentcolor", "fix-geo-mark-domain", "fix-geopath-canvas-tooltip", "fix-geopath-undefined-handlers", @@ -118,6 +121,7 @@ "fix-pie-arc-xrange", "fix-scale-band-invert", "fix-series-state-effect-root", + "fix-spline-canvas-class-opacity", "fix-spline-series-props-opacity", "fix-text-negative-string-position", "fix-transform-projection-reactivity", @@ -161,6 +165,7 @@ "huge-rocks-sip", "hull-style-props", "icy-llamas-jump", + "image-pointer-events-default", "khaki-pugs-hammer", "kind-melons-invent", "kind-shirts-sniff", @@ -212,6 +217,7 @@ "polite-parts-learn", "poor-clocks-occur", "pretty-roses-invent", + "primitives-inherit-chart-accessors", "proud-camels-cut", "proud-llamas-fold", "proud-melons-warn", @@ -274,6 +280,7 @@ "tame-lamps-report", "tangy-lies-strive", "tasty-states-raise", + "text-fontsize-prop", "text-format-tween", "thick-months-join", "thirty-glasses-pick", diff --git a/packages/layerchart/CHANGELOG.md b/packages/layerchart/CHANGELOG.md index 6589ff458..d7bd4ea27 100644 --- a/packages/layerchart/CHANGELOG.md +++ b/packages/layerchart/CHANGELOG.md @@ -1,5 +1,72 @@ # LayerChart +## 2.0.0-next.63 + +### Minor Changes + +- feat(Dodge): Add Dodge component for deterministic non-overlapping layout ([#862](https://github.com/techniq/layerchart/pull/862)) + + A new composition component (similar to `ForceSimulation`) that packs items along one axis to avoid overlaps. Modeled after [Observable Plot's `dodge` transform](https://observablehq.com/plot/transforms/dodge): + - `axis`: `'x'` or `'y'` — which axis to dodge along (default `'y'`) + - `anchor`: `'top'`/`'middle'`/`'bottom'` (for `axis='y'`) or `'left'`/`'middle'`/`'right'` (for `axis='x'`) — controls which edge items grow away from + - `padding`: minimum px gap between items + - `r`: collision radius per item (constant or accessor). When omitted, falls back to the chart's `r` accessor / `rScale` (matching `Points`), then to a default of `5`. + - `position`: override the anchor-axis pixel accessor (defaults to chart's `xGet`/`yGet`) + + Yields each item's computed pixel `x`/`y` (and original `index`) via the children snippet, so you can render with any primitive (`Circle`, `Text`, etc.). + + Also includes a `rowHeight` mode that switches from circular to row-based rectangular packing — useful for text labels where circular collision would produce unnecessarily large vertical gaps. The pure `dodge()` algorithm is exported from `Dodge.shared.svelte.ts` for direct use. + + Algorithm modeled after Observable Plot / SveltePlot: maintains an interval tree of placed items keyed by anchor-axis extent, queries it for items in the new item's collision zone, and builds candidate dodge-axis positions from circle-tangency math. Currently implemented as a linear-scan tracker with the same API; can be swapped for a real interval tree without API changes if profiling demands it. + +- feat(Circle, Text): Inherit chart accessors by default in data mode ([#862](https://github.com/techniq/layerchart/pull/862)) + + `` and `` now fall back to the chart's `x`/`y`/`r` accessors (via `xGet`/`yGet`/`rGet`) when the corresponding position prop is omitted — matching how `` and the new `` work. This lets the chart be the single source of truth for `x`/`y`/`r` and removes the boilerplate of repeating those props on every primitive: + + ```svelte + + + + + + + + + + ``` + + `Circle` and `Text` also now enter data mode when `data` is explicitly passed (in addition to the existing trigger when `cx`/`cy`/`x`/`y` are data-driven), so the implicit-accessor pattern works without needing to pass redundant string accessors just to trigger iteration. + + Behavior is unchanged whenever any position prop is set explicitly — the hardcoded defaults (0/0/1) only apply when neither prop nor chart-level config is present. All existing usages in the docs pass explicit position props, so this is purely additive. + +- feat(Text): Add `fontSize` prop with auto-derived `capHeight` ([#862](https://github.com/techniq/layerchart/pull/862)) + + Adds a typed `fontSize?: number | string` prop on `` (number = pixels, string passes through). When set, `capHeight` defaults to `fontSize * 0.71` instead of the legacy `'0.71em'` — so per-item scaled labels with `verticalAnchor="middle"` align to a common visual baseline without an explicit `capHeight` override. + + Previously, `getPixelValue` resolved `'0.71em'` against a hard-coded 16px, so vertical centering was only correct for ~16px text. Larger labels sat too low, smaller ones too high — visible on text-driven beeswarms or any caller scaling labels per-element. + + ```svelte + + + + + + ``` + +### Patch Changes + +- fix(Chart): Don't compute `[undefined, undefined]` domain when `series` is metadata-only ([#449](https://github.com/techniq/layerchart/pull/449)) + + When `series` is configured for legend/color metadata only (no per-series `data`, and items lack the series-key properties on the value axis), the value-axis domain calculation collected all-undefined values and returned `[undefined, undefined]`. Combined with `motion`, this threw `Cannot spring undefined values` whenever the series visibility changed (e.g. toggling a legend swatch). + + The series-aware branch now filters out null/undefined values and falls through to the other domain-resolution paths when nothing remains, instead of returning a poisoned extent. + +- fix(canvas): Resolve `currentColor` for `fill`/`stroke` (and other style props) ([#449](https://github.com/techniq/layerchart/pull/449)) + +- fix(Spline): Allow CSS class `opacity` to fade lines on the Canvas layer. `Spline` was always passing `opacity={1}` to the underlying `Path` when no series fade was active, which became `constantStyles.opacity = 1` in the canvas renderer and shadowed the value resolved from a user's `class` (e.g. `class="opacity-20"`). Now skip passing `opacity` when the computed series fade is the no-fade default, so the class can take effect — matching SVG behavior where CSS class rules override the presentation attribute. ([#449](https://github.com/techniq/layerchart/pull/449)) + +- fix(Image): Stop disabling pointer events by default ([#862](https://github.com/techniq/layerchart/pull/862)) + ## 2.0.0-next.62 ### Minor Changes diff --git a/packages/layerchart/package.json b/packages/layerchart/package.json index 2bd2c89e1..16db50cfe 100644 --- a/packages/layerchart/package.json +++ b/packages/layerchart/package.json @@ -5,7 +5,7 @@ "license": "MIT", "repository": "techniq/layerchart", "homepage": "https://layerchart.com", - "version": "2.0.0-next.62", + "version": "2.0.0-next.63", "scripts": { "dev": "pnpm package:watch", "build": "svelte-package",