Skip to content

Update dependency layerchart to v2.0.0-next.64#190

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/layerchart-2.x
Open

Update dependency layerchart to v2.0.0-next.64#190
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/layerchart-2.x

Conversation

@renovate
Copy link
Copy Markdown
Contributor

@renovate renovate Bot commented Jan 11, 2026

ℹ️ Note

This PR body was truncated due to platform limits.

This PR contains the following updates:

Package Change Age Confidence
layerchart 2.0.0-next.432.0.0-next.64 age confidence

Release Notes

techniq/layerchart (layerchart)

v2.0.0-next.64

Compare Source

Patch Changes
  • fix(ArcChart): (Re-)disable grid by default (regression from recent refactor) (#​449)

v2.0.0-next.63

Compare Source

Minor Changes
  • feat(Dodge): Add Dodge component for deterministic non-overlapping layout (#​862)

  • feat(Waffle): Add Waffle component for countable-cell visualizations (#​864)

  • feat(Pattern): Add rects shape definition for tile patterns for rendering one or more rectangles per pattern tile (#​864)

  • feat(Text): Add fontSize prop with auto-derived capHeight (#​862)

Patch Changes
  • fix(Chart): Don't compute [undefined, undefined] domain when series is metadata-only (#​449)

  • fix(canvas): Resolve currentColor for fill/stroke (and other style props) (#​449)

  • fix(Pattern): fix alignment and sharply render on high-DPI displays when using Canvas layers (#​864)

  • fix(downloadImage / getChartImageBlob): Fix image download (container sizing and text clipping) (#​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)

  • fix(Image): Stop disabling pointer events by default (#​862)

  • fix(Circle, Text): Inherit chart accessors by default in data mode (#​862)

  • fix(Rect): Support non-uniform corners in data/edge mode (#​449)

v2.0.0-next.62

Compare Source

Minor Changes
  • feat(Blur): Add Canvas support (#​449)
Patch Changes
  • perf(Chart): Eliminate per-instance props spread in ChartState (#​857)

  • fix(SeriesState): Avoid derived_inert crash when chart unmounts under a <svelte:boundary> (#​855)

    The selectedKeys sync effect was wrapped in $effect.root, creating an isolated scope that survived chart unmount. When the parent chart was destroyed (e.g. an example reloading inside the docs <svelte:boundary> after an async $derived re-evaluated), the #series derived became inert while the orphaned effect kept reading it — producing Reading a derived belonging to a now-destroyed effect may result in stale values warnings followed by TypeError: e.some is not a function. The effect now lives in the constructor, scoped to the component that instantiated SeriesState, so it is torn down with the chart.

  • fix(Arc, RectClipPath, ChartClipPath): Restore on-mount tween animations (#​855)

    Two related regressions introduced in the layer-component split (#​848) prevented motion + initial* props from animating on mount.

    Arcmotion, value, initialValue and the rest of Arc's geometry props (domain, range, startAngle, endAngle, innerRadius, outerRadius, cornerRadius, padAngle, track*, offset) were not destructured in Arc.base.svelte, so they leaked through {...restProps} onto the inner <Path>. The forwarded motion made Path also tween the path-string on top of the end-angle tween that ArcState already drives, producing visibly wrong arcs (NaN coordinates, runaway radii). They are now extracted and passed explicitly to ArcState.

    RectClipPath / ChartClipPathmotion, initialX, initialY, initialWidth, initialHeight were declared on the type but never consumed: the path was a plain $derived of the static x/y/width/height props, so passing <ChartClipPath initialWidth={0} motion={{ width: { type: 'tween', … } }}> rendered the final width on mount with no animation. Each dimension now flows through its own createMotion (using the corresponding initial* value as the animation start), and the path is built from the animated values.

  • perf: Reduce per-tick reactive overhead in Path / Link (force-simulation graphs) (#​855)

    In mark-heavy scenes (force simulations with hundreds of links flowing through Link → Path) several reactive structures unconditionally subscribed every <path> template updater to props that don't change on a tick, causing per-frame work to scale with the number of props × the number of marks. Each fix below is independent; together they take the lattice (n=20, 760 links) example from ~5–6 fps to ~9 fps during simulation.

    PathState.tweenedPathData now reads only pathData, not all Path props.
    Pre-fix, the getter resolved pathData via getProps(), a function that constructs an object literal of every reactive Path prop. Each read of tweenedPathData (i.e. each per-tick <path d=...> update) therefore subscribed the updater to every Path prop and re-read all of them. PathState now takes a dedicated getPathData getter alongside getProps, and the hot-path tween / DOM read only touches pathData. Path.svg.svelte and Path.canvas.svelte pass them as separate getters.

    Link.base.svelte passes a stable getPathData function rather than motionPath.current directly.
    Reading motionPath.current from Link.base.svelte's template subscribed the entire <Path> block to every tick, forcing the parent's prop spread ({...restProps}) and cls(...) evaluation to re-run on every change. Passing a stable function reference moves the per-tick read inside <Path>'s own template, keeping Link.base.svelte stable. Requires the new pathData?: string | (() => string) form on Path.

    Path.svg.svelte allocates draw-related state lazily.

    • endPoint = createControlledMotion(..., { type: 'none' }) was created for every Path, even when no draw transition was configured. Now only created when draw is set.
    • The $effect that tracked tweenedPathData for startContent / endContent positioning ran on every Path, even when neither prop was provided. Now only registered when at least one is set.
    • drawKey is only ever set when draw is configured, so the {#key c.drawKey} block is a no-op for paths without a draw transition. The block stays unconditional — splitting it behind {#if draw} showed no measurable benefit over leaving the inert subscription in place.

    Path.svg.svelte extracts styling props out of ...rest.
    pathData, class, fill / fillOpacity / stroke / strokeOpacity / strokeWidth / opacity and motion are now destructured out of $props() rather than left in ...rest, so the <path> element's {...rest} spread doesn't re-evaluate every frame when those props change (pathData changes on every force-sim tick; class is typically a fresh cls(...) string per parent render).

    Link.base.svelte drops a redundant prop spread.
    Removed {...extractLayerProps(restProps, 'lc-link')} before {...restProps} — the call's only contribution (class) was being immediately overridden by the explicit class={cls('lc-link', …)} that follows, making the spread pure overhead.

  • perf: Skip mark-info $effect for pixel-mode primitives (#​855)

    registerComponent now probes markInfo() once at construction; if the result is initially empty (pixel-mode primitives where cx/cy/r/etc. are numbers rather than string/function accessors), it skips creating the tracking $effect entirely. Saves one effect frame per primitive — adds up in mark-heavy scenes (force simulations, scatter plots with hundreds of nodes).

    Trade-off: a primitive that starts in pixel mode and later flips to data mode at runtime (e.g. cx mutates from a number to a string) will not register a mark. Mark mode is typically static; if a chart needs runtime data-mode marks, define an explicit series on the chart instead.

v2.0.0-next.61

Compare Source

Minor Changes
  • feat: Per-layer variants for primitives, compound marks, and high-level charts (layerchart/svg, layerchart/canvas, layerchart/html) (#​848)

    Layer-agnostic components auto-detect the surrounding <Svg>, <Canvas>, or <Html> layer and bundle every render path. The new sub-path exports expose layer-specific variants so consumers committed to a single rendering layer can opt into a smaller bundle.

    // Default: agnostic, dispatches at runtime — works in any layer
    import { Rect, Circle, Text, Path, LineChart } from 'layerchart';
    
    // SVG-only — skips canvas + html branches
    import { Rect, Circle, Text, Path, LineChart } from 'layerchart/svg';
    
    // Canvas-only
    import { Rect, Circle, Text, LineChart } from 'layerchart/canvas';
    
    // HTML-only — drops canvas + svg overhead (some primitives are ~95% smaller)
    import { Rect, Circle, Text, Pattern, LinearGradient } from 'layerchart/html';

    Each agnostic component (e.g. Rect.svelte) now dispatches to the corresponding per-layer variant under the hood (Rect.svg.svelte, Rect.canvas.svelte, Rect.html.svelte) — no breaking change for existing consumers.

What's split
**Primitives (13)** — the basic graphics building blocks
`Circle`, `Text`, `Rect`, `Line`, `Path`, `Ellipse`, `Polygon`, `Group`, `Image`, `ClipPath`, `Pattern`, `LinearGradient`, `RadialGradient`

**Compound marks (~30)** — chart axes, marks, annotations, and chart-relative shapes
`Axis`, `Grid`, `Rule`, `Highlight`, `Layer`, `ChartChildren`, `ChartClipPath`, `CircleClipPath`, `Bars`, `Bar`, `Spline`, `Area`, `Pie`, `Arc`, `ArcLabel`, `Points`, `Cell`, `Frame`, `Threshold`, `Trail`, `Vector`, `Link`, `Labels`, `AnnotationLine`, `AnnotationPoint`, `AnnotationRange`, `Hull`, `Density`, `Voronoi`, `Contour`, `Raster`, `Violin`, `BoxPlot`, `Calendar`, `Month`

**Geo components (`layerchart/geo`)**
`GeoPath`, `GeoSpline`, `GeoPoint`, `GeoCircle`, `GeoTile`, `TileImage`, `Graticule`, `GeoClipPath`, `GeoEdgeFade`

**Graph components (`layerchart/graph`)**
`Ribbon`

**High-level chart wrappers** — pre-composed charts with built-in tooltips, highlights, and series handling
`LineChart`, `AreaChart`, `BarChart`, `ScatterChart`, `PieChart`, `ArcChart`

The geo, graph, hierarchy, and force sub-paths also re-export every layer-agnostic helper they previously included, so a single `from 'layerchart/svg'` import covers a typical SVG chart end-to-end without falling back to `'layerchart'`.
Standout per-layer wins (gz, vs agnostic baseline)
**Primitives where the per-layer rendering is dramatically simpler:**

-   `Pattern` html: 14.81 → 0.92 KB (-94%) — HTML implementation is just CSS-string generation
-   `LinearGradient` html: 14.38 → 0.53 KB (-96%)
-   `Image` canvas: 14.95 → 3.73 KB (-75%)
-   `Text` svg/html: 29.13 → ~16 KB (-45%)
-   `Circle` / `Rect` / `Ellipse` / `Line` / `Path`: ~22–27% smaller per-layer

**Compound marks:** typically 8–15% gz savings per-layer; outliers like `Highlight` (-30% canvas) and `Cell` (-22% svg) are larger because their HTML/canvas vs. SVG paths diverge significantly.

**High-level charts:** ~5–12% gz savings (~5–11 KB) when imported from `layerchart/svg` or `layerchart/canvas`. A single-layer LineChart drops from 89.6 KB → 79.0 KB gz on the SVG path.

For a consumer who migrates all imports to a single layer, cumulative savings across primitives and compound marks are 60–80 KB gz.
Bundle reductions on the default <Chart> path
In addition to opt-in per-layer variants, this release also makes a few previously-eager features lazy:

-   **`<TransformContext>`** is now dynamically imported when `<Chart transform={...}>` is set — saves ~2.8 KB gz on every chart that doesn't pan/zoom.
-   **`<BrushContext>`** was already lazy; nothing changes there.
<ChartCore> for non-cartesian charts (new)
A new `<ChartCore>` component is exported alongside `<Chart>` from each layer sub-path (`layerchart`, `layerchart/svg`, `layerchart/canvas`, `layerchart/html`). It provides the chart context, sizing, brush, transform, and tooltip plumbing — but skips `<ChartChildren>` and the `Layer` / `Axis` / `Grid` / `Rule` / `Highlight` / `ChartClipPath` import chain it pulls in.

Use it for geo maps, custom layouts, or any chart that renders its own primitives directly via the `children` snippet:

```svelte
<script>
  import { ChartCore, Svg, GeoProjection, GeoPath } from 'layerchart/svg';
</script>

<ChartCore data={countries}>
  {#snippet children({ context })}
    <Svg>
      <GeoProjection projection={geoMercator} fitGeojson={countries}>
        <GeoPath geojson={countries} fill="steelblue" />
      </GeoProjection>
    </Svg>
  {/snippet}
</ChartCore>
```

Measured savings (bundle scenarios):

-   `base` (`<Chart>`) → `core` (`<ChartCore>`): 83.42 → 50.93 KB gz (**−39%**)
-   `geo` (`<Chart>` + `GeoPath`/`GeoPoint`) → `core-geo` (`<ChartCore>` + `GeoProjection` + `GeoPath`): 87.23 → 54.67 KB gz (**−37%**)
-   `base-svg` (per-layer) → `core-svg` (per-layer): 77.37 → 50.88 KB gz (**−34%**)
Behavior
Identical to the agnostic versions: visual output, props, types, and bindable refs all match. The dispatcher pattern adds ~0.2 KB per primitive to `core` for users on the agnostic API (transitive cost from `Highlight` / `Axis` / `Chart`) — a worthwhile tradeoff for the opt-in per-layer savings.

See the updated ["Bundle Size" guide](https://layerchart.com/docs/guides/bundle-size) for the full table, tradeoffs, and when to opt into per-layer imports.

v2.0.0-next.60

Compare Source

Minor Changes
  • breaking: Move heavy-dep components into sub-path exports (#​845)

    The following components are no longer re-exported from 'layerchart' and must be imported from new sub-paths:

    • 'layerchart/geo'GeoCircle, GeoClipPath, GeoEdgeFade, GeoLegend, GeoPath, GeoPoint, GeoProjection, GeoRaster, GeoSpline, GeoTile, GeoVisible, Graticule, TileImage
    • 'layerchart/hierarchy'Tree, Treemap, Pack, Partition
    • 'layerchart/force'ForceSimulation
    • 'layerchart/graph'Dagre, Sankey, Chord, Ribbon

    This isolates each group's external d3 dependency (@dagrejs/dagre ~22 KB, d3-geo ~15 KB, d3-force ~7 KB, d3-hierarchy ~6 KB, d3-sankey ~6 KB, d3-chord ~2 KB) behind an opt-in import — defending against bundlers that don't tree-shake the root barrel cleanly.

    Voronoi/Hull stay at root (already lazy-loaded via TooltipContext). Contour/Density/Raster/BoxPlot/Violin/Threshold and high-level charts (LineChart, BarChart, etc.) remain at root.

    Migration: update affected imports, e.g.

    -import { Tree, GeoPath, ForceSimulation } from 'layerchart';
    +import { Tree } from 'layerchart/hierarchy';
    +import { GeoPath } from 'layerchart/geo';
    +import { ForceSimulation } from 'layerchart/force';
Patch Changes
  • perf: Lazy-load opt-in features in core path (#​845)

    5 components/dependencies that previously sat in every <Chart> user's sync graph are now dynamically imported only when the corresponding feature is used:

    • BrushContext in Chart — only loads when <Chart brush={...}> is set (default undefined)
    • DefaultTooltip in ChartChildren — only loads when tooltipContext is set and no custom tooltip snippet is provided
    • d3-quadtree in TooltipContext — only loads when mode is 'quadtree', 'quadtree-x', or 'quadtree-y'
    • Spline in Grid — only loads when rendering radial linear grid lines (<Chart radial> with radialY="linear")
    • Bar in Highlight — only loads when <Chart highlight={{ bar: ... }}> is set (default false)

    Result: ~10 KB gz off core (115.6 → 105.25 KB) and comparable savings on every cartesian/geo/graph/hierarchy scenario, with no impact on rendered output for users who already opt into these features.

    Also switches internal @layerstack/svelte-actions imports from the barrel (@layerstack/svelte-actions) to sub-paths (@layerstack/svelte-actions/styles, @layerstack/svelte-actions/portal). No production bundle effect — bundlers already tree-shake the unused popover.js — but it stops the Svelte REPL/CDN from eagerly fetching @floating-ui/dom (popover's transitive dep) when consumers load layerchart from a CDN.

v2.0.0-next.59

Compare Source

Patch Changes
  • fix: Prevent submitting forms when clicking legend buttons (#​841)

v2.0.0-next.58

Compare Source

Major Changes
  • breaking: Merge Connector into Link, remove Connector component (#​449)

    Link now supports both pixel mode (x1/y1/x2/y2 props) and data mode (data + source/target/x/y accessors), mirroring the pattern used by primitives like Circle, Text, and Rect.

    Migration:

    • <Connector source={{...}} target={{...}} ... /><Link x1={...} y1={...} x2={...} y2={...} ... />
    • <Link explicitCoords={{ x1, y1, x2, y2 }} /><Link {x1} {y1} {x2} {y2} /> (or <Link {...linkPositions[i]} />)

    All Connector props (type, curve, sweep, radius, bend, orientation, radial, markers, motion) are available directly on Link. The explicitCoords prop and Connector export are removed.

Minor Changes
  • feat(AnnotationLine): Add x1/y1/x2/y2 props for sloped lines (#​449)

    • Pass any combination of x1, y1, x2, y2 to draw a line between arbitrary points. Missing coordinates fall back to the corresponding axis range (so x1/x2 alone still span the y range, etc.). The existing x / y shorthand for full-span vertical/horizontal lines is unchanged.
    • Labels on sloped lines automatically rotate to follow the line angle (normalized to stay upright), with labelPlacement, labelXOffset, and labelYOffset applied along and perpendicular to the line.
  • feat(AnnotationPoint): Add link prop for ring-note style callouts, plus geo projection support (#​449)

    • Pass link={true} or link={{ type: 'beveled', radius: 20, ... }} etc. to draw a <Link> from the ring edge to the label. Any Link prop (type, curve, sweep, radius, bend, class, ...) can be passed through.
    • Inside a geo <Chart>, x/y are now interpreted as [lon, lat] and projected directly, so AnnotationPoint can be used on maps.
  • feat(Connector): Add 'swoop' connector type (#​449)

    New 'swoop' connector type draws a circular arc between source and target, equivalent to ObservablePlot's Arrow bend option. Configured via a new bend prop (degrees, default 22.5) — positive bends right (clockwise from source to target), negative bends left, 0 draws a straight line. Works in both cartesian and radial modes; Link forwards it automatically.

  • feat(tooltipContext, Voronoi): Add x/y accessor overrides and default array endpoint to max (#​449)

    • New x/y props on tooltipContext and Voronoi accept an Accessor (property name string or function). When set, hit-detection points use these accessors instead of the Chart's x/y. Useful when the Chart's accessor returns an array (e.g. x={['POP_1980', 'POP_2015']}) and you want detection at a specific endpoint:
      <Chart {data} x={['POP_1980', 'POP_2015']} tooltipContext={{ mode: 'voronoi', x: 'POP_2015', y: 'R90_10_2015' }}>
    • Breaking (minor): when the chart's x/y accessor returns an array (duration bars, candlesticks, stacked areas, etc.), quadtree and voronoi hit-detection now default to the max value of the array instead of the min. For most use cases (target endpoint, stack top) this is the more natural hover position. If you need the old behavior, pass an explicit x/y accessor on tooltipContext/Voronoi.
Patch Changes
  • fix(Chart): Explicit <Chart data> now takes precedence over marks' implicit-series data (#​449)

    When a mark registered its own filtered dataset via markInfo (e.g. a decorative <Text data={highlighted}> showing labels for a subset), two things went wrong:

    1. ctx.data would silently switch to the filtered subset via seriesState.visibleSeriesData, causing sibling array-driven marks (like <Link>) to iterate only the subset.
    2. An implicit series would be created from the decorative mark, narrowing the domain calculation to only the subset's values.

    Now when <Chart data> is explicit (non-empty):

    • ctx.data always returns the chart's data.
    • Marks whose axis accessor matches the chart's axis accessor (including any element of an array accessor like y={['v1', 'v2']}) are treated as decorative and don't create implicit series — even if they have their own data array.

    Marks with their own data still contribute to flatData for domain calculation when their accessor differs from the chart's (the multi-dataset / multi-series scenario).

  • fix(Connector, Link): Orient d3 step curves by orientation (#​449)

    • Added orientation?: 'horizontal' | 'vertical' prop to Connector (defaults to 'horizontal'). Link forwards its own orientation so step curves step along the natural flow direction.
    • curveStep, curveStepBefore, and curveStepAfter now step along y in vertical orientation instead of always stepping along x.
  • fix(GeoPath): Avoid passing undefined event handlers to underlying Path, preventing a Svelte error while preserving canvas hit-testing for non-interactive paths (#​449)

  • fix: Allow negative string values (e.g. y="-6") in Text position props to be treated as pixel values instead of data property names (#​449)

v2.0.0-next.57

Compare Source

Patch Changes
  • fix(AnnotationRange): Don't extend past chart bounds when x is omitted on band scales, and treat null on either side of x/y as "extend to chart edge". (#​449)

  • fix(Spline): Restore series.props.opacity (and other style props) precedence over the computed series fade opacity. Regression introduced by per-segment styling refactor where the explicit opacity was spread after series.props, clobbering per-series opacity values (e.g. series={[{ props: { opacity: 0.1 } }, ...]}). (#​449)

  • fix(ChartState): Don't filter explicit x1Domain/y1Domain by visible series when no series are configured. Restores grouped layout for composable <Chart> usage (e.g. <Bars> with x1/x1Domain/x1Range) where the visible-series filter previously emptied the secondary band scale domain, collapsing all bars to a single category position. (#​449)

v2.0.0-next.56

Compare Source

Minor Changes
  • feat(Circle, Ellipse): Support pattern/gradient fill values on the <Html> layer by switching from background-color to the background shorthand (with background-origin: border-box to keep patterns aligned under the border). Accepts values produced by <Pattern> / <LinearGradient> in HTML mode. (#​449)

  • feat(Pattern): Support <Html> layer by producing CSS repeating-linear-gradient (lines) and radial-gradient (circles) values usable as a background/fill. Gradient-valued background (e.g. <Pattern background={gradient}>) is also supported. (#​449)

Patch Changes
  • fix(Pattern): Restore canvas layer support by registering as a group node so snippet children (e.g. <Rect fill={pattern}>) render correctly (#​449)

  • fix(Rect): On the <Html> layer, set background-origin: border-box so fills/patterns start at the outer edge — previously the CSS background shorthand reset origin to padding-box, shifting patterns inward by border-width when a stroke was applied. (#​449)

  • fix(Rect, Circle, Ellipse): Apply box-sizing: border-box on the <Html> layer so the visual extent equals width×height (or r * 2, rx * 2×ry * 2) — the border is drawn within that extent instead of added to it, matching SVG bounds. (#​449)

  • fix(Rect, Circle, Ellipse): On the <Html> layer, default border-width to 1px when stroke is set without an explicit strokeWidth, matching SVG's implicit stroke-width: 1. Also ensures Circle/Ellipse border-width gets the required px unit. (#​449)

v2.0.0-next.55

Compare Source

Minor Changes
  • feat(Bar, Bars): Support <Html> layer (#​449)

    Bar/Bars now render in <Html> layers in addition to <Svg> and <Canvas>, including per-corner rounded variants (top, bottom, left, right, edge, and individual corners). Previously, any non-uniform rounded value fell through to a <Path> and was SVG-only.

  • feat(ClipPath, RectClipPath, CircleClipPath, GeoClipPath): HTML layer support + unified path API (#​449)

    ClipPath now accepts a single path: string (SVG path d syntax) that drives all three layers:

    • SVG: rendered as <path d={path}> inside the <clipPath> element.
    • Canvas: wrapped in Path2D and applied via ctx.clip(...).
    • HTML: emitted as clip-path: path("${path}") on a wrapper <div> covering the chart container.

    This replaces the previous canvasClip / canvasClipDeps callbacks (and skipped HTML entirely) with a single declarative value. The clip snippet is still accepted for advanced/custom SVG content.

    RectClipPath, CircleClipPath, and GeoClipPath are rewritten on top of this — they each compute a path string (d3-geo-path already emits one natively) and pass it through. All three now support <Html> layers in addition to <Svg> and <Canvas>.

    Note: clip-path: path() requires Chrome 88+, Safari 13.1+, Firefox 118+.

  • feat(ClipPath, RectClipPath, CircleClipPath, GeoClipPath): Add invert prop to render content outside the clip shape (cutouts/masks) across SVG, Canvas, and HTML layers (#​449)

  • feat(Line, Rect, Circle, Text): Multi-layer compatible dashArray and inline color props (#​449)

    • Added a typed dashArray prop to Line, Rect, and Circle. Accepts a number, array, or SVG-style string and maps to stroke-dasharray (SVG), setLineDash (Canvas), and either repeating-linear-gradient (HTML lines) or border-style: dashed (HTML borders). Previously dashed styling was SVG-only when applied via CSS class or attribute.
    • Text and Line HTML branches now honor the fill/stroke props as inline color/background, so prop-based colors work across all three layers (not just SVG/Canvas).
    • Grid.x/Grid.y and Axis.grid now accept stroke, strokeWidth, opacity, and dashArray in their object form, matching the props forwarded to the underlying line.
    • Rule already forwarded arbitrary Line props via spread; dashArray now works there unchanged.
    • Exports parseDashArray and dashArrayToGradient helpers from path utils.
  • feat(Tree, Link, Connector): Add radial support (#​831)

    Tree now detects <Chart radial> and lays out with d3.tree().size([2π, min(width, height)/2]) plus radial separation. Nodes emit polar coords (x = angle, y = radius).

    Connector gains a radial prop (defaults to ctx.radial) that interprets source/target as polar and dispatches to new getConnectorRadialPresetPath / getConnectorRadialD3Path helpers. Radial behavior per connector type:

    • straight — straight cartesian line
    • square — radial → arc at midR → radial
    • beveled — chord at source radius with chamfered corner (controlled by radius)
    • rounded — visx LinkRadialCurve Bezier
    • d3d3.linkRadial by default; with a curve prop, curveStep / curveStepBefore / curveStepAfter map to polar arcs/radials, other curves go through d3.lineRadial

    Link forwards radial to Connector automatically when inside a radial <Chart>.

  • feat(Rect): Add corners prop for per-corner rounding (#​449)

    New corners prop accepts either a number (equivalent to rx), a [topLeft, topRight, bottomRight, bottomLeft] tuple, or { topLeft, topRight, bottomRight, bottomLeft }. Works across <Svg>, <Canvas>, and <Html> layers — Svg renders a <rect> when corners are uniform and a <path> when they differ, Canvas uses roundRect's per-corner radii, and Html uses the 4-value border-radius shorthand.

    Also exports a shared roundedRectPath(x, y, width, height, [tl, tr, br, bl]) helper from path utils for building per-corner rounded-rect path data.

Patch Changes
  • fix(canvas): Compose globalAlpha multiplicatively so Group opacity propagates to children (#​831)

    Canvas renderPathData was overwriting ctx.globalAlpha with absolute values for element opacity, fill opacity, and stroke opacity. This meant a parent <Group opacity={0.2}> had no effect on child marks rendered on canvas — the child's own opacity (defaulting to 1) would replace the inherited value.

    Now all three sites multiply against the current globalAlpha, which correctly composes with ancestor Group opacity set via save()/restore() scoping. Also removes double-application of element opacity inside the fill/stroke blocks (it's already applied at the element level).

v2.0.0-next.54

Compare Source

Minor Changes
  • feat: New GeoClipPath component for clipping content to GeoJSON boundaries in both SVG and Canvas modes (#​449)

  • feat(Text): Add segments prop for inline mixed-style text (#​449)

    New segments prop accepts an array of { value, class } objects to render text with different styles (font size, weight, color) inline. Works across SVG (via tspans), Canvas (via sequential measureText/fillText), and HTML layers. Useful for labels that combine a bold name with a lighter value, such as treemap headers.

  • feat(Hull): Add CommonStyleProps (fill, fillOpacity, stroke, strokeOpacity, strokeWidth, opacity) for Canvas layer compatibility (#​449)

  • feat(Tooltip): Add fadeDuration prop to control fade in/out transition (#​828)

    The fade transition on Tooltip.Root is now configurable via the fadeDuration prop (default: 100ms). Set to 0 to disable the fade transition entirely.

  • feat(Tooltip): Portal tooltip to body by default to fix overflow clipping. Resolves #​446 (#​828)

    Tooltip.Root now portals to document.body (or .PortalTarget) by default using the portal action from @layerstack/svelte-actions. This prevents tooltips from being clipped by ancestor elements with overflow: hidden. The tooltip uses position: fixed with viewport-relative coordinates when portaled. Set portal={false} to restore the previous inline behavior. Both contained="container" and contained="window" modes continue to work correctly with portaling.

Patch Changes
  • fix(ArcLabel): Support rotation in Canvas mode (#​449)

    Changed centroid-rotated and centroid-radial placements to pass rotate prop instead of SVG transform string to Text, enabling rotation in Canvas rendering.

  • fix: Pie and Arc components now correctly use Chart's xRange prop for angle degrees instead of the computed viewport pixel range, and compute radius from chart dimensions instead of scale range (#​449)

v2.0.0-next.53

Compare Source

Minor Changes
  • feat: Support pre-projected topologies in GeoLegend via referenceScale (#​449)

    Add a referenceScale prop to GeoLegend for charts that render pre-projected data with geoIdentity (e.g. us-atlas's counties-albers-10m / states-albers-10m, pre-projected with geoAlbersUsa().scale(1300)). When provided, pixels-per-distance is derived from the chart's fit scale and the supplied base scale, bypassing the projection.invert + geoDistance path which only works for real lon/lat projections. The GeoPath bubble-map example now renders a correct scale bar.

v2.0.0-next.52

Compare Source

Minor Changes
  • feat(ArcLabel): New component for positioning text labels on arc segments (#​817)

    ArcLabel is a new marking component for placing text (and optional leader lines) relative to an arc. It's used internally by PieChart and ArcChart when the labels prop is set, but can also be rendered directly inside an Arc children snippet.

    Supported placements:

    • centroid — at the arc centroid (horizontal text, default)
    • centroid-rotated — at the centroid, rotated to follow the arc tangent, flipped where needed so text stays upright
    • centroid-radial — at the centroid, rotated to read along the radial direction (center → outer edge)
    • inner / middle / outer — along the inner, medial, or outer arc path (centered via startOffset: '50%' by default)
    • callout — outside the arc with a leader line that bends horizontally to the label

    ArcLabel accepts a single offset prop that is routed to the placement-appropriate radial padding (centroid offset, innerPadding/outerPadding, or calloutLineLength), plus calloutLineLength / calloutLabelOffset / calloutPadding for fine-grained control of callout leader lines. The leader line renders via the Path primitive, so it works in both SVG and Canvas chart layers.

  • breaking(Arc): Center arc text along path by default for inner/middle/outer positions (#​817)

    getArcTextProps('inner' | 'middle' | 'outer') now defaults to startOffset: '50%' with textAnchor: 'middle', centering the text along the arc path rather than anchoring it at the arc start. When an explicit startOffset is provided, the anchor falls back to 'start' so the text begins at that position (matching prior behavior for callers that set a start offset).

  • feat(Arc): Add innerPadding option to getArcTextProps / getTrackTextProps (#​817)

    ArcTextOptions now supports an innerPadding option, symmetric to the existing outerPadding. Positive values shrink the inner radius used to build the inner/middle arc text paths, moving text inward (toward the chart center). Previously, offsetting an inner-placed arc label away from the arc edge required overriding the path manually; now it works the same as outerPadding does for outer text.

  • feat(CircleLegend): New component for visualizing radius (rScale) values as nested circles (#​818)

    CircleLegend displays a set of bottom-aligned nested circles representing values from a radius scale, useful alongside bubble maps and scatter charts that encode magnitude via circle area. By default it reads rScale from the chart context, but a scale prop can also be passed to render standalone.

    Supports tickValues / ticks / tickFormat for value selection and formatting, a title rendered centered above the circles, and labelPlacement="right" | "left" | "inline" to render tick labels with a leader line on either side of the circles or centered inside each circle near the top.

  • feat(GeoLegend): New scale-bar legend showing real-world distance for the current Chart projection (#​818)

    GeoLegend reads the active geo projection from the chart context and renders a labeled scale bar with tick subdivisions. By default it picks a "nice" round distance that covers ~25% of the chart width, but distance can be passed for an explicit value. Supports units="km" | "mi", configurable ticks, tickFormat, title, and the standard placement props. Inspired by Harry Stevens' d3-geo-scale-bar.

  • feat(Labels): Add middle placement and change center to center within the bar body (#​449)

    placement="center" now positions the label at the center of the bar body (between the value edge and the baseline). The previous center behavior (label aligned to the value edge with a middle anchor) is now available as the new placement="middle".

  • feat(Legend, CircleLegend): Show an indicator of the current tooltip value on the legend (#​818)

    Legend (ramp variant) now draws a small upward-pointing arrow below the color ramp at the position of the currently hovered value, and CircleLegend draws a 50%-opacity filled circle at the corresponding radius. Both auto-read the hovered data from ctx.tooltip.data and pipe it through the chart's color (ctx.c) / radius (ctx.r) accessors, so wiring is automatic for charts that configure c / r / cScale / rScale via Chart props.

    A new value prop on both components allows explicitly setting the indicator value (overriding the auto-detection), useful when the tooltip data shape doesn't match the chart's accessor.

    For scaleThreshold / scaleQuantize / scaleQuantile scales, the Legend indicator centers on the matching bucket swatch.

  • feat(PieChart/ArcChart): Add top-level labels prop (#​817)

    PieChart and ArcChart now accept a labels prop that renders text labels on each arc without requiring a custom arc snippet. Pass true to enable defaults (centroid placement, default value accessor), or an object to configure any ArcLabel props — placement, offset, value accessor, callout line lengths, leader line style, text class, etc.

    <PieChart {data} labels={{ placement: 'callout', value: 'fruit' }} />

v2.0.0-next.51

Compare Source

Minor Changes
  • feat: New GeoRaster component for reprojecting raster imagery (e.g. NASA Blue Marble) onto any d3-geo projection via per-pixel inverse sampling on Canvas (#​815)

  • feat: Add renderChart() to layerchart/server for server-side chart-to-image rendering (PNG/JPEG) (#​813)

Patch Changes
  • feat: Add stroke and fill props to Axis and Grid for explicit color control (useful for SSR where CSS variables are unavailable) (#​813)

  • fix: Skip mark x/y/data from domain/series calculation when geo projection is active (#​449)

  • fix: Default geo projection translate to container center when translate and fitGeojson are not specified, instead of using d3-geo's fixed default ([480, 250]) (#​815)

  • fix: improve compatibility with UnoCSS Svelte scoped preprocessing (#​813)

    • Remove TypeScript-only as assertions from exported Svelte markup in core mark components so preprocessors that parse markup expressions as plain JavaScript can consume packaged components without failing

v2.0.0-next.50

Compare Source

Minor Changes
  • feat: New Trail component for variable-width lines (#​449)

  • fix(Axis): Default tickSpacing to null for categorical band scales, showing all ticks by default instead of reducing them. Use tickSpacing={80} to opt-in to tick reducing on categorical band scale axes. (#​449)

Patch Changes
  • fix(Spline): Make motion prop reactive so toggling between tween/none updates without remount (#​449)

v2.0.0-next.49

Compare Source

Minor Changes
  • feat(Labels): Add smart placement option (#​799)

    New placement="smart" mode that dynamically positions labels based on neighboring point values (peak, trough, rising, falling) to reduce overlapping.

  • feat(Chart, BrushState): Add band scale (categorical) support for transform pan/zoom and brush selection. Uses range-rescaling pattern to smoothly zoom and pan categorical bar charts. Automatically constrains panning to data boundaries and prevents zooming out past initial view. (#​449)

  • feat(Chart): In projection mode, scaleExtent and translateExtent are now interpreted as relative values (like d3-zoom). scaleExtent: [0.5, 8] means 0.5x to 8x of the fitted projection scale. translateExtent is offset from the initial fitted position in pixels. (#​449)

  • feat(Spline): Support function-valued stroke, fill, and opacity for per-segment styling (#​449)

  • feat(Text): Add format prop and tween numeric value when motion is configured (#​449)

Patch Changes
  • Support tickSpacing for band scales on Axis, thinning tick labels when the domain is larger than the available space. Automatically shows more tick labels when zoomed in on band scale transforms. (#​449)

  • perf: Optimize primitive component instantiation (~3-5x faster for Rect, Circle, Ellipse, Line, Text, Path, Group) (#​449)

    • createMotion: Fast-path passthrough when no motion prop is provided, avoiding $state/$effect overhead per axis
    • createDataMotionMap: Short-circuit when motion is undefined, skipping parseMotionProp overhead
    • createKey: Only create fill/stroke key trackers in canvas layer (skipped for SVG/HTML)
    • registerComponent: Skip registerMark for empty MarkInfo (pixel-mode marks)
    • All primitives: Skip $effect for data motion tracking when no motion is configured
    • Rect/Image: Avoid per-axis parseMotionProp calls when motion is undefined
  • feat(Marker): Add square and square-stroke types (#​805)

  • fix(GeoPath): Fix canvas tooltip by conditionally passing onclick to Path, preventing non-interactive overlays from capturing hit canvas events (#​449)

  • fix(scaleBandInvert): Account for range offset in band scale inversion. Previously assumed range started at 0, causing incorrect pixel-to-category mapping when the scale range was transformed. (#​449)

  • fix(TransformContext): Reactively sync processTranslate and disablePointer to TransformState when props change. Fixes inverted globe dragging when dynamically switching between flat and globe projections. (#​449)

  • fix(Chart): Enable scroll zoom for globe projections by including scale: true in default transformApply for globes. (#​449)

  • feat(Raster, Contour): support bounded geo raster overlays with projected interpolation (#​449)

  • feat: Add Month component (#​671)

  • fix(LinearGradient, RadialGradient): Register as group instead of mark in canvas component tree so wrapped children (e.g. Arc, Path) are rendered (#​449)

v2.0.0-next.48

Compare Source

Patch Changes
  • fix(ChartState): Don't create spurious implicit series when mark accessor matches chart's own axis accessor, fixing domain corruption for heatmap/Cell charts (#​449)

v2.0.0-next.47

Compare Source

Major Changes
  • breaking(BrushContext|TransformContext): Rename bind:brushContext / bind:transformContext to bind:state (#​663)

    Both BrushContext and TransformContext now use bind:state instead of their previous named bindings. Additionally, properties on ChartState have been renamed:

    • chartContext.brushContextchartContext.brushState
    • chartContext.transformContextchartContext.transformState
    - <BrushContext bind:brushContext>
    + <BrushContext bind:state>
    
    - <TransformContext bind:transformContext>
    + <TransformContext bind:state>
  • breaking(TransformContext): Rename domainExtent: 'original' to domainExtent: 'data' (#​663)

    The 'original' value for domainExtent has been renamed to 'data' to better describe that it constrains pan/zoom to the data's domain bounds:

    - <Chart transform={{ domainExtent: 'original' }}>
    + <Chart transform={{ domainExtent: 'data' }}>
  • breaking(GeoContext): Rename GeoContext component to GeoProjection (#​663)

    The GeoContext component has been renamed to GeoProjection to better describe its purpose. Update your imports and template usage:

    - import { GeoContext } from 'layerchart'
    + import { GeoProjection } from 'layerchart'
    - <GeoContext projection={geoAlbersUsa}>
    + <GeoProjection projection={geoAlbersUsa}>
  • breaking: Rename render context APIs to layer context (#​663)

    • getRenderContext()getLayerContext()
    • setRenderContext()setLayerContext()
    • supportedContexts prop → layers prop on components
    • Internal layout/ directory moved to layers/ (affects deep imports)
    - import { getRenderContext } from 'layerchart'
    + import { getLayerContext } from 'layerchart'
  • breaking(Chart): Remove isVertical from ChartState, add valueAxis prop to Chart (#​663)

    ChartState.isVertical has been removed in favor of ChartState.valueAxis ('x' | 'y'), which explicitly defines which axis represents the value (dependent variable).

    Simplified charts (BarChart, LineChart, AreaChart, ScatterChart) still accept the orientation prop as before — each chart maps it to the correct valueAxis internally. The <Chart> component itself now uses valueAxis directly, since orientation is ambiguous at that level (a "vertical" BarChart has valueAxis="y" while a "vertical" LineChart has valueAxis="x").

    When accessing chart state:

    - if (chartContext.isVertical) { ... }
    + if (chartContext.valueAxis === 'y') { ... }

    When using <Chart> directly (not simplified charts):

    - <Chart ...>
    + <Chart valueAxis="x" ...>
  • breaking: Remove standalone context getter/setter functions (#​663)

    The following standalone context functions have been removed in favor of the unified getChartContext() API:

    • getTooltipContext() / setTooltipContext() → use getChartContext().tooltip
    • getBrushContext() / setBrushContext() → use getChartContext().brushState
    • getTransformContext() / setTransformContext() → use getChartContext().transformState
    - import { getTooltipContext } from 'layerchart'
    - const tooltip = getTooltipContext()
    + import { getChartContext } from 'layerchart'
    + const chart = getChartContext()
    + // access via chart.tooltip
  • breaking(Arc|Pie|Calendar|GeoPath): Rename tooltipContext to simple tooltip (boolean), simplifying use case (#​663)

Minor Changes
  • feat: Add BoxPlot component for box-and-whisker plots (#​663)

    New composite mark that renders whiskers, caps, IQR box, median line, and outlier dots. Supports both pre-computed statistics (min, q1, median, q3, max, outliers accessors) and automatic computation from raw values via the values prop. Orientation-aware via valueAxis context.

  • feat: Add statistical utility functions computeBoxStats() and kde() (#​663)

    • computeBoxStats(values, k?) computes the five-number summary and outliers using the Tukey IQR method
    • kde(values, options?) computes kernel density estimation using the Epanechnikov kernel with Silverman's rule-of-thumb bandwidth
  • feat: Add Violin component for violin plots (#​663)

    New composite mark that renders a symmetric density curve (mirrored area) from raw data using kernel density estimation (Ep

Note

PR body was truncated to here.


Configuration

📅 Schedule: (UTC)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR is behind base branch, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@vercel
Copy link
Copy Markdown

vercel Bot commented Jan 11, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
gradecompass Ready Ready Preview, Comment Jan 11, 2026 5:07am

@cloudflare-workers-and-pages
Copy link
Copy Markdown

cloudflare-workers-and-pages Bot commented Jan 11, 2026

Deploying gradecompass with  Cloudflare Pages  Cloudflare Pages

Latest commit: 32fa162
Status:🚫  Build failed.

View logs

@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch 4 times, most recently from 167f13f to 18ebee8 Compare January 24, 2026 23:17
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.44 Update dependency layerchart to v2.0.0-next.45 Feb 18, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from 18ebee8 to f7cc925 Compare February 18, 2026 17:15
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.45 Update dependency layerchart to v2.0.0-next.46 Feb 19, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from f7cc925 to dd90006 Compare February 19, 2026 17:03
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.46 Update dependency layerchart to v2.0.0-next.48 Mar 31, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from dd90006 to 5e59e1f Compare March 31, 2026 21:02
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.48 Update dependency layerchart to v2.0.0-next.49 Apr 2, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from 5e59e1f to e532125 Compare April 2, 2026 21:16
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.49 Update dependency layerchart to v2.0.0-next.50 Apr 4, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from e532125 to dcba557 Compare April 4, 2026 02:04
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.50 Update dependency layerchart to v2.0.0-next.51 Apr 7, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch 2 times, most recently from ebdf8f5 to 085d50d Compare April 9, 2026 13:58
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.51 Update dependency layerchart to v2.0.0-next.52 Apr 9, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from 085d50d to 21e4ee9 Compare April 9, 2026 18:04
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.52 Update dependency layerchart to v2.0.0-next.53 Apr 9, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from 21e4ee9 to bc902fc Compare April 13, 2026 15:16
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.53 Update dependency layerchart to v2.0.0-next.54 Apr 13, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from bc902fc to 1ca94f0 Compare April 17, 2026 12:05
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.54 Update dependency layerchart to v2.0.0-next.55 Apr 17, 2026
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.55 Update dependency layerchart to v2.0.0-next.57 Apr 17, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch 2 times, most recently from 15b3e92 to 4243afd Compare April 21, 2026 16:42
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.57 Update dependency layerchart to v2.0.0-next.58 Apr 21, 2026
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.58 Update dependency layerchart to v2.0.0-next.59 Apr 24, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch 2 times, most recently from 880dbca to 865c980 Compare April 29, 2026 19:44
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.59 Update dependency layerchart to v2.0.0-next.61 Apr 29, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from 865c980 to c8b325e Compare May 1, 2026 18:26
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.61 Update dependency layerchart to v2.0.0-next.62 May 1, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from c8b325e to 255b9e6 Compare May 9, 2026 16:44
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.62 Update dependency layerchart to v2.0.0-next.63 May 9, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch 2 times, most recently from e038e0b to 7a05190 Compare May 10, 2026 06:08
@renovate renovate Bot changed the title Update dependency layerchart to v2.0.0-next.63 Update dependency layerchart to v2.0.0-next.64 May 18, 2026
@renovate renovate Bot force-pushed the renovate/layerchart-2.x branch from 7a05190 to 32fa162 Compare May 18, 2026 18:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants