Releases: techniq/layerchart
layerchart@2.0.0-next.64
Patch Changes
- fix(ArcChart): (Re-)disable grid by default (regression from recent refactor) (#449)
layerchart@2.0.0-next.63
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
rectsshape definition for tile patterns for rendering one or more rectangles per pattern tile (#864) -
feat(Text): Add
fontSizeprop with auto-derivedcapHeight(#862)
Patch Changes
-
fix(Chart): Don't compute
[undefined, undefined]domain whenseriesis metadata-only (#449) -
fix(canvas): Resolve
currentColorforfill/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
opacityto fade lines on the Canvas layer.Splinewas always passingopacity={1}to the underlyingPathwhen no series fade was active, which becameconstantStyles.opacity = 1in the canvas renderer and shadowed the value resolved from a user'sclass(e.g.class="opacity-20"). Now skip passingopacitywhen 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
cornersin data/edge mode (#449)
layerchart@2.0.0-next.62
Minor Changes
- feat(Blur): Add Canvas support (#449)
Patch Changes
-
perf(Chart): Eliminate per-instance props spread in
ChartState(#857) -
fix(SeriesState): Avoid
derived_inertcrash when chart unmounts under a<svelte:boundary>(#855)The
selectedKeyssync 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$derivedre-evaluated), the#seriesderived became inert while the orphaned effect kept reading it — producingReading a derived belonging to a now-destroyed effect may result in stale valueswarnings followed byTypeError: e.some is not a function. The effect now lives in the constructor, scoped to the component that instantiatedSeriesState, 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.Arc—motion,value,initialValueand the rest of Arc's geometry props (domain,range,startAngle,endAngle,innerRadius,outerRadius,cornerRadius,padAngle,track*,offset) were not destructured inArc.base.svelte, so they leaked through{...restProps}onto the inner<Path>. The forwardedmotionmadePathalso tween the path-string on top of the end-angle tween thatArcStatealready drives, producing visibly wrong arcs (NaN coordinates, runaway radii). They are now extracted and passed explicitly toArcState.RectClipPath/ChartClipPath—motion,initialX,initialY,initialWidth,initialHeightwere declared on the type but never consumed: the path was a plain$derivedof the staticx/y/width/heightprops, so passing<ChartClipPath initialWidth={0} motion={{ width: { type: 'tween', … } }}>rendered the final width on mount with no animation. Each dimension now flows through its owncreateMotion(using the correspondinginitial*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.tweenedPathDatanow reads onlypathData, not all Path props.
Pre-fix, the getter resolvedpathDataviagetProps(), a function that constructs an object literal of every reactive Path prop. Each read oftweenedPathData(i.e. each per-tick<path d=...>update) therefore subscribed the updater to every Path prop and re-read all of them.PathStatenow takes a dedicatedgetPathDatagetter alongsidegetProps, and the hot-path tween / DOM read only touchespathData.Path.svg.svelteandPath.canvas.sveltepass them as separate getters.Link.base.sveltepasses a stablegetPathDatafunction rather thanmotionPath.currentdirectly.
ReadingmotionPath.currentfromLink.base.svelte's template subscribed the entire<Path>block to every tick, forcing the parent's prop spread ({...restProps}) andcls(...)evaluation to re-run on every change. Passing a stable function reference moves the per-tick read inside<Path>'s own template, keepingLink.base.sveltestable. Requires the newpathData?: string | (() => string)form onPath.Path.svg.svelteallocatesdraw-related state lazily.endPoint = createControlledMotion(..., { type: 'none' })was created for everyPath, even when nodrawtransition was configured. Now only created whendrawis set.- The
$effectthat trackedtweenedPathDataforstartContent/endContentpositioning ran on everyPath, even when neither prop was provided. Now only registered when at least one is set. drawKeyis only ever set whendrawis 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.svelteextracts styling props out of...rest.
pathData,class,fill/fillOpacity/stroke/strokeOpacity/strokeWidth/opacityandmotionare 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 (pathDatachanges on every force-sim tick;classis typically a freshcls(...)string per parent render).Link.base.sveltedrops a redundant prop spread.
Removed{...extractLayerProps(restProps, 'lc-link')}before{...restProps}— the call's only contribution (class) was being immediately overridden by the explicitclass={cls('lc-link', …)}that follows, making the spread pure overhead. -
perf: Skip mark-info
$effectfor pixel-mode primitives (#855)registerComponentnow probesmarkInfo()once at construction; if the result is initially empty (pixel-mode primitives wherecx/cy/r/etc. are numbers rather than string/function accessors), it skips creating the tracking$effectentirely. 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.
cxmutates 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 explicitserieson the chart instead.
layerchart@2.0.0-next.61
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,RadialGradientCompound 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,MonthGeo components (
layerchart/geo)
GeoPath,GeoSpline,GeoPoint,GeoCircle,GeoTile,TileImage,Graticule,GeoClipPath,GeoEdgeFadeGraph components (
layerchart/graph)
RibbonHigh-level chart wrappers — pre-composed charts with built-in tooltips, highlights, and series handling
LineChart,AreaChart,BarChart,ScatterChart,PieChart,ArcChartThe 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:
Patternhtml: 14.81 → 0.92 KB (-94%) — HTML implementation is just CSS-string generationLinearGradienthtml: 14.38 → 0.53 KB (-96%)Imagecanvas: 14.95 → 3.73 KB (-75%)Textsvg/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) andCell(-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/svgorlayerchart/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>pathIn 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 theLayer/Axis/Grid/Rule/Highlight/ChartClipPathimport chain it pulls in.Use it for geo maps, custom layouts, or any chart that renders its own primitives directly via the
childrensnippet:<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
corefor users on the agnostic API (transitive cost fromHighlight/Axis/Chart) — a worthwhile tradeoff for the opt-in per-layer savings.See the updated "Bundle Size" guide for the full table, tradeoffs, and when to opt into per-layer imports.
layerchart@2.0.0-next.60
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/Hullstay at root (already lazy-loaded viaTooltipContext).Contour/Density/Raster/BoxPlot/Violin/Thresholdand 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
corepath (#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:BrushContextinChart— only loads when<Chart brush={...}>is set (defaultundefined)DefaultTooltipinChartChildren— only loads whentooltipContextis set and no customtooltipsnippet is providedd3-quadtreeinTooltipContext— only loads whenmodeis'quadtree','quadtree-x', or'quadtree-y'SplineinGrid— only loads when rendering radial linear grid lines (<Chart radial>withradialY="linear")BarinHighlight— only loads when<Chart highlight={{ bar: ... }}>is set (defaultfalse)
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-actionsimports 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 unusedpopover.js— but it stops the Svelte REPL/CDN from eagerly fetching@floating-ui/dom(popover's transitive dep) when consumers loadlayerchartfrom a CDN.
layerchart@2.0.0-next.59
Patch Changes
- fix: Prevent submitting forms when clicking legend buttons (#841)
layerchart@2.0.0-next.58
Major Changes
-
breaking: Merge
ConnectorintoLink, removeConnectorcomponent (#449)Linknow supports both pixel mode (x1/y1/x2/y2props) and data mode (data+source/target/x/yaccessors), mirroring the pattern used by primitives likeCircle,Text, andRect.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 onLink. TheexplicitCoordsprop andConnectorexport are removed.
Minor Changes
-
feat(AnnotationLine): Add
x1/y1/x2/y2props for sloped lines (#449)- Pass any combination of
x1,y1,x2,y2to draw a line between arbitrary points. Missing coordinates fall back to the corresponding axis range (sox1/x2alone still span the y range, etc.). The existingx/yshorthand 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, andlabelYOffsetapplied along and perpendicular to the line.
- Pass any combination of
-
feat(AnnotationPoint): Add
linkprop for ring-note style callouts, plus geo projection support (#449)- Pass
link={true}orlink={{ type: 'beveled', radius: 20, ... }}etc. to draw a<Link>from the ring edge to the label. AnyLinkprop (type,curve,sweep,radius,bend,class, ...) can be passed through. - Inside a geo
<Chart>,x/yare now interpreted as[lon, lat]and projected directly, soAnnotationPointcan be used on maps.
- Pass
-
feat(Connector): Add
'swoop'connector type (#449)New
'swoop'connector type draws a circular arc between source and target, equivalent to ObservablePlot's Arrowbendoption. Configured via a newbendprop (degrees, default22.5) — positive bends right (clockwise from source to target), negative bends left,0draws a straight line. Works in both cartesian and radial modes;Linkforwards it automatically. -
feat(tooltipContext, Voronoi): Add
x/yaccessor overrides and default array endpoint to max (#449)- New
x/yprops ontooltipContextandVoronoiaccept anAccessor(property name string or function). When set, hit-detection points use these accessors instead of the Chart'sx/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/yaccessor ontooltipContext/Voronoi.
- New
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:ctx.datawould silently switch to the filtered subset viaseriesState.visibleSeriesData, causing sibling array-driven marks (like<Link>) to iterate only the subset.- 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.dataalways 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 owndataarray.
Marks with their own data still contribute to
flatDatafor 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 toConnector(defaults to'horizontal').Linkforwards its own orientation so step curves step along the natural flow direction. curveStep,curveStepBefore, andcurveStepAfternow step alongyin vertical orientation instead of always stepping alongx.
- Added
-
fix(GeoPath): Avoid passing
undefinedevent handlers to underlyingPath, preventing a Svelte error while preserving canvas hit-testing for non-interactive paths (#449) -
fix: Allow negative string values (e.g.
y="-6") inTextposition props to be treated as pixel values instead of data property names (#449)
layerchart@2.0.0-next.57
Patch Changes
-
fix(AnnotationRange): Don't extend past chart bounds when
xis omitted on band scales, and treatnullon either side ofx/yas "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 explicitopacitywas spread afterseries.props, clobbering per-series opacity values (e.g.series={[{ props: { opacity: 0.1 } }, ...]}). (#449) -
fix(ChartState): Don't filter explicit
x1Domain/y1Domainby visible series when no series are configured. Restores grouped layout for composable<Chart>usage (e.g.<Bars>withx1/x1Domain/x1Range) where the visible-series filter previously emptied the secondary band scale domain, collapsing all bars to a single category position. (#449)
layerchart@2.0.0-next.56
Minor Changes
-
feat(Circle, Ellipse): Support pattern/gradient
fillvalues on the<Html>layer by switching frombackground-colorto thebackgroundshorthand (withbackground-origin: border-boxto keep patterns aligned under the border). Accepts values produced by<Pattern>/<LinearGradient>in HTML mode. (#449) -
feat(Pattern): Support
<Html>layer by producing CSSrepeating-linear-gradient(lines) andradial-gradient(circles) values usable as abackground/fill. Gradient-valuedbackground(e.g.<Pattern background={gradient}>) is also supported. (#449)
Patch Changes
-
fix(Pattern): Restore canvas layer support by registering as a
groupnode so snippet children (e.g.<Rect fill={pattern}>) render correctly (#449) -
fix(Rect): On the
<Html>layer, setbackground-origin: border-boxso fills/patterns start at the outer edge — previously the CSSbackgroundshorthand reset origin topadding-box, shifting patterns inward byborder-widthwhen a stroke was applied. (#449) -
fix(Rect, Circle, Ellipse): Apply
box-sizing: border-boxon the<Html>layer so the visual extent equalswidth×height(orr * 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, defaultborder-widthto1pxwhenstrokeis set without an explicitstrokeWidth, matching SVG's implicitstroke-width: 1. Also ensures Circle/Ellipseborder-widthgets the requiredpxunit. (#449)
layerchart@2.0.0-next.55
Minor Changes
-
feat(Bar, Bars): Support
<Html>layer (#449)Bar/Bars now render in
<Html>layers in addition to<Svg>and<Canvas>, including per-cornerroundedvariants (top,bottom,left,right,edge, and individual corners). Previously, any non-uniformroundedvalue fell through to a<Path>and was SVG-only. -
feat(ClipPath, RectClipPath, CircleClipPath, GeoClipPath): HTML layer support + unified
pathAPI (#449)ClipPathnow accepts a singlepath: string(SVG pathdsyntax) that drives all three layers:- SVG: rendered as
<path d={path}>inside the<clipPath>element. - Canvas: wrapped in
Path2Dand applied viactx.clip(...). - HTML: emitted as
clip-path: path("${path}")on a wrapper<div>covering the chart container.
This replaces the previous
canvasClip/canvasClipDepscallbacks (and skipped HTML entirely) with a single declarative value. Theclipsnippet is still accepted for advanced/custom SVG content.RectClipPath,CircleClipPath, andGeoClipPathare 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+. - SVG: rendered as
-
feat(ClipPath, RectClipPath, CircleClipPath, GeoClipPath): Add
invertprop to render content outside the clip shape (cutouts/masks) across SVG, Canvas, and HTML layers (#449) -
feat(Line, Rect, Circle, Text): Multi-layer compatible
dashArrayand inline color props (#449)- Added a typed
dashArrayprop toLine,Rect, andCircle. Accepts a number, array, or SVG-style string and maps tostroke-dasharray(SVG),setLineDash(Canvas), and eitherrepeating-linear-gradient(HTML lines) orborder-style: dashed(HTML borders). Previously dashed styling was SVG-only when applied via CSS class or attribute. TextandLineHTML branches now honor thefill/strokeprops as inlinecolor/background, so prop-based colors work across all three layers (not just SVG/Canvas).Grid.x/Grid.yandAxis.gridnow acceptstroke,strokeWidth,opacity, anddashArrayin their object form, matching the props forwarded to the underlying line.Rulealready forwarded arbitrary Line props via spread;dashArraynow works there unchanged.- Exports
parseDashArrayanddashArrayToGradienthelpers frompathutils.
- Added a typed
-
feat(Tree, Link, Connector): Add radial support (#831)
Treenow detects<Chart radial>and lays out withd3.tree().size([2π, min(width, height)/2])plus radial separation. Nodes emit polar coords (x= angle,y= radius).Connectorgains aradialprop (defaults toctx.radial) that interpretssource/targetas polar and dispatches to newgetConnectorRadialPresetPath/getConnectorRadialD3Pathhelpers. Radial behavior per connectortype:straight— straight cartesian linesquare— radial → arc at midR → radialbeveled— chord at source radius with chamfered corner (controlled byradius)rounded— visx LinkRadialCurve Bezierd3—d3.linkRadialby default; with acurveprop,curveStep/curveStepBefore/curveStepAftermap to polar arcs/radials, other curves go throughd3.lineRadial
LinkforwardsradialtoConnectorautomatically when inside a radial<Chart>. -
feat(Rect): Add
cornersprop for per-corner rounding (#449)New
cornersprop accepts either a number (equivalent torx), 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 usesroundRect's per-corner radii, and Html uses the 4-valueborder-radiusshorthand.Also exports a shared
roundedRectPath(x, y, width, height, [tl, tr, br, bl])helper frompathutils for building per-corner rounded-rect path data.
Patch Changes
-
fix(canvas): Compose globalAlpha multiplicatively so Group opacity propagates to children (#831)
Canvas
renderPathDatawas overwritingctx.globalAlphawith 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 viasave()/restore()scoping. Also removes double-application of elementopacityinside the fill/stroke blocks (it's already applied at the element level).