dynamic-smart-labels#799
Conversation
🦋 Changeset detectedLatest commit: 3d29e24 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
built with Refined Cloudflare Pages Action⚡ Cloudflare Pages Deployment
|
| {:else if labels} | ||
| {#each seriesState.visibleSeries as s, i (s.key)} | ||
| <Labels {...getLabelsProps(s, i)} /> | ||
| <Labels {...getLabelsProps(s, i)} placement="smart" /> |
There was a problem hiding this comment.
placement="smart" should come before getLabelProps so it can be overridden (ex. Labels within points)
Note: where this is handled is changing within state-refactor branch/PR, which is going to cause a merge conflict. I might keep this PR open and manually merge into state-refactor once the dust settles there.
| } | ||
| } | ||
|
|
||
| function getDynamicTextProps( |
There was a problem hiding this comment.
Let's call this getSmartTextProps(), although I wonder if we could merge this into getTextProps() (instead of early returning in getTextProps(), capture the baseProps and then use them if placement === 'smart' or return as is if not.
Although not sure how much of baseProps we really need at first glance
techniq
left a comment
There was a problem hiding this comment.
Thanks @cycle4passion! I need to do more work to improve Text with regards to font-size / line-height (defined as class, style, props, etc) and make sure it stays performant, but that's for another day (I've put some thought on it a few times, and need to tackle it)
* Add new docs changeset. ignore docs/examples from changeset
* cleanup changeset
* Version Packages (next) (#791)
* Version Packages (next)
* Update CHANGELOG for version 2.0.0-next.44
Updated CHANGELOG to reflect breaking changes, new features, and fixes in version 2.0.0-next.44.
---------
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* Setup OIDC publishing
* Fix @dagrejs/dagre "module is not defined" SSR error
Move @dagrejs/dagre to ssr.external instead of ssr.optimizeDeps.include.
The experimental ssr.optimizeDeps pre-bundling wasn't converting the
CJS module to ESM. Externalizing lets Node.js load it natively as CJS.
* update deps
* update content-collection and eslint
* Update Svelte to 5.51.5 (before rollup issue of 5.52.0)
* Rename collections => content after updating content-collections
* Update dagre 1.1.8 => 2.0.4, fix CJS/ESM build and dev issues
* fix: Workaround Svelte 5.52+ regression (Parse failure: Expected '{', got '(')
* Version Packages (next) (#792)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update examples to latest `layerchart@next` release
* fix direct loading of example after enabling SSR
* Improve loading boundary display
* Fix SSR display of examples browse info
* Improve display of Search with SSR
* Disable SSR for examples page
* initial pass Auto-Showcase (#798)
* initial pass
* Fix typo
* Show star count
* Switch getDependents from runtime query to build-time prerender and parallelize GraphQL batch requests to reduce fetch time from ~44s to ~6s.
* pass built-in GITHUB_TOKEN when building for prerender()
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* Use a dedicated github token instead of the provided GITHUB_TOKEN for API access
* Enable full page prerender for showcase
* Fix some rehydration errors due to nested `<a>` tags
* Add conditional rendering for edit link and remove style to hide it
* Add star counts to featured/supporter/highlighted sites and fix dedup. Organize
* Correctly set llms.txt base url based on deployed origin (use next.layerchart.com instead of layerchart.com)
* on the README.md. The NPM badges were formatted incorrectly causing an underline (from link status) between dl/month and d/l week. This fixes that. (#803)
* Move "Become a sponsor" link to the correct location
* Update deps (include Svelte UX, fixing MenuField chevron)
* Downgrade unocss examle from Vite 8 => 7 (not compat yet)
* Update deps
* fix(TooltipContext): correct hit detection by accounting for chart padding (#806)
* State improvements (#663)
* Geopoint icons remove controls (#772)
* fix for empty layers toggle showing small circle
* geopoint-icons-remove-controls
* Additional axis examples (#764)
* fix for empty layers toggle showing small circle
* New barchart-xinterval-xinset and linechart-tickspacing
- updates to Axis.md and BarChart.md text
- updated Scatterplot domain-nice to use Switch instead of autotoggling
* added needed padding
* Add `tickSpacing` @default to jsdoc
* refine docs
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* feat(Chart|Svg): Support passing `clip` prop to hide overflown content
* also add for `<Html>` layers
* Clipping (#774)
* Text trunc wrap fix (#775)
* Update deps (namely Svelte to 5.48.2 with dev-mode performance improvements)
* Add clip to collision detection example
* cleanup import
* Stats (#776)
* fix for empty layers toggle showing small circle
* initial
* move to footer
* Landing Page Stats
- Stats handled by src/lib/Stats.svelte
- stats loaded via svelte remote function $lib/stats.remote.ts
- stats nonblock via {#await}
- for scrolling NPM downloads - Used ScrollValue from Svelte-UX
- npm scrolling paused if not in viewport (used runed inViewport). This allows for consistent 1st visualization.
- npm scrolling also pauses if npm hovered - less jarring
- all stats are links to corresponding pages (NPM, Github, Discord, Bluesky)
- responsive design dropping to block at small screens
* refine using runed's useInterval with pause/resume
* Use `GITHUB_API_TOKEN` if available (docs/.env, env var). Improve error handling
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* Missing clips (#778)
* fix for empty layers toggle showing small circle
* missing-clips
* add `User-Agent` header to make Github happy when running in Cloudflare - https://docs.github.com/en/rest/overview/resources-in-the-rest-api#user-agent-required
* Open in LLM feature (#753)
* Open in LLM feature
* removed grok
* open-in-llm-component
- rewrote copy for LLMs
* minor copy change
* used markdown icons
* llms.txt - 3 levels
1. Individual pages like `layerchart.com/docs/components/Linechart/llms.txt .`
2. Site links index at `layerchart.com/llms.txt`
3. Complete text at `layerchart.com/docs/llms.txt .`
API endpoint creation for sections
1. Getting Started
2. Guide Pages
3. Components
4. Individual Examples
5. Utils
Added processMarkdownContent(content) to handle custom markdown conversion to vanilla MD for LLMs. In `docs/src/lib/markdown/utils.ts`
* fix spelling error
* another spelling fix
* Change OpenLLMs.svelte to OpenWithButton.svelte
- cleaned up logic on `ddocs/src/routes/docs/guides/[name]/llms.txt/+server.ts` was getting title by url name, now uses frontmatter like others.
* Change "View Page Markdown" to open in modal
* refine OpenWithButton
* update `p` markdown component to only apply margins when within main (not nested in note, blockquote, etc)
* refine some wording
* Create guides content collection and use to build menu
* Extract and consolidate common llms.txt utils
* Add common sortCollection util
* add component links to examples llms.txt
* consolidate more logic into llms/utils.ts
* Replace `fs`/`path` usage with Vite's `import.meta.glob`
* Move processMarkdownContent to llms/utils.ts
* processMarkdownContent within generateComponentMarkdown / generateUtilMarkdown
* include `:example { }`directives
* cleanup
* move related section to bottom of component docs (also matches llms.txt)
* Add examples to component llms.txt
* Rename `Component docs` to just `Components` when viewing an example
* Extract generateExampleMarkdown from request handler into llms/tuils.ts
* move generateFullLlmsTxt to llms/utils.ts, always use markdownResponse (remove textResponse)
* move generateLlmsTxt to llms/utils.ts,
* replace generateGuidesSection with generateCollectionListSection
* Uwe docsUrl in `inlineExampleDirectives` and `generateComponentMarkdown` to build example links
* remove unneeded exports
* cleanup types
* delete outdated tests
* update docs test setup to match packages/layerchart
* add llms tests and add to ci
* Add LLMs link to frontpage footer
* Update LLMs docs
* Disable docs tests until contentCollections() can be enabled without triggering `__dirname is not defined`
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* Update deps
* fix dagre `module is not defined` after bumping deps (but not dagre to v2). If dagre was bumped to v2, was getting: `"Dynamic require of "@dagrejs/graphlib" is not supported"`
* Tree clips (#779)
* fix for empty layers toggle showing small circle
* add missing clips for tree examples
* fix build
* extract table of contents from markdown instead of html
* add toc to guides
* improve header and toc slugs when `:icon{..}` directives are used
* remove `meta.tableOfContents` and just use `metadata.toc` to determine when to display toc. Add toc to getting starting but disable until heading improved
* Use IntersectionObserver for improve active highlighting
* Update deps
* Clip force text example
* flexsearch (#745)
* flexsearch
- command-K toggles open/close
- Escape toggles search closed, clicking outside search box toggles closed
- used runed persistedState to show last 5 searches - seen only after selecting a search option, and 2nd
search
- supports clearing prior searches
- needs some styling help
- dummy data needs replaced.
* update pnpm-lock.yaml
* Fix catalog example paths
* Remove outdated examples (markdown) content collection
* Build search index using content collections and examples catalog, and use remote function to query
* Cleanup search
* Improve display of search results
* improve display of search results
* fix sticky search input
* refine results
* move stripMarkdown to lib/markdown/utils
* refine results
* refine search styling
* Fix reactivity when loading examples
* support searching from home page
* Use `@layerstack/svelte-state` instead of '@layerstack/svelte-stores' for javascript media query
* Refactor search functionality: replace remote search with local index and improve search performance
* improve search
* Dynamically import search module to avoid SSR bundling issues (fix Cloudflare)
* Add quick links when no search is set
* Add support for headings in search entries
* Add top-level navigation to search
* Use preprender remote function instead of API server endpoint and fetch
* Revert "Use preprender remote function instead of API server endpoint and fetch"
This reverts commit f9427de4a010242b56810494a1e089e1dced0a4c.
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* Cleanup headers (especially remove duplicate "## Examples" headers causing key error)
* add playwright-cli skills
* fix parent component's table of contents showing on examples
* generate:all (catalog, screenshots)
* remove "actions" export
* Add LineChart threshold example
* fix threshold with linear gradient examples
* add links
* Do not highlight/mark examples in search
* Ignore anchor tags / hash fragment (ex. `#examples`) in llms.txt URLs
* fix(Threshold): Properly clip `above` snippet (resolving 1/2 width clipping issues when using Spline)
* refine
* Add `defaultExample` to `components` collection to use first on docs (ex. BarChart.md) and fallback to first example in catalog (ex. BarChart.json).
Use ComponentLink for example component links and also Related section in docs
* Improve ExampleScreenshot when image is not available, with fallback icon
* Improve primitives doc
* fix border on light mode
* cleanup
* docs(Points): Add docs regarding color
* Add Nocturne to showcase
* fix(showcase): handle source-only items
* Cmd K (uppercase) (#784)
* Fix loading web containers
* remove color from Axis/arrow-markers example
* Extract ExampleListing component and show additional examples at the bottom of an example
* Improve/fix histogram examples (better axis ticks and use Rect instead of Bar)
* fix(BarChartControls): handling of interval and threshold sizing
* generate:all to update catalog and screenshots
* Hide playground menu item until it's more polished
* fix clipping
* fix showing component source for layers (Layer, Svg, etc)
* fix(Bar): Fix bar rounding direction when using xReverse/yReverse with interval scales
* fix(Bar): Fix bar rounding direction when using xReverse/yReverse with interval scales
* remove reverse/annotations from example
* Move data doc to content/guides like other guides
* Remove old reference
* remove unneeded page test
* Fix Arc tooltip test
* Integrate SeriesState into ChartChart and improve handling of series data
* Improve examples page on small viewports
* Improve animated globe example on small viewports
* feat(Chart): Add cartesian pan/zoom via `transform={{ mode: 'domain' }}` with single or both axis support. Resolves #366
* Improve interop between brush and transform
* Automatically clip marks when using transform mode: 'transform' (like `brush`). Add BarChart examples
* feat(Chart): Support `motion` prop to transition x/y scales using tween or spring
* Add a fallback transformState until bind is applied
* Update catalog and screenshots
* Fix tootip/highlight handling for ScatterChart
* Fix AreaChart with separate series data
* Fix tooltip for ScatterChart single dimension example. Remove grid from BarChart single dimension
* fix light mode screenshots
* Update remaining examples for `<Chart tooltip={...}>` => `<Chart tooltipContext={...}>` rename (needed for `tooltip` snippet)
* Fix disabling tooltip context
* Move brush, padding, and onTooltipClick from simplified charts (Area, Line, Bar, Scatter) to Chart/ChartState
* Update catalog
* fix(Area|Highlight): Properly handling diveraging stack layouts for negative values (line, highlight point). Resolves #677
* Add support for setting scale, transcale, domain extents and custom constrain handler. Add docs
* regenerate catalog and screenshots
* Replace `geo.applyTransform` with `transform.mode: 'projection' | 'rotate'`
* Support category for guides, group state docs
* simplify example
* organize doc
* fix translucent / backpane example (remove unneeded transform state sync in GeoProjection)
* Swap order of play/pause and current feature after moving button from right to left side
* Rename domainExtent `original` to `data`
* Add examles for different `zoomTo` use cases
* Add examples for each quick reference use cases
* cleanup
* Add pan zoom with dynamic data example
* Clip highlight/points/labels as well when transform is enabled
* feat: Add inertia (momentum) support for transform drag gestures
* Update data examples to use Chart instead of LineChart
* feat: Data driven primitives
* fix(TooltipContext): Support band mode with array-based range accessors (e.g. histograms using `x={['x0', 'x1']}`)
* Simplify histogram examples using new data-driven primitives
* Moved valueAxis-aware grid/rule defaults from BarChart into ChartChildren for all chart types
* regenerate catalog and screenshots
* add planet distances example (TransformContext and more)
* feat: Add Image component. Resolves #628
* Improve planet distances example
* regenerate catalog and screenshots
* add inertia dragging to animated globe
* Remove `transform={{ mode: 'rotate' }}` and handle with `transform={{ mode: 'projection' }}`. Add `transform={{ apply: { translate: boolean, rotation: boolean, scale: boolean } }}` for granular control (and support zoom with rotation)
* Add pan zoom domain extent example for BarChart
* feat: Add Cell mark. Resolves #627.
* feat: Add Chord layout and Ribbon primitive
* Add gradient example
* Fix html pan/zoom image
* Add Chord example with axis ticks
* Add ridgeline example
* Improve ridgeline example
* Add another ridgeline example
* generate catalog and screenshots
* Add more examples to homepage
* Add oscilloscope-ridgeline example (WIP)
* Reduce Cloudflare Worker bundle size to stay under 25 MiB limit
Load shiki dynamically on the client only (using the lighter bundle/web) and externalize shiki + CodeMirror from the SSR bundle since they are not needed server-side.
* Improve Chord/ticks example and fix "negative radius" error in Chord/Ribbon
* re-add codemirror to allow resolving
* Improve Chord/hover tooltips
* feat: Add geo projection support for primitives (Circle, Rect, etc). Also enable motion support when using data mode.
* Add College football map example
* feat(Spline): Support geo projection. Add geo route example
* Move geo-route example from line to spline
* Improve oscilloscope frequency example (clipped high/unused frequencies)
* Add satellite example
* Fix hash target scrolling
* feat: Add Vector component
* Update primitives to support data driven class, opacity, etc
* Improve election-wind-map example
* Replace flow-field example with wind-map
* update catalog and screenshots
* fix(Highlight): Use valueAxis instead of Array.isArray(yValue) for axis detection to avoid incorrectly showing horizontal highlights on grouped/stacked series charts
* Add BarChart series-stack-separate-data example (issue #486)
* fix(Points|Labels): Correctly position when using x1 / y1 scales (issue #773)
* fix(Points|Labels): Correctly position when using array accessors (duration charts, etc). Fixes #633
* update catalog and screenshots
* feat(Bar): Support fixed `width` and `height` props to override scale-derived dimensions, centering the bar within its band. Resolves #360
* feat(Labels): Support `seriesKey` in `labels` prop to filter which series renders labels. Resolves #633
* update catalog and screenshots
* breaking(Brush): Redesign brush API
* feat(SeriesState): Support passing `selected` as part of series declaration (Ex. ` <Chart series={...}>`). Add docs (including programmatic control example), and tests
* Fix baseline for multi-series charts
* Show guides not in category (ex. layers.md) before those in category (ex. state / brush.md)
* improve layout
* feat(TransformContext): Add `scrollActivationKey` option to require a modifier key (meta, alt, control, shift) for scroll/wheel zoom/pan, preventing accidental page scroll from triggering transforms. Also rename `initialScrollMode` to `scrollMode` and make it reactive
* Fix brush sync beteween 2 charts (AreaChart/brush-sync)
* Fix zoomOnBrush test
* docs: Add tooltip guide
* Add links between guides and context/api
* refine
* cleanup
* Remove explicit order from guides (sort alpha) except overview
* Fix GeoSpline
* Add geo guide
* clip histogram examples so transitions do not extend passed container
* generate catalog and screenshots
* Add animation guide
* Update state overview
* feat: Mark registration for implicit series/domain calculation and unified component tree for Canvas rendering
Marks register data, accessors, and colors with Chart via registerMark() for automatic domain calculation and implicit series generation, eliminating the need for explicit y={[...]} or series props. A new registerComponentNode() API replaces the flat Canvas registry with a tree structure, fixing Group transform scoping (fixes #662) and providing composite-mark detection for child marks.
* Improve data guide
* Add test to check if domain is updated when hiding implicit and explicit series
* Add structure guide to explain snippets and Chart / simplified chart
* Setup`pnpm bench` to help with performance evalulation
* refactor: consolidate registerMark into registerComponentNode
* cleanup for clarity (number accessor is only used recursively in accessor() with x={[0, 1]})
* feat: implement edge rounding for stackDiverging layout in BarChart
* feat: add `downloadImage`, `downloadSvg`, `getChartImageBlob`, and `getChartSvgString` utilities to export charts as PNG/JPEG/WebP images or SVG files
* refactor: consolidate component tree and mark registration into ChartState
* fix(Canavs): support `strokeOpacity` for Path component
* Remove outdated warning
* fix(Text): handle inline styles and CSS class-based text-anchor
* test(canvas): add comprehensive test suite for canvas utility functions
* fix(ClipPath): Support canvas layers. Resolves #660
* fix(Canvas): support event handlers on Group components in canvas mode
* fix(Rect): Handle strokeOpacity when using canvas layers
* fix(docs): strip markdown links from TOC heading text
* fix(TransformState): properly handle y axis when in domain/cartesian mode
* feat(Highlight): Support data-driven radius for highlight points. Add docs
* Add a pan/zoom with overview example to show how transform/brush can work together with separate charts
* Add zoomable bubble chart example for ScatterChart
* update catalog and screenshots
* docs: Add world map transform examples (canvas & projection modes) with click-to-zoom
* docs: Add world transform examples (canvas and projection) similar to US
* feat: Support continuous color scales via `cScale` prop without requiring `cRange`. Simplify LineChart/gradient-encoding example
* Add migration guides: `v1 -> v2` and `next -> state-refactor`
* Improve v1 => v2 guide
* feat: Add BoxPlot and Violin components
* fix typos
* cleanup
* improve styles doc
* feat: Add Contour, Density, Raster components
* update catalog and screenshots
* docs: Add seriesKey mark awareness and get*Props removal to migration guide
* feat: Auto-compute Bar/Bars mount animation initial values from chart scales
Bar now automatically derives `initialY`/`initialHeight` (vertical) or `initialX`/`initialWidth` (horizontal) from the chart's scale range when `motion` is configured, removing the need to hardcode pixel values.
Also improves `valueAxis` inference on `ChartState` — when not explicitly set, it is now derived from scale types (band scale on y → `valueAxis: 'x'`, band scale on x → `valueAxis: 'y'`).
* fix: `flattenPathData` now handles relative arc commands, fixing rounded bars starting below the baseline during mount animation
* fix(Area): Handle degenerate domains (e.g. all-zero data) and unify y0/y1 baseline logic
* fix LineChart defining single axis (<LineChart axis="x">)
* Handle class for new statistic components
* Show canvas support for Density
* Add Density/weighted example
* feat(Spline): Add motion support for mount animation from baseline
* Add tween examples for Area/AreaChart/BarChart/LineChart
* generate catalog and images, add more examples to frontpage
* Add tooltip circle to college footmap map
* fix(Tooltip): Apply inverse transform for quadtree lookup when zoomed/panned
* Improve perf of college football map by using canvas instead of projection mode (and scale images/etc based on zoom)
* Improve Density/walmart example with pan/zoom, tooltip, and improved data
* Improve Raster/math-functions example
* Update Raster to support Canavs and Html layers (not just Svg)
* Move download after Edit
* Add contours switch to Raster/math-functions
* Fix tooltip value resolution for ArcChart series with per-item data by falling back to ctx.x when ctx.y is unset
* fix(Area): Default y0 baseline to chart's yBaseline when set
* Improve handling of arc/pie chart tooltips
* Cleanup ChartState
* fix series colors without breaking color scale
* Improve tooltip data handling for quadtree and voronoi modes
* Update and use DefaultTooltip for ScatterPlot use cases
* fix(Tooltip): Fade non-highlighted series items on hover to match chart highlight state
* Improve migration guide, handle diff formatting
* improve diff style
* Cleanup migration guides
* Lazily load Example unless on detail view or initially within viewport
* Add TransformContext/pan-zoom-axis example
* update catalog and screenshots
* improve TransformContext/planet-distantces example
* Fix handling of x1Domain when toggling series/legend
* Move scale/domain/baseline/nice logic from BarChart into ChartState
* update catalog
* add logging
* Add safeguard for explicitly using Examples header
* Register Dagre as composite-mark to prevent child marks from polluting chart scales with raw layout coordinates
* Rename `registerComponentNode` to `registerComponent`
* update text docs
* Use ChartState type instead of removed ChartContextValue
* Remove stroke from eclipses example
* Fix BarChart regressions from ChartState scale/baseline refactor
- Fix yReverse checking props.yScale instead of resolved _yScaleProp, which reversed band scale domain order (horizontal diverging bars)
- Fix xInterval/yInterval not taking precedence over bandPadding for scale selection, collapsing time-based bars into a single band
- Fix auto-baseline ignoring explicit null by using !== undefined check, and update single-stack example to use xBaseline={null}
* Update Density/walmart to scale stroke/radius by zoom/scale
---------
Co-authored-by: Scott Rhamy <scottrhamy@me.com>
* Fix changeset
* Version Packages (next) (#807)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Improve primitive geo docs
* fix(ChartState): Don't create spurious implicit series when mark accessor matches chart's own axis accessor, fixing domain corruption for heatmap/Cell charts
* Version Packages (next) (#808)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Fix Spline/gradient.threshold example
* feat(Raster, Contour): support bounded geo raster overlays with projected interpolation
* fix(LinearGradient, RadialGradient): Register as `group` instead of `mark` in canvas component tree so wrapped children (e.g. Arc, Path) are rendered
* Add gauge, speedometer, and clock Arc examples
* add waterfall example
* Add gauge-gradient example and improve speedometer
* feat(Text): Add `format` prop and tween numeric `value` when `motion` is configured
* Add comapny and proramming language bar chart race examples
* improve gauge gradient example
* generate catalog and screenshots
* Update frontpage examples
* dynamic-smart-labels (#799)
* dynamic-smart-labels
* Merge getDynamicTextProps into getTextProps. Add example
* Add changeset
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* Add squares to markers (#805)
* Add squares to markers
Documenation listed squares as an option, but this did not exits. I have added 'square' and 'square-stroke' as options. I have also updated line and spline examples to illustrate it.
* Add changeset
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* feat: Month component (#671)
* Add Month component (WIP)
* Support start/end that do not align on year boundaries (ex. last 90 days)
* Refactor Month component to remove unused rangeMonths and enhance month label generation
* Update monthLabelHeight calculation to conditionally account for label visibility
* Update Month component to use current date as end date instead of last day of year
* cleanup examples
* remove old Month docs
* Remove `optimizeDeps.include` from vite.config.js (not needed anymore for "optimized dependencies changed. reloading" issues
* 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.
* 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.
* Allow passing `null` to ignore tickSpacing for band scales
* update catalog and screenshots
* Add "Best match" group to search results for title matches
Prioritizes results whose title starts with or contains the search query, showing them in a "Best match" group above regular results.
* Fix searching before index is loaded
* fix(GeoPath): Fix canvas tooltip by conditionally passing onclick to Path, preventing non-interactive overlays from capturing hit canvas events
* fix(TransformContext): Reactively sync `processTranslate` and `disablePointer` to TransformState when props change. Fixes inverted globe dragging when dynamically switching between flat and globe projections.
* fix(Chart): Enable scroll zoom for globe projections by including `scale: true` in default `transformApply` for globes.
* feat(Chart): In projection mode, `scaleExtent` and `translateExtent` are now interpreted as relative values. `scaleExtent: [0.5, 8]` means 0.5x to 8x of the fitted projection scale. `translateExtent` is offset from the initial fitted position in pixels.
* Add GeoProjection/true-size to easily compare countries and us state with one another across different projections (mercator, orthographic, natural earth, etc)
* perf: Optimize primitive component instantiation (~3-5x faster for Rect, Circle, Ellipse, Line, Text, Path, Group)
* fix(bench): Reduce primitives benchmark to prevent browser tab crash during bench:save
Trim to 5 representative primitives (rect, circle, group, text, path) and cap scaling at 250 instances. The full suite with 7 primitives and 1000-instance scaling accumulated enough memory to crash the browser tab when run alongside all other benchmark suites.
* feat(Spline): Support function-valued `stroke`, `fill`, and `opacity` for per-segment styling
* Update catalog and screenshots
* Version Packages (next) (#810)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix(Axis): Default `tickSpacing` to `null` for band scales, showing all ticks by default instead of thinning them. Use `tickSpacing={80}` to opt-in to tick thinning on band scale axes.
* Add interpolating projections examples
* 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.
* Support custom example title and description via <script module> exports
Examples can now export title and description from a <script module> block to override the filename-derived title and add a description. These are extracted by the catalog generator, displayed in the component layout and example listings, and indexed for search (both browse page filter and command+k).
* fix(Spline): Make motion prop reactive so toggling between tween/none updates without remount
* feat: New Trail component for variable-width lines
* generate catalog and screenshots
* Version Packages (next) (#812)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Add examples to frontpage
* Ignore bench tests when running `pnpm test:unit`
* fix: Skip mark x/y/data from domain/series calculation when geo projection is active
* SSR chart images (#813)
* Initial progress
* Add more examples and docs
* Support passing background color as query param
* Fix SSR image support Grid, Axis, and Rule. Add tests. General improvements
* fix `pnpm check`
* Prerender chart API endpoints for Cloudflare compatibility and document edge runtime limitations
* Skip url.searchParams during prerendering to avoid SvelteKit build error
* Fix geo chart server-side rendering by converting GeoState projection from $effect.pre to $derived.by
* cleanup old changes.md
* Add geo SSR image example
* Add Sankey, Tree, and Treemap examples
* Improve treemap example (text/clip)
* Use `workspace:*` instead of `next` for `examples/*` projects to make sure `pnpm build:examples` is always using up to date library
* fix: improve compatibility with UnoCSS Svelte scoped preprocessing
* Remove unneeded changeset
* Reduce changeset level for stroke/fill improvements
* GeoRaster component (#815)
* 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
* 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]`)
* Update catalog and screenshots. Add GeoRaster examples to frontpage.
* Add spinning to planet example
* Version Packages (next) (#814)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat(Labels): Add `middle` placement and change `center` to center within the bar body. Improve docs. Resolves #378
* New ArcLabel component (#817)
* feat(ArcLabel): New component for positioning text labels on arc segments. Resolves #7
* Add labels to Partition/sunburst example
* Default `PieChart labels` to `placement="callout"
* Remove ArcChart/labels and just use ArcChart/series-labels example in docs
* update catalog and images
* Legends (new CircleLegend and GeoLegend) and value indicator (tooltip, explicit) (#818)
* feat(CircleLegend): New component for visualizing radius (`rScale`) values as nested circles
* update catalog and screenshots
* feat(GeoLegend): New scale-bar legend showing real-world distance for the current `Chart` projection
* update catalog and screenshots
* Update bubble-map to use integrated cScale and rScale, and use data-driven Circle
* feat(Legend, CircleLegend): Show an indicator of the current tooltip value on the legend
* update catalog and screenshots
* persist-series-brush (#819)
* persist-series-brush
- add 2 examples showing using bind:context for external programmatic control for localStorage persistance of series selection and brush/zoom state.
- update guide:brush and guide:series referencing these examples.
* persist-series-brush
spelling fix
* Fix reactivity of peristed examples
* update catalog and screenshots
* Revert "update catalog and screenshots"
This reverts commit 21076af93112a949bf7158a8bf13c36782a978c7.
---------
Co-authored-by: Sean Lynch <techniq35@gmail.com>
* update catalog and images
* Version Packages (next) (#816)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* feat: Support pre-projected topologies in `GeoLegend` via `referenceScale`
* Version Packages (next) (#820)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Upgrade deps
* fix: Skip known routes when resolving individual example pages in component layout
* fix: Move top-level await to <script module> in example components to prevent browser lockups
Components using $derived(await fn()) or top-level await in instance <script> became async, overwhelming Svelte's scheduler when many rendered simultaneously (e.g., scrolling example pages).
Since the data functions use SvelteKit's prerender (static data), moving await to <script module> makes components synchronous — data loads once at import time, not on every render.
* fix: Restore bind:this on example component for Data button
* Update `compound-common-scale-with-extra-marks` to only show support for `svg` and `canvas`
* Fix build
* feat: New `GeoClipPath` component for clipping content to GeoJSON boundaries in both SVG and Canvas modes
* Update catalog and screenshots
* feat(Text): Add `segments` prop to `Text` component for inline mixed-style text
* Update catalog and screenshots
* 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
* Update test after fixing Arc xRange handling
* Fix Canvas support for some Partition examples by using Text component instead of text elements
* fix(ArcLabel): Support rotation in Canvas mode
* cell-punchcard (#826)
* cell-punchcard
- fixed color of cells in HTML
- fixed Week and Week # appearing different lines on HTML using non-btreaking space
* cell-punchcard
- fixed color of cells in HTML
- fixed Week and Week # appearing different lines on HTML using non-bteaking space
* Change SVG for download (#822)
* Change SVG for download
* Rename `Download` to `Export`
* Motion examples using showField.svelte do not show/start until in view. (#821)
* Motion examples using showField.svelte do not show/start until in view.
used runed useIntersectionObserver
1 second delay after visibility
fires only once
added wrapping divs for reserved height for simplechart w/comment
removed TODO FIXED.md - old, never used, github takes precedence
* Motion examples using showField.svelte do not show/start until in view.
used runed useIntersectionObserver
1 second delay after visibility
fires only once
added wrapping divs for reserved height for simplechart w/comment
updated MotionPathControls to use showField
gave showfield option for "inline" not absolutely positioning
removed TODO FIXED.md - old, never used, github takes precedence
* Motion examples using showField.svelte do not show/start until in view.
updated multicontrols to use showField.svelte where appropriate.
updated additonal motion examples using those controls.
* math-formula (#824)
* math-formula
* Move mathjs to dev deps
* Use MenuField with stepper instead of Radio
* Add raster toggle
* Merge branch 'next' into pr/cycle4passion/824
* Add color interpolator input
* Fix Cloudflare Pages deploy by externalizing mathjs from SSR bundle
* Improve Hull and Contour docs
* fix(docs): dynamically import mathjs to avoid Cloudflare Workers deploy failure
* feat(Hull): Add CommonStyleProps (fill, fillOpacity, stroke, strokeOpacity, strokeWidth, opacity) for Canvas layer compatibility
* Update catalog and screenshots
* feat(Tooltip): Portal tooltip to body by default to fix overflow clipping. Resolves #446 (#828)
* feat(Tooltip): Portal tooltip to body by default to fix overflow clipping. Resolves #446
* feat(Tooltip): Add `fadeDuration` prop to control fade in/out transition
* Version Packages (next) (#827)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Update catalog and screenshots
* Fix searching example for "true"
* Add GeoProjection/true-size-globe example
* Add GeoPath/paint-brush-selection
* Update catalog and screenshots
* Add pan/zoom to pain-brush-selection example
* Correct layer support for ArcLabel, *ClipPath, Contour, Group, and Tooltip (they support canvas)
* fix clipped-area-on-tooltip example
* feat(Bar, Bars): Support `<Html>` layer
* Update ChartClipPath layer support
* feat(Line, Rect, Circle, Text): Multi-layer compatible `dashArray` and inline color props
* feat(ClipPath, RectClipPath, CircleClipPath, GeoClipPath): HTML layer support + unified `path` API
* docs: derive example layer toggle from used components
Narrow the layer toggle on an example page to the intersection of each used component's `layers` frontmatter, so e.g. a Chart example containing a Spline only exposes [svg, canvas] in the toggle.
Affects 61 example toggles across the docs: 58 drop `html` (due ot path-geometry primitives such as Area, Spline, Arc, GeoPath, etc) and 3 drop`canvas` (due to Threshold/Blur).
* feat(ClipPath, RectClipPath, CircleClipPath, GeoClipPath): Add `invert` prop to render content *outside* the clip shape (cutouts/masks) across SVG, Canvas, and HTML layers
* update catalog and screenshots
* docs: Update ClipPath docs with `clip` snippet and `useId` examples
* Add text selectable/copyable feature to layers table
* feat(Tree, Link, Connector): Add radial support (#831)
* Improve Tree controls
* feat(Tree, Link, Connector): Add radial support
* fix(canvas): Compose globalAlpha multiplicatively so Group opacity propagates to children
* Rename "basic" example to "playground", improve playground, and add new basic
* Show error message when an example fails to render
* improve root node links for step curves
* Improve tree playground example
* update catalog and screenshots
* Delay screenshots motion (#833)
* delay-screenshot-motion
since adding lazy loaded charts which contain motion, screenshots for them are firing before they are rendered.
I added "lazy-loaded" class to showControl.svelte, and check for that in generate-screenshots.ts. If found introduce pause to allow them to fully render.
* delay-screenshot-motion
since adding lazy loaded charts which contain motion, screenshots for them are firing before they are rendered.
I added "screenshot-delay" class to showControl.svelte, and check for that in generate-screenshots.ts. If found introduce pause to allow them to fully render.
* strong-webkit-fix (#832)
Currently <strong> text elements rendering dark Safari in darkmode. Webkit treats color: initial on inline replaced/formatted elements differently than Chrome/Firefox. The most reliable fix is avoiding inherit entirely and just setting an explicit color directly
Example [Transform](https://next.layerchart.com/docs/guides/transform#pointer-interactions)
Fix has been tested for dark and light modes in Safari, Chrome, Firefox.
* Version Packages (next) (#829)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix(Pattern): Restore canvas layer support by registering as a `group` node so snippet children (e.g. `<Rect fill={pattern}>`) render correctly
* 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.
* 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.
* 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.
* prettier
* Version Packages (next) (#834)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* fix screenshot delay logic
* 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".
* docs(Text/Segments): Fix Html styling
* fix typo
* update catalog and screenshots
* 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 } }, ...]}`).
* 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.
* update screenshots
* Version Packages (next) (#835)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* docs(releases): Auto-fetch releases on publish. Trigger prod deploy on `release: published`, add `generate:releases` to `prebuild` (and `generate:all`) so each build pulls the latest from the GitHub API, and have the script use `GITHUB_API_TOKEN` to avoid the unauthenticated rate limit.
* docs(releases): Move generated output to a new `docs/generated/` dir (`src/generated/api/` → `generated/api/`, `src/content/releases/` → `generated/releases/`) — this also keeps mdsx's `.md` preprocessor away from the release files, which was choking on `{`/`}` in arbitrary GitHub release-note text.
* fix-header-link-onhover (#836)
- this fixes the previous issue on Steps where too little space between left col of circled numbers/line and right content header text. When you hovered the header line the popup link icon overlapped the circle.
- also better aligned circles w/header text.
- fixed checkmark as last content of circle.
* getting-start-text (#837)
- fixed some wording
- adding note referencing setup darkmode
- cleaned up content to 'git up and running quicker' tabs
* Improve code examples in release notes (including diff)
* docs(search): support multi-word queries
bestMatchRank now tokenizes the query, requires every token to appear in the haystack (title + component name for examples), and requires at least one token in the title — so e.g. "tree playground" or "playground tree" promotes the Tree/playground example to "Best match" while keeping long-content guides whose titles don't match out of the top group.
getSnippet and highlightMatch now operate per-token: the snippet anchors on the earliest token hit and all tokens are highlighted via a single alternation regex.
* docs(search): support `tags` export on examples
Examples can now declare search keywords via `export let tags = [...]` in their `<script module>` block. The catalog generator picks them up (also accepting `export const`), threads them through to the search index, and includes them in the "Best match" haystack alongside the title and component name — so e.g. tagging the Tree playground with `['tiger']` makes it discoverable by that keyword.
* fix(Text): Allow negative string values (e.g. `y="-6"`) in position props to be treated as pixel values instead of data property names
* fix(Connector, Link): Orient d3 step curves by `orientation`
* feat(Connector): Add `'swoop'` connector type
* breaking: Merge `Connector` into `Link`, remove `Connector` component
* add links and types examples
* fix(Chart): Explicit `<Chart data>` now takes precedence over marks' implicit-series data
* fix domain handling
* feat(tooltipContext, Voronoi): Add `x`/`y` accessor overrides and default array endpoint to max
* add bended arrows/link example
* generate catalog and screenshots
* add more Link related components
* Remove Connector from Path related
* feat(AnnotationPoint): Add `link` prop for ring-note style callouts
Pass `link={true}` (or `link={{ type: 'beveled', radius: 20, ... }}`, etc.) to draw a `<Link>` from the ring edge to the label. The link source sits on the ring in the direction of `labelPlacement` (diagonals land on the ring at 45°); `labelXOffset` / `labelYOffset` extend the label further along that direction without rotating the ring intersection. Any `Link` prop — `type` (`straight`, `square`, `beveled`, `rounded`, `swoop`, `d3`), `curve`, `sweep`, `radius`, `bend`, `class`, etc. — can be passed through.
Also renames the internal connector utilities to match:
- `$lib/utils/connectorUtils.js` → `$lib/utils/linkUtils.js`
- `ConnectorType` / `ConnectorSweep` / `ConnectorCoords` / `PresetConnectorType` → `LinkType` / `LinkSweep` / `LinkCoords` / `PresetLinkType`
- `getConnectorPresetPath` / `getConnectorD3Path` / `getConnectorRadialPresetPath` / `getConnectorRadialD3Path` → `getLinkPresetPath` / `getLinkD3Path` / `getLinkRadialPresetPath` / `getLinkRadialD3Path`
* feat(AnnotationPoint): Add geo support
* fix(GeoPath): Avoid passing `undefined` event handlers to underlying `Path`, preventing a Svelte error while preserving canvas hit-testing for non-interactive paths. Fixes #840
* feat(AnnotationLine): Add `x1`/`y1`/`x2`/`y2` props for sloped lines
* update catalog and screenshots
* Retry unauthenticated if the provided token is rejected
* Add AnnotationLine/playground example
* update catalog and screenshots
* Version Packages (next) (#838)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Render API descriptions via content-collections, drop /generated/api fetch
Move the per-component API JSON load from the [name] layout's
`import.meta.glob('/generated/api/*.json')` into the components
content-collection transform. JSDoc descriptions are now compiled to
HTML with remark-gfm so backticks and links render as inline code and
anchors, surfaced as `descriptionHtml` on each PropertyInfo. The page
renders `{@html row.descriptionHtml}` with a fallback to the raw text,
and a `.prose-inline` rule scopes link/code styling without bleeding
block-level prose resets.
Eliminates the dev-server 403s caused by `/generated/api/*.json`
falling outside `server.fs.allow`, since the data now ships through
the collection rather than a runtime URL fetch.
* `pnpm dev` now run `pnpm dev` in parrallel for both packagesl/layerchart and docs
* add basic svelte-milestones example
* fix: Prevent submitting forms when clicking legend buttons (#841)
* Version Packages (next) (#842)
* fix(docs): replace `{#await}` with `query.loading`/`current` in Stats
The `{#await}` block doesn't anchor a remote `query` to SSR's hydratable serialization, so on hydration the client threw `hydratable_missing_but_required` looking for `getStats/`. Switch to the `query.loading`/`error`/`current` pattern, which is the supported path for remote queries and also avoids the async-mode `<svelte:boundary>` commit that triggered a "Batch has scheduled roots" invariant.
* Bundle analyzer (#843)
* Initialize bundle analyzer package
* update bundle baseline
* Improve bundle analyzer: count sync deps, add treemap visualization
- Sum entry chunk + all chunks reachable via static imports (so the reported size reflects true up-front cost; lazy chunks excluded)
- Add `--visualize` flag (and `bundle:visualize` script) that emits an interactive treemap HTML per scenario via `rollup-plugin-visualizer`
- Regenerate `latest.json` baseline with the new methodology
* Reduce bundle size (#845)
* Initialize bundle analyzer package
* update bundle baseline
* Prepare ChartChildren and Chart for tree-shaking
- Add `"sideEffects": ["**/*.css"]` to layerchart/package.json so downstream bundlers can prune unused barrel re-exports
- Convert ChartChildren's value imports of components only referenced in `ComponentProps<typeof X>` to `import type` (Area, Arc, Bars, BrushContext, Group, Line, Pie, Spline, TooltipContext)
- Inline `geoFitObjectTransform` into Chart.svelte to drop the static import edge through `$lib/utils/geo.js` (which transitively imports d3-geo)
No visible change in the bundle analyzer (it already does aggressive treeshaking), but unlocks the dynamic-import refactor in the next commit and protects consumers whose bundlers tree-shake less aggressively.
* Lazy-load conditionally-rendered components in Chart
Convert statically-imported components to `{#await import(...)}` so they only ship to users who opt in via the corresponding prop:
- ChartChildren: ChartAnnotations (when annotations.length > 0), DefaultTooltip (tooltipContext truthy), Labels, Legend, Points
- TooltipContext: Voronoi (mode === 'voronoi'), Arc (radial bounds/band)
Voronoi alone removes d3-geo-voronoi and its transitive d3-geo from the always-loaded bundle.
Update the bundle analyzer to sum the entry chunk plus all chunks reachable via static imports (lazy chunks excluded), so the reported size reflects up-front cost rather than total feature surface.
Result: `core` (`Chart` + `Svg`) drops 154.94 → 109.95 KB gz (-29%). Comparable savings on every scenario except `all` (which exercises every lazy path).
* Add `pnpm bundle:visualize` to generate treemaps using rollup-plugin-visualizer
* Fix BarChart legend toggle test for lazy-loaded Legend
The test queried `.lc-legend-swatch-button` synchronously, but `Legend` is now dynamically imported inside `ChartChildren` and isn't in the DOM until the chunk resolves. Wrap the query in `vi.waitFor` so the test waits for the buttons to mount before clicking.
* Fix analyzer footgun: don't overwrite latest.json on filtered runs
A filtered run (e.g. `pnpm bundle:visualize -- core`) was overwriting `bundle-reports/latest.json` with just the filtered scenarios, causing the PR comparison comment to show "0 KB" for every scenario the filtered run didn't cover. Now `latest.json` is only updated when no `--components`, scenario, or component filters are passed; filtered runs still get a timestamped report. Also regenerate the full baseline against the current lazy-loaded code.
* Fix CI test failure by avoiding tooltip namespace barrel in DefaultTooltip
DefaultTooltip is dynamically imported from ChartChildren. It was using `import * as Tooltip from '../tooltip/index.js'`, which dragged the entire tooltip barrel — including TooltipContext.svelte (already in the static graph via Chart.svelte) — into its lazy chunk. Under CI's resource-constrained dev server this broke the DefaultTooltip browser test ("Failed to fetch dynamically imported module"). Replace the namespace import with explicit named imports of just the 5 components actually used (no Context). The local `const Tooltip = { Root, Header, List, Item, Separator }` keeps the existing template syntax (`<Tooltip.Root>`, etc.) unchanged. Bonus: tightens tree-shaking — `all` scenario drops ~3 KB gz.
* Revert DefaultTooltip lazy-load to fix vitest-browser CI test
The dynamic import of `DefaultTooltip` from `ChartChildren` caused a CI-only "Failed to fetch dynamically imported module" failure in `DefaultTooltip.svelte.test.ts`. Local tests passed; only the Linux/playwright runner reproduced. Switching the inner `import * as Tooltip` namespace to named imports (commit 7e5d6e7) didn't help. The savings were small (~5 KB gz on `core`) and not worth the test instability — the other lazy-loads (Voronoi, Arc, ChartAnnotations, Labels, Legend, Points) remain. Net Phase 2 gain on `core` is now -39 KB gz (-25%) instead of -45 KB gz (-29%).
* Revert ChartChildren lazy-loads; keep TooltipContext lazy-loads
The DefaultTooltip vitest-browser test still failed in CI ("Failed to fetch dynamically imported module") even after reverting just DefaultTooltip's lazy-load and after switching the inner namespace import to named imports. Rather than continue narrowing, revert all 4 ChartChildren lazy-loads (Labels, Legend, Points, ChartAnnotations). The TooltipContext lazy-loads (Voronoi, Arc) stay — they're the biggest win (~17 KB gz on core from removing d3-geo-voronoi + d3-geo from the static graph) and aren't in the test failure path. Net Phase 2 gain on `core` is now -17 KB gz (-11%).
* Switch ChartChildren lazy-loads from `{#await}` to `$effect`
The `{#await import('./X.svelte')}` template pattern broke `DefaultTooltip.svelte.test.ts` in CI ("Failed to fetch dynamically imported module" on the test file). Local tests passed; only the Linux/playwright runner reproduced. Move the dynamic imports back into `$effect` blocks (script-side `import()`), which Vite/vitest-browser appears to handle differently. Same chunks, same bundle savings, but the dynamic imports live in regular JS rather than Svelte template syntax. TooltipContext keeps `{#await}` for Voronoi/Arc — those weren't in the test failure path. Net Phase 2 gain on `core` recovered to -40 KB gz (-25%).
* Refactor lazy-loading to a `<Lazy>` wrapper with prop-spread + `then` snippet
Replace per-component `$state`/`$effect`/conditional-render boilerplate in ChartChildren with a generic `<Lazy>` component that takes a `load` factory and either spreads remaining props to the loaded component (single-render case: ChartAnnotations, Legend) or passes it via a `then` snippet (loop case: Points, Labels). Conditional gating uses standard `{#if}` outside `<Lazy>` rather than a `when` prop. The snippet is named `then` (not `children`) to avoid collisions with loaded components that have their own `children` prop. Same bundle behavior and CI-friendly `$effect`-under-the-hood as the previous explicit pattern; ~half the lines per lazy-load.
* Use `{#await import(...)}` for lazy-loads; remove `<Lazy>` wrapper
Now that `optimizeDeps.include: ['d3-interpolate']` prevents the mid-test Vite reload (the actual cause of the CI flake), the cleaner inline `{#await import('./X.svelte') then { default: X }}` pattern works fine in CI. Revert ChartChildren back to that pattern, matching what TooltipContext already does. Remove `Lazy.svelte` since it's no longer needed. Same chunks, same ~25% savings on `core` (115.60 KB gz).
* Add `build` script alias so CI's `build:packages` actually builds layerchart
The bundle analysis CI workflow runs `pnpm build:packages` (which calls `pnpm --filter './packages/*' build`) before `pnpm bundle:analyze`. layerchart only had a `package` script (svelte-package convention), no `build`, so the filter call did nothing in CI — the analyzer ran against an empty `dist/` and produced 0-byte sizes for every scenario. That's why the PR comment showed "0.00 KB" for "New". Add a `build` alias for `svelte-package` (kept alongside existing `package` for back-compat) so CI's existing build step now actually rebuilds layerchart's `dist/`.
* Add percentage change to bundle analysis PR comment
The script already computed `sizePercent` and `gzipSizePercent`; now display them inline in the Change column alongside the raw KB deltas (e.g. `-160.00 KB (-25.1%)`). Easier to scan relative impact across scenarios than raw byte counts alone. Same for the Individual Components table.
* Group bundle analysis scenarios in PR comment by category
Add a `group` field to scenarios (Foundation, Cartesian charts, Geo, Hierarchy, Graph / network, Worst case) and render the PR comment with one sub-table per group instead of one alphabetized list. Reorder `define-scenarios.ts` to put `core` first and scenarios within their category. Remove the alphabetical sort in `analyzeChanges` so the comment preserves the natural order.
* Move heavy-dep components into sub-path exports
Remove from root `layerchart`: `Geo*` + `Graticule` + `TileImage`, `Tree`/`Treemap`/`Pack`/`Partition`, `ForceSimulation`, `Dagre`/`Sankey`/`Chord`/`Ribbon`. Each group now lives in its own folder + sub-path entry: `layerchart/geo`, `layerchart/hierarchy`, `layerchart/force`, `layerchart/graph`.
Defends against bundlers that don't tree-shake the root barrel cleanly — `@dagrejs/dagre` (~22 KB), `d3-geo` (~15 KB), `d3-force` (~7 KB), `d3-hierarchy` (~6 KB), `d3-sankey` (~6 KB), and `d3-chord` (~2 KB) are now reachable only via opt-in imports. Per-scenario bundle sizes are unchanged for already-good consumers; the worst-case `all` scenario drops 241.8 → 235.5 KB gz.
`Voronoi`/`Hull` stay at root (already lazy via `TooltipContext`). `Contour`/`Density`/`Raster`/`BoxPlot`/`Violin`/`Threshold` also stay (not category-specific). High-level charts (`LineChart`, `BarChart`, etc.) remain at root.
Breaking: imports for the moved components must move to the new sub-paths.
* Lazy-load opt-in features in core path
Three components that everyone pays for in `core` today, but only some users actually need:
- `Spline` in `Grid` (radial linear grid lines only — non-radial users never render it)
- `Bar` in `Highlight` (only when user sets `bar` prop, default `false`)
- `BrushContext` in `Chart` (only when user sets `brush` prop, default `undefined`) — required splitting the inner `<TooltipContext>` tree across the brush/no-brush branches; brush tests now wait for the lazy chunk via a new `awaitBrushReady` helper
Saves ~4 KB gz on `core` (115.60 → 111.31 KB) and similar on every cartesian/geo/graph/hierarchy scenario. ~28% total reduction on `core` vs the pre-Phase-1 baseline.
Also switch `@layerstack/svelte-actions` imports from the barrel to sub-paths (`/styles`, `/portal`). No bundle effect since tree-shaking already stripped the unused `popover.js`, but it stops the Svelte REPL/CDN from eagerly fetching `@floating-ui/dom` (popover's transitive dep) when users load `layerchart` from a CDN.
* add changeset for lazy loading opt-in features (brush, radial spline, etc)
* lazy load d3-quadtree and DefaultTooltip based on usage
* Render chart subtree during BrushContext lazy load
The previous structure put `<TooltipContext>` + `<ChartChildren>` *inside* the `{#await import('./BrushContext.svelte')}` block, so on slow networks the entire chart was blocked on the chunk fetch (~300-1000ms on Fast 4G). Move the same subtree into the `{#await}`'s pending branch as well so the chart paints immediately; the `{:then}` branch then re-mounts it inside `BrushContext` once the chunk arrives.
Trade-off: brief one-time re-mount of `TooltipContext` + `ChartChildren` (~50ms) when the chunk lands. Acceptable because it happens before any user interaction (no tooltip/series state to lose) and brush is opt-in. Bundle savings preserved (core +0.1 KB from the duplicated template, since the actual modules are deduped).
The other lazy-load sites (`Voronoi`/`Arc` in `TooltipContext`, `DefaultTooltip`, `Bar`, `Points`/`Labels`/`Legend`/`ChartAnnotations` in `ChartChildren`, `Spline` in `Grid`) don't need the same treatment — none of them block visible chart content from rendering.
* chore: update bundle size baseline (#847)
Co-authored-by: github-actions[bot] <action@github.com>
* Version Packages (next) (#846)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Reduce bundle size: Layer-specific components (#848)
* split Circle.svelte into 3 layer-specific components (Circle.svg.svelte, etc) along with CircleState (Circle.shared.svelte.ts). Keep Circle.svelte and delegate to underlying type
* split Text.svelte into 3 layer-specific components
* Organize into component directories
* split Rect, Line, and Path into 3 layer-specific components
* split Ellipse, Polygon, Group, Image, ClipPath, Pattern, LinearGradient, and RadialGradient into 3 layer-specific components
* Add changeset for per-layer primitive
* split Axis into 3 layer-specific components
* Add full-chart layer examples (to monitor progress)
* split Grid and Rule into 3 layer-specific components
* split Chart and ChartChildren into 3 layer-specific components, and alias Layer based on layer type (Layer within layerchart/svg => Svg)
* refine bundle scenarios
* refine bundle scenarios
* Add more foundation examples
Co-authored-by: Copilot <copilot@github.com>
* improve bundle comment
* split Highlight, ChartClipPath, RectClipPath into 3 layer-specific components
* split Arc, Area, and Spline into 3 layer-specific components
* split ArcLabel, Bar, Bars, Labels, Pie, and Points into 3 layer-specific components
* split Frame, Cell, Threshold, AnnotationLine, AnnotationPoint, and Trail into 3 layer-specific components
* split AnnotationRange, CircleClipPath, Vector, Link, Hull, Density, and Calendar into 3 layer-specific components
* split BoxPlot, Violin, Raster, Month, Contour, and Voronoi into 3 layer-specific components
* split geo components (GeoPath, GeoSpline, etc) into 3 layer-specific components
* split Ribbon into 3 layer-specific components. Re-export all layout/helper components
* split high-level charts (BarChart, LineChart, etc) into 3 layer-specific components. Re-export all layout/helper components
* update changeset and docs
* Update bundle size PR comment with collapsible sections
* Remove `Svg` from core (just Chart)
* Split `Foundation` scenarios into `Core (agnostic)` and `Core (layer-specific)`
* update bundle report
* Lazy load transform context (and only when used) similar to brush context
* Add ChartCore. Fix TransformContext test
* update bundle sizes in docs
* move core section above base
* Fix primitive fill/stroke for canvas primitives
* fix(Text): Render on `<Svg>` layer when only one of `x`/`y` is set
The static-mode render guard required both `x` and `y` to be explicit, so
`<Text y={-6}>` inside a positioned `<Group>` (e.g. tooltip labels in the
GeoPoint world-capitals example) was skipped on the Svg layer — Canvas
worked because it doesn't gate on coordinate validity.
Change `&&` to `||` so Text renders when either coordinate is set; the
missing one falls through to the existing `motionX`/`motionY` default of 0,
matching SVG's natural "missing coord = 0" behavior and the Canvas variant.
* fix components missing html impls (Calendar, Bars, Annotation*, etc)
* Fix Text within group
---------
Co-authored-by: Copilot <copilot@github.com>
* chore: update bundle size baseline (#850)
Co-authored-by: github-actions[bot] <action@github.com>
* Version Packages (next) (#849)
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
* Fix API generation after refactor from bundle size changes
* Move tests into component directories
* fix typo
* update catalog
* update screenshots
* feat(Blur): Add Canvas support
* fix CI
* perf improvements (#855)
* perf: Skip motion container allocation when `motion` prop is `undefined`
* perf: Skip mark-info `$effect` for pixel-mode primitives
* perf: Reduce per-tick reactive overhead in `Path` / `Link` (force-simulation graphs)
* fix(Arc, RectClipPath, ChartClipPath): Restore on-mount tween animations
* Force SVG for lattice example to verify delegation perf issue
* Revert lattice svg force
* Improve bundle size warnings
* sort bundle scenarios by size desc
* sort warnings by change desc
* Revert "perf: Skip motion container allocation when `motion` prop is `undefined`"
This reverts b45f47aea. Empirical measurements on the lattice (n=20,
760 links) and tree force-simulation examples showed the call-site
gating produced no measurable FPS difference vs. an unmodified
`createMotion` — the fast path at `motion.svelte.ts:197-213`
(passthrough returned when `motionProp === undefined`) already
covers the no-motion case.
| Example | Phase | Before | After (revert) |
|----------|-------------|-----------|---------------:|
| Lattice | steady sim | 6.46-6.53 | 6.52-6.58 |
| Tree | active sim | 16.88-17.28 | 17.46-17.51 |
The 728-line, 13-file diff added per-call-site gates and null-check
fallbacks for an optimization that was already happening one layer
down. Reverting restores the simpler unconditional construction.
The Path.shared.svelte.ts merge keeps ee6b33233's `#getPathData`
hot-path getter (which is independent of the motion-alloc question)
and switches the initial-pathData resolution to `resolvePathData()`
to handle the polymorphic `string | () => string` form added by
that commit.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* fix(SeriesState): Avoid `derived_inert` crash when chart unmounts under a `<svelte:boundary>`
-…
No description provided.