From 182376872828a065fb63248b5bf28b627b7f1444 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 9 Jul 2024 23:30:33 -0400 Subject: [PATCH 001/177] [Chart] Expose `x`/`y`/`z`/`r` accessors via slot props --- .changeset/long-crabs-teach.md | 5 +++++ packages/layerchart/src/lib/components/Chart.svelte | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 .changeset/long-crabs-teach.md diff --git a/.changeset/long-crabs-teach.md b/.changeset/long-crabs-teach.md new file mode 100644 index 000000000..8abc5afb9 --- /dev/null +++ b/.changeset/long-crabs-teach.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +[Chart] Expose `x`/`y`/`z`/`r` accessors via slot props diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index f12b0ca7c..eb4513e44 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -270,12 +270,16 @@ let:height let:width let:element + let:x let:xScale let:xGet + let:y let:yScale let:yGet + let:z let:zScale let:zGet + let:r let:rScale let:rGet let:padding @@ -333,12 +337,16 @@ {projection} transform={_transform} {tooltip} + {x} {xScale} {xGet} + {y} {yScale} {yGet} + {z} {zScale} {zGet} + {r} {rScale} {rGet} {padding} From 6ab467ba036b38f2db96f9dbbe6929e043c1fa41 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 9 Jul 2024 23:55:26 -0400 Subject: [PATCH 002/177] Begin to experiment with new AreaChart component --- .../lib/components/charts/AreaChart.svelte | 47 ++ .../src/lib/components/charts/index.ts | 1 + .../layerchart/src/lib/components/index.ts | 2 + .../layerchart/src/routes/_NavMenu.svelte | 66 +- .../routes/docs/charts/AreaChart/+page.svelte | 627 ++++++++++++++++++ .../src/routes/docs/charts/AreaChart/+page.ts | 15 + 6 files changed, 728 insertions(+), 30 deletions(-) create mode 100644 packages/layerchart/src/lib/components/charts/AreaChart.svelte create mode 100644 packages/layerchart/src/lib/components/charts/index.ts create mode 100644 packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte create mode 100644 packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte new file mode 100644 index 000000000..9904c1e56 --- /dev/null +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -0,0 +1,47 @@ + + + + + + + + + + + + + format(x(data))} let:data> + + + + + diff --git a/packages/layerchart/src/lib/components/charts/index.ts b/packages/layerchart/src/lib/components/charts/index.ts new file mode 100644 index 000000000..3f4cb2522 --- /dev/null +++ b/packages/layerchart/src/lib/components/charts/index.ts @@ -0,0 +1 @@ +export { default as AreaChart } from './AreaChart.svelte'; diff --git a/packages/layerchart/src/lib/components/index.ts b/packages/layerchart/src/lib/components/index.ts index 5042f5034..082cff9f6 100644 --- a/packages/layerchart/src/lib/components/index.ts +++ b/packages/layerchart/src/lib/components/index.ts @@ -1,6 +1,8 @@ // Re-export for easy access (Svg and Canvas are provided by LayerChart) export { Html, WebGL } from 'layercake'; +export * from './charts/index.js'; + export { default as Arc } from './Arc.svelte'; export { default as Area } from './Area.svelte'; export { default as AreaStack } from './AreaStack.svelte'; diff --git a/packages/layerchart/src/routes/_NavMenu.svelte b/packages/layerchart/src/routes/_NavMenu.svelte index ea7de4010..7f032cb14 100644 --- a/packages/layerchart/src/routes/_NavMenu.svelte +++ b/packages/layerchart/src/routes/_NavMenu.svelte @@ -6,6 +6,10 @@ type LinkCollection = Record>; + const charts: LinkCollection = { + 'Cartesian & Polar': ['AreaChart'], + }; + const examples: LinkCollection = { 'Cartesian & Polar': [ 'Arc', @@ -123,25 +127,34 @@ /> +

Charts

+{#each Object.entries(charts) as [header, items]} +

{header}

+ {#each items as item} + {@const label = typeof item === 'object' ? item.label : item} + {@const pathValue = typeof item === 'object' ? item.value : item} + + {/each} +{/each} +

Examples

{#each Object.entries(examples) as [header, items]}

{header}

{#each items as item} - {#if typeof item === 'object'} - - {:else} - - {/if} + {@const label = + typeof item === 'object' ? item.label : item.replace(/([a-z])([A-Z])/g, '$1 $2')} + {@const pathValue = typeof item === 'object' ? item.value : item} + {/each} {/each} @@ -149,21 +162,14 @@ {#each Object.entries(components) as [header, items]}

{header}

{#each items as item} - {#if typeof item === 'object'} - - {:else} - - {/if} + {@const label = typeof item === 'object' ? item.label : item} + {@const pathValue = typeof item === 'object' ? item.value : item} + {/each} {/each} diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte new file mode 100644 index 000000000..9d39c1229 --- /dev/null +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte @@ -0,0 +1,627 @@ + + +

Examples

+ +

Basic

+ + +
+ +
+
+ +

Accessor override

+ + +
+ +
+
+ +

Custom tooltip

+ + +
+ + + format(x(data), PeriodType.DayTime)} let:data> + + + + +
+
+ +

Full chart override

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + + + + format(x(data), PeriodType.DayTime)} let:data> + + + +
+
+ + diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts new file mode 100644 index 000000000..035a27e5b --- /dev/null +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts @@ -0,0 +1,15 @@ +import { parse } from 'svelte-ux'; + +import pageSource from './+page.svelte?raw'; +import type { AppleStockData } from '$static/data/examples/date/apple-stock.js'; + +export async function load() { + return { + appleStock: await fetch('/data/examples/date/apple-stock.json').then(async (r) => + parse(await r.text()) + ), + meta: { + pageSource, + }, + }; +} From abfc4175b7577e08185e3ac4cfa7381eae3d30bf Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 14 Jul 2024 01:30:26 -0400 Subject: [PATCH 003/177] Add TooltipHeader component --- .../layerchart/src/lib/components/TooltipHeader.svelte | 7 +++++++ packages/layerchart/src/lib/components/index.ts | 1 + 2 files changed, 8 insertions(+) create mode 100644 packages/layerchart/src/lib/components/TooltipHeader.svelte diff --git a/packages/layerchart/src/lib/components/TooltipHeader.svelte b/packages/layerchart/src/lib/components/TooltipHeader.svelte new file mode 100644 index 000000000..57db94f2f --- /dev/null +++ b/packages/layerchart/src/lib/components/TooltipHeader.svelte @@ -0,0 +1,7 @@ + + +
+ +
diff --git a/packages/layerchart/src/lib/components/index.ts b/packages/layerchart/src/lib/components/index.ts index 082cff9f6..77dd01258 100644 --- a/packages/layerchart/src/lib/components/index.ts +++ b/packages/layerchart/src/lib/components/index.ts @@ -59,6 +59,7 @@ export { default as Threshold } from './Threshold.svelte'; export { default as TileImage } from './TileImage.svelte'; export { default as Tooltip } from './Tooltip.svelte'; export { default as TooltipContext } from './TooltipContext.svelte'; +export { default as TooltipHeader } from './TooltipHeader.svelte'; export { default as TooltipItem } from './TooltipItem.svelte'; export { default as TooltipSeparator } from './TooltipSeparator.svelte'; export { default as TransformContext, transformContext } from './TransformContext.svelte'; From c15cd879ec8bdbb541faf68083a1c287c0a9540e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 14 Jul 2024 01:32:19 -0400 Subject: [PATCH 004/177] [TooltipItem] Support `color` prop to add swatch, support theme colors and any color via `color="variable"` --- .changeset/twelve-otters-count.md | 5 ++ .../src/lib/components/TooltipItem.svelte | 57 +++++++++++++------ 2 files changed, 46 insertions(+), 16 deletions(-) create mode 100644 .changeset/twelve-otters-count.md diff --git a/.changeset/twelve-otters-count.md b/.changeset/twelve-otters-count.md new file mode 100644 index 000000000..eb62fc7c1 --- /dev/null +++ b/.changeset/twelve-otters-count.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +[TooltipItem] Support `color` prop to add swatch, support theme colors and any color via `color="variable"` diff --git a/packages/layerchart/src/lib/components/TooltipItem.svelte b/packages/layerchart/src/lib/components/TooltipItem.svelte index 3bc5e4ef7..636e53586 100644 --- a/packages/layerchart/src/lib/components/TooltipItem.svelte +++ b/packages/layerchart/src/lib/components/TooltipItem.svelte @@ -1,32 +1,57 @@ -
- {label}: -
+
+
+ {#if color} +
+ {/if} + {label} +
-
- {format ? formatUtil(value, format) : value} +
+ {format ? formatUtil(value, format) : value} +
From 7c94f0c2b16614284b5c3075c068e8fe75829cd7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 19 Jul 2024 18:07:36 -0400 Subject: [PATCH 005/177] Refined Tooltip design WIP --- .../src/lib/components/Tooltip.svelte | 11 ++- .../docs/components/Tooltip/+page.svelte | 97 ++++++++++++++++++- 2 files changed, 102 insertions(+), 6 deletions(-) diff --git a/packages/layerchart/src/lib/components/Tooltip.svelte b/packages/layerchart/src/lib/components/Tooltip.svelte index 4a06eebc7..4a11eb9df 100644 --- a/packages/layerchart/src/lib/components/Tooltip.svelte +++ b/packages/layerchart/src/lib/components/Tooltip.svelte @@ -155,9 +155,10 @@
@@ -190,7 +191,7 @@ {#if $$slots.default}
diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index f0171276f..0c87571e4 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -14,6 +14,7 @@ Points, Svg, Tooltip, + TooltipHeader, TooltipItem, TooltipSeparator, } from 'layerchart'; @@ -174,13 +175,107 @@ - format(data.date, 'eee, MMMM do')} let:data> + + {format(data.date, 'eee, MMMM do')}
+

Custom content

+ + +
+ + + + formatDate(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + + + Anything can go here test + +
+
+ +

theme color swatch

+ + +
+ + + + formatDate(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + + + + {format(data.date, 'eee, MMMM do')} + + + +
+
+ +

custom color swatch

+ + +
+ + + + formatDate(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + + + + {format(data.date, 'eee, MMMM do')} + + + +
+
+

invert variant

From 4c323df4741a5b1d2416991ac62f043a7cfafa3a Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 1 Aug 2024 00:47:02 -0400 Subject: [PATCH 006/177] [AreaChart] Add api, source, and related --- .../layerchart/src/routes/docs/charts/AreaChart/+page.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts index 035a27e5b..95c83d44a 100644 --- a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.ts @@ -1,6 +1,9 @@ import { parse } from 'svelte-ux'; +import api from '$lib/components/charts/AreaChart.svelte?raw&sveld'; +import source from '$lib/components/charts/AreaChart.svelte?raw'; import pageSource from './+page.svelte?raw'; + import type { AppleStockData } from '$static/data/examples/date/apple-stock.js'; export async function load() { @@ -9,7 +12,10 @@ export async function load() { parse(await r.text()) ), meta: { + api, + source, pageSource, + related: ['components/Area', 'examples/Area'], }, }; } From 8f6e138b4cf04ebf7356f6b02a381d1a067d5abd Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 1 Aug 2024 00:59:32 -0400 Subject: [PATCH 007/177] [AreaChart] Require passing x/y accessors and default xScale based on first data's `x` value. Other minor refinements --- .../lib/components/charts/AreaChart.svelte | 19 +++++++++++++------ .../routes/docs/charts/AreaChart/+page.svelte | 13 ++----------- 2 files changed, 15 insertions(+), 17 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 9904c1e56..fc411d503 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -1,8 +1,8 @@
- -
-
- -

Accessor override

- - -
- +
@@ -72,7 +63,7 @@
- + format(x(data), PeriodType.DayTime)} let:data> From 23bdedb086c707afaa3f6442ad04c5d047f185e7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 1 Aug 2024 01:35:43 -0400 Subject: [PATCH 008/177] Update more usage to use instead of ...}> --- .../lib/components/charts/AreaChart.svelte | 4 ++- .../routes/docs/charts/AreaChart/+page.svelte | 7 +++-- .../docs/components/Calendar/+page.svelte | 31 ++++++++++++++++--- .../docs/components/Tooltip/+page.svelte | 24 +++++++------- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index fc411d503..bfc38e427 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -11,6 +11,7 @@ import Svg from '../layout/Svg.svelte'; import TooltipItem from '../TooltipItem.svelte'; import Tooltip from '../Tooltip.svelte'; + import TooltipHeader from '../TooltipHeader.svelte'; import { accessor, chartDataArray, type Accessor } from '../../utils/common.js'; @@ -46,7 +47,8 @@ - format(x(data))} let:data> + + {format(x(data))} diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte index 8cc08caca..2c61af691 100644 --- a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte @@ -20,6 +20,7 @@ Tooltip, TooltipItem, pivotLonger, + TooltipHeader, } from 'layerchart'; import { format, Field, Switch, Toggle, PeriodType } from 'svelte-ux'; @@ -65,7 +66,8 @@
- format(x(data), PeriodType.DayTime)} let:data> + + {format(x(data), PeriodType.DayTime)} @@ -89,7 +91,8 @@ - format(x(data), PeriodType.DayTime)} let:data> + + {format(x(data), PeriodType.DayTime)} diff --git a/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte b/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte index d75d2ffbe..88dd7acc7 100644 --- a/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte @@ -4,7 +4,16 @@ import { scaleThreshold } from 'd3-scale'; import { range } from 'd3-array'; - import { Calendar, Chart, Group, Text, Tooltip, TooltipItem, Svg } from 'layerchart'; + import { + Calendar, + Chart, + Group, + Text, + Tooltip, + TooltipItem, + Svg, + TooltipHeader, + } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; @@ -47,7 +56,13 @@ - format(d.date, PeriodType.Day)} /> + + {format(data.date, PeriodType.Day)} + + {#if data.value != null} + + {/if} +
@@ -74,7 +89,13 @@ - format(d.date, PeriodType.Day)} /> + + {format(data.date, PeriodType.Day)} + + {#if data.value != null} + + {/if} +
@@ -117,7 +138,9 @@ {/each} - format(d.date, PeriodType.Day)} let:data> + + {format(data.date, PeriodType.Day)} + {#if data.value != null} {/if} diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index 0c87571e4..dd2480d82 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -207,7 +207,7 @@ - Anything can go here test + Anything can go here test
@@ -335,7 +335,8 @@ - format(data.date, 'eee, MMMM do')} let:data> + + {format(data.date, 'eee, MMMM do')} @@ -366,7 +367,8 @@ - format(data.date, 'eee, MMMM do')} let:data> + + {format(data.date, 'eee, MMMM do')} @@ -489,9 +491,9 @@ xOffset={['top', 'center', 'bottom'].includes(anchor ?? '') ? 0 : 10} y={snap} yOffset={['left', 'center', 'right'].includes(anchor ?? '') ? 0 : 10} - header={(data) => format(data.date, 'eee, MMMM do')} let:data > + {format(data.date, 'eee, MMMM do')} @@ -539,9 +541,9 @@ format(data.date, 'eee, MMMM do')} let:data > + {format(data.date, 'eee, MMMM do')} @@ -591,9 +593,9 @@ format(data.data.date, 'eee, MMMM do')} let:data > + {format(data.date, 'eee, MMMM do')} {#each keys as key} {/each} @@ -637,9 +639,9 @@ data.name} let:data > + {data.name} @@ -683,9 +685,9 @@ data.name} let:data > + {data.name} @@ -733,9 +735,9 @@ data.name} let:data > + {data.name} @@ -789,9 +791,9 @@ format(data.date, 'eee, MMMM do')} let:data > + {format(data.date, 'eee, MMMM do')} @@ -849,9 +851,9 @@ format(data.date, 'eee, MMMM do')} let:data > + {format(data.date, 'eee, MMMM do')} From fda2ac333522c2aa05944cddab6526c05f6df733 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 4 Aug 2024 00:36:34 -0400 Subject: [PATCH 009/177] Consolidate Tooltip components (, , etc) to , , etc, rename to , and other Tooltip-based refinements. Begin updating all examples --- .changeset/five-plums-speak.md | 5 + .changeset/four-rockets-cry.md | 5 + .changeset/grumpy-masks-agree.md | 5 + .changeset/polite-tools-chew.md | 5 + .../src/lib/components/Calendar.svelte | 2 +- .../src/lib/components/Chart.svelte | 2 +- .../src/lib/components/GeoPath.svelte | 2 +- .../src/lib/components/Highlight.svelte | 2 +- .../layerchart/src/lib/components/Pie.svelte | 2 +- .../lib/components/charts/AreaChart.svelte | 14 +- .../layerchart/src/lib/components/index.ts | 6 +- .../components/{ => tooltip}/Tooltip.svelte | 33 +-- .../{ => tooltip}/TooltipContext.svelte | 8 +- .../{ => tooltip}/TooltipHeader.svelte | 2 +- .../{ => tooltip}/TooltipItem.svelte | 3 +- .../lib/components/tooltip/TooltipList.svelte | 13 ++ .../{ => tooltip}/TooltipSeparator.svelte | 0 .../src/lib/components/tooltip/index.ts | 6 + .../routes/docs/charts/AreaChart/+page.svelte | 22 +- .../routes/docs/components/Brush/+page.svelte | 8 +- .../docs/components/Calendar/+page.svelte | 30 ++- .../docs/components/HitCanvas/+page.svelte | 4 +- .../routes/docs/components/Pie/+page.svelte | 42 ++-- .../docs/components/Tooltip/+page.svelte | 207 ++++++++++-------- .../routes/docs/components/Tooltip/+page.ts | 4 +- .../src/routes/docs/examples/Arc/+page.svelte | 4 +- .../routes/docs/examples/DotPlot/+page.svelte | 42 ++-- .../docs/examples/Histogram/+page.svelte | 169 +++++++------- 28 files changed, 345 insertions(+), 302 deletions(-) create mode 100644 .changeset/five-plums-speak.md create mode 100644 .changeset/four-rockets-cry.md create mode 100644 .changeset/grumpy-masks-agree.md create mode 100644 .changeset/polite-tools-chew.md rename packages/layerchart/src/lib/components/{ => tooltip}/Tooltip.svelte (85%) rename packages/layerchart/src/lib/components/{ => tooltip}/TooltipContext.svelte (98%) rename packages/layerchart/src/lib/components/{ => tooltip}/TooltipHeader.svelte (51%) rename packages/layerchart/src/lib/components/{ => tooltip}/TooltipItem.svelte (93%) create mode 100644 packages/layerchart/src/lib/components/tooltip/TooltipList.svelte rename packages/layerchart/src/lib/components/{ => tooltip}/TooltipSeparator.svelte (100%) create mode 100644 packages/layerchart/src/lib/components/tooltip/index.ts diff --git a/.changeset/five-plums-speak.md b/.changeset/five-plums-speak.md new file mode 100644 index 000000000..e8b66440a --- /dev/null +++ b/.changeset/five-plums-speak.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +Rename Tooltip to Tooltip.Root diff --git a/.changeset/four-rockets-cry.md b/.changeset/four-rockets-cry.md new file mode 100644 index 000000000..511c5bce5 --- /dev/null +++ b/.changeset/four-rockets-cry.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +Remove default grid on Tooltip.Root and add Tooltip.List as Tooltip.Item container diff --git a/.changeset/grumpy-masks-agree.md b/.changeset/grumpy-masks-agree.md new file mode 100644 index 000000000..b12f82ce5 --- /dev/null +++ b/.changeset/grumpy-masks-agree.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +Consolidate Tooltip components (TooltipItem, TooltipSeparator, etc) to Tooltip.Item, Tooltip.Separtor, etc diff --git a/.changeset/polite-tools-chew.md b/.changeset/polite-tools-chew.md new file mode 100644 index 000000000..cee1fe66b --- /dev/null +++ b/.changeset/polite-tools-chew.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +Remove and replace with diff --git a/packages/layerchart/src/lib/components/Calendar.svelte b/packages/layerchart/src/lib/components/Calendar.svelte index c8fed37eb..52e08491d 100644 --- a/packages/layerchart/src/lib/components/Calendar.svelte +++ b/packages/layerchart/src/lib/components/Calendar.svelte @@ -6,7 +6,7 @@ import { chartContext } from './ChartContext.svelte'; import Rect from './Rect.svelte'; - import type { TooltipContextValue } from './TooltipContext.svelte'; + import type { TooltipContextValue } from './tooltip/TooltipContext.svelte'; import MonthPath from './MonthPath.svelte'; import Text from './Text.svelte'; import { chartDataArray } from '../utils/common.js'; diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index eb4513e44..efe646061 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -33,7 +33,7 @@ import ChartContext from './ChartContext.svelte'; import GeoContext from './GeoContext.svelte'; - import TooltipContext from './TooltipContext.svelte'; + import TooltipContext from './tooltip/TooltipContext.svelte'; import TransformContext from './TransformContext.svelte'; import { geoFitObjectTransform } from '$lib/utils/geo.js'; diff --git a/packages/layerchart/src/lib/components/GeoPath.svelte b/packages/layerchart/src/lib/components/GeoPath.svelte index 128bee7ea..74baec873 100644 --- a/packages/layerchart/src/lib/components/GeoPath.svelte +++ b/packages/layerchart/src/lib/components/GeoPath.svelte @@ -12,7 +12,7 @@ import { chartContext } from './ChartContext.svelte'; import { geoContext } from './GeoContext.svelte'; - import type { TooltipContextValue } from './TooltipContext.svelte'; + import type { TooltipContextValue } from './tooltip/TooltipContext.svelte'; import { curveLinearClosed, type CurveFactory, type CurveFactoryLineOnly } from 'd3-shape'; import { geoCurvePath } from '$lib/utils/geo.js'; diff --git a/packages/layerchart/src/lib/components/Highlight.svelte b/packages/layerchart/src/lib/components/Highlight.svelte index 5ab2815fe..7115c8faf 100644 --- a/packages/layerchart/src/lib/components/Highlight.svelte +++ b/packages/layerchart/src/lib/components/Highlight.svelte @@ -9,7 +9,7 @@ import Line from './Line.svelte'; import Bar from './Bar.svelte'; import Rect from './Rect.svelte'; - import { tooltipContext } from './TooltipContext.svelte'; + import { tooltipContext } from './tooltip/TooltipContext.svelte'; import { isScaleBand } from '$lib/utils/scales.js'; import { accessor, type Accessor } from '$lib/utils/common.js'; diff --git a/packages/layerchart/src/lib/components/Pie.svelte b/packages/layerchart/src/lib/components/Pie.svelte index 55fea4e71..8989b1f99 100644 --- a/packages/layerchart/src/lib/components/Pie.svelte +++ b/packages/layerchart/src/lib/components/Pie.svelte @@ -8,7 +8,7 @@ import Group from './Group.svelte'; import { degreesToRadians } from '$lib/utils/math.js'; import { motionStore } from '$lib/stores/motionStore.js'; - import type { TooltipContextValue } from './TooltipContext.svelte'; + import type { TooltipContextValue } from './tooltip/TooltipContext.svelte'; /* TODO: diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index bfc38e427..9a15c8941 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -9,9 +9,7 @@ import Chart from '../Chart.svelte'; import Highlight from '../Highlight.svelte'; import Svg from '../layout/Svg.svelte'; - import TooltipItem from '../TooltipItem.svelte'; - import Tooltip from '../Tooltip.svelte'; - import TooltipHeader from '../TooltipHeader.svelte'; + import * as Tooltip from '../tooltip/index.js'; import { accessor, chartDataArray, type Accessor } from '../../utils/common.js'; @@ -47,10 +45,12 @@ - - {format(x(data))} - - + + {format(x(data))} + + + + diff --git a/packages/layerchart/src/lib/components/index.ts b/packages/layerchart/src/lib/components/index.ts index 77dd01258..566681db9 100644 --- a/packages/layerchart/src/lib/components/index.ts +++ b/packages/layerchart/src/lib/components/index.ts @@ -57,11 +57,7 @@ export { default as Svg } from './layout/Svg.svelte'; export { default as Text } from './Text.svelte'; export { default as Threshold } from './Threshold.svelte'; export { default as TileImage } from './TileImage.svelte'; -export { default as Tooltip } from './Tooltip.svelte'; -export { default as TooltipContext } from './TooltipContext.svelte'; -export { default as TooltipHeader } from './TooltipHeader.svelte'; -export { default as TooltipItem } from './TooltipItem.svelte'; -export { default as TooltipSeparator } from './TooltipSeparator.svelte'; +export * as Tooltip from './tooltip/index.js'; export { default as TransformContext, transformContext } from './TransformContext.svelte'; export { default as TransformControls } from './TransformControls.svelte'; export { default as Tree } from './Tree.svelte'; diff --git a/packages/layerchart/src/lib/components/Tooltip.svelte b/packages/layerchart/src/lib/components/tooltip/Tooltip.svelte similarity index 85% rename from packages/layerchart/src/lib/components/Tooltip.svelte rename to packages/layerchart/src/lib/components/tooltip/Tooltip.svelte index 4a11eb9df..78d98386c 100644 --- a/packages/layerchart/src/lib/components/Tooltip.svelte +++ b/packages/layerchart/src/lib/components/tooltip/Tooltip.svelte @@ -2,9 +2,9 @@ import { fade } from 'svelte/transition'; import { cls } from 'svelte-ux'; - import { chartContext } from './ChartContext.svelte'; + import { chartContext } from './../ChartContext.svelte'; import { tooltipContext } from './TooltipContext.svelte'; - import { motionStore } from '../stores/motionStore.js'; + import { motionStore } from '../../stores/motionStore.js'; /** `x` position of tooltip. By default uses the pointer/mouse, can also snap to data or an explicit fixed position. */ export let x: 'pointer' | 'data' | number | undefined = 'pointer'; @@ -35,8 +35,6 @@ /** Set to `false` to disable spring transitions */ export let motion = true; - export let header: ((data: any) => any) | undefined = undefined; - export let classes: { root?: string; container?: string; @@ -154,12 +152,7 @@ >
- {#if header || $$slots.header} -
- - {header?.($tooltip.data)} - -
- {/if} - {#if $$slots.default} -
+
{/if} diff --git a/packages/layerchart/src/lib/components/TooltipContext.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte similarity index 98% rename from packages/layerchart/src/lib/components/TooltipContext.svelte rename to packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte index 5f19c9f6b..9dbbd2966 100644 --- a/packages/layerchart/src/lib/components/TooltipContext.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte @@ -37,10 +37,10 @@ import { quadtree as d3Quadtree, type Quadtree } from 'd3-quadtree'; import { cls, sortFunc } from 'svelte-ux'; - import { Svg } from './Chart.svelte'; - import { chartContext } from './ChartContext.svelte'; - import ChartClipPath from './ChartClipPath.svelte'; - import Voronoi from './Voronoi.svelte'; + import { Svg } from './../Chart.svelte'; + import { chartContext } from './../ChartContext.svelte'; + import ChartClipPath from './../ChartClipPath.svelte'; + import Voronoi from './../Voronoi.svelte'; import { localPoint } from '$lib/utils/event.js'; import { isScaleBand, scaleInvert } from '$lib/utils/scales.js'; diff --git a/packages/layerchart/src/lib/components/TooltipHeader.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte similarity index 51% rename from packages/layerchart/src/lib/components/TooltipHeader.svelte rename to packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte index 57db94f2f..25592ecd1 100644 --- a/packages/layerchart/src/lib/components/TooltipHeader.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte @@ -2,6 +2,6 @@ import { cls } from 'svelte-ux'; -
+
diff --git a/packages/layerchart/src/lib/components/TooltipItem.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte similarity index 93% rename from packages/layerchart/src/lib/components/TooltipItem.svelte rename to packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte index 636e53586..0234bd62e 100644 --- a/packages/layerchart/src/lib/components/TooltipItem.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte @@ -17,7 +17,7 @@
-
+
{#if color}
+ import { cls } from 'svelte-ux'; + + +
+ +
diff --git a/packages/layerchart/src/lib/components/TooltipSeparator.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipSeparator.svelte similarity index 100% rename from packages/layerchart/src/lib/components/TooltipSeparator.svelte rename to packages/layerchart/src/lib/components/tooltip/TooltipSeparator.svelte diff --git a/packages/layerchart/src/lib/components/tooltip/index.ts b/packages/layerchart/src/lib/components/tooltip/index.ts new file mode 100644 index 000000000..a3d575a8e --- /dev/null +++ b/packages/layerchart/src/lib/components/tooltip/index.ts @@ -0,0 +1,6 @@ +export { default as Context } from './TooltipContext.svelte'; +export { default as Header } from './TooltipHeader.svelte'; +export { default as Item } from './TooltipItem.svelte'; +export { default as List } from './TooltipList.svelte'; +export { default as Separator } from './TooltipSeparator.svelte'; +export { default as Root } from './Tooltip.svelte'; diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte index 2c61af691..b4f0acf53 100644 --- a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte @@ -18,9 +18,7 @@ Svg, Text, Tooltip, - TooltipItem, pivotLonger, - TooltipHeader, } from 'layerchart'; import { format, Field, Switch, Toggle, PeriodType } from 'svelte-ux'; @@ -66,10 +64,12 @@
- - {format(x(data), PeriodType.DayTime)} - - + + {format(x(data), PeriodType.DayTime)} + + + +
@@ -91,10 +91,12 @@ - - {format(x(data), PeriodType.DayTime)} - - + + {format(x(data), PeriodType.DayTime)} + + + +
diff --git a/packages/layerchart/src/routes/docs/components/Brush/+page.svelte b/packages/layerchart/src/routes/docs/components/Brush/+page.svelte index a4f689c50..eba7610b4 100644 --- a/packages/layerchart/src/routes/docs/components/Brush/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Brush/+page.svelte @@ -475,7 +475,7 @@ /> - {format(data.value, 'currency')} - + - {format(data.date, PeriodType.Day)} - +
diff --git a/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte b/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte index 88dd7acc7..838f609fb 100644 --- a/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte @@ -56,13 +56,15 @@ - - {format(data.date, PeriodType.Day)} + + {format(data.date, PeriodType.Day)} {#if data.value != null} - + + + {/if} - +
@@ -89,13 +91,15 @@ - - {format(data.date, PeriodType.Day)} + + {format(data.date, PeriodType.Day)} {#if data.value != null} - + + + {/if} - +
@@ -138,13 +142,15 @@ {/each} - - {format(data.date, PeriodType.Day)} + + {format(data.date, PeriodType.Day)} {#if data.value != null} - + + + {/if} - +
diff --git a/packages/layerchart/src/routes/docs/components/HitCanvas/+page.svelte b/packages/layerchart/src/routes/docs/components/HitCanvas/+page.svelte index df97aeeaf..751e252de 100644 --- a/packages/layerchart/src/routes/docs/components/HitCanvas/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/HitCanvas/+page.svelte @@ -76,7 +76,9 @@ /> - data.properties.name} /> + + {data.properties.name} +
diff --git a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte index 8751ff79e..9fe61a9bf 100644 --- a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte @@ -267,15 +267,18 @@ - format(data.date, 'eee, MMMM do')} let:data> - - - + + {format(data.date, 'eee, MMMM do')} + + + + +
@@ -331,15 +334,18 @@ - format(data.date, 'eee, MMMM do')} let:data> - - - + + {format(data.date, 'eee, MMMM do')} + + + + +
diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index dd2480d82..ed5a53f5e 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -4,20 +4,7 @@ import { stack, type Series, type Stack } from 'd3-shape'; import { format } from 'date-fns'; - import { - Area, - AreaStack, - Axis, - Bars, - Chart, - Highlight, - Points, - Svg, - Tooltip, - TooltipHeader, - TooltipItem, - TooltipSeparator, - } from 'layerchart'; + import { Area, AreaStack, Axis, Bars, Chart, Highlight, Points, Svg, Tooltip } from 'layerchart'; import { Button, @@ -145,7 +132,7 @@ 'bottom', 'bottom-right', ] as const; - let anchor: ComponentProps['anchor'] = 'top-left'; + let anchor: ComponentProps['anchor'] = 'top-left'; let snap: 'pointer' | 'data' = 'pointer'; @@ -175,10 +162,12 @@ - - {format(data.date, 'eee, MMMM do')} - - + + {format(data.date, 'eee, MMMM do')} + + + + @@ -207,7 +196,7 @@ - Anything can go here test + Anything can go here test @@ -236,10 +225,12 @@ - - {format(data.date, 'eee, MMMM do')} - - + + {format(data.date, 'eee, MMMM do')} + + + + @@ -268,10 +259,12 @@ - - {format(data.date, 'eee, MMMM do')} - - + + {format(data.date, 'eee, MMMM do')} + + + + @@ -300,12 +293,14 @@ - -
+ + {format(data.date, 'eee, MMMM do')} -
- -
+ + + + +
@@ -335,10 +330,12 @@ - - {format(data.date, 'eee, MMMM do')} - - + + {format(data.date, 'eee, MMMM do')} + + + + @@ -367,10 +364,12 @@ - - {format(data.date, 'eee, MMMM do')} - - + + {format(data.date, 'eee, MMMM do')} + + + + @@ -402,28 +401,26 @@ - {data.value} - + - {formatDate(data.date, PeriodType.Day)} - + @@ -485,7 +482,7 @@ - - {format(data.date, 'eee, MMMM do')} - - + {format(data.date, 'eee, MMMM do')} + + + + @@ -538,14 +537,16 @@ axis={charts.area.axis} /> - - {format(data.date, 'eee, MMMM do')} - - + {format(data.date, 'eee, MMMM do')} + + + + @@ -590,16 +591,18 @@ axis={charts.areaStack.axis} /> - - {format(data.date, 'eee, MMMM do')} - {#each keys as key} - - {/each} - + {format(data.date, 'eee, MMMM do')} + + {#each keys as key} + + {/each} + + @@ -636,14 +639,16 @@ axis={charts.dateTime.axis} /> - - {data.name} - - + {data.name} + + + + @@ -682,19 +687,21 @@ axis={charts.duration.axis} /> - - {data.name} - - - - - - - + {data.name} + + + + + + + + + @@ -732,19 +739,21 @@ axis={charts.multiDuration.axis} /> - - {data.name} - - - - - - - + {data.name} + + + + + + + + + @@ -788,14 +797,16 @@ axis={charts.bars.axis} /> - - {format(data.date, 'eee, MMMM do')} - - + {format(data.date, 'eee, MMMM do')} + + + + @@ -848,15 +859,17 @@ : false} /> - - {format(data.date, 'eee, MMMM do')} - - - + {format(data.date, 'eee, MMMM do')} + + + + + @@ -890,14 +903,16 @@ axis={charts.scatter.axis} /> - - - - + + + + + diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts b/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts index 54c872feb..91ffed3ef 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.ts @@ -1,5 +1,5 @@ -import api from '$lib/components/Tooltip.svelte?raw&sveld'; -import source from '$lib/components/Tooltip.svelte?raw'; +import api from '$lib/components/tooltip/Tooltip.svelte?raw&sveld'; +import source from '$lib/components/tooltip/Tooltip.svelte?raw'; import pageSource from './+page.svelte?raw'; export async function load() { diff --git a/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte b/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte index 40653b90e..736836924 100644 --- a/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte @@ -192,7 +192,9 @@ {/each} - data} /> + + {data} + diff --git a/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte b/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte index 33892c5dd..63d05071a 100644 --- a/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte @@ -3,16 +3,7 @@ import { addMinutes, startOfDay } from 'date-fns'; import { Duration, PeriodType, format } from 'svelte-ux'; - import { - Axis, - Chart, - Highlight, - Points, - Svg, - Tooltip, - TooltipItem, - TooltipSeparator, - } from 'layerchart'; + import { Axis, Chart, Highlight, Points, Svg, Tooltip } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { getRandomInteger } from '$lib/utils/genData.js'; @@ -61,20 +52,23 @@ - data.name} let:data> - - - - - - - + + {data.name} + + + + + + + + + diff --git a/packages/layerchart/src/routes/docs/examples/Histogram/+page.svelte b/packages/layerchart/src/routes/docs/examples/Histogram/+page.svelte index fd9d83f60..8f30dcc4e 100644 --- a/packages/layerchart/src/routes/docs/examples/Histogram/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Histogram/+page.svelte @@ -12,17 +12,7 @@ import { timeDays, timeMonths, timeWeeks } from 'd3-time'; import { subDays } from 'date-fns'; - import { - Axis, - Bars, - Chart, - Highlight, - Svg, - Tooltip, - TooltipItem, - TooltipSeparator, - thresholdTime, - } from 'layerchart'; + import { Axis, Bars, Chart, Highlight, Svg, Tooltip, thresholdTime } from 'layerchart'; import { MenuField, RangeField, NumberStepper, format, PeriodType, State } from 'svelte-ux'; import Preview from '$lib/docs/Preview.svelte'; @@ -80,17 +70,20 @@ - data.x0 + ' - ' + (data.x1 - 1)} let:data> - - - {#each data.slice(0, 5) as d} - - {/each} - {#if data.length > 5} - - ... - {/if} - + + {data.x0 + ' - ' + (data.x1 - 1)} + + + + {#each data.slice(0, 5) as d} + + {/each} + {#if data.length > 5} + + ... + {/if} + + @@ -115,17 +108,20 @@ - data.x0 + ' - ' + (data.x1 - 1)} let:data> - - - {#each data.slice(0, 5) as d} - - {/each} - {#if data.length > 5} - - ... - {/if} - + + {data.x0 + ' - ' + (data.x1 - 1)} + + + + {#each data.slice(0, 5) as d} + + {/each} + {#if data.length > 5} + + ... + {/if} + + @@ -207,17 +203,20 @@ - data.x0 + ' - ' + (data.x1 - 0.01)} let:data> - - - {#each data.slice(0, 5) as d} - - {/each} - {#if data.length > 5} - - ... - {/if} - + + {data.x0 + ' - ' + (data.x1 - 0.01)} + + + + {#each data.slice(0, 5) as d} + + {/each} + {#if data.length > 5} + + ... + {/if} + + @@ -262,25 +261,28 @@ - - format(data.x0, PeriodType.Day) + ' - ' + format(data.x1, PeriodType.Day)} - let:data - > - - - {#each data.slice(0, 5) as d} - format(value, PeriodType.DayTime)} - /> - {/each} - {#if data.length > 5} - - ... - {/if} - + + + {format(data.x0, PeriodType.Day) + + ' - ' + + format(data.x1, PeriodType.Day)} + + + + {#each data.slice(0, 5) as d} + format(value, PeriodType.DayTime)} + /> + {/each} + {#if data.length > 5} + + ... + {/if} + + @@ -339,25 +341,28 @@ - - format(data.x0, PeriodType.Day) + ' - ' + format(new Date(data.x1 - 1), PeriodType.Day)} - let:data - > - - - {#each data.slice(0, 5) as d} - format(value, PeriodType.DayTime)} - /> - {/each} - {#if data.length > 5} - - ... - {/if} - + + {format(data.x0, PeriodType.Day) + + ' - ' + + format(new Date(data.x1 - 1), PeriodType.Day)} + + + + {#each data.slice(0, 5) as d} + format(value, PeriodType.DayTime)} + /> + {/each} + {#if data.length > 5} + + ... + {/if} + + From be1fd3a626c67b3f95fb92d5794449191be8094f Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 4 Aug 2024 11:20:58 -0400 Subject: [PATCH 010/177] Update more examples to new Tooltip module components --- .../routes/docs/charts/AreaChart/+page.svelte | 33 +--------- .../docs/components/Calendar/+page.svelte | 2 +- .../routes/docs/examples/Area/+page.svelte | 64 +++++++++++-------- .../docs/examples/AreaStack/+page.svelte | 13 ++-- .../routes/docs/examples/Bars/+page.svelte | 39 +++++++---- .../docs/examples/Beeswarm/+page.svelte | 17 +++-- .../docs/examples/Candlestick/+page.svelte | 17 +++-- .../routes/docs/examples/Columns/+page.svelte | 39 +++++++---- 8 files changed, 118 insertions(+), 106 deletions(-) diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte index b4f0acf53..ea0bce6ea 100644 --- a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte @@ -25,7 +25,7 @@ import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; - export let data; + // export let data; const dateSeriesData = createDateSeries({ count: 30, min: 50, max: 100, value: 'integer' }); // Align with AreaChart defaults (label/value) @@ -101,36 +101,7 @@ - + @@ -173,10 +175,13 @@ - d.name} let:data> - - - + + {data.name} + + + + + @@ -229,10 +234,13 @@ - d.name} let:data> - - - + + {data.name} + + + + + diff --git a/packages/layerchart/src/routes/docs/examples/GeoTile/+page.svelte b/packages/layerchart/src/routes/docs/examples/GeoTile/+page.svelte index 9d7b548f9..bd0956f91 100644 --- a/packages/layerchart/src/routes/docs/examples/GeoTile/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/GeoTile/+page.svelte @@ -3,7 +3,7 @@ import { geoMercator } from 'd3-geo'; import { feature } from 'topojson-client'; - import { Canvas, ClipPath, Chart, GeoPath, GeoTile, Svg, Tooltip, TooltipItem } from 'layerchart'; + import { Canvas, ClipPath, Chart, GeoPath, GeoTile, Svg, Tooltip } from 'layerchart'; import { Field, RangeField, Switch } from 'svelte-ux'; import Preview from '$lib/docs/Preview.svelte'; @@ -61,11 +61,15 @@ /> {/each} - data.properties.name} let:data> + + {@const [longitude, latitude] = projection.invert?.([tooltip.x, tooltip.y]) ?? []} - - - + {data.properties.name} + + + + + @@ -97,11 +101,15 @@ /> {/each} - data.properties.name} let:data> + + {@const [longitude, latitude] = projection.invert?.([tooltip.x, tooltip.y]) ?? []} - - - + {data.properties.name} + + + + + diff --git a/packages/layerchart/src/routes/docs/examples/Line/+page.svelte b/packages/layerchart/src/routes/docs/examples/Line/+page.svelte index 7a6136e88..b4df74eb3 100644 --- a/packages/layerchart/src/routes/docs/examples/Line/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Line/+page.svelte @@ -16,7 +16,6 @@ Svg, Text, Tooltip, - TooltipItem, pivotLonger, } from 'layerchart'; @@ -104,9 +103,13 @@ - format(data.date, 'eee, MMMM do')} let:data> - - + + + {format(data.date, 'eee, MMMM do')} + + + + @@ -259,9 +262,13 @@ {/each} - format(data.date, 'eee, MMMM do')} let:data> - - + + + {format(data.date, 'eee, MMMM do')} + + + + @@ -296,10 +303,13 @@ d.y1} points={{ fill: fruitColors.oranges }} /> - - - - + + + + + + + @@ -352,9 +362,12 @@ {/each} - format(data.date, 'eee, MMMM do')} let:data> - - + + {format(data.date, 'eee, MMMM do')} + + + + @@ -392,9 +405,12 @@ - format(data.date, 'eee, MMMM do')} let:data> - - + + {format(data.date, 'eee, MMMM do')} + + + + diff --git a/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte b/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte index 0e14265fa..e645fb08f 100644 --- a/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/PunchCard/+page.svelte @@ -3,7 +3,7 @@ import { max, range } from 'd3-array'; import { getDay, getWeek } from 'date-fns'; - import { Axis, Chart, Circle, Highlight, Points, Svg, Tooltip, TooltipItem } from 'layerchart'; + import { Axis, Chart, Circle, Highlight, Points, Svg, Tooltip } from 'layerchart'; import { formatDate, PeriodType } from 'svelte-ux'; import Preview from '$lib/docs/Preview.svelte'; @@ -59,9 +59,12 @@ - formatDate(d.date, PeriodType.Day)} let:data> - - + + {formatDate(data.date, PeriodType.Day)} + + + + diff --git a/packages/layerchart/src/routes/docs/examples/Sankey/+page.svelte b/packages/layerchart/src/routes/docs/examples/Sankey/+page.svelte index ea725ecf6..1bc9d2981 100644 --- a/packages/layerchart/src/routes/docs/examples/Sankey/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Sankey/+page.svelte @@ -17,8 +17,6 @@ Svg, Text, Tooltip, - TooltipItem, - TooltipSeparator, graphFromHierarchy, graphFromNode, } from 'layerchart'; @@ -146,8 +144,8 @@ - -
+ + {#if data.node} {data.node.name} {:else if data.link} @@ -155,30 +153,32 @@ {data.link.target.name} {/if} -
+ - {#if data.node} - - - {#if data.node.targetLinks.length} - -
Sources
- {#each data.node.targetLinks as link} - - {/each} - {/if} - - {#if data.node.sourceLinks.length} - -
Targets
- {#each data.node.sourceLinks as link} - - {/each} + + {#if data.node} + + + {#if data.node.targetLinks.length} + +
Sources
+ {#each data.node.targetLinks as link} + + {/each} + {/if} + + {#if data.node.sourceLinks.length} + +
Targets
+ {#each data.node.sourceLinks as link} + + {/each} + {/if} + {:else if data.link} + {/if} - {:else if data.link} - - {/if} -
+ + @@ -317,8 +317,8 @@ - -
+ + {#if data.node} {data.node.name} {:else if data.link} @@ -326,30 +326,32 @@ {data.link.target.name} {/if} -
+ - {#if data.node} - - - {#if data.node.targetLinks.length} - -
Sources
- {#each data.node.targetLinks as link} - - {/each} - {/if} - - {#if data.node.sourceLinks.length} - -
Targets
- {#each data.node.sourceLinks as link} - - {/each} + + {#if data.node} + + + {#if data.node.targetLinks.length} + +
Sources
+ {#each data.node.targetLinks as link} + + {/each} + {/if} + + {#if data.node.sourceLinks.length} + +
Targets
+ {#each data.node.sourceLinks as link} + + {/each} + {/if} + {:else if data.link} + {/if} - {:else if data.link} - - {/if} -
+ + diff --git a/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte b/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte index 15de49826..e72d4dc92 100644 --- a/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte @@ -3,7 +3,7 @@ import { format } from 'date-fns'; import { formatDate, PeriodType } from 'svelte-ux'; - import { Axis, Chart, Highlight, Labels, Points, Svg, Tooltip, TooltipItem } from 'layerchart'; + import { Axis, Chart, Highlight, Labels, Points, Svg, Tooltip } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; @@ -63,9 +63,13 @@ - format(data.date, 'eee, MMMM do')} let:data> - - + + + {format(data.date, 'eee, MMMM do')} + + + + diff --git a/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte b/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte index b380aef38..deefcdd60 100644 --- a/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte @@ -2,7 +2,7 @@ import { scaleBand } from 'd3-scale'; import { format } from 'date-fns'; - import { Bars, Chart, Highlight, Svg, Tooltip, TooltipItem } from 'layerchart'; + import { Bars, Chart, Highlight, Svg, Tooltip } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; @@ -77,14 +77,13 @@ - format(data.date, 'eee, MMM do')} - let:data - > - - + + + {format(data.date, 'eee, MMMM do')} + + + + @@ -107,12 +106,12 @@ -
@@ -121,7 +120,7 @@
{data.value}
- +
@@ -146,16 +145,19 @@ - format(data.date, 'eee, MMM do')} y={containerHeight + 4} xOffset={0} let:data > - - + {format(data.date, 'eee, MMM do')} + + + + Sed ipsum justo, facilisis id tempor hendrerit, suscipit eu ipsum. Mauris ut sapien quis nibh volutpat venenatis. Ut viverra justo varius sapien convallis venenatis vel faucibus urna. diff --git a/packages/layerchart/src/routes/docs/examples/Sparkline/+page.svelte b/packages/layerchart/src/routes/docs/examples/Sparkline/+page.svelte index 81c0b5f75..4e45fdf08 100644 --- a/packages/layerchart/src/routes/docs/examples/Sparkline/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Sparkline/+page.svelte @@ -2,7 +2,7 @@ import { scaleTime } from 'd3-scale'; import { format } from 'date-fns'; - import { Chart, Highlight, Spline, Svg, Tooltip, TooltipItem } from 'layerchart'; + import { Chart, Highlight, Spline, Svg, Tooltip } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; @@ -62,14 +62,13 @@ - format(data.date, 'eee, MMM do')} - let:data - > - - + + + {format(data.date, 'eee, MMM do')} + + + + @@ -90,7 +89,7 @@ - {data.value} - + @@ -128,16 +127,19 @@ - format(data.date, 'eee, MMM do')} y={containerHeight + 4} xOffset={0} let:data > - - + {format(data.date, 'eee, MMM do')} + + + + Sed ipsum justo, facilisis id tempor hendrerit, suscipit eu ipsum. Mauris ut sapien quis nibh volutpat venenatis. Ut viverra justo varius sapien convallis venenatis vel faucibus urna. From ae98d4e0e9158e6ab6655a84e57f076275e63f86 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 4 Aug 2024 17:12:17 -0400 Subject: [PATCH 015/177] Update remaining examples to new Tooltip module components --- .../docs/components/Calendar/+page.svelte | 11 +-- .../routes/docs/components/Pie/+page.svelte | 2 +- .../docs/examples/Compound/+page.svelte | 12 +-- .../docs/examples/SpikeMap/+page.svelte | 95 ++++++++++--------- .../SubmarineCablesGlobe/+page.svelte | 11 ++- .../docs/examples/Sunburst/+page.svelte | 22 ++--- .../docs/examples/Threshold/+page.svelte | 18 ++-- .../docs/examples/Timezones/+page.svelte | 19 ++-- .../routes/docs/examples/Treemap/+page.svelte | 11 ++- .../docs/examples/ZoomableMap/+page.svelte | 49 ++++++---- .../examples/ZoomableTileMap/+page.svelte | 35 ++++--- .../docs/tools/GeojsonPreview/+page.svelte | 15 +-- .../docs/tools/TopojsonPreview/+page.svelte | 15 +-- 13 files changed, 165 insertions(+), 150 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte b/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte index f90522e95..c26d1a081 100644 --- a/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Calendar/+page.svelte @@ -4,16 +4,7 @@ import { scaleThreshold } from 'd3-scale'; import { range } from 'd3-array'; - import { - Calendar, - Chart, - Group, - Text, - Tooltip, - TooltipItem, - Svg, - TooltipHeader, - } from 'layerchart'; + import { Calendar, Chart, Group, Text, Tooltip, Svg } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; diff --git a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte index 9fe61a9bf..6e93a41d1 100644 --- a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte @@ -4,7 +4,7 @@ import { sum } from 'd3-array'; import { cls, format as formatUtil } from 'svelte-ux'; - import { Arc, Chart, Group, Pie, Svg, Text, Tooltip, TooltipItem } from 'layerchart'; + import { Arc, Chart, Group, Pie, Svg, Text, Tooltip } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; diff --git a/packages/layerchart/src/routes/docs/examples/Compound/+page.svelte b/packages/layerchart/src/routes/docs/examples/Compound/+page.svelte index 1c82d61ee..105aab7c3 100644 --- a/packages/layerchart/src/routes/docs/examples/Compound/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Compound/+page.svelte @@ -1,17 +1,7 @@ + + + + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + + + {#if labels} + + {/if} + + + + + {format(isVertical ? x(data) : y(data))} + + + + + + + diff --git a/packages/layerchart/src/lib/components/charts/index.ts b/packages/layerchart/src/lib/components/charts/index.ts index 3f4cb2522..b22d5cd5d 100644 --- a/packages/layerchart/src/lib/components/charts/index.ts +++ b/packages/layerchart/src/lib/components/charts/index.ts @@ -1 +1,2 @@ export { default as AreaChart } from './AreaChart.svelte'; +export { default as BarChart } from './BarChart.svelte'; diff --git a/packages/layerchart/src/routes/_NavMenu.svelte b/packages/layerchart/src/routes/_NavMenu.svelte index 7f032cb14..c30ae100a 100644 --- a/packages/layerchart/src/routes/_NavMenu.svelte +++ b/packages/layerchart/src/routes/_NavMenu.svelte @@ -7,7 +7,7 @@ type LinkCollection = Record>; const charts: LinkCollection = { - 'Cartesian & Polar': ['AreaChart'], + 'Cartesian & Polar': ['AreaChart', 'BarChart'], }; const examples: LinkCollection = { diff --git a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte index ea0bce6ea..d3d10f456 100644 --- a/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/charts/AreaChart/+page.svelte @@ -75,7 +75,7 @@ -

Full chart override

+

Custom chart

diff --git a/packages/layerchart/src/routes/docs/charts/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/charts/BarChart/+page.svelte new file mode 100644 index 000000000..47955a482 --- /dev/null +++ b/packages/layerchart/src/routes/docs/charts/BarChart/+page.svelte @@ -0,0 +1,182 @@ + + +

Examples

+ +

Vertical (default)

+ + +
+ +
+
+ +

Horizontal

+ + +
+ +
+
+ +

Labels

+ + +
+ +
+
+ +

Labels (inside placement)

+ + +
+ +
+
+ +

Custom tooltip

+ + +
+ + + + {format(x(data), PeriodType.DayTime)} + + + + + + +
+
+ +

Custom chart

+ + +
+ + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + + + + + + {format(x(data))} + + + + + +
+
diff --git a/packages/layerchart/src/routes/docs/charts/BarChart/+page.ts b/packages/layerchart/src/routes/docs/charts/BarChart/+page.ts new file mode 100644 index 000000000..519d350c4 --- /dev/null +++ b/packages/layerchart/src/routes/docs/charts/BarChart/+page.ts @@ -0,0 +1,14 @@ +import api from '$lib/components/charts/BarChart.svelte?raw&sveld'; +import source from '$lib/components/charts/BarChart.svelte?raw'; +import pageSource from './+page.svelte?raw'; + +export async function load() { + return { + meta: { + api, + source, + pageSource, + related: ['components/Bars', 'examples/Bars', 'examples/Histogram', 'examples/Sparkbar'], + }, + }; +} diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.ts b/packages/layerchart/src/routes/docs/examples/Bars/+page.ts index e737de2ed..b40169ef0 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.ts +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.ts @@ -5,7 +5,7 @@ export async function load() { meta: { title: 'Bar Chart (Horizontal)', pageSource, - related: ['components/Bars', 'examples/Columns', 'examples/Histogram'], + related: ['components/Bars', 'examples/Columns', 'examples/Histogram', 'charts/BarChart'], }, }; } From a20f89b6d650003a217e7b4d0487f62f1f9d11fc Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 6 Aug 2024 23:51:48 -0400 Subject: [PATCH 020/177] Add 2 examples for an Area with threshold coloring using RectClipPath or LinearGradient --- .../routes/docs/examples/Area/+page.svelte | 77 +++++++++++++++++++ 1 file changed, 77 insertions(+) diff --git a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte index f6485f539..eeb10cf3b 100644 --- a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte @@ -14,6 +14,7 @@ LinearGradient, Point, RectClipPath, + Rule, Spline, Svg, Text, @@ -28,6 +29,12 @@ export let data; const dateSeriesData = createDateSeries({ count: 30, min: 50, max: 100, value: 'integer' }); + const negativeDateSeriesData = createDateSeries({ + count: 30, + min: -20, + max: 50, + value: 'integer', + }); const keys = ['apples', 'bananas', 'oranges']; const multiSeriesData = createDateSeries({ @@ -553,6 +560,74 @@ +

Threshold with RectClipPath

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} /> + + + + + + + + + +
+
+ +

Threshold with LinearGradient

+ + +
+ + {@const thresholdOffset = (yScale(0) / (height + padding.bottom)) * 100 + '%'} + + + format(d, PeriodType.Day, { variant: 'short' })} /> + + + + + + +
+
+

Clipped area on Tooltip

@@ -585,6 +660,7 @@ @@ -599,6 +675,7 @@ x="data" y={height + padding.top + 2} anchor="top" + variant="none" class="text-sm font-semibold bg-primary text-primary-content leading-3 px-2 py-1 rounded whitespace-nowrap" let:data > From 673a4365eb49046ffd08aaef6cea079d4c68e07a Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 7 Aug 2024 09:25:58 -0400 Subject: [PATCH 021/177] [Area] Add over/under threshold examples --- .../routes/docs/examples/Area/+page.svelte | 73 +++++++++++++++++++ 1 file changed, 73 insertions(+) diff --git a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte index eeb10cf3b..cb8fd2b60 100644 --- a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte @@ -591,6 +591,37 @@
+

Threshold with RectClipPath (over/under)

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} /> + + + + + + 0} line={{ class: 'stroke-2 stroke-danger' }} class="fill-danger/20" /> + + + +
+
+

Threshold with LinearGradient

@@ -628,6 +659,48 @@ +

Threshold with LinearGradient (over/under)

+ + +
+ + {@const thresholdOffset = (yScale(0) / (height + padding.bottom)) * 100 + '%'} + + + format(d, PeriodType.Day, { variant: 'short' })} /> + + + 0} + line={{ stroke: url, class: 'stroke-2' }} + fill={url} + fill-opacity={0.2} + /> + + + +
+
+

Clipped area on Tooltip

From 2da8547d7d8f84d9272e08c166e081a068ad66cb Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 7 Aug 2024 14:33:14 -0400 Subject: [PATCH 022/177] [Area] Add Highlight color based on value example --- .../routes/docs/examples/Area/+page.svelte | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte index cb8fd2b60..7a3289776 100644 --- a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte @@ -622,6 +622,49 @@ +

Highlight color based on value

+ + +
+ (d.value < 0 ? 'under' : 'over')} + rScale={scaleOrdinal()} + rDomain={['over', 'under']} + rRange={['hsl(var(--color-success))', 'hsl(var(--color-danger))']} + let:width + let:height + let:yScale + > + + + format(d, PeriodType.Day, { variant: 'short' })} /> + + + 0} line={{ class: 'stroke-2 stroke-success' }} class="fill-success/20" /> + + + 0} line={{ class: 'stroke-2 stroke-danger' }} class="fill-danger/20" /> + + + + + + {formatDate(data.date, 'eee, MMMM do')} + + + + + +
+
+

Threshold with LinearGradient

From 2c38f947502aa3933f806361b471c9d1976802a7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 7 Aug 2024 15:26:37 -0400 Subject: [PATCH 023/177] [Area] Add "Highlight color based on value using tooltip slot prop" example --- .../routes/docs/examples/Area/+page.svelte | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte index 7a3289776..f2b2fec5e 100644 --- a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte @@ -622,7 +622,7 @@ -

Highlight color based on value

+

Highlight color based on value using color scale

@@ -665,6 +665,53 @@
+

Highlight color based on value using tooltip slot prop

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} /> + + + 0} line={{ class: 'stroke-2 stroke-success' }} class="fill-success/20" /> + + + 0} line={{ class: 'stroke-2 stroke-danger' }} class="fill-danger/20" /> + + + + + + {formatDate(data.date, 'eee, MMMM do')} + + + + + +
+
+

Threshold with LinearGradient

From 6eaa71ae1ea00083451bfdc900fe522cce15da95 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 14 Aug 2024 23:48:41 -0400 Subject: [PATCH 024/177] Add @layerstack svelte-stores, tailwind, and utils packages and move `svelte-ux` package to devDependancies (components for docs only) --- .changeset/lucky-tables-retire.md | 5 + packages/layerchart/package.json | 5 +- .../layerchart/src/lib/components/Area.svelte | 2 +- .../layerchart/src/lib/components/Axis.svelte | 4 +- .../layerchart/src/lib/components/Blur.svelte | 2 +- .../src/lib/components/Brush.svelte | 3 +- .../src/lib/components/Circle.svelte | 2 +- .../src/lib/components/CircleClipPath.svelte | 2 +- .../src/lib/components/ClipPath.svelte | 2 +- .../src/lib/components/GeoPath.svelte | 6 +- .../src/lib/components/Highlight.svelte | 3 +- .../src/lib/components/HitCanvas.svelte | 2 +- .../layerchart/src/lib/components/Hull.svelte | 2 +- .../src/lib/components/Labels.svelte | 5 +- .../src/lib/components/Legend.svelte | 6 +- .../layerchart/src/lib/components/Line.svelte | 2 +- .../src/lib/components/LinearGradient.svelte | 2 +- .../src/lib/components/MotionPath.svelte | 2 +- .../src/lib/components/Points.svelte | 2 +- .../src/lib/components/RadialGradient.svelte | 2 +- .../layerchart/src/lib/components/Rect.svelte | 2 +- .../src/lib/components/RectClipPath.svelte | 2 +- .../layerchart/src/lib/components/Rule.svelte | 2 +- .../src/lib/components/Spline.svelte | 2 +- .../layerchart/src/lib/components/Text.svelte | 2 +- .../lib/components/TransformControls.svelte | 3 +- .../src/lib/components/Voronoi.svelte | 2 +- .../lib/components/charts/AreaChart.svelte | 2 +- .../src/lib/components/charts/BarChart.svelte | 2 +- .../src/lib/components/layout/Canvas.svelte | 2 +- .../src/lib/components/layout/Html.svelte | 2 +- .../src/lib/components/layout/Svg.svelte | 2 +- .../src/lib/components/tooltip/Tooltip.svelte | 2 +- .../components/tooltip/TooltipContext.svelte | 3 +- .../components/tooltip/TooltipHeader.svelte | 2 +- .../lib/components/tooltip/TooltipItem.svelte | 3 +- .../lib/components/tooltip/TooltipList.svelte | 2 +- .../tooltip/TooltipSeparator.svelte | 2 +- .../layerchart/src/lib/docs/Blockquote.svelte | 3 +- packages/layerchart/src/lib/docs/Code.svelte | 3 +- .../src/lib/docs/CurveMenuField.svelte | 3 +- .../layerchart/src/lib/docs/GeoDebug.svelte | 4 +- packages/layerchart/src/lib/docs/Json.svelte | 2 +- .../layerchart/src/lib/docs/Preview.svelte | 3 +- .../src/lib/docs/TransformDebug.svelte | 3 +- packages/layerchart/src/lib/utils/ticks.ts | 3 +- packages/layerchart/src/routes/+layout.svelte | 6 +- .../layerchart/src/routes/docs/+layout.svelte | 16 +-- .../routes/docs/charts/AreaChart/+page.svelte | 3 +- .../src/routes/docs/charts/AreaChart/+page.ts | 2 +- .../routes/docs/charts/BarChart/+page.svelte | 3 +- .../routes/docs/components/Arc/+page.svelte | 1 - .../routes/docs/components/Area/+page.svelte | 1 - .../routes/docs/components/Axis/+page.svelte | 3 +- .../routes/docs/components/Brush/+page.svelte | 4 +- .../src/routes/docs/components/Brush/+page.ts | 2 +- .../docs/components/Calendar/+page.svelte | 2 +- .../docs/components/ColorRamp/+page.svelte | 3 +- .../routes/docs/components/Pie/+page.svelte | 3 +- .../docs/components/Tooltip/+page.svelte | 15 +-- .../docs/examples/AnimatedGlobe/+page.svelte | 5 +- .../src/routes/docs/examples/Arc/+page.svelte | 4 +- .../routes/docs/examples/Area/+page.svelte | 3 +- .../src/routes/docs/examples/Area/+page.ts | 2 +- .../docs/examples/AreaStack/+page.svelte | 4 +- .../routes/docs/examples/Bars/+page.svelte | 11 +- .../docs/examples/Beeswarm/+page.svelte | 2 +- .../docs/examples/BubbleMap/+page.svelte | 2 +- .../docs/examples/Candlestick/+page.svelte | 2 +- .../routes/docs/examples/Candlestick/+page.ts | 2 +- .../docs/examples/Choropleth/+page.svelte | 2 +- .../routes/docs/examples/Columns/+page.svelte | 11 +- .../docs/examples/Compound/+page.svelte | 4 +- .../routes/docs/examples/Compound/+page.ts | 2 +- .../routes/docs/examples/DotPlot/+page.svelte | 3 +- .../examples/EarthquakeGlobe/+page.svelte | 3 +- .../docs/examples/EclipsesGlobe/+page.svelte | 14 +-- .../docs/examples/EclipsesGlobe/+page.ts | 2 +- .../docs/examples/ForceTree/+page.svelte | 2 +- .../docs/examples/Histogram/+page.svelte | 3 +- .../routes/docs/examples/Line/+page.svelte | 2 +- .../src/routes/docs/examples/Line/+page.ts | 2 +- .../routes/docs/examples/Pack/+page.svelte | 12 +-- .../docs/examples/Partition/+page.svelte | 5 +- .../docs/examples/PunchCard/+page.svelte | 2 +- .../docs/examples/RadialLine/+page.svelte | 3 +- .../routes/docs/examples/Sankey/+page.svelte | 3 +- .../routes/docs/examples/Scatter/+page.svelte | 2 +- .../docs/examples/SketchyGlobe/+page.svelte | 3 +- .../docs/examples/StateMap/+page.svelte | 3 +- .../SubmarineCablesGlobe/+page.svelte | 4 +- .../docs/examples/Sunburst/+page.svelte | 12 +-- .../docs/examples/Threshold/+page.svelte | 2 +- .../docs/examples/Timezones/+page.svelte | 3 +- .../examples/TranslucentGlobe/+page.svelte | 3 +- .../routes/docs/examples/Tree/+page.svelte | 3 +- .../routes/docs/examples/Treemap/+page.svelte | 5 +- packages/layerchart/tailwind.config.cjs | 2 +- pnpm-lock.yaml | 101 +++++++++++------- 99 files changed, 226 insertions(+), 217 deletions(-) create mode 100644 .changeset/lucky-tables-retire.md diff --git a/.changeset/lucky-tables-retire.md b/.changeset/lucky-tables-retire.md new file mode 100644 index 000000000..e487c1356 --- /dev/null +++ b/.changeset/lucky-tables-retire.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +Add @layerstack svelte-stores, tailwind, and utils packages and move `svelte-ux` package to devDependancies (components for docs only) diff --git a/packages/layerchart/package.json b/packages/layerchart/package.json index c8ce1a523..d655d8f81 100644 --- a/packages/layerchart/package.json +++ b/packages/layerchart/package.json @@ -66,6 +66,7 @@ "svelte-check": "^3.8.5", "svelte-json-tree": "^2.2.0", "svelte-preprocess": "^6.0.2", + "svelte-ux": "^0.74.4", "svelte2tsx": "^0.7.15", "tailwindcss": "^3.4.10", "topojson-client": "^3.1.0", @@ -78,6 +79,9 @@ }, "type": "module", "dependencies": { + "@layerstack/svelte-stores": "^0.0.3", + "@layerstack/tailwind": "^0.0.5", + "@layerstack/utils": "^0.0.3", "d3-array": "^3.2.4", "d3-color": "^3.1.0", "d3-delaunay": "^6.0.4", @@ -102,7 +106,6 @@ "lodash-es": "^4.17.21", "posthog-js": "^1.155.4", "shapefile": "^0.6.6", - "svelte-ux": "^0.74.4", "topojson-client": "^3.1.0" }, "peerDependencies": { diff --git a/packages/layerchart/src/lib/components/Area.svelte b/packages/layerchart/src/lib/components/Area.svelte index d3bf335fd..1b5a07bbc 100644 --- a/packages/layerchart/src/lib/components/Area.svelte +++ b/packages/layerchart/src/lib/components/Area.svelte @@ -6,7 +6,7 @@ import { max } from 'd3-array'; import { interpolatePath } from 'd3-interpolate-path'; - import { cls } from 'svelte-ux'; + import { cls } from '@layerstack/tailwind'; import { motionStore } from '$lib/stores/motionStore.js'; diff --git a/packages/layerchart/src/lib/components/Axis.svelte b/packages/layerchart/src/lib/components/Axis.svelte index d66bd4132..fef076697 100644 --- a/packages/layerchart/src/lib/components/Axis.svelte +++ b/packages/layerchart/src/lib/components/Axis.svelte @@ -8,7 +8,9 @@ import { extent } from 'd3-array'; import { pointRadial } from 'd3-shape'; - import { format as formatValue, type FormatType, cls, type TransitionParams } from 'svelte-ux'; + import { format as formatValue, type FormatType } from '@layerstack/utils'; + import { cls } from '@layerstack/tailwind'; + import type { TransitionParams } from 'svelte-ux'; // TODO: Replace with `@layerstack/svelte-types` or similar import { chartContext } from './ChartContext.svelte'; import Circle from './Circle.svelte'; diff --git a/packages/layerchart/src/lib/components/Blur.svelte b/packages/layerchart/src/lib/components/Blur.svelte index 267989210..868ed9ad3 100644 --- a/packages/layerchart/src/lib/components/Blur.svelte +++ b/packages/layerchart/src/lib/components/Blur.svelte @@ -1,5 +1,5 @@
- import { cls, format as formatUtil, type FormatType, type ThemeColors } from 'svelte-ux'; + import { format as formatUtil, type FormatType } from '@layerstack/utils'; + import { cls, type ThemeColors } from '@layerstack/tailwind'; export let label: any; /** Value to be formatted and displayed. Can also be passed as default slot */ diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipList.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipList.svelte index b18930d57..144643220 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipList.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipList.svelte @@ -1,5 +1,5 @@
- import { cls } from 'svelte-ux'; + import { cls } from '@layerstack/tailwind';
diff --git a/packages/layerchart/src/lib/docs/Blockquote.svelte b/packages/layerchart/src/lib/docs/Blockquote.svelte index 438ffbafa..adde7486c 100644 --- a/packages/layerchart/src/lib/docs/Blockquote.svelte +++ b/packages/layerchart/src/lib/docs/Blockquote.svelte @@ -1,6 +1,7 @@
import Prism from 'prismjs'; import 'prism-svelte'; - import { CopyButton, cls } from 'svelte-ux'; + import { CopyButton } from 'svelte-ux'; + import { cls } from '@layerstack/tailwind'; export let source: string | null = null; export let language = 'svelte'; diff --git a/packages/layerchart/src/lib/docs/CurveMenuField.svelte b/packages/layerchart/src/lib/docs/CurveMenuField.svelte index bcf6cbf35..10bf08ace 100644 --- a/packages/layerchart/src/lib/docs/CurveMenuField.svelte +++ b/packages/layerchart/src/lib/docs/CurveMenuField.svelte @@ -1,7 +1,8 @@
@@ -101,9 +101,9 @@ let:tooltip > {#if projection === geoMercator} - + - + {/if} From b92f705c76baa978e41a9335794e258d5413236c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 15 Aug 2024 16:35:58 -0400 Subject: [PATCH 032/177] Add map pan/zoom to topojson and geosjon previews with enhanced tile layers --- .../docs/tools/GeojsonPreview/+page.svelte | 26 ++++++++++++++++--- .../docs/tools/TopojsonPreview/+page.svelte | 22 +++++++++++++++- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/layerchart/src/routes/docs/tools/GeojsonPreview/+page.svelte b/packages/layerchart/src/routes/docs/tools/GeojsonPreview/+page.svelte index b26aa8508..298f940bd 100644 --- a/packages/layerchart/src/routes/docs/tools/GeojsonPreview/+page.svelte +++ b/packages/layerchart/src/routes/docs/tools/GeojsonPreview/+page.svelte @@ -15,7 +15,16 @@ import { schemeCategory10 } from 'd3-scale-chromatic'; import { color } from 'd3-color'; - import { Canvas, Chart, GeoPath, GeoTile, HitCanvas, Tooltip } from 'layerchart'; + import { + Canvas, + Chart, + GeoPath, + GeoTile, + HitCanvas, + Svg, + Tooltip, + TransformControls, + } from 'layerchart'; import { EmptyMessage, RangeField, @@ -89,16 +98,27 @@ geo={{ projection, fitGeojson: geojson, + applyTransform: ['translate', 'scale'], + }} + transform={{ + translateOnScale: true, + initialScrollMode: 'scale', }} padding={{ top: 8, bottom: 8, left: 8, right: 8 }} let:tooltip > {#if projection === geoMercator} - + + + + + - + {/if} + + {#if projection === geoMercator} diff --git a/packages/layerchart/src/routes/docs/tools/TopojsonPreview/+page.svelte b/packages/layerchart/src/routes/docs/tools/TopojsonPreview/+page.svelte index 831777e7f..db0e55e7e 100644 --- a/packages/layerchart/src/routes/docs/tools/TopojsonPreview/+page.svelte +++ b/packages/layerchart/src/routes/docs/tools/TopojsonPreview/+page.svelte @@ -17,7 +17,16 @@ import { feature } from 'topojson-client'; import type { GeometryCollection, Topology } from 'topojson-specification'; - import { Canvas, Chart, GeoPath, GeoTile, HitCanvas, Svg, Tooltip } from 'layerchart'; + import { + Canvas, + Chart, + GeoPath, + GeoTile, + HitCanvas, + Svg, + Tooltip, + TransformControls, + } from 'layerchart'; import { CopyButton, EmptyMessage, @@ -96,16 +105,27 @@ geo={{ projection, fitGeojson: geojson, + applyTransform: ['translate', 'scale'], + }} + transform={{ + translateOnScale: true, + initialScrollMode: 'scale', }} padding={{ top: 8, bottom: 8, left: 8, right: 8 }} let:tooltip > {#if projection === geoMercator} + + + + {/if} + + {#if projection === geoMercator} From 47330c9f5d33b26376b0b86e31990172a78e0177 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 16 Aug 2024 00:22:04 -0400 Subject: [PATCH 033/177] feat(AreaChart): Add `labels` prop and pass `tooltip` as slot prop --- .../src/lib/components/charts/AreaChart.svelte | 16 ++++++++++++---- .../docs/components/AreaChart/+page.svelte | 14 +++++++++----- 2 files changed, 21 insertions(+), 9 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 9b46714ae..4c4aa3848 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -1,24 +1,28 @@ @@ -35,8 +39,9 @@ {...$$restProps} let:x let:y + let:tooltip > - + + {#if labels} + + {/if} diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 937cf6371..1d1c12310 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -26,11 +26,7 @@ import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; - // export let data; - const dateSeriesData = createDateSeries({ count: 30, min: 50, max: 100, value: 'integer' }); - // Align with AreaChart defaults (label/value) - const chartData = dateSeriesData.map((d) => ({ ...d, label: d.date })); const keys = ['apples', 'bananas', 'oranges']; const multiSeriesData = createDateSeries({ @@ -55,7 +51,15 @@
- + +
+
+ +

Labels

+ + +
+
From d9efcbb5fa52c6fb99f58ece75fe5a65d89b0f87 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 16 Aug 2024 00:23:41 -0400 Subject: [PATCH 034/177] feat(BarChart): Add `tooltip` slot prop --- packages/layerchart/src/lib/components/charts/BarChart.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 80039016e..c62ac2576 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -51,8 +51,9 @@ {...$$restProps} let:x let:y + let:tooltip > - + Date: Fri, 16 Aug 2024 00:25:36 -0400 Subject: [PATCH 035/177] feat(TooltipItem): Rework `color` prop to be any string color and use CSS variables for theme colors --- .../lib/components/tooltip/TooltipItem.svelte | 20 +++---------------- .../docs/components/Tooltip/+page.svelte | 8 ++++---- 2 files changed, 7 insertions(+), 21 deletions(-) diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte index c9c4189e3..64364df3a 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte @@ -7,7 +7,7 @@ export let value: any = undefined; export let format: FormatType | undefined = undefined; export let valueAlign: 'left' | 'right' | 'center' = 'left'; - export let color: ThemeColors | 'variable' | undefined = undefined; + export let color: string | undefined = undefined; export let classes: { root?: string; @@ -21,22 +21,8 @@
{#if color}
{/if} {label} diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index 9c370d517..e9265ce66 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -192,7 +192,7 @@
-

theme color swatch

+

color swatch

@@ -219,14 +219,14 @@ {format(data.date, 'eee, MMMM do')} - +
-

custom color swatch

+

color swatch using theme

@@ -253,7 +253,7 @@ {format(data.date, 'eee, MMMM do')} - + From f1293fb46f57f9294b98294d0562cfe37148102e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 16 Aug 2024 00:26:23 -0400 Subject: [PATCH 036/177] feat: Add LineChart component --- .../lib/components/charts/LineChart.svelte | 87 +++ .../src/lib/components/charts/index.ts | 1 + .../layerchart/src/routes/_NavMenu.svelte | 2 +- .../docs/components/LineChart/+page.svelte | 641 ++++++++++++++++++ .../routes/docs/components/LineChart/+page.ts | 22 + .../routes/docs/examples/Line/+page.svelte | 2 +- 6 files changed, 753 insertions(+), 2 deletions(-) create mode 100644 packages/layerchart/src/lib/components/charts/LineChart.svelte create mode 100644 packages/layerchart/src/routes/docs/components/LineChart/+page.svelte create mode 100644 packages/layerchart/src/routes/docs/components/LineChart/+page.ts diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte new file mode 100644 index 000000000..eb349dd1d --- /dev/null +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -0,0 +1,87 @@ + + + d.value)} + yDomain={[0, null]} + yNice + padding={{ left: 16, bottom: 16 }} + tooltip={{ mode: 'bisect-x' }} + {...$$restProps} + let:x + let:y + let:tooltip +> + + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + + {#each series as s} + {@const valueAccessor = accessor(s.value)} + + + {/each} + + + {#if labels} + + {/if} + + + + + {format(x(data))} + + {#each series as s} + {@const valueAccessor = accessor(s.value)} + + {/each} + + + + + diff --git a/packages/layerchart/src/lib/components/charts/index.ts b/packages/layerchart/src/lib/components/charts/index.ts index b22d5cd5d..1661e3dca 100644 --- a/packages/layerchart/src/lib/components/charts/index.ts +++ b/packages/layerchart/src/lib/components/charts/index.ts @@ -1,2 +1,3 @@ export { default as AreaChart } from './AreaChart.svelte'; export { default as BarChart } from './BarChart.svelte'; +export { default as LineChart } from './LineChart.svelte'; diff --git a/packages/layerchart/src/routes/_NavMenu.svelte b/packages/layerchart/src/routes/_NavMenu.svelte index 53c8ccc75..c0c60884e 100644 --- a/packages/layerchart/src/routes/_NavMenu.svelte +++ b/packages/layerchart/src/routes/_NavMenu.svelte @@ -65,7 +65,7 @@ }; const components: LinkCollection = { - Charts: ['Chart', 'AreaChart', 'BarChart'], + Charts: ['Chart', 'AreaChart', 'BarChart', 'LineChart'], Common: ['Axis', 'Frame', 'Legend', 'Rule'], Primitives: ['Arc', 'Circle', 'Group', 'Line', 'Point', 'Rect', 'Text'], 'Data-driven': [ diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte new file mode 100644 index 000000000..f8c23a141 --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -0,0 +1,641 @@ + + +

Examples

+ +

Basic

+ + +
+ +
+
+ +

Series

+ + +
+ +
+
+ +

Series (highlight on hover)

+ + +
+ + {@const series = [ + { label: 'apples', value: 'apples', color: 'hsl(var(--color-danger))' }, + { label: 'bananas', value: 'bananas', color: 'hsl(var(--color-success))' }, + { label: 'oranges', value: 'oranges', color: 'hsl(var(--color-warning))' }, + ]} + {@const activeSeriesColor = series.find((s) => s.value === tooltip.data?.fruit)?.color} + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + + {#each series as s} + {@const color = + tooltip.data == null || tooltip.data.fruit === s.value + ? s.color + : 'hsl(var(--color-surface-content) / 20%)'} + + {/each} + + + + + + {format(x(data))} + + + + + +
+
+ +

Labels

+ + +
+ +
+
+ +

Custom tooltip

+ + +
+ + + + {format(x(data), PeriodType.DayTime)} + + + + + + +
+
+ +

Custom chart

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + + + + + {format(x(data), PeriodType.DayTime)} + + + + + +
+
+ + diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.ts b/packages/layerchart/src/routes/docs/components/LineChart/+page.ts new file mode 100644 index 000000000..af9b62a1d --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.ts @@ -0,0 +1,22 @@ +import { parse } from '@layerstack/utils'; + +import api from '$lib/components/charts/LineChart.svelte?raw&sveld'; +import source from '$lib/components/charts/LineChart.svelte?raw'; +import pageSource from './+page.svelte?raw'; + +import type { AppleStockData } from '$static/data/examples/date/apple-stock.js'; + +export async function load() { + return { + appleStock: await fetch('/data/examples/date/apple-stock.json').then(async (r) => + parse(await r.text()) + ), + meta: { + api, + source, + pageSource, + description: 'Streamlined Chart configuration for Line charts', + related: ['components/Chart', 'components/Spline', 'examples/Line'], + }, + }; +} diff --git a/packages/layerchart/src/routes/docs/examples/Line/+page.svelte b/packages/layerchart/src/routes/docs/examples/Line/+page.svelte index d89d0b041..0873bfa33 100644 --- a/packages/layerchart/src/routes/docs/examples/Line/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Line/+page.svelte @@ -287,7 +287,7 @@ y="y" yDomain={[0, null]} yNice - padding={{ left: 16, bottom: 24, right: 48 }} + padding={{ left: 16, bottom: 24 }} tooltip={{ mode: 'bisect-x' }} > From 0e7283ba366c7d9500673ce67009b841513c608e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 16 Aug 2024 00:40:05 -0400 Subject: [PATCH 037/177] Format --- .../src/routes/docs/components/LineChart/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index f8c23a141..378fd6c93 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -101,7 +101,7 @@
- +
From e906257b76541adc9db089f192a29fa2e7bb7458 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 16 Aug 2024 23:21:29 -0400 Subject: [PATCH 038/177] feat(AreaChart): Add `series` support --- .../lib/components/charts/AreaChart.svelte | 27 +- .../docs/components/AreaChart/+page.svelte | 610 +++--------------- 2 files changed, 115 insertions(+), 522 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 4c4aa3848..233744d20 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -14,6 +14,7 @@ import { accessor, chartDataArray, type Accessor } from '../../utils/common.js'; interface $$Props extends ComponentProps> { + series?: typeof series; labels?: typeof labels; } @@ -21,6 +22,10 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; + export let series: { label?: string; value: Accessor; color?: string }[] = [ + { value: y, color: 'hsl(var(--color-primary))' }, + ]; + export let labels: ComponentProps | boolean = false; // Default xScale based on first data's `x` value @@ -31,7 +36,7 @@ {data} {x} {xScale} - {y} + y={y ?? series.map((d) => d.value)} yDomain={[0, null]} yNice padding={{ left: 16, bottom: 16 }} @@ -54,8 +59,19 @@ rule format={(value) => format(value, undefined, { variant: 'short' })} /> - - + + {#each series as s} + {@const valueAccessor = accessor(s.value)} + + + {/each} + + {#if labels} {/if} @@ -65,7 +81,10 @@ {format(x(data))} - + {#each series as s} + {@const valueAccessor = accessor(s.value)} + + {/each} diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 1d1c12310..1471e7b79 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -1,26 +1,6 @@

Examples

@@ -55,341 +29,128 @@
-

Labels

- - -
- -
-
- -

Custom tooltip

- - -
- - - - {format(x(data), PeriodType.DayTime)} - - - - - - -
-
- -

Custom chart

- - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - - - - - {format(x(data), PeriodType.DayTime)} - - - - - -
-
- - - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - {#each dataByFruit as [fruit, data]} - {@const color = rScale(fruit)} - - - - {/each} - + + - formatDate(data.date, 'eee, MMMM do')} let:data> - - - + + + {format(x(data))} + + + + +
-

Multiple series (using overrides)

+

Labels

- +
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - d.apples} - class="stroke-2" - fill={fruitColors.apples} - fill-opacity={0.3} - line={{ stroke: fruitColors.apples, class: 'stroke-2' }} - /> - - d.bananas} - class="stroke-2" - fill={fruitColors.bananas} - fill-opacity={0.3} - line={{ stroke: fruitColors.bananas, class: 'stroke-2' }} - /> - - d.oranges} - class="stroke-2" - fill={fruitColors.oranges} - fill-opacity={0.3} - line={{ stroke: fruitColors.oranges, class: 'stroke-2' }} - /> - - d.apples} points={{ fill: fruitColors.apples }} /> - d.bananas} points={{ fill: fruitColors.bananas }} /> - d.oranges} points={{ fill: fruitColors.oranges }} /> - - - formatDate(data.date, 'eee, MMMM do')} let:data> - - - - - +
-

Multiple series (highlight on hover)

+

Custom tooltip

- +
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - {#each dataByFruit as [fruit, data]} - {@const color = - tooltip.data == null || tooltip.data.fruit === fruit - ? rScale(fruit) - : 'hsl(var(--color-surface-content) / 20%)'} - - - - - - {/each} - - - formatDate(data.date, 'eee, MMMM do')} let:data> - - - + + + + {format(x(data), PeriodType.DayTime)} + + + + + +
-

Multiple series with labels

+

Custom chart

- +
- + format(d, PeriodType.Day, { variant: 'short' })} rule /> - {#each dataByFruit as [fruit, data]} - {@const color = rScale(fruit)} - - {/each} - + - formatDate(data.date, 'eee, MMMM do')} let:data> - - - -
-
- -

Clip tween on mount

- - -
- - - -
- - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - {#if show} - - - - {/if} - - -
-
-
- - -
- - - -
- - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - {#if show} - - - - - {/if} - - -
-
-
- - -
- - - -
- - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - {#if show} - - - - - {/if} - - -
-
-
- -

Clipped area on Tooltip

- - -
- - - - - - - - - - - - - {format(data.value, 'currency')} - - - - {format(data.date, PeriodType.Day)} - - - - {format(data.date, PeriodType.Day)} - - + + {format(x(data), PeriodType.DayTime)} + + + + +
-
--> +
From 45dd039c3c01c66a90b4940cf9fff13aeb06ba0f Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 17 Aug 2024 11:18:38 -0400 Subject: [PATCH 039/177] Always show tooltip highlight points above areas and simplify by leveraging component value accessor directly --- .../src/lib/components/charts/AreaChart.svelte | 9 +++++---- .../layerchart/src/lib/components/charts/BarChart.svelte | 1 + .../src/lib/components/charts/LineChart.svelte | 8 +++----- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 233744d20..fb451fa8a 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -61,16 +61,17 @@ /> {#each series as s} - {@const valueAccessor = accessor(s.value)} - {/each} - + + {#each series as s, i} + + {/each} {#if labels} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index c62ac2576..7623ad042 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -69,6 +69,7 @@ /> + {#if labels} {/if} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index eb349dd1d..8c240b064 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -60,12 +60,10 @@ format={(value) => format(value, undefined, { variant: 'short' })} /> - {#each series as s} - {@const valueAccessor = accessor(s.value)} - - + {#each series as s, i} + + {/each} - {#if labels} From d0c22c5d0832d19562da192ead827ba5fad2dc85 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 17 Aug 2024 11:56:53 -0400 Subject: [PATCH 040/177] feat: Add ScatterChart --- .../lib/components/charts/ScatterChart.svelte | 75 +++++++++++++++++++ .../src/lib/components/charts/index.ts | 1 + .../layerchart/src/routes/_NavMenu.svelte | 2 +- .../docs/components/ScatterChart/+page.svelte | 66 ++++++++++++++++ .../docs/components/ScatterChart/+page.ts | 15 ++++ 5 files changed, 158 insertions(+), 1 deletion(-) create mode 100644 packages/layerchart/src/lib/components/charts/ScatterChart.svelte create mode 100644 packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte create mode 100644 packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte new file mode 100644 index 000000000..3dde6689d --- /dev/null +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -0,0 +1,75 @@ + + + + + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + + + + + {#if labels} + format(value)} /> + {/if} + + + + + {format(x(data))} + + + + + + + diff --git a/packages/layerchart/src/lib/components/charts/index.ts b/packages/layerchart/src/lib/components/charts/index.ts index 1661e3dca..aebd05f72 100644 --- a/packages/layerchart/src/lib/components/charts/index.ts +++ b/packages/layerchart/src/lib/components/charts/index.ts @@ -1,3 +1,4 @@ export { default as AreaChart } from './AreaChart.svelte'; export { default as BarChart } from './BarChart.svelte'; export { default as LineChart } from './LineChart.svelte'; +export { default as ScatterChart } from './ScatterChart.svelte'; diff --git a/packages/layerchart/src/routes/_NavMenu.svelte b/packages/layerchart/src/routes/_NavMenu.svelte index c0c60884e..f596682e8 100644 --- a/packages/layerchart/src/routes/_NavMenu.svelte +++ b/packages/layerchart/src/routes/_NavMenu.svelte @@ -65,7 +65,7 @@ }; const components: LinkCollection = { - Charts: ['Chart', 'AreaChart', 'BarChart', 'LineChart'], + Charts: ['Chart', 'AreaChart', 'BarChart', 'LineChart', 'ScatterChart'], Common: ['Axis', 'Frame', 'Legend', 'Rule'], Primitives: ['Arc', 'Circle', 'Group', 'Line', 'Point', 'Rect', 'Text'], 'Data-driven': [ diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte new file mode 100644 index 000000000..a1c4f92fe --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte @@ -0,0 +1,66 @@ + + +

Examples

+ +

Basic

+ + +
+ +
+
+ +

Labels

+ + +
+ +
+
+ +

Custom tooltip

+ + +
+ + + + {format(x(data), 'integer')} + + + + + + +
+
+ +

Custom chart

+ + +
+ + + + + + + + + + {format(x(data), 'integer')} + + + + + +
+
diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts new file mode 100644 index 000000000..ccd26bdfd --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts @@ -0,0 +1,15 @@ +import api from '$lib/components/charts/ScatterChart.svelte?raw&sveld'; +import source from '$lib/components/charts/ScatterChart.svelte?raw'; +import pageSource from './+page.svelte?raw'; + +export async function load() { + return { + meta: { + api, + source, + pageSource, + description: 'Streamlined Chart configuration for Scatter charts', + related: ['components/Chart', 'components/Points', 'examples/Scatter'], + }, + }; +} From 547a294e353d7439417ab58318ded0800be4ff97 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 17 Aug 2024 21:14:04 -0400 Subject: [PATCH 041/177] docs(Axis): Add responsive ticks example --- .../routes/docs/components/Axis/+page.svelte | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/packages/layerchart/src/routes/docs/components/Axis/+page.svelte b/packages/layerchart/src/routes/docs/components/Axis/+page.svelte index a44f4cafc..acf45889b 100644 --- a/packages/layerchart/src/routes/docs/components/Axis/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Axis/+page.svelte @@ -2,6 +2,7 @@ import { scaleTime } from 'd3-scale'; import { Field, PeriodType, Switch } from 'svelte-ux'; import { format } from '@layerstack/utils'; + import { mdScreen } from '@layerstack/svelte-stores'; import { Axis, Chart, Svg, Frame, Rule, Text } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; @@ -337,6 +338,27 @@
+

tick count (responsive)

+ + +
+ + + + + + +
+
+

remove default tick count

From ca8b4d528ddbd39817edb6da2777a6dc4048dc93 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 18 Aug 2024 11:03:33 -0400 Subject: [PATCH 042/177] Use only layerstack/utils format instead of date-fns for bar examples. Add diverging bar examples --- .../routes/docs/examples/Bars/+page.svelte | 104 +++++++++++++----- .../routes/docs/examples/Columns/+page.svelte | 103 ++++++++++++----- 2 files changed, 151 insertions(+), 56 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte index 0b9416735..b9716572d 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte @@ -1,12 +1,11 @@ + +

Examples

+ +
+ + + + +
+ + +
+ + + (i ? 0 : (-width * 2) / 10)), + }} + alphaTarget={1} + velocityDecay={0.2} + let:nodes + > + {#each nodes as node, i} + {#if i > 0} + + {/if} + {/each} + + { + mouseNode.xTarget = e.offsetX; + mouseNode.yTarget = e.offsetY; + }} + class="fill-transparent" + /> + + + +
+
diff --git a/packages/layerchart/src/routes/docs/examples/ForceText/+page.ts b/packages/layerchart/src/routes/docs/examples/ForceText/+page.ts new file mode 100644 index 000000000..cdeabe134 --- /dev/null +++ b/packages/layerchart/src/routes/docs/examples/ForceText/+page.ts @@ -0,0 +1,10 @@ +import pageSource from './+page.svelte?raw'; + +export async function load() { + return { + meta: { + pageSource, + related: ['https://d3og.com/armollica/06a202c9f7df191ace8a1f97e33ffb97/'], + }, + }; +} From 850043dd98a7cd961f4ba56b8d6380542fb4f7fe Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 18 Aug 2024 23:00:15 -0400 Subject: [PATCH 044/177] Make pnpm check happpy --- packages/layerchart/src/lib/utils/string.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/utils/string.ts b/packages/layerchart/src/lib/utils/string.ts index 29b628ca0..3624843f5 100644 --- a/packages/layerchart/src/lib/utils/string.ts +++ b/packages/layerchart/src/lib/utils/string.ts @@ -91,7 +91,7 @@ export function rasterizeText(text: string, options: RasterizeTextOptions = {}) } function getPixel(imageData: ImageData, x: number, y: number) { - var i = 4 * (parseInt(x) + parseInt(y) * imageData.width); + var i = 4 * (Math.floor(x) + Math.floor(y) * imageData.width); var d = imageData.data; return [d[i], d[i + 1], d[i + 2], d[i + 3]]; } From 4b6d669e7d75b116a1ff1224398a9a5db61db51f Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 09:11:00 -0400 Subject: [PATCH 045/177] Pass width, height, and padding to chart slots. Improve ScatterChart custom tooltip example --- .../lib/components/charts/AreaChart.svelte | 7 +++-- .../src/lib/components/charts/BarChart.svelte | 7 +++-- .../lib/components/charts/LineChart.svelte | 7 +++-- .../lib/components/charts/ScatterChart.svelte | 7 +++-- .../docs/components/ScatterChart/+page.svelte | 31 ++++++++++++++----- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index fb451fa8a..15584a248 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -44,9 +44,12 @@ {...$$restProps} let:x let:y + let:width + let:height + let:padding let:tooltip > - + - + {format(x(data))} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 7623ad042..274dc01c4 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -51,9 +51,12 @@ {...$$restProps} let:x let:y + let:width + let:height + let:padding let:tooltip > - + - + {format(isVertical ? x(data) : y(data))} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 8c240b064..a691d4598 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -44,9 +44,12 @@ {...$$restProps} let:x let:y + let:width + let:height + let:padding let:tooltip > - + - + {format(x(data))} diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index 3dde6689d..b5dbd654f 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -38,9 +38,12 @@ {...$$restProps} let:x let:y + let:width + let:height + let:padding let:tooltip > - + - + {format(x(data))} diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte index a1c4f92fe..38592e32f 100644 --- a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte @@ -29,14 +29,29 @@

Custom tooltip

-
+
- - - {format(x(data), 'integer')} - - - + + + {format(y(data), 'integer')} + + + + {format(x(data), 'integer')} @@ -52,7 +67,7 @@ - + From 24787c28e2e3fcbe47464b8f603d8483e7b3d26b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 10:33:28 -0400 Subject: [PATCH 046/177] fix(Voronoi): Dispatch custom `pointerevent` instead of forwarding to fix console errors --- .changeset/sharp-ways-move.md | 5 +++++ packages/layerchart/src/lib/components/Voronoi.svelte | 11 +++++++++-- .../src/lib/components/tooltip/TooltipContext.svelte | 1 - 3 files changed, 14 insertions(+), 3 deletions(-) create mode 100644 .changeset/sharp-ways-move.md diff --git a/.changeset/sharp-ways-move.md b/.changeset/sharp-ways-move.md new file mode 100644 index 000000000..2e19b1940 --- /dev/null +++ b/.changeset/sharp-ways-move.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Voronoi): Dispatch custom `pointerevent` instead of forwarding to fix console errors diff --git a/packages/layerchart/src/lib/components/Voronoi.svelte b/packages/layerchart/src/lib/components/Voronoi.svelte index 99905e09a..5c16fe422 100644 --- a/packages/layerchart/src/lib/components/Voronoi.svelte +++ b/packages/layerchart/src/lib/components/Voronoi.svelte @@ -24,6 +24,12 @@ const dispatch = createEventDispatcher<{ click: { data: any; point?: [number, number]; feature?: GeoPermissibleObjects }; + pointerenter: { + event: PointerEvent; + data: any; + point?: [number, number]; + feature?: GeoPermissibleObjects; + }; pointermove: { event: PointerEvent; data: any; @@ -58,7 +64,8 @@ + dispatch('pointerenter', { event: e, data: feature.properties.site.data, feature })} on:pointermove={(e) => dispatch('pointermove', { event: e, data: feature.properties.site.data, feature })} on:pointerleave @@ -78,7 +85,7 @@ dispatch('pointerenter', { event: e, data: point.data, point })} on:pointermove={(e) => dispatch('pointermove', { event: e, data: point.data, point })} on:pointerleave on:touchmove={(e) => { diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte index f66a14000..814374bee 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte @@ -397,7 +397,6 @@ { - // @ts-expect-error showTooltip(e.detail.event, e.detail.data); }} on:pointermove={(e) => { From b871dd4ffbb97910688e97451a6e5fca18296c6b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 10:36:31 -0400 Subject: [PATCH 047/177] Add more slots (axis, marks, highlight) for more granular overrides --- .../lib/components/charts/AreaChart.svelte | 55 +++++++++++-------- .../src/lib/components/charts/BarChart.svelte | 41 ++++++++------ .../lib/components/charts/LineChart.svelte | 44 +++++++++------ .../lib/components/charts/ScatterChart.svelte | 40 ++++++++------ 4 files changed, 107 insertions(+), 73 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 15584a248..a6e210178 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -49,39 +49,46 @@ let:padding let:tooltip > - + {@const slotProps = { x, y, width, height, padding, tooltip, series }} + - format(value, undefined, { variant: 'short' })} - /> - format(value, undefined, { variant: 'short' })} - /> - - {#each series as s} - + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} /> - {/each} + + + + {#each series as s} + + {/each} + - {#each series as s, i} - - {/each} + + {#each series as s, i} + + {/each} + {#if labels} {/if} - + {format(x(data))} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 274dc01c4..246fb83db 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -56,29 +56,38 @@ let:padding let:tooltip > - + {@const slotProps = { x, y, width, height, padding, tooltip }} + - format(value, undefined, { variant: 'short' })} - /> - format(value, undefined, { variant: 'short' })} - /> - - + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + + + + + + + + + {#if labels} {/if} - + {format(isVertical ? x(data) : y(data))} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index a691d4598..c89573000 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -49,31 +49,41 @@ let:padding let:tooltip > - + {@const slotProps = { x, y, width, height, padding, tooltip, series }} + - format(value, undefined, { variant: 'short' })} - /> - format(value, undefined, { variant: 'short' })} - /> + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + - {#each series as s, i} - - - {/each} + + {#each series as s, i} + + {/each} + + + + {#each series as s, i} + + {/each} + {#if labels} {/if} - + {format(x(data))} diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index b5dbd654f..707b9f7ad 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -43,30 +43,38 @@ let:padding let:tooltip > - + {@const slotProps = { x, y, width, height, padding, tooltip }} + - format(value, undefined, { variant: 'short' })} - /> - format(value, undefined, { variant: 'short' })} - /> + + format(value, undefined, { variant: 'short' })} + /> + format(value, undefined, { variant: 'short' })} + /> + - - + + + + + + + {#if labels} format(value)} /> {/if} - + {format(x(data))} From 16969e66e3906089fbb0b79562b3c0f411cda515 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 10:47:36 -0400 Subject: [PATCH 048/177] Use new granular slots for AreaChart highlight series example --- .../docs/components/AreaChart/+page.svelte | 46 ++++++++----------- 1 file changed, 18 insertions(+), 28 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 1471e7b79..3a9635ff5 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -61,11 +61,7 @@ data={multiSeriesFlatData} x="date" y="value" - tooltip={{ mode: 'voronoi' }} - let:x - let:tooltip - > - {@const series = [ + series={[ { label: 'apples', value: 'apples', color: 'hsl(var(--color-danger))' }, { label: 'bananas', @@ -78,26 +74,14 @@ color: 'hsl(var(--color-warning))', }, ]} - {@const activeSeriesColor = series.find((s) => s.value === tooltip.data?.fruit)?.color} - - format(value, undefined, { variant: 'short' })} - /> - format(value, undefined, { variant: 'short' })} - /> - + tooltip={{ mode: 'voronoi' }} + > + {#each series as s} {@const color = tooltip.data == null || tooltip.data.fruit === s.value ? s.color : 'hsl(var(--color-surface-content) / 20%)'} - {/each} + - - + + {@const activeSeries = series.find((s) => s.value === tooltip.data?.fruit)} + + - - {format(x(data))} - - - - + + {@const activeSeries = series.find((s) => s.value === tooltip.data?.fruit)} + + {format(x(data))} + + + + +
From 1dc2830e5ab9e23b6c5667ff7af179e59f4b3231 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 12:18:51 -0400 Subject: [PATCH 049/177] Add xScale and yScale to slot props --- .../layerchart/src/lib/components/charts/AreaChart.svelte | 4 +++- packages/layerchart/src/lib/components/charts/BarChart.svelte | 4 +++- .../layerchart/src/lib/components/charts/LineChart.svelte | 4 +++- .../layerchart/src/lib/components/charts/ScatterChart.svelte | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index a6e210178..767ebe166 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -43,13 +43,15 @@ tooltip={{ mode: 'bisect-x' }} {...$$restProps} let:x + let:xScale let:y + let:yScale let:width let:height let:padding let:tooltip > - {@const slotProps = { x, y, width, height, padding, tooltip, series }} + {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 246fb83db..324d2eca8 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -50,13 +50,15 @@ tooltip={{ mode: 'band' }} {...$$restProps} let:x + let:xScale let:y + let:yScale let:width let:height let:padding let:tooltip > - {@const slotProps = { x, y, width, height, padding, tooltip }} + {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip }} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index c89573000..a6940f059 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -43,13 +43,15 @@ tooltip={{ mode: 'bisect-x' }} {...$$restProps} let:x + let:xScale let:y + let:yScale let:width let:height let:padding let:tooltip > - {@const slotProps = { x, y, width, height, padding, tooltip, series }} + {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }} diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index 707b9f7ad..c4c23d2eb 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -37,13 +37,15 @@ tooltip={{ mode: 'voronoi' }} {...$$restProps} let:x + let:xScale let:y + let:yScale let:width let:height let:padding let:tooltip > - {@const slotProps = { x, y, width, height, padding, tooltip }} + {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip }} From 1da5cc052e6e5c57a086b56b5dea0c99eb3d510a Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 12:19:12 -0400 Subject: [PATCH 050/177] [AreaChart] Add Gradient and ThresholdGradient examples --- .../docs/components/AreaChart/+page.svelte | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 3a9635ff5..e97e1317a 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -1,5 +1,15 @@
+

Gradient

+ +
+ + + + + + + +
+
+ +

Threshold Gradient

+ + {@const colors = { + positive: 'hsl(var(--color-success))', + negative: 'hsl(var(--color-danger))', + }} + +
+ + + {@const thresholdOffset = (yScale(0) / (height + padding.bottom)) * 100 + '%'} + + + 0} + line={{ stroke: url, class: 'stroke-2' }} + fill={url} + fill-opacity={0.2} + /> + + + + + {@const value = tooltip.data && y(tooltip.data)} + + + + + + {@const value = y(data)} + {format(x(data), PeriodType.DayTime)} + + + + + + +
+
+

Series

From 9e23a1e0040ebc4f085cdc25c65eeabf1099446e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 13:31:50 -0400 Subject: [PATCH 051/177] Refine setting thresholdOffset for better readability --- .../src/routes/docs/components/AreaChart/+page.svelte | 3 ++- .../layerchart/src/routes/docs/examples/Area/+page.svelte | 6 ++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index e97e1317a..4e9cdb4db 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -68,7 +68,8 @@
- {@const thresholdOffset = (yScale(0) / (height + padding.bottom)) * 100 + '%'} + {@const thresholdValue = 0} + {@const thresholdOffset = yScale(thresholdValue) / (height + padding.bottom)} - {@const thresholdOffset = (yScale(0) / (height + padding.bottom)) * 100 + '%'} + {@const thresholdValue = 0} + {@const thresholdOffset = yScale(thresholdValue) / (height + padding.bottom)} format(d, PeriodType.Day, { variant: 'short' })} /> @@ -766,7 +767,8 @@ let:height let:padding > - {@const thresholdOffset = (yScale(0) / (height + padding.bottom)) * 100 + '%'} + {@const thresholdValue = 0} + {@const thresholdOffset = yScale(thresholdValue) / (height + padding.bottom)} format(d, PeriodType.Day, { variant: 'short' })} /> From 5f4cdaf95288c3b667854c86a5f8be6a3ad5d471 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 23:08:31 -0400 Subject: [PATCH 052/177] feat(BarChart) Support series (with props) and add `before-marks` and `after-marks` slots. Add examples --- .../src/lib/components/charts/BarChart.svelte | 42 ++++- .../docs/components/BarChart/+page.svelte | 155 ++++++++---------- 2 files changed, 102 insertions(+), 95 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 324d2eca8..8f3b9aef1 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -11,12 +11,13 @@ import Svg from '../layout/Svg.svelte'; import * as Tooltip from '../tooltip/index.js'; - import { type Accessor } from '../../utils/common.js'; + import { accessor, type Accessor } from '../../utils/common.js'; interface $$Props extends ComponentProps> { + series?: typeof series; + labels?: typeof labels; layout?: typeof layout; bandPadding?: typeof bandPadding; - labels?: typeof labels; } export let data: $$Props['data'] = []; @@ -24,11 +25,18 @@ export let y: Accessor = undefined; export let layout: 'vertical' | 'horizontal' = 'vertical'; - export let bandPadding = 0.4; - export let labels: ComponentProps | boolean = false; - $: isVertical = layout === 'vertical'; + export let series: { + label?: string; + value: Accessor; + color?: string; + props?: ComponentProps; + }[] = [{ value: layout === 'vertical' ? y : x, color: 'hsl(var(--color-primary))' }]; + + export let labels: ComponentProps | boolean = false; + export let bandPadding = 0.4; + $: xScale = isVertical ? scaleBand().padding(bandPadding) : scaleLinear(); $: xDomain = isVertical ? undefined : [0, null]; @@ -38,11 +46,11 @@ s.value)} {xScale} {xDomain} xNice={layout === 'horizontal'} - {y} + y={y ?? series.map((d) => d.value)} {yScale} {yDomain} yNice={layout === 'vertical'} @@ -76,10 +84,23 @@ /> + + - + {#each series as s} + + {/each} + + @@ -93,7 +114,10 @@ {format(isVertical ? x(data) : y(data))} - + {#each series as s} + {@const valueAccessor = accessor(s.value)} + + {/each} diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index c6f6025fc..c2f329847 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -1,33 +1,10 @@

Examples

@@ -118,6 +35,72 @@
+

Series

+ + +
+ +
+
+ +

Series (horizontal)

+ + +
+ +
+
+ +

Series (diverging)

+ + +
+ -d.baseline, + color: 'hsl(var(--color-secondary))', + props: { rounded: 'bottom' }, + }, + ]} + > + + + + +
+
+

Labels

From 5c4f557b709617ecadd67b0e91e83a56bf450df8 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 22 Aug 2024 23:09:50 -0400 Subject: [PATCH 053/177] fix(Spline): Enable passing `fill` prop (useful for Bar with single rounded edge) --- .changeset/stale-tools-taste.md | 5 +++++ packages/layerchart/src/lib/components/Spline.svelte | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 .changeset/stale-tools-taste.md diff --git a/.changeset/stale-tools-taste.md b/.changeset/stale-tools-taste.md new file mode 100644 index 000000000..6dd26914f --- /dev/null +++ b/.changeset/stale-tools-taste.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +[Spline] Enable passing `fill` prop (useful for Bar with single rounded edge) diff --git a/packages/layerchart/src/lib/components/Spline.svelte b/packages/layerchart/src/lib/components/Spline.svelte index 8f73681fc..6ecd0d800 100644 --- a/packages/layerchart/src/lib/components/Spline.svelte +++ b/packages/layerchart/src/lib/components/Spline.svelte @@ -133,7 +133,12 @@ Date: Thu, 22 Aug 2024 23:33:30 -0400 Subject: [PATCH 054/177] feat(AreaChart,LineChart,ScatterChart) Support passing props per series. Add `before-marks` and `after-marks` slots. --- .../src/lib/components/charts/AreaChart.svelte | 14 +++++++++++--- .../src/lib/components/charts/LineChart.svelte | 17 ++++++++++++----- .../lib/components/charts/ScatterChart.svelte | 4 ++++ 3 files changed, 27 insertions(+), 8 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 767ebe166..ce1ed11c3 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -22,9 +22,12 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; - export let series: { label?: string; value: Accessor; color?: string }[] = [ - { value: y, color: 'hsl(var(--color-primary))' }, - ]; + export let series: { + label?: string; + value: Accessor; + color?: string; + props?: ComponentProps; + }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; @@ -68,6 +71,8 @@ />
+ + {#each series as s} {/each} + + {#each series as s, i} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index a6940f059..3b9a57b8c 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -22,9 +22,12 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; - export let series: { label?: string; value: Accessor; color?: string }[] = [ - { value: y, color: 'hsl(var(--color-primary))' }, - ]; + export let series: { + label?: string; + value: Accessor; + color?: string; + props?: ComponentProps; + }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; @@ -68,12 +71,16 @@ /> + + - {#each series as s, i} - + {#each series as s} + {/each} + + {#each series as s, i} diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index c4c23d2eb..139a7d223 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -63,10 +63,14 @@ /> + + + + From 020028cc85d5f24c5ffc8ed52a3c9229e0505c51 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 23 Aug 2024 00:04:02 -0400 Subject: [PATCH 055/177] Workaround svelte-check / typescript error --- .../src/routes/docs/components/AreaChart/+page.svelte | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 4e9cdb4db..dff5c83be 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -176,12 +176,14 @@ - {@const activeSeries = series.find((s) => s.value === tooltip.data?.fruit)} + + {@const activeSeries = [...series].find((s) => s.value === tooltip.data?.fruit)} - {@const activeSeries = series.find((s) => s.value === tooltip.data?.fruit)} + + {@const activeSeries = [...series].find((s) => s.value === tooltip.data?.fruit)} {format(x(data))} From cd047d585e0605a594be3ec71a8c4f22b82d4597 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 24 Aug 2024 17:05:04 -0400 Subject: [PATCH 056/177] Add PieChart (WIP) --- .../layerchart/src/lib/components/Arc.svelte | 2 +- .../layerchart/src/lib/components/Pie.svelte | 1 - .../src/lib/components/charts/PieChart.svelte | 163 ++++++++++++++++++ .../src/lib/components/charts/index.ts | 1 + .../layerchart/src/routes/_NavMenu.svelte | 2 +- .../docs/components/PieChart/+page.svelte | 68 ++++++++ .../routes/docs/components/PieChart/+page.ts | 15 ++ 7 files changed, 249 insertions(+), 3 deletions(-) create mode 100644 packages/layerchart/src/lib/components/charts/PieChart.svelte create mode 100644 packages/layerchart/src/routes/docs/components/PieChart/+page.svelte create mode 100644 packages/layerchart/src/routes/docs/components/PieChart/+page.ts diff --git a/packages/layerchart/src/lib/components/Arc.svelte b/packages/layerchart/src/lib/components/Arc.svelte index 05e142591..27b0767a0 100644 --- a/packages/layerchart/src/lib/components/Arc.svelte +++ b/packages/layerchart/src/lib/components/Arc.svelte @@ -86,7 +86,7 @@ $: scale = scaleLinear().domain(domain).range(range); function getOuterRadius(outerRadius: number | undefined, chartRadius: number) { - if (outerRadius == null) { + if (!outerRadius) { return chartRadius; } else if (outerRadius > 1) { // discrete value diff --git a/packages/layerchart/src/lib/components/Pie.svelte b/packages/layerchart/src/lib/components/Pie.svelte index 8989b1f99..6032e65f4 100644 --- a/packages/layerchart/src/lib/components/Pie.svelte +++ b/packages/layerchart/src/lib/components/Pie.svelte @@ -51,7 +51,6 @@ export let cornerRadius = 0; export let padAngle = 0; - // export let padRadius = 0; export let placement: 'left' | 'center' | 'right' | 'none' = 'center'; diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte new file mode 100644 index 000000000..dc090586f --- /dev/null +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -0,0 +1,163 @@ + + + + {@const slotProps = { label, value, x, xScale, y, yScale, width, height, padding, tooltip }} + + + + + + {#if separateTracks} + + {@const sumValue = Number(sum(chartData, valueAccessor))} + {#each chartData as d, i} + {console.log(chartData, i)} + tooltip?.show(e, d)} + on:pointermove={(e) => tooltip?.show(e, d)} + on:pointerleave={(e) => tooltip?.hide()} + on:touchmove={(e) => { + // Prevent touch to not interfer with pointer when using tooltip + e.preventDefault(); + }} + /> + {/each} + + {:else} + + {/if} + + + + + + + + + + + + + + diff --git a/packages/layerchart/src/lib/components/charts/index.ts b/packages/layerchart/src/lib/components/charts/index.ts index aebd05f72..d2f2c6bd3 100644 --- a/packages/layerchart/src/lib/components/charts/index.ts +++ b/packages/layerchart/src/lib/components/charts/index.ts @@ -1,4 +1,5 @@ export { default as AreaChart } from './AreaChart.svelte'; export { default as BarChart } from './BarChart.svelte'; export { default as LineChart } from './LineChart.svelte'; +export { default as PieChart } from './PieChart.svelte'; export { default as ScatterChart } from './ScatterChart.svelte'; diff --git a/packages/layerchart/src/routes/_NavMenu.svelte b/packages/layerchart/src/routes/_NavMenu.svelte index 8325ac3e0..f2708c522 100644 --- a/packages/layerchart/src/routes/_NavMenu.svelte +++ b/packages/layerchart/src/routes/_NavMenu.svelte @@ -66,7 +66,7 @@ }; const components: LinkCollection = { - Charts: ['Chart', 'AreaChart', 'BarChart', 'LineChart', 'ScatterChart'], + Charts: ['Chart', 'AreaChart', 'BarChart', 'LineChart', 'PieChart', 'ScatterChart'], Common: ['Axis', 'Frame', 'Legend', 'Rule'], Primitives: ['Arc', 'Circle', 'Group', 'Line', 'Point', 'Rect', 'Text'], 'Data-driven': [ diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte new file mode 100644 index 000000000..0fd4bb4ea --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -0,0 +1,68 @@ + + +

Examples

+ +

Basic

+ + +
+ +
+
+ +

Arc (range)

+ + +
+ +
+
+ +

Donut (innerRadius)

+ + +
+ +
+
+ +

Separate tracks

+ + +
+ +
+
+ + diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.ts b/packages/layerchart/src/routes/docs/components/PieChart/+page.ts new file mode 100644 index 000000000..d1eaceae4 --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.ts @@ -0,0 +1,15 @@ +import api from '$lib/components/charts/PieChart.svelte?raw&sveld'; +import source from '$lib/components/charts/PieChart.svelte?raw'; +import pageSource from './+page.svelte?raw'; + +export async function load() { + return { + meta: { + api, + source, + pageSource, + description: 'Streamlined Chart configuration for Pie charts', + related: ['components/Chart', 'components/Pie', 'examples/Arc'], + }, + }; +} From 783cd8a205e761a4ca7eefe94700fcf12f58ddb8 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 24 Aug 2024 21:42:22 -0400 Subject: [PATCH 057/177] feat(Arc): Support passing `tooltip` and `data` props to simplify setting up tooltip pointer events --- .changeset/weak-tigers-poke.md | 5 +++++ .../layerchart/src/lib/components/Arc.svelte | 20 +++++++++++++++++++ .../layerchart/src/lib/components/Pie.svelte | 13 +++--------- .../src/lib/components/charts/PieChart.svelte | 10 ++-------- 4 files changed, 30 insertions(+), 18 deletions(-) create mode 100644 .changeset/weak-tigers-poke.md diff --git a/.changeset/weak-tigers-poke.md b/.changeset/weak-tigers-poke.md new file mode 100644 index 000000000..ab0e3a6e3 --- /dev/null +++ b/.changeset/weak-tigers-poke.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Arc): Support passing `tooltip` and `data` props to simplify setting up tooltip pointer events diff --git a/packages/layerchart/src/lib/components/Arc.svelte b/packages/layerchart/src/lib/components/Arc.svelte index 27b0767a0..f23ddd44f 100644 --- a/packages/layerchart/src/lib/components/Arc.svelte +++ b/packages/layerchart/src/lib/components/Arc.svelte @@ -27,6 +27,7 @@ import { chartContext } from './ChartContext.svelte'; import { motionStore } from '$lib/stores/motionStore.js'; import { degreesToRadians } from '$lib/utils/math.js'; + import type { TooltipContextValue } from './tooltip/TooltipContext.svelte'; export let spring: boolean | Parameters[1] = undefined; export let tweened: boolean | Parameters[1] = undefined; @@ -172,6 +173,16 @@ $: angle = ((startAngle ?? 0) + (endAngle ?? 0)) / 2; $: xOffset = Math.sin(angle) * offset; $: yOffset = -Math.cos(angle) * offset; + + /** + * Tooltip context to setup pointer events to show tooltip for related data. Must set `data` prop as well + */ + export let tooltip: TooltipContextValue | undefined = undefined; + + /** + * Data to set when showing tooltip + */ + export let data: any = undefined; {#if track} @@ -188,6 +199,15 @@ d={arc()} transform="translate({xOffset}, {yOffset})" {...$$restProps} + on:pointerenter={(e) => tooltip?.show(e, data)} + on:pointermove={(e) => tooltip?.show(e, data)} + on:pointerleave={(e) => tooltip?.hide()} + on:touchmove={(e) => { + if (tooltip) { + // Prevent touch to not interfer with pointer when using tooltip + e.preventDefault(); + } + }} on:click on:pointerenter on:pointermove diff --git a/packages/layerchart/src/lib/components/Pie.svelte b/packages/layerchart/src/lib/components/Pie.svelte index 6032e65f4..95ce88769 100644 --- a/packages/layerchart/src/lib/components/Pie.svelte +++ b/packages/layerchart/src/lib/components/Pie.svelte @@ -63,7 +63,7 @@ export let offset = 0; /** - * Tooltip context to setup mouse events to show tooltip for related data + * Tooltip context to setup pointer events to show tooltip for related data */ export let tooltip: TooltipContextValue | undefined = undefined; @@ -109,15 +109,8 @@ {cornerRadius} {offset} fill={$config.r ? $rGet(arc.data) : null} - on:pointerenter={(e) => tooltip?.show(e, arc.data)} - on:pointermove={(e) => tooltip?.show(e, arc.data)} - on:pointerleave={(e) => tooltip?.hide()} - on:touchmove={(e) => { - if (tooltip) { - // Prevent touch to not interfer with pointer when using tooltip - e.preventDefault(); - } - }} + data={arc.data} + {tooltip} /> {/each}
diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index dc090586f..ea3a4bbfa 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -112,7 +112,6 @@ {@const sumValue = Number(sum(chartData, valueAccessor))} {#each chartData as d, i} - {console.log(chartData, i)} tooltip?.show(e, d)} - on:pointermove={(e) => tooltip?.show(e, d)} - on:pointerleave={(e) => tooltip?.hide()} - on:touchmove={(e) => { - // Prevent touch to not interfer with pointer when using tooltip - e.preventDefault(); - }} + {tooltip} + data={d} /> {/each} From d06572e69f6d98fb5db07190a6bf6197c402794f Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 24 Aug 2024 22:58:48 -0400 Subject: [PATCH 058/177] Support passing props to inner components --- .../lib/components/charts/AreaChart.svelte | 18 +++++-- .../src/lib/components/charts/BarChart.svelte | 18 +++++-- .../lib/components/charts/LineChart.svelte | 19 +++++-- .../src/lib/components/charts/PieChart.svelte | 54 ++++++++++++++----- .../lib/components/charts/ScatterChart.svelte | 20 +++++-- .../docs/components/AreaChart/+page.svelte | 8 ++- .../docs/components/PieChart/+page.svelte | 10 +++- 7 files changed, 118 insertions(+), 29 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index ce1ed11c3..3c6f51b32 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -16,6 +16,7 @@ interface $$Props extends ComponentProps> { series?: typeof series; labels?: typeof labels; + props?: typeof props; } export let data: $$Props['data'] = []; @@ -26,13 +27,21 @@ label?: string; value: Accessor; color?: string; - props?: ComponentProps; + props?: Partial>; }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; // Default xScale based on first data's `x` value $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear(); + + export let props: { + axisLeft?: Partial>; + axisBottom?: Partial>; + area?: Partial>; + highlight?: Partial>; + labels?: Partial>; + } = {}; format(value, undefined, { variant: 'short' })} + {...props.axisLeft} /> format(value, undefined, { variant: 'short' })} + {...props.axisBottom} />
@@ -80,6 +91,7 @@ line={{ class: 'stroke-2', stroke: s.color }} fill={s.color} fill-opacity={0.3} + {...props.area} {...s.props} /> {/each} @@ -89,12 +101,12 @@ {#each series as s, i} - + {/each} {#if labels} - + {/if} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 8f3b9aef1..7113fd735 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -18,6 +18,7 @@ labels?: typeof labels; layout?: typeof layout; bandPadding?: typeof bandPadding; + props?: typeof props; } export let data: $$Props['data'] = []; @@ -31,7 +32,7 @@ label?: string; value: Accessor; color?: string; - props?: ComponentProps; + props?: Partial>; }[] = [{ value: layout === 'vertical' ? y : x, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; @@ -42,6 +43,14 @@ $: yScale = isVertical ? scaleLinear() : scaleBand().padding(bandPadding); $: yDomain = isVertical ? [0, null] : undefined; + + export let props: { + axisLeft?: Partial>; + axisBottom?: Partial>; + bars?: Partial>; + highlight?: Partial>; + labels?: Partial>; + } = {}; format(value, undefined, { variant: 'short' })} + {...props.axisLeft} /> format(value, undefined, { variant: 'short' })} + {...props.axisBottom} />
@@ -94,6 +105,7 @@ radius={4} strokeWidth={1} fill={s.color} + {...props.bars} {...s.props} /> {/each} @@ -102,11 +114,11 @@ - + {#if labels} - + {/if} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 3b9a57b8c..40f09a414 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -16,6 +16,7 @@ interface $$Props extends ComponentProps> { series?: typeof series; labels?: typeof labels; + props?: typeof props; } export let data: $$Props['data'] = []; @@ -26,13 +27,21 @@ label?: string; value: Accessor; color?: string; - props?: ComponentProps; + props?: Partial>; }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; // Default xScale based on first data's `x` value $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear(); + + export let props: { + axisLeft?: Partial>; + axisBottom?: Partial>; + spline?: Partial>; + highlight?: Partial>; + labels?: Partial>; + } = {}; format(value, undefined, { variant: 'short' })} + {...props.axisLeft} /> format(value, undefined, { variant: 'short' })} + {...props.axisBottom} /> @@ -75,7 +86,7 @@ {#each series as s} - + {/each} @@ -83,12 +94,12 @@ {#each series as s, i} - + {/each} {#if labels} - + {/if} diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index ea3a4bbfa..0c8d2aca0 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -21,6 +21,7 @@ padAngle?: typeof padAngle; placement?: typeof placement; separateTracks?: typeof separateTracks; + props?: typeof props; // series?: typeof series; // labels?: typeof labels; } @@ -56,30 +57,28 @@ export let outerRadius: number | undefined = undefined; export let cornerRadius = 0; - export let padAngle = 0; export let placement: 'left' | 'center' | 'right' | 'none' = 'center'; + /** + * Show values as individual, concentric arcs + */ export let separateTracks = false; - // export let series: { - // label?: string; - // value: Accessor; - // color?: string; - // props?: ComponentProps; - // }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; - - // export let labels: ComponentProps | boolean = false; - export let colorScale = scaleOrdinal(); + export let colorKeys = [...new Set(chartDataArray(data).map((d) => accessor(label)(d)))]; export let colors = [ 'hsl(var(--color-info))', 'hsl(var(--color-success))', 'hsl(var(--color-warning))', 'hsl(var(--color-danger))', ]; - export let colorKeys = [...new Set(chartDataArray(data).map((d) => accessor(label)(d)))]; + + export let props: { + pie?: Partial>; + arc?: Partial>; + } = {}; {#if separateTracks} - + {@const sumValue = Number(sum(chartData, valueAccessor))} {#each chartData as d, i} {/each} @@ -133,8 +143,24 @@ {padAngle} {cornerRadius} {placement} - {tooltip} - /> + {...props.pie} + let:arcs + > + {#each arcs as arc} + + {/each} + {/if}
diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index 139a7d223..95e22342a 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -25,6 +25,14 @@ // Default xScale based on first data's `x` value $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear(); + + export let props: { + axisLeft?: Partial>; + axisBottom?: Partial>; + points?: Partial>; + highlight?: Partial>; + labels?: Partial>; + } = {}; format(value, undefined, { variant: 'short' })} + {...props.axisLeft} /> format(value, undefined, { variant: 'short' })} + {...props.axisBottom} />
- + - + {#if labels} - format(value)} /> + format(value)} + {...props.highlight} + {...typeof labels === 'object' ? labels : null} + /> {/if} diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index dff5c83be..9dd6e930f 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -66,7 +66,13 @@ }}
- + {@const thresholdValue = 0} {@const thresholdOffset = yScale(thresholdValue) / (height + padding.bottom)} diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index 0fd4bb4ea..58519d8e0 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -54,11 +54,19 @@ separateTracks outerRadius={-25} innerRadius={-20} - cornerRadius={5} + cornerRadius={10} />
+

Inner component props (Arc class)

+ + +
+ +
+
+ + + + + format(value, undefined, { variant: 'short' })} + /> + format(value, 'metric')} /> + + +
+ +

Labels

- +
- +

Labels (inside placement)

- +
- +

Custom tooltip

- +
- + {format(x(data), PeriodType.DayTime)} @@ -136,9 +181,9 @@

Custom chart

- +
- + csvParse(await r.text(), autoType))) as WorldPopulationDemographicsData, meta: { api, source, diff --git a/packages/layerchart/static/data/examples/world-population-demographics.csv b/packages/layerchart/static/data/examples/world-population-demographics.csv new file mode 100644 index 000000000..c7ccf5a79 --- /dev/null +++ b/packages/layerchart/static/data/examples/world-population-demographics.csv @@ -0,0 +1,22 @@ +age,male,female +0-4,337082467,319557714 +5-9,351715561,331015496 +10-14,346898098,325046485 +15-19,328189555,307629576 +20-24,313191215,294184526 +25-29,304421477,287497451 +30-34,308206126,294461443 +35-39,293650660,283742580 +40-44,264954566,258134000 +45-49,238892693,235655907 +50-54,230886182,231469447 +55-59,204396487,210274344 +60-64,162559789,173807303 +65-69,135678685,152556237 +70-74,99662458,119189625 +75-79,61653088,78620257 +80-84,36107650,52173305 +85-89,17564615,30311032 +90-94,5956267,12939489 +95-99,1189572,3510425 +100+,130480,547105 diff --git a/packages/layerchart/static/data/examples/world-population-demographics.d.ts b/packages/layerchart/static/data/examples/world-population-demographics.d.ts new file mode 100644 index 000000000..cd9d8155f --- /dev/null +++ b/packages/layerchart/static/data/examples/world-population-demographics.d.ts @@ -0,0 +1,5 @@ +export type WorldPopulationDemographicsData = { + age: string; + male: number; + female: number; +}[]; From 2ae86c8112319d67e94ec43f507c6482b3ba2fd4 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 00:02:42 -0400 Subject: [PATCH 063/177] Add vitest --- packages/layerchart/package.json | 4 +- pnpm-lock.yaml | 310 +++++++++++++++++++++++++++++++ 2 files changed, 313 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/package.json b/packages/layerchart/package.json index 9566410f0..0ed9ff65b 100644 --- a/packages/layerchart/package.json +++ b/packages/layerchart/package.json @@ -13,6 +13,7 @@ "prepublishOnly": "svelte-package", "check": "svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", + "test:unit": "TZ=UTC+4 vitest", "lint": "prettier --check .", "format": "prettier --write .", "prepare": "svelte-kit sync" @@ -75,7 +76,8 @@ "typescript": "^5.5.4", "unist-util-visit": "^5.0.0", "us-atlas": "^3.0.1", - "vite": "^5.4.0" + "vite": "^5.4.0", + "vitest": "^2.0.5" }, "type": "module", "dependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2f195ca5f..819fb7e08 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -276,6 +276,9 @@ importers: vite: specifier: ^5.4.0 version: 5.4.0(@types/node@22.3.0) + vitest: + specifier: ^2.0.5 + version: 2.0.5(@types/node@22.3.0) packages: @@ -1037,6 +1040,24 @@ packages: '@types/unist@3.0.2': resolution: {integrity: sha512-dqId9J8K/vGi5Zr7oo212BGii5m3q5Hxlkwy3WpYuKPklmBEvsbMYYyLxAQpSffdLl/gdW0XUpKWFvYmyoWCoQ==} + '@vitest/expect@2.0.5': + resolution: {integrity: sha512-yHZtwuP7JZivj65Gxoi8upUN2OzHTi3zVfjwdpu2WrvCZPLwsJ2Ey5ILIPccoW23dd/zQBlJ4/dhi7DWNyXCpA==} + + '@vitest/pretty-format@2.0.5': + resolution: {integrity: sha512-h8k+1oWHfwTkyTkb9egzwNMfJAEx4veaPSnMeKbVSjp4euqGSbQlm5+6VHwTr7u4FJslVVsUG5nopCaAYdOmSQ==} + + '@vitest/runner@2.0.5': + resolution: {integrity: sha512-TfRfZa6Bkk9ky4tW0z20WKXFEwwvWhRY+84CnSEtq4+3ZvDlJyY32oNTJtM7AW9ihW90tX/1Q78cb6FjoAs+ig==} + + '@vitest/snapshot@2.0.5': + resolution: {integrity: sha512-SgCPUeDFLaM0mIUHfaArq8fD2WbaXG/zVXjRupthYfYGzc8ztbFbu6dUNOblBG7XLMR1kEhS/DNnfCZ2IhdDew==} + + '@vitest/spy@2.0.5': + resolution: {integrity: sha512-c/jdthAhvJdpfVuaexSrnawxZz6pywlTPe84LUB2m/4t3rl2fTo9NFGBG4oWgaD+FTgDDV8hJ/nibT7IfH3JfA==} + + '@vitest/utils@2.0.5': + resolution: {integrity: sha512-d8HKbqIcya+GR67mkZbrzhS5kKhtp8dQLcmRZLGTscGVg7yImT82cIrhtn2L8+VujWcy6KZweApgNmPsTAO/UQ==} + acorn-walk@8.3.3: resolution: {integrity: sha512-MxXdReSRhGO7VlFe1bRG/oI7/mdLV9B9JJT0N8vZOhF7gFRR5l3M8W9G8JxmKV+JC5mGqJ0QvqfSOLsCPa4nUw==} engines: {node: '>=0.4.0'} @@ -1101,6 +1122,10 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -1152,6 +1177,10 @@ packages: resolution: {integrity: sha512-zhaCDicdLuWN5UbN5IMnFqNMhNfo919sH85y2/ea+5Yg9TsTkeZxpL+JLbp6cgYFS4sRLp3YV4S6yDuqVWHYOw==} engines: {node: '>=6'} + cac@6.7.14: + resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} + engines: {node: '>=8'} + camelcase-css@2.0.1: resolution: {integrity: sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==} engines: {node: '>= 6'} @@ -1162,6 +1191,10 @@ packages: capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + chai@5.1.1: + resolution: {integrity: sha512-pT1ZgP8rPNqUgieVaEY+ryQr6Q4HXNg8Ei9UnLUrjN4IA7dvQC5JB+/kxVcPNDHyBcc/26CXPkbNzq3qwrOEKA==} + engines: {node: '>=12'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1169,6 +1202,10 @@ packages: chardet@0.7.0: resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} + check-error@2.1.1: + resolution: {integrity: sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==} + engines: {node: '>= 16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -1384,6 +1421,10 @@ packages: dedent-js@1.0.1: resolution: {integrity: sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==} + deep-eql@5.0.2: + resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} + engines: {node: '>=6'} + deepmerge@4.3.1: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} @@ -1480,6 +1521,10 @@ packages: estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + execa@8.0.1: + resolution: {integrity: sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==} + engines: {node: '>=16.17'} + exit-hook@2.2.1: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} @@ -1549,9 +1594,16 @@ packages: function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + get-func-name@2.0.2: + resolution: {integrity: sha512-8vXOvuE167CtIc3OyItco7N/dpRtBbYOsPsXCz7X/PMnlGjYjSGuZJgM1Y7mmew7BKf9BqvLX2tnOVy1BBUsxQ==} + get-source@2.0.12: resolution: {integrity: sha512-X5+4+iD+HoSeEED+uwrQ07BOQr0kEDFMVqqpBuI+RaZBpBpHCuXxo70bjar6f0b0u/DQJsJ7ssurpP0V60Az+w==} + get-stream@8.0.1: + resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} + engines: {node: '>=16'} + github-slugger@2.0.0: resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} @@ -1609,6 +1661,10 @@ packages: human-id@1.0.2: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} + human-signals@5.0.0: + resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} + engines: {node: '>=16.17.0'} + iconv-lite@0.4.24: resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} engines: {node: '>=0.10.0'} @@ -1675,6 +1731,10 @@ packages: is-reference@3.0.2: resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==} + is-stream@3.0.0: + resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + is-subdir@1.2.0: resolution: {integrity: sha512-2AT6j+gXe/1ueqbW6fLZJiIw3F8iXGJtt0yDrZaBhAZEG1raiTxKWU+IPqMCzQAXOUCKdA4UDMgacKH25XG2Cw==} engines: {node: '>=4'} @@ -1755,6 +1815,9 @@ packages: lodash.startcase@4.4.0: resolution: {integrity: sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==} + loupe@3.1.1: + resolution: {integrity: sha512-edNu/8D5MKVfGVFRhFf8aAxiTM6Wumfz5XsaatSxlD3w4R1d/WEKUTydCdPGbl9K7QG/Ca3GnDV2sIKIpXRQcw==} + lower-case@2.0.2: resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} @@ -1790,6 +1853,9 @@ packages: peerDependencies: svelte: ^3.56.0 || ^4.0.0 || ^5.0.0-next.120 + merge-stream@2.0.0: + resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} + merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} engines: {node: '>= 8'} @@ -1807,6 +1873,10 @@ packages: engines: {node: '>=10.0.0'} hasBin: true + mimic-fn@4.0.0: + resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} + engines: {node: '>=12'} + min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} engines: {node: '>=4'} @@ -1891,6 +1961,10 @@ packages: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} engines: {node: '>=0.10.0'} + npm-run-path@5.3.0: + resolution: {integrity: sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -1902,6 +1976,10 @@ packages: once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + onetime@6.0.0: + resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} + engines: {node: '>=12'} + os-tmpdir@1.0.2: resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} engines: {node: '>=0.10.0'} @@ -1955,6 +2033,10 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -1979,6 +2061,10 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathval@2.0.0: + resolution: {integrity: sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==} + engines: {node: '>= 14.16'} + periscopic@3.1.0: resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==} @@ -2228,6 +2314,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -2271,9 +2360,15 @@ packages: sprintf-js@1.0.3: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + std-env@3.7.0: + resolution: {integrity: sha512-JPbdCEQLj1w5GilpiHAx3qJvFndqybBysA3qUOnznweH4QbNYUsW/ea8QzSrnh0vNsezMMw5bcVool8lM0gwzg==} + stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} @@ -2301,6 +2396,10 @@ packages: resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} engines: {node: '>=4'} + strip-final-newline@3.0.0: + resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} + engines: {node: '>=12'} + strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} engines: {node: '>=8'} @@ -2454,6 +2553,21 @@ packages: tiny-glob@0.2.9: resolution: {integrity: sha512-g/55ssRPUjShh+xkfx9UPDXqhckHEsHr4Vd9zX55oSdGZc/MD0m3sferOkwWtp98bv+kcVfEHtRJgBVJzelrzg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinypool@1.0.1: + resolution: {integrity: sha512-URZYihUbRPcGv95En+sz6MfghfIc2OJ1sv/RmhWZLouPY0/8Vo80viwPvg3dlaS9fuq7fQMEfgRRK7BBZThBEA==} + engines: {node: ^18.0.0 || >=20.0.0} + + tinyrainbow@1.2.0: + resolution: {integrity: sha512-weEDEq7Z5eTHPDh4xjX789+fHfF+P8boiFB+0vbWzpbnbsEr/GRaohi/uMKxg8RZMXnl1ItAi/IUHWMsjDV7kQ==} + engines: {node: '>=14.0.0'} + + tinyspy@3.0.0: + resolution: {integrity: sha512-q5nmENpTHgiPVd1cJDDc9cVoYN5x4vCvwT3FMilvKPKneCBZAxn2YWQjDF0UMcE9k0Cay1gBiDfTMU0g+mPMQA==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -2539,6 +2653,11 @@ packages: vfile-message@2.0.4: resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} + vite-node@2.0.5: + resolution: {integrity: sha512-LdsW4pxj0Ot69FAoXZ1yTnA9bjGohr2yNBU7QKRxpz8ITSkhuDl6h3zS/tvgz4qrNjeRnvrWeXQ8ZF7Um4W00Q==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + vite@5.4.0: resolution: {integrity: sha512-5xokfMX0PIiwCMCMb9ZJcMyh5wbBun0zUzKib+L65vAZ8GY9ePZMXxFrHbr/Kyll2+LSCY7xtERPpxkBDKngwg==} engines: {node: ^18.0.0 || >=20.0.0} @@ -2578,6 +2697,31 @@ packages: vite: optional: true + vitest@2.0.5: + resolution: {integrity: sha512-8GUxONfauuIdeSl5f9GTgVEpg5BTOlplET4WEDaeY2QBiN8wSm68vxN/tb5z405OwppfoCavnwXafiaYBC/xOA==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@types/node': ^18.0.0 || >=20.0.0 + '@vitest/browser': 2.0.5 + '@vitest/ui': 2.0.5 + happy-dom: '*' + jsdom: '*' + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + web-vitals@4.2.3: resolution: {integrity: sha512-/CFAm1mNxSmOj6i0Co+iGFJ58OS4NRGVP+AWS/l509uIK5a1bSoIVaHz/ZumpHTfHSZBpgrJ+wjfpAOrTHok5Q==} @@ -2600,6 +2744,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + workerd@1.20240806.0: resolution: {integrity: sha512-yyNtyzTMgVY0sgYijHBONqZFVXsOFGj2jDjS8MF/RbO2ZdGROvs4Hkc/9QnmqFWahE0STxXeJ1yW1yVotdF0UQ==} engines: {node: '>=16'} @@ -3408,6 +3557,39 @@ snapshots: '@types/unist@3.0.2': {} + '@vitest/expect@2.0.5': + dependencies: + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + tinyrainbow: 1.2.0 + + '@vitest/pretty-format@2.0.5': + dependencies: + tinyrainbow: 1.2.0 + + '@vitest/runner@2.0.5': + dependencies: + '@vitest/utils': 2.0.5 + pathe: 1.1.2 + + '@vitest/snapshot@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + magic-string: 0.30.11 + pathe: 1.1.2 + + '@vitest/spy@2.0.5': + dependencies: + tinyspy: 3.0.0 + + '@vitest/utils@2.0.5': + dependencies: + '@vitest/pretty-format': 2.0.5 + estree-walker: 3.0.3 + loupe: 3.1.1 + tinyrainbow: 1.2.0 + acorn-walk@8.3.3: dependencies: acorn: 8.12.1 @@ -3457,6 +3639,8 @@ snapshots: dependencies: printable-characters: 1.0.42 + assertion-error@2.0.1: {} + autoprefixer@10.4.20(postcss@8.4.41): dependencies: browserslist: 4.23.3 @@ -3509,6 +3693,8 @@ snapshots: builtin-modules@3.3.0: {} + cac@6.7.14: {} + camelcase-css@2.0.1: {} caniuse-lite@1.0.30001651: {} @@ -3520,6 +3706,14 @@ snapshots: transitivePeerDependencies: - supports-color + chai@5.1.1: + dependencies: + assertion-error: 2.0.1 + check-error: 2.1.1 + deep-eql: 5.0.2 + loupe: 3.1.1 + pathval: 2.0.0 + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -3528,6 +3722,8 @@ snapshots: chardet@0.7.0: {} + check-error@2.1.1: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -3723,6 +3919,8 @@ snapshots: dedent-js@1.0.1: {} + deep-eql@5.0.2: {} + deepmerge@4.3.1: {} defu@6.1.4: {} @@ -3833,6 +4031,18 @@ snapshots: dependencies: '@types/estree': 1.0.5 + execa@8.0.1: + dependencies: + cross-spawn: 7.0.3 + get-stream: 8.0.1 + human-signals: 5.0.0 + is-stream: 3.0.0 + merge-stream: 2.0.0 + npm-run-path: 5.3.0 + onetime: 6.0.0 + signal-exit: 4.1.0 + strip-final-newline: 3.0.0 + exit-hook@2.2.1: {} extendable-error@0.1.7: {} @@ -3910,11 +4120,15 @@ snapshots: function-bind@1.1.2: {} + get-func-name@2.0.2: {} + get-source@2.0.12: dependencies: data-uri-to-buffer: 2.0.2 source-map: 0.6.1 + get-stream@8.0.1: {} + github-slugger@2.0.0: {} glob-parent@5.1.2: @@ -3985,6 +4199,8 @@ snapshots: human-id@1.0.2: {} + human-signals@5.0.0: {} + iconv-lite@0.4.24: dependencies: safer-buffer: 2.1.2 @@ -4038,6 +4254,8 @@ snapshots: dependencies: '@types/estree': 1.0.5 + is-stream@3.0.0: {} + is-subdir@1.2.0: dependencies: better-path-resolve: 1.0.0 @@ -4113,6 +4331,10 @@ snapshots: lodash.startcase@4.4.0: {} + loupe@3.1.1: + dependencies: + get-func-name: 2.0.2 + lower-case@2.0.2: dependencies: tslib: 2.6.3 @@ -4150,6 +4372,8 @@ snapshots: svelte: 4.2.18 vfile-message: 2.0.4 + merge-stream@2.0.0: {} + merge2@1.4.1: {} micromatch@4.0.5: @@ -4164,6 +4388,8 @@ snapshots: mime@3.0.0: {} + mimic-fn@4.0.0: {} + min-indent@1.0.1: {} miniflare@3.20240806.0: @@ -4240,6 +4466,10 @@ snapshots: normalize-range@0.1.2: {} + npm-run-path@5.3.0: + dependencies: + path-key: 4.0.0 + object-assign@4.1.1: {} object-hash@3.0.0: {} @@ -4248,6 +4478,10 @@ snapshots: dependencies: wrappy: 1.0.2 + onetime@6.0.0: + dependencies: + mimic-fn: 4.0.0 + os-tmpdir@1.0.2: {} outdent@0.5.0: {} @@ -4289,6 +4523,8 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + path-parse@1.0.7: {} path-scurry@1.11.1: @@ -4312,6 +4548,8 @@ snapshots: pathe@1.1.2: {} + pathval@2.0.0: {} + periscopic@3.1.0: dependencies: '@types/estree': 1.0.5 @@ -4560,6 +4798,8 @@ snapshots: shebang-regex@3.0.0: {} + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -4596,11 +4836,15 @@ snapshots: sprintf-js@1.0.3: {} + stackback@0.0.2: {} + stacktracey@2.1.8: dependencies: as-table: 1.0.55 get-source: 2.0.12 + std-env@3.7.0: {} + stoppable@1.1.0: {} stream-source@0.3.5: {} @@ -4627,6 +4871,8 @@ snapshots: strip-bom@3.0.0: {} + strip-final-newline@3.0.0: {} + strip-indent@3.0.0: dependencies: min-indent: 1.0.1 @@ -4819,6 +5065,14 @@ snapshots: globalyzer: 0.1.0 globrex: 0.1.2 + tinybench@2.9.0: {} + + tinypool@1.0.1: {} + + tinyrainbow@1.2.0: {} + + tinyspy@3.0.0: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -4903,6 +5157,24 @@ snapshots: '@types/unist': 2.0.10 unist-util-stringify-position: 2.0.3 + vite-node@2.0.5(@types/node@22.3.0): + dependencies: + cac: 6.7.14 + debug: 4.3.6 + pathe: 1.1.2 + tinyrainbow: 1.2.0 + vite: 5.4.0(@types/node@22.3.0) + transitivePeerDependencies: + - '@types/node' + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + vite@5.4.0(@types/node@22.3.0): dependencies: esbuild: 0.21.5 @@ -4916,6 +5188,39 @@ snapshots: optionalDependencies: vite: 5.4.0(@types/node@22.3.0) + vitest@2.0.5(@types/node@22.3.0): + dependencies: + '@ampproject/remapping': 2.3.0 + '@vitest/expect': 2.0.5 + '@vitest/pretty-format': 2.0.5 + '@vitest/runner': 2.0.5 + '@vitest/snapshot': 2.0.5 + '@vitest/spy': 2.0.5 + '@vitest/utils': 2.0.5 + chai: 5.1.1 + debug: 4.3.6 + execa: 8.0.1 + magic-string: 0.30.11 + pathe: 1.1.2 + std-env: 3.7.0 + tinybench: 2.9.0 + tinypool: 1.0.1 + tinyrainbow: 1.2.0 + vite: 5.4.0(@types/node@22.3.0) + vite-node: 2.0.5(@types/node@22.3.0) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 22.3.0 + transitivePeerDependencies: + - less + - lightningcss + - sass + - sass-embedded + - stylus + - sugarss + - supports-color + - terser + web-vitals@4.2.3: {} webidl-conversions@3.0.1: {} @@ -4938,6 +5243,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + workerd@1.20240806.0: optionalDependencies: '@cloudflare/workerd-darwin-64': 1.20240806.0 From 497d6e16735621c8efd6f5918d9e375b1d6c593b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 07:33:23 -0400 Subject: [PATCH 064/177] Format all tooltip values by default (using default formatter based on value) --- .../layerchart/src/lib/components/charts/AreaChart.svelte | 7 ++++++- .../layerchart/src/lib/components/charts/BarChart.svelte | 7 ++++++- .../layerchart/src/lib/components/charts/LineChart.svelte | 7 ++++++- .../layerchart/src/lib/components/charts/PieChart.svelte | 3 ++- .../src/lib/components/charts/ScatterChart.svelte | 2 +- 5 files changed, 21 insertions(+), 5 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 3c6f51b32..4a8c5a081 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -116,7 +116,12 @@ {#each series as s} {@const valueAccessor = accessor(s.value)} - + {/each} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 7113fd735..9812a99a5 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -128,7 +128,12 @@ {#each series as s} {@const valueAccessor = accessor(s.value)} - + {/each} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 40f09a414..0f19dc540 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -109,7 +109,12 @@ {#each series as s} {@const valueAccessor = accessor(s.value)} - + {/each} diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index c93684137..7161326e2 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -2,6 +2,7 @@ import { type ComponentProps } from 'svelte'; import { scaleOrdinal } from 'd3-scale'; import { sum } from 'd3-array'; + import { format } from '@layerstack/utils'; import Arc from '../Arc.svelte'; import Chart from '../Chart.svelte'; @@ -171,7 +172,7 @@ label={labelAccessor(data)} value={valueAccessor(data)} color={rScale(r(data))} - format="integer" + {format} /> diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index 95e22342a..e58f0df65 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -98,7 +98,7 @@ {format(x(data))} - + From edb045d5f2d7ce1cf19b06f9b2eb1bd178617fdb Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 07:36:53 -0400 Subject: [PATCH 065/177] fix(BarChart): Change `layout` prop to `orientation` to align with other components --- .../src/lib/components/charts/BarChart.svelte | 12 ++++++------ .../src/routes/docs/components/BarChart/+page.svelte | 6 +++--- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 9812a99a5..5b0851d20 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -16,7 +16,7 @@ interface $$Props extends ComponentProps> { series?: typeof series; labels?: typeof labels; - layout?: typeof layout; + orientation?: typeof orientation; bandPadding?: typeof bandPadding; props?: typeof props; } @@ -25,15 +25,15 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; - export let layout: 'vertical' | 'horizontal' = 'vertical'; - $: isVertical = layout === 'vertical'; + export let orientation: 'vertical' | 'horizontal' = 'vertical'; + $: isVertical = orientation === 'vertical'; export let series: { label?: string; value: Accessor; color?: string; props?: Partial>; - }[] = [{ value: layout === 'vertical' ? y : x, color: 'hsl(var(--color-primary))' }]; + }[] = [{ value: orientation === 'vertical' ? y : x, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; export let bandPadding = 0.4; @@ -58,11 +58,11 @@ x={x ?? series.map((s) => s.value)} {xScale} {xDomain} - xNice={layout === 'horizontal'} + xNice={orientation === 'horizontal'} y={y ?? series.map((d) => d.value)} {yScale} {yDomain} - yNice={layout === 'vertical'} + yNice={orientation === 'vertical'} padding={{ left: 16, bottom: 16 }} tooltip={{ mode: 'band' }} {...$$restProps} diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index ce086cc44..3e295a727 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -32,7 +32,7 @@
- +
@@ -63,7 +63,7 @@ d.age).reverse()} - layout="horizontal" + orientation="horizontal" padding={{ left: 32, bottom: 16 }} series={[ { From 2561bb612f6b2c40e71ee05253210379d7c99b4c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 08:48:58 -0400 Subject: [PATCH 066/177] feat(Points): Add `xValue` and `yValue` to each point, and improve types --- .changeset/green-crews-change.md | 5 +++ .../src/lib/components/Points.svelte | 34 ++++++++++++------- 2 files changed, 27 insertions(+), 12 deletions(-) create mode 100644 .changeset/green-crews-change.md diff --git a/.changeset/green-crews-change.md b/.changeset/green-crews-change.md new file mode 100644 index 000000000..3613c3398 --- /dev/null +++ b/.changeset/green-crews-change.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Points): Add `xValue` and `yValue` to each point, and improve types diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index f85ca392d..532a24e39 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -10,7 +10,7 @@ import { isScaleBand, type AnyScale } from '../utils/scales.js'; const context = chartContext() as any; - const { data: contextData, xGet, y, yGet, xScale, yScale, rGet, config } = context; + const { data: contextData, x, xScale, xGet, y, yScale, yGet, rGet, config } = context; type Offset = number | ((value: number, context: any) => number) | undefined; @@ -47,12 +47,15 @@ x={["prop1" ,"prop2"]} y="prop3" */ - return $xGet(d) + return $x(d) .filter(notNull) - .map((x: number) => { + .map((xValue: number) => { + const yValue = $y(d); return { - x: x + getOffset(x, offsetX, $xScale), - y: $yGet(d) + getOffset($yGet(d), offsetY, $yScale), + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue: $y(d), data: d, }; }); @@ -61,12 +64,15 @@ x="prop1" y={["prop2" ,"prop3"]} */ - return $yGet(d) + return $y(d) .filter(notNull) - .map((y: number) => { + .map((yValue: number) => { + const xValue = $x(d); return { - x: $xGet(d) + getOffset($xGet(d), offsetX, $xScale), - y: y + getOffset(y, offsetY, $yScale), + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue: $y(d), data: d, }; }); @@ -75,13 +81,17 @@ x="prop1" y="prop2" */ + const xValue = $x(d); + const yValue = $y(d); return { - x: $xGet(d) + getOffset($xGet(d), offsetX, $xScale), - y: $yGet(d) + getOffset($yGet(d), offsetY, $yScale), + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue, data: d, }; } - }); + }) as { x: number; y: number; xValue: any; yValue: any; data: any }[]; $: _links = pointsData.flatMap((d: any) => { if (Array.isArray($config.x)) { From b7927c8f6c0f34c0f0f840d31320ea2b630fd972 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 08:50:50 -0400 Subject: [PATCH 067/177] fix(Labels): Handle multiple x or y properties (stack, diverting) by leveraging Points component internally --- .changeset/four-months-judge.md | 5 + .../src/lib/components/Labels.svelte | 110 ++++++------------ .../docs/components/BarChart/+page.svelte | 17 +-- .../docs/examples/Threshold/+page.svelte | 2 - 4 files changed, 47 insertions(+), 87 deletions(-) create mode 100644 .changeset/four-months-judge.md diff --git a/.changeset/four-months-judge.md b/.changeset/four-months-judge.md new file mode 100644 index 000000000..072a5fee2 --- /dev/null +++ b/.changeset/four-months-judge.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Labels): Handle multiple x or y properties (stack, diverting) by leveraging Points component internally diff --git a/packages/layerchart/src/lib/components/Labels.svelte b/packages/layerchart/src/lib/components/Labels.svelte index c0d0a08c8..875d70222 100644 --- a/packages/layerchart/src/lib/components/Labels.svelte +++ b/packages/layerchart/src/lib/components/Labels.svelte @@ -1,75 +1,35 @@ - {#each $flatData as item, index} - - - {/each} + + {#each points as point} + + {/each} + diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index 3e295a727..339bc9ed4 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -113,6 +113,12 @@ yDomain={data.worldPopulationDemographics.map((d) => d.age).reverse()} orientation="horizontal" padding={{ left: 32, bottom: 16 }} + labels={{ format: (value) => format(Math.abs(value), 'metric') }} + props={{ + axisBottom: { + format: 'metric', + }, + }} series={[ { label: 'male', @@ -130,17 +136,6 @@ > - - - - - format(value, undefined, { variant: 'short' })} - /> - format(value, 'metric')} />
diff --git a/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte b/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte index 6c0f25813..176bb2e00 100644 --- a/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte @@ -119,8 +119,6 @@

With Labels

- -
Date: Mon, 26 Aug 2024 09:29:11 -0400 Subject: [PATCH 068/177] Finish horizontal / diverging example and add percent-based version as well --- .../src/lib/components/charts/BarChart.svelte | 2 +- .../docs/components/BarChart/+page.svelte | 85 +++++++++++++++++-- 2 files changed, 80 insertions(+), 7 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 5b0851d20..eebcdced2 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -75,7 +75,7 @@ let:padding let:tooltip > - {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip }} + {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }} diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index 339bc9ed4..8717a6400 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -1,6 +1,6 @@

Series (horizontal / diverging)

+ {@const totalPopulation = sum(data.worldPopulationDemographics, (d) => d.male + d.female)}
d.age).reverse()} + yDomain={data.worldPopulationDemographics.map((d) => d.age)} orientation="horizontal" padding={{ left: 32, bottom: 16 }} labels={{ format: (value) => format(Math.abs(value), 'metric') }} props={{ - axisBottom: { - format: 'metric', - }, + axisLeft: { rule: false }, + axisBottom: { format: (value) => format(Math.abs(value), 'metric') }, }} series={[ { @@ -137,6 +137,79 @@ + + + + Age: {format(y(data))} + + {#each series as s} + {@const valueAccessor = accessor(s.value)} + {@const value = Math.abs(valueAccessor(data))} + + {format(value)} + ({format(value / totalPopulation, 'percent')}) + + {/each} + + + + +
+
+ +

Series (horizontal / diverging) as percent

+ + + {@const totalPopulation = sum(data.worldPopulationDemographics, (d) => d.male + d.female)} +
+ d.age)} + orientation="horizontal" + padding={{ left: 32, bottom: 16 }} + labels={{ format: 'percent' }} + props={{ + axisLeft: { rule: false }, + axisBottom: { format: 'percentRound' }, + }} + series={[ + { + label: 'male', + value: (d) => -d.male / totalPopulation, + color: 'hsl(var(--color-primary))', + props: { rounded: 'left' }, + }, + { + label: 'female', + value: (d) => d.female / totalPopulation, + color: 'hsl(var(--color-secondary))', + props: { rounded: 'right' }, + }, + ]} + > + + + + + + + Age: {format(y(data))} + + {#each series as s} + {@const valueAccessor = accessor(s.value)} + {@const value = Math.abs(valueAccessor(data))} + + {format(value * totalPopulation)} + ({format(value, 'percent')}) + + {/each} + + +
From 6d98f57b0665a5c0e7ff67373ca317c6e1663f48 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 09:37:21 -0400 Subject: [PATCH 069/177] Fix negative labels/axis on percent version --- .../src/routes/docs/components/BarChart/+page.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index 8717a6400..d1ab1f241 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -171,10 +171,10 @@ yDomain={data.worldPopulationDemographics.map((d) => d.age)} orientation="horizontal" padding={{ left: 32, bottom: 16 }} - labels={{ format: 'percent' }} + labels={{ format: (value) => format(Math.abs(value), 'percent') }} props={{ axisLeft: { rule: false }, - axisBottom: { format: 'percentRound' }, + axisBottom: { format: (value) => format(Math.abs(value), 'percentRound') }, }} series={[ { From 2b9e68e4fad57d9bb6e82920af3c5afb26954c9f Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 12:17:30 -0400 Subject: [PATCH 070/177] Add data source links for population pyramid --- .../routes/docs/components/BarChart/+page.svelte | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index d1ab1f241..8740f2918 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -4,6 +4,7 @@ import { format, PeriodType } from '@layerstack/utils'; import Preview from '$lib/docs/Preview.svelte'; + import Blockquote from '$lib/docs/Blockquote.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; export let data; @@ -159,6 +160,12 @@
+
+ Data source: + Population pyramid + +
+

Series (horizontal / diverging) as percent

@@ -214,6 +221,12 @@
+
+ Data source: + Population pyramid + +
+

Labels

From 22e94bf8301fe079510a07633420da6ecc7c673a Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 15:25:02 -0400 Subject: [PATCH 071/177] Add stack tests (WIP - fix build by adding test) --- .../layerchart/src/lib/utils/stack.test.ts | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) create mode 100644 packages/layerchart/src/lib/utils/stack.test.ts diff --git a/packages/layerchart/src/lib/utils/stack.test.ts b/packages/layerchart/src/lib/utils/stack.test.ts new file mode 100644 index 000000000..7553e68ec --- /dev/null +++ b/packages/layerchart/src/lib/utils/stack.test.ts @@ -0,0 +1,45 @@ +import { describe, it, expect } from 'vitest'; + +import { createStackData } from './stack.js'; + +export const testData = [ + { year: 2019, basket: 1, fruit: 'apples', value: 3840 }, + { year: 2019, basket: 1, fruit: 'bananas', value: 1920 }, + { year: 2019, basket: 2, fruit: 'cherries', value: 960 }, + { year: 2019, basket: 2, fruit: 'dates', value: 400 }, + + { year: 2018, basket: 1, fruit: 'apples', value: 1600 }, + { year: 2018, basket: 1, fruit: 'bananas', value: 1440 }, + { year: 2018, basket: 2, fruit: 'cherries', value: 960 }, + { year: 2018, basket: 2, fruit: 'dates', value: 400 }, + + { year: 2017, basket: 1, fruit: 'apples', value: 820 }, + { year: 2017, basket: 1, fruit: 'bananas', value: 1000 }, + { year: 2017, basket: 2, fruit: 'cherries', value: 640 }, + { year: 2017, basket: 2, fruit: 'dates', value: 400 }, + + { year: 2016, basket: 1, fruit: 'apples', value: 820 }, + { year: 2016, basket: 1, fruit: 'bananas', value: 560 }, + { year: 2016, basket: 2, fruit: 'cherries', value: 720 }, + { year: 2016, basket: 2, fruit: 'dates', value: 400 }, +]; + +describe('createStackData', () => { + it('xKey only', () => { + const actual = createStackData(testData, { xKey: 'year' }); + + expect(actual.length).toEqual(4); + const expected = {}; + // expect(actual).toEqual(expected); + }); + + it('xKey with groupBy', () => { + const xKey = 'year'; + const groupBy = 'fruit'; + const actual = createStackData(testData, { xKey, groupBy }); + + expect(actual.length).toEqual(16); // same length, but with + const expected = {}; + // expect(actual).toEqual(expected); + }); +}); From 50d32c2b75928342632369afbb71b59cbbbee4ec Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 26 Aug 2024 15:58:39 -0400 Subject: [PATCH 072/177] fix(Labels): Restore passing $$restProps to fix check/build, but also remove unneeded override --- packages/layerchart/src/lib/components/Labels.svelte | 1 + .../layerchart/src/routes/docs/examples/Scatter/+page.svelte | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/components/Labels.svelte b/packages/layerchart/src/lib/components/Labels.svelte index 875d70222..873929e6e 100644 --- a/packages/layerchart/src/lib/components/Labels.svelte +++ b/packages/layerchart/src/lib/components/Labels.svelte @@ -83,6 +83,7 @@ : 'fill-surface-content stroke-surface-100' )} {...getTextProps(point)} + {...$$restProps} /> {/each} diff --git a/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte b/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte index fd987d1f5..e935d76d3 100644 --- a/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Scatter/+page.svelte @@ -95,7 +95,7 @@ rule /> - +
From 7779db3da9731e4712b40383f1e5996ed6f671f4 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 27 Aug 2024 08:32:47 -0400 Subject: [PATCH 073/177] docs(ForceText): Add force and trransition toggles --- .../docs/examples/ForceText/+page.svelte | 43 ++++++++++++++----- 1 file changed, 33 insertions(+), 10 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte b/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte index d46257fdd..6b4681018 100644 --- a/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte @@ -2,7 +2,7 @@ import { forceX, forceY, forceManyBody, forceCollide } from 'd3-force'; import { Chart, Circle, ForceSimulation, Svg } from 'layerchart'; - import { RangeField, TextField } from 'svelte-ux'; + import { Field, RangeField, Switch, TextField } from 'svelte-ux'; import Preview from '$lib/docs/Preview.svelte'; @@ -14,6 +14,10 @@ let radius = 2; const collisionStrength = 0.01; + let hasCollideForce = false; // TODO: Determine why unable to remove if enabled true by default + let hasChargeForce = false; + let transition = false; + function onResize(e: ChartResizeEvent) { width = e.detail.width; height = e.detail.height; @@ -39,10 +43,8 @@ $: pixels = rasterizeText(text, textOptions).map(function (d) { return { - x: Math.random() * width, - y: Math.random() * height, - // x: d[0], - // y: d[1], + x: transition ? d[0] : Math.random() * width, + y: transition ? d[1] : Math.random() * height, xTarget: d[0], yTarget: d[1], rTarget: radius, @@ -60,12 +62,23 @@

Examples

-
+
+
+ + + + + + + + + +
@@ -75,16 +88,26 @@ forces={{ x: xForce, y: yForce, - collide: collideForce, - // charge: manyBodyForce.strength((d, i) => (i ? 0 : (-width * 2) / 10)), + ...(hasCollideForce && { + collide: collideForce, + }), + ...(hasChargeForce && { + charge: manyBodyForce.strength((d, i) => (i ? 0 : (-width * 2) / 10)), + }), }} alphaTarget={1} velocityDecay={0.2} let:nodes > - {#each nodes as node, i} + {#each nodes as node, i (i)} {#if i > 0} - + {/if} {/each} From eeb3032d056c936cfd4e0f284a4113873e83b54c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 27 Aug 2024 08:50:35 -0400 Subject: [PATCH 074/177] docs(Chart): Improve description --- packages/layerchart/src/routes/docs/components/Chart/+page.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/Chart/+page.ts b/packages/layerchart/src/routes/docs/components/Chart/+page.ts index b7f4d5d32..01a8d26f4 100644 --- a/packages/layerchart/src/routes/docs/components/Chart/+page.ts +++ b/packages/layerchart/src/routes/docs/components/Chart/+page.ts @@ -9,7 +9,7 @@ export async function load() { source, pageSource, description: - 'Sets up chart context, including tooltip and geo contexts. See also simplified charts such as AreaChart and BarChart for streamline configuration', + 'Sets up chart context, including dimension scales and additional contexts such as `TooltipContext`, `GeoContext`, and `TransformContext`. See also simplified charts such as `AreaChart` and `BarChart` for streamline configuration', features: ['Adds support for x and y baselines (always show 0, etc)'], related: [ 'components/AreaChart', From 20114e981156ab612db3f7f811648fcdca8d5a07 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 27 Aug 2024 15:06:16 -0400 Subject: [PATCH 075/177] docs(Arc): Improve segmented example --- .../src/routes/docs/examples/Arc/+page.svelte | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte b/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte index f325cf6d2..b80175614 100644 --- a/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte @@ -127,15 +127,15 @@
-
+
- {#each { length: segments } as _, segmentIndex} - {@const segmentAngle = (2 * Math.PI) / segments} - {@const startAngle = segmentIndex * segmentAngle} - {@const endAngle = (segmentIndex + 1) * segmentAngle} - + + {#each { length: segments } as _, segmentIndex} + {@const segmentAngle = (2 * Math.PI) / segments} + {@const startAngle = segmentIndex * segmentAngle} + {@const endAngle = (segmentIndex + 1) * segmentAngle} - - - - {/each} + > + {/each} + + + From 19b10605b3691bf8bf9735963f6a9f78a2d0d874 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 27 Aug 2024 20:34:55 -0400 Subject: [PATCH 076/177] test(accessor): Add tests for accessor function --- .../layerchart/src/lib/utils/common.test.ts | 42 +++++++++++++++++++ packages/layerchart/src/lib/utils/common.ts | 1 + 2 files changed, 43 insertions(+) create mode 100644 packages/layerchart/src/lib/utils/common.test.ts diff --git a/packages/layerchart/src/lib/utils/common.test.ts b/packages/layerchart/src/lib/utils/common.test.ts new file mode 100644 index 000000000..de78e8704 --- /dev/null +++ b/packages/layerchart/src/lib/utils/common.test.ts @@ -0,0 +1,42 @@ +import { describe, it, expect } from 'vitest'; + +import { accessor } from './common.js'; + +export const testData = { + one: 1, + two: 2, + obj: { value: 2 }, + arr: ['one', 'two', 'three'], +}; + +describe('accessor', () => { + it('string', () => { + const actual = accessor('one')(testData); + expect(actual).toEqual(testData.one); + }); + + it('nested string', () => { + const actual = accessor('obj.value')(testData); + expect(actual).toEqual(testData.obj.value); + }); + + it('multiple properties', () => { + const actual = accessor(['one', 'two', 'obj.value', (d) => d.arr[0]])(testData); + expect(actual).toEqual([testData.one, testData.two, testData.obj.value, testData.arr[0]]); + }); + + it('function', () => { + const actual = accessor((d) => d.obj.value)(testData); + expect(actual).toEqual(testData.obj.value); + }); + + it('string array', () => { + const actual = accessor('arr[0]')(testData); + expect(actual).toEqual(testData.arr[0]); + }); + + it('null returns full object', () => { + const actual = accessor(null)(testData); + expect(actual).toEqual(testData); + }); +}); diff --git a/packages/layerchart/src/lib/utils/common.ts b/packages/layerchart/src/lib/utils/common.ts index 258e85445..8654fa1fb 100644 --- a/packages/layerchart/src/lib/utils/common.ts +++ b/packages/layerchart/src/lib/utils/common.ts @@ -7,6 +7,7 @@ export type Accessor = | string | ((d: TData) => any) | undefined + | null | Accessor[]; export function accessor(prop: Accessor): (d: TData) => any { From 7aba7121a87ed9a79314f8bc5a2c76009fb0911c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 27 Aug 2024 20:35:32 -0400 Subject: [PATCH 077/177] Set timezone when running tests to EST --- packages/layerchart/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/package.json b/packages/layerchart/package.json index 0ed9ff65b..ec5d8fcc4 100644 --- a/packages/layerchart/package.json +++ b/packages/layerchart/package.json @@ -13,7 +13,7 @@ "prepublishOnly": "svelte-package", "check": "svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch", - "test:unit": "TZ=UTC+4 vitest", + "test:unit": "TZ=UTC-5 vitest", "lint": "prettier --check .", "format": "prettier --write .", "prepare": "svelte-kit sync" From ccf643bd00ce07fb030e55da65429ec58116204a Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 27 Aug 2024 20:41:39 -0400 Subject: [PATCH 078/177] feat(Chart): Use `accessor()` util before passsing x/y accessors to LayerCake (i.e. support `x="keys[0]"`) --- .changeset/tasty-pigs-eat.md | 5 +++++ packages/layerchart/src/lib/components/Chart.svelte | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 .changeset/tasty-pigs-eat.md diff --git a/.changeset/tasty-pigs-eat.md b/.changeset/tasty-pigs-eat.md new file mode 100644 index 000000000..c68fd8b88 --- /dev/null +++ b/.changeset/tasty-pigs-eat.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Chart): Use `accessor()` util before passsing x/y accessors to LayerCake (i.e. support `x="keys[0]"`) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index efe646061..04ea297e7 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -257,9 +257,9 @@ Date: Wed, 28 Aug 2024 00:06:51 -0400 Subject: [PATCH 079/177] feat: Rename `createStackData()` to `groupStackData()`, refine returned structure to simplify tooltips and make consistent with different options combinations, and add tests --- .changeset/mighty-teachers-rest.md | 5 + .../layerchart/src/lib/utils/stack.test.ts | 133 ++++++++++++++++-- packages/layerchart/src/lib/utils/stack.ts | 60 +++++--- 3 files changed, 169 insertions(+), 29 deletions(-) create mode 100644 .changeset/mighty-teachers-rest.md diff --git a/.changeset/mighty-teachers-rest.md b/.changeset/mighty-teachers-rest.md new file mode 100644 index 000000000..fd2037030 --- /dev/null +++ b/.changeset/mighty-teachers-rest.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat: Rename `createStackData()` to `groupStackData()`, refine returned structure to simplify tooltips and make consistent with different options combinations, and add tests diff --git a/packages/layerchart/src/lib/utils/stack.test.ts b/packages/layerchart/src/lib/utils/stack.test.ts index 7553e68ec..d01af7b8f 100644 --- a/packages/layerchart/src/lib/utils/stack.test.ts +++ b/packages/layerchart/src/lib/utils/stack.test.ts @@ -1,6 +1,7 @@ import { describe, it, expect } from 'vitest'; -import { createStackData } from './stack.js'; +import { groupStackData } from './stack.js'; +import { group } from 'd3-array'; export const testData = [ { year: 2019, basket: 1, fruit: 'apples', value: 3840 }, @@ -24,22 +25,136 @@ export const testData = [ { year: 2016, basket: 2, fruit: 'dates', value: 400 }, ]; +const testDataByYear = group(testData, (d) => d.year); + describe('createStackData', () => { it('xKey only', () => { - const actual = createStackData(testData, { xKey: 'year' }); + const actual = groupStackData(testData, { xKey: 'year' }); expect(actual.length).toEqual(4); - const expected = {}; - // expect(actual).toEqual(expected); + expect(actual[0]).toEqual({ + year: 2019, + keys: { year: 2019 }, + value: 7120, + values: [0, 7120], + data: testDataByYear.get(2019), + }); }); - it('xKey with groupBy', () => { + it('xKey with groupBy (unique)', () => { const xKey = 'year'; const groupBy = 'fruit'; - const actual = createStackData(testData, { xKey, groupBy }); + const actual = groupStackData(testData, { xKey, groupBy }); + + // 4 years, 4 fruits each (each a separate bar) + expect(actual.length).toEqual(16); + + expect(actual[0]).toEqual({ + year: 2019, + fruit: 'apples', + value: 3840, + keys: { year: 2019, fruit: 'apples' }, + values: [0, 3840], + data: testDataByYear.get(2019), + }); + + expect(actual[1]).toEqual({ + year: 2019, + fruit: 'bananas', + value: 1920, + keys: { year: 2019, fruit: 'bananas' }, + values: [0, 1920], + data: testDataByYear.get(2019), + }); + }); + + it('xKey with groupBy (grouped)', () => { + const xKey = 'year'; + const groupBy = 'basket'; + const actual = groupStackData(testData, { xKey, groupBy }); + + // 4 years, 2 buckets each + expect(actual.length).toEqual(8); + + expect(actual[0]).toEqual({ + year: 2019, + basket: 1, + value: 3840, + keys: { year: 2019, basket: 1 }, + values: [0, 5760], + data: testDataByYear.get(2019), + }); + + expect(actual[1]).toEqual({ + year: 2019, + basket: 2, + value: 960, + keys: { year: 2019, basket: 2 }, + values: [0, 1360], + data: testDataByYear.get(2019), + }); + + expect(actual[2]).toEqual({ + year: 2018, + basket: 1, + value: 1600, + keys: { year: 2018, basket: 1 }, + values: [0, 3040], + data: testDataByYear.get(2018), + }); + }); + + it('xKey with stackBy', () => { + const xKey = 'year'; + const stackBy = 'fruit'; + const actual = groupStackData(testData, { xKey, stackBy }); + + // 4 years, 4 fruits each (each a separate bar) + expect(actual.length).toEqual(16); + + expect(actual[0]).toEqual({ + year: 2019, + fruit: 'apples', + value: 3840, + keys: { year: 2019, fruit: 'apples' }, + values: [0, 3840], + data: testDataByYear.get(2019), + }); + + expect(actual[1]).toEqual({ + year: 2018, + fruit: 'apples', + value: 1600, + keys: { year: 2018, fruit: 'apples' }, + values: [0, 1600], + data: testDataByYear.get(2018), + }); + + expect(actual[2]).toEqual({ + year: 2017, + fruit: 'apples', + value: 820, + keys: { year: 2017, fruit: 'apples' }, + values: [0, 820], + data: testDataByYear.get(2017), + }); + + expect(actual[3]).toEqual({ + year: 2016, + fruit: 'apples', + value: 820, + keys: { year: 2016, fruit: 'apples' }, + values: [0, 820], + data: testDataByYear.get(2016), + }); - expect(actual.length).toEqual(16); // same length, but with - const expected = {}; - // expect(actual).toEqual(expected); + expect(actual[4]).toEqual({ + year: 2019, + fruit: 'bananas', + value: 1920, + keys: { year: 2019, fruit: 'bananas' }, + values: [3840, 5760], + data: testDataByYear.get(2019), + }); }); }); diff --git a/packages/layerchart/src/lib/utils/stack.ts b/packages/layerchart/src/lib/utils/stack.ts index 50ea3dfc9..dafffd7fd 100644 --- a/packages/layerchart/src/lib/utils/stack.ts +++ b/packages/layerchart/src/lib/utils/stack.ts @@ -1,11 +1,11 @@ -import { flatGroup, max, rollup, sum } from 'd3-array'; +import { flatGroup, group, max, rollup, sum } from 'd3-array'; import { stack, stackOffsetNone, stackOrderNone } from 'd3-shape'; import { pivotWider } from './pivot.js'; type OrderType = typeof stackOrderNone; // all orders share the same API type OffsetType = typeof stackOffsetNone; // all offsets share the same API -export function createStackData( +export function groupStackData( data: TData[], options: { xKey: string; @@ -15,27 +15,27 @@ export function createStackData( offset?: OffsetType; } ): { - keys: (string | number)[]; + keys: Record; // TODO: Improve type based on key, groupBy, and stackBy values values: number[]; }[] { + const dataByKey = group(data, (d: any) => d[options.xKey]); + if (options.groupBy) { // Group then Stack (if needed) const groupedData = flatGroup( data, - // @ts-expect-error - (d) => d[options.xKey], - // @ts-expect-error - (d) => d[options.groupBy ?? ''] + (d: any) => d[options.xKey], + (d: any) => d[options.groupBy ?? ''] ); const result = groupedData.flatMap((d, i) => { const groupKeys = d.slice(0, -1); // all but last item - const itemData = d.slice(-1)[0]; // last item + const groupData = d.slice(-1)[0]; // last item - const pivotData = pivotWider(itemData, options.xKey, options.stackBy ?? '', 'value'); + const pivotData = pivotWider(groupData, options.xKey, options.stackBy ?? '', 'value'); const stackKeys: Array = [ - ...new Set(itemData.map((d: any) => d[options.stackBy ?? ''])), + ...new Set(groupData.map((d: any) => d[options.stackBy ?? ''])), ]; // @ts-expect-error const stackData = stack().keys(stackKeys).order(options.order).offset(options.offset)( @@ -44,10 +44,20 @@ export function createStackData( return stackData.flatMap((series) => { return series.flatMap((s) => { + const keys = { + [options.xKey]: groupKeys[0], + [options.groupBy ?? '']: groupKeys[1], + }; + if (options.stackBy) { + keys[options.stackBy] = series.key; + } + return { - ...itemData[0], // TODO: More than one should use stacks or aggregate values? - keys: options.stackBy ? [...groupKeys, series.key] : groupKeys, - values: options.stackBy ? [s[0], s[1]] : [0, sum(itemData, (d: any) => d.value)], + ...keys, + keys, + value: groupData[0].value, + values: options.stackBy ? [s[0], s[1]] : [0, sum(groupData, (d: any) => d.value)], + data: dataByKey.get(keys[options.xKey]), }; }); }); @@ -67,10 +77,16 @@ export function createStackData( const result = stackData.flatMap((series) => { return series.flatMap((s) => { + const keys = { + [options.xKey]: s.data[options.xKey], + [options.stackBy ?? '']: series.key, + }; return { - ...s.data, - keys: [s.data[options.xKey], series.key], + ...keys, + keys, + value: s[1] - s[0], values: [s[0], s[1]], + data: dataByKey.get(keys[options.xKey]), }; }); }); @@ -82,11 +98,15 @@ export function createStackData( rollup( data, (items) => { + // @ts-expect-error + const keys = { [options.xKey]: items[0][options.xKey] }; + const value = sum(items, (d: any) => d.value); return { - // @ts-expect-error - keys: [items[0][options.xKey]], - // @ts-expect-error - values: [0, sum(items, (d) => d.value)], + ...keys, + keys, + value, + values: [0, value], + data: dataByKey.get(keys[options.xKey]), }; }, // @ts-expect-error @@ -100,7 +120,7 @@ export function createStackData( * Function to offset each layer by the maximum of the previous layer * - see: https://observablehq.com/@mkfreeman/separated-bar-chart */ -// TODO: Try to find way to support separated with createStackData() (which has isolated stacked per group) +// TODO: Try to find way to support separated with groupStackData() (which has isolated stacked per group) // @ts-expect-error export function stackOffsetSeparated(series, order) { const gap = 200; // TODO: Determine way to pass in as option (curry?) From d52b8071d4affca3e950eed92d91cc474ba3211c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 00:26:28 -0400 Subject: [PATCH 080/177] docs: Add tooltip examples to Bar/Columns group/stack examples --- .../layerchart/src/lib/components/Bars.svelte | 2 +- .../routes/docs/examples/Bars/+page.svelte | 201 +++++++++++++++--- .../routes/docs/examples/Columns/+page.svelte | 196 ++++++++++++++--- 3 files changed, 329 insertions(+), 70 deletions(-) diff --git a/packages/layerchart/src/lib/components/Bars.svelte b/packages/layerchart/src/lib/components/Bars.svelte index f052f4313..af96f75c6 100644 --- a/packages/layerchart/src/lib/components/Bars.svelte +++ b/packages/layerchart/src/lib/components/Bars.svelte @@ -46,10 +46,10 @@ {stroke} {strokeWidth} {radius} + {inset} {spring} {tweened} {groupBy} - {inset} {groupPaddingInner} {groupPaddingOuter} {...$$restProps} diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte index b9716572d..18e3c7492 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte @@ -1,7 +1,7 @@

Examples

@@ -775,23 +782,49 @@
d.values))} + x="value" xNice y="year" yScale={scaleBand().paddingInner(0.3).paddingOuter(0.1)} - r={(d) => d} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -807,17 +840,45 @@ xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} - r={(d) => d.keys[1]} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -833,17 +894,45 @@ xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} - r={(d) => d.keys[1]} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -859,7 +948,7 @@ xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} - r={(d) => d.keys[1]} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} @@ -880,23 +969,50 @@
d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} - r={(d) => d} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -923,14 +1039,12 @@ xNice y="year" yScale={scaleBand().paddingInner(0.2).paddingOuter(0.1)} - r={(d) => { - // Color by fruit (last key) - return d.keys.at(-1); - }} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} let:data let:rScale > @@ -939,15 +1053,13 @@ - {#each transitionData as bar (bar.keys - .filter((key) => typeof key !== 'number') - .join('-'))} + {#each transitionData as bar (bar.year + '-' + bar.fruit)} {/each} + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -1019,10 +1157,7 @@ xNice y="year" yScale={scaleBand().paddingInner(0.2).paddingOuter(0.1)} - r={(d) => { - // Color by fruit (last key) - return d.keys.at(-1); - }} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} @@ -1035,15 +1170,13 @@ - {#each transitionData as bar (bar.keys - .filter((key) => typeof key !== 'number') - .join('-'))} + {#each transitionData as bar (bar.year + '-' + bar.fruit)} import { cubicInOut } from 'svelte/easing'; import { scaleBand, scaleOrdinal, scaleTime } from 'd3-scale'; - import { extent, mean } from 'd3-array'; + import { extent, mean, sum } from 'd3-array'; import { stackOffsetExpand } from 'd3-shape'; import { @@ -18,7 +18,7 @@ Svg, Text, Tooltip, - createStackData, + groupStackData, stackOffsetSeparated, } from 'layerchart'; @@ -37,19 +37,19 @@ }); const negativeData = createDateSeries({ count: 30, min: -20, max: 50, value: 'integer' }); - const groupedData = createStackData(longData, { xKey: 'year', groupBy: 'fruit' }); - const stackedData = createStackData(longData, { xKey: 'year', stackBy: 'fruit' }); - const groupedStackedData = createStackData(longData, { + const groupedData = groupStackData(longData, { xKey: 'year', groupBy: 'fruit' }); + const stackedData = groupStackData(longData, { xKey: 'year', stackBy: 'fruit' }); + const groupedStackedData = groupStackData(longData, { xKey: 'year', groupBy: 'basket', stackBy: 'fruit', }); - const stackedPercentData = createStackData(longData, { + const stackedPercentData = groupStackData(longData, { xKey: 'year', stackBy: 'fruit', offset: stackOffsetExpand, }); - const stackedSeperatedData = createStackData(longData, { + const stackedSeperatedData = groupStackData(longData, { xKey: 'year', stackBy: 'fruit', offset: stackOffsetSeparated, @@ -84,17 +84,17 @@ groupBy: undefined, stackBy: undefined, }; - $: transitionData = createStackData(longData, { + $: transitionData = groupStackData(longData, { xKey: 'year', groupBy: transitionChart.groupBy, stackBy: transitionChart.stackBy, }) as { - basket: number; + year: string; fruit: string; + basket: number; keys: string[]; value: number; values: number[]; - year: string; }[]; @@ -784,23 +784,49 @@
d.values))} + y="value" yNice={4} - r={(d) => d} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -816,17 +842,45 @@ y="values" yDomain={extent(stackedData.flatMap((d) => d.values))} yNice={4} - r={(d) => d.keys[1]} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -842,17 +896,45 @@ y="values" yDomain={extent(stackedPercentData.flatMap((d) => d.values))} yNice={4} - r={(d) => d.keys[1]} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -868,7 +950,7 @@ y="values" yDomain={extent(stackedSeperatedData.flatMap((d) => d.values))} yNice={4} - r={(d) => d.keys[1]} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} @@ -889,23 +971,50 @@
d.values))} yNice={4} - r={(d) => d} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} + let:rScale > + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + +
@@ -932,14 +1041,12 @@ y="values" yDomain={extent(stackedData.flatMap((d) => d.values))} yNice={4} - r={(d) => { - // Color by fruit (last key) - return d.keys.at(-1); - }} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'band' }} let:data let:rScale > @@ -948,15 +1055,13 @@ - {#each transitionData as bar (bar.keys - .filter((key) => typeof key !== 'number') - .join('-'))} + {#each transitionData as bar (bar.year + '-' + bar.fruit)} {/each} + + + + {data.year} + + {#each data.data as d} + + {/each} + + + + + d.value)} + format="integer" + valueAlign="right" + /> + + @@ -1028,10 +1159,7 @@ y="values" yDomain={extent(stackedData.flatMap((d) => d.values))} yNice={4} - r={(d) => { - // Color by fruit (last key) - return d.keys.at(-1); - }} + r="fruit" rScale={scaleOrdinal()} rDomain={colorKeys} rRange={keyColors} @@ -1044,15 +1172,13 @@ - {#each transitionData as bar (bar.keys - .filter((key) => typeof key !== 'number') - .join('-'))} + {#each transitionData as bar (bar.year + '-' + bar.fruit)} Date: Wed, 28 Aug 2024 00:38:23 -0400 Subject: [PATCH 081/177] fix(accessor): Handle number indexes (ex. stack) --- packages/layerchart/src/lib/utils/common.test.ts | 11 ++++++++--- packages/layerchart/src/lib/utils/common.ts | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/packages/layerchart/src/lib/utils/common.test.ts b/packages/layerchart/src/lib/utils/common.test.ts index de78e8704..7f5dad0e6 100644 --- a/packages/layerchart/src/lib/utils/common.test.ts +++ b/packages/layerchart/src/lib/utils/common.test.ts @@ -10,12 +10,12 @@ export const testData = { }; describe('accessor', () => { - it('string', () => { + it('string path', () => { const actual = accessor('one')(testData); expect(actual).toEqual(testData.one); }); - it('nested string', () => { + it('nested path', () => { const actual = accessor('obj.value')(testData); expect(actual).toEqual(testData.obj.value); }); @@ -25,12 +25,17 @@ describe('accessor', () => { expect(actual).toEqual([testData.one, testData.two, testData.obj.value, testData.arr[0]]); }); + it('multiple properties as numbers (index)', () => { + const actual = accessor([0, 1])(testData.arr); + expect(actual).toEqual([testData.arr[0], testData.arr[1]]); + }); + it('function', () => { const actual = accessor((d) => d.obj.value)(testData); expect(actual).toEqual(testData.obj.value); }); - it('string array', () => { + it('string path with array value', () => { const actual = accessor('arr[0]')(testData); expect(actual).toEqual(testData.arr[0]); }); diff --git a/packages/layerchart/src/lib/utils/common.ts b/packages/layerchart/src/lib/utils/common.ts index 8654fa1fb..6e005ac39 100644 --- a/packages/layerchart/src/lib/utils/common.ts +++ b/packages/layerchart/src/lib/utils/common.ts @@ -16,8 +16,8 @@ export function accessor(prop: Accessor): (d: TData) => any } else if (typeof prop === 'function') { // function return prop; - } else if (typeof prop === 'string') { - // path string + } else if (typeof prop === 'string' || typeof prop === 'number') { + // path string or number (array index) return (d: TData) => get(d, prop); } else { // return full object From 54bdeabbb7ed8521a670e8162b0bae2e9920ebe3 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 00:48:40 -0400 Subject: [PATCH 082/177] Use `[...data]` array copying to fix type workaround --- .../routes/docs/examples/Bars/+page.svelte | 20 +++++++++---------- .../routes/docs/examples/Columns/+page.svelte | 20 +++++++++---------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte index 18e3c7492..7ed2e9555 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte @@ -816,10 +816,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -870,10 +870,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -924,10 +924,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -1004,10 +1004,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -1089,10 +1089,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> diff --git a/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte b/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte index 1bdfec62b..7589e1e5f 100644 --- a/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte @@ -818,10 +818,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -872,10 +872,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -926,10 +926,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -1006,10 +1006,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> @@ -1091,10 +1091,10 @@ - + d.value)} + value={sum([...data.data], (d) => d.value)} format="integer" valueAlign="right" /> From e6da55d74835206beacfc626c0f798415bb97aac Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 01:12:00 -0400 Subject: [PATCH 083/177] feat(Bar): Forward pointer events to enable individual bar tooltips --- .changeset/cuddly-avocados-trade.md | 5 +++++ packages/layerchart/src/lib/components/Bar.svelte | 8 ++++++++ 2 files changed, 13 insertions(+) create mode 100644 .changeset/cuddly-avocados-trade.md diff --git a/.changeset/cuddly-avocados-trade.md b/.changeset/cuddly-avocados-trade.md new file mode 100644 index 000000000..30d4c7b62 --- /dev/null +++ b/.changeset/cuddly-avocados-trade.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Bar): Forward pointer events to enable individual bar tooltips diff --git a/packages/layerchart/src/lib/components/Bar.svelte b/packages/layerchart/src/lib/components/Bar.svelte index 8c620fb09..0e1853166 100644 --- a/packages/layerchart/src/lib/components/Bar.svelte +++ b/packages/layerchart/src/lib/components/Bar.svelte @@ -94,6 +94,10 @@ {...dimensions} {...$$restProps} on:click + on:pointerenter + on:pointermove + on:pointerleave + on:touchmove /> {:else} {/if} From 5cc576007afa4063eea9bfbf26e4c4b0b9604b7d Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 01:12:21 -0400 Subject: [PATCH 084/177] docs(Bars/Columns): Add individual tooltip examples --- .../routes/docs/examples/Bars/+page.svelte | 85 +++++++++++-------- .../routes/docs/examples/Columns/+page.svelte | 85 +++++++++++-------- 2 files changed, 102 insertions(+), 68 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte index 7ed2e9555..fafdfb75c 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte @@ -1102,40 +1102,7 @@ -

Click handler

- - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - - - -
-
- -

Click handlers for stack/grouped bars

+

Tooltip and click handlers for individual stack/grouped bar

@@ -1162,6 +1129,7 @@ rDomain={colorKeys} rRange={keyColors} padding={{ left: 16, bottom: 24 }} + let:tooltip let:data let:rScale > @@ -1189,10 +1157,59 @@ on:click={(e) => { alert('You clicked on:\n' + JSON.stringify(bar, null, 2)); }} + on:pointerenter={(e) => tooltip?.show(e, bar)} + on:pointermove={(e) => tooltip?.show(e, bar)} + on:pointerleave={(e) => tooltip?.hide()} /> {/each} + + + {data.year} + + + + + +
+ + +

Click handler

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + +
diff --git a/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte b/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte index 7589e1e5f..1df344588 100644 --- a/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte @@ -1104,40 +1104,7 @@ -

Click handler

- - -
- - - - format(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - - - -
-
- -

Click handlers for stack/grouped bars

+

Tooltip and click handlers for individual stack/grouped bar

@@ -1166,6 +1133,7 @@ padding={{ left: 16, bottom: 24 }} let:data let:rScale + let:tooltip > @@ -1191,10 +1159,59 @@ on:click={(e) => { alert('You clicked on:\n' + JSON.stringify(bar, null, 2)); }} + on:pointerenter={(e) => tooltip?.show(e, bar)} + on:pointermove={(e) => tooltip?.show(e, bar)} + on:pointerleave={(e) => tooltip?.hide()} /> {/each} + + + {data.year} + + + + + +
+ + +

Click handler

+ + +
+ + + + format(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + +
From 339d082612ebaca3695a063038d1e8922377338b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 01:15:10 -0400 Subject: [PATCH 085/177] fix(groupStackData): Fix `value` when using `groupBy` and `stackBy` --- packages/layerchart/src/lib/utils/stack.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/utils/stack.ts b/packages/layerchart/src/lib/utils/stack.ts index dafffd7fd..6e2c80a75 100644 --- a/packages/layerchart/src/lib/utils/stack.ts +++ b/packages/layerchart/src/lib/utils/stack.ts @@ -55,7 +55,7 @@ export function groupStackData( return { ...keys, keys, - value: groupData[0].value, + value: s[1] - s[0], values: options.stackBy ? [s[0], s[1]] : [0, sum(groupData, (d: any) => d.value)], data: dataByKey.get(keys[options.xKey]), }; From 3fb6145f58fcce97508c8e619c989f2366835496 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 07:09:05 -0400 Subject: [PATCH 086/177] fix(Rect/Spline): Forward `pointerenter` events --- packages/layerchart/src/lib/components/Rect.svelte | 1 + packages/layerchart/src/lib/components/Spline.svelte | 1 + 2 files changed, 2 insertions(+) diff --git a/packages/layerchart/src/lib/components/Rect.svelte b/packages/layerchart/src/lib/components/Rect.svelte index b4b31ee66..08600db1c 100644 --- a/packages/layerchart/src/lib/components/Rect.svelte +++ b/packages/layerchart/src/lib/components/Rect.svelte @@ -47,6 +47,7 @@ class={cls($$props.fill == null && 'fill-surface-content')} {...$$restProps} on:click + on:pointerenter on:pointerover on:pointermove on:pointerout diff --git a/packages/layerchart/src/lib/components/Spline.svelte b/packages/layerchart/src/lib/components/Spline.svelte index 6ecd0d800..83760c7d6 100644 --- a/packages/layerchart/src/lib/components/Spline.svelte +++ b/packages/layerchart/src/lib/components/Spline.svelte @@ -141,6 +141,7 @@ )} in:drawTransition|global={typeof draw === 'object' ? draw : undefined} on:click + on:pointerenter on:pointermove on:pointerleave bind:this={pathEl} From 6102677b44148bfec481d259b59f58603ddaabb7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 07:27:56 -0400 Subject: [PATCH 087/177] test(groupStackData): Fix `value` with groupBy only --- packages/layerchart/src/lib/utils/stack.test.ts | 8 ++++---- packages/layerchart/src/lib/utils/stack.ts | 6 ++++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/packages/layerchart/src/lib/utils/stack.test.ts b/packages/layerchart/src/lib/utils/stack.test.ts index d01af7b8f..5fa0dd0e3 100644 --- a/packages/layerchart/src/lib/utils/stack.test.ts +++ b/packages/layerchart/src/lib/utils/stack.test.ts @@ -27,7 +27,7 @@ export const testData = [ const testDataByYear = group(testData, (d) => d.year); -describe('createStackData', () => { +describe('groupStackData', () => { it('xKey only', () => { const actual = groupStackData(testData, { xKey: 'year' }); @@ -79,7 +79,7 @@ describe('createStackData', () => { expect(actual[0]).toEqual({ year: 2019, basket: 1, - value: 3840, + value: 5760, keys: { year: 2019, basket: 1 }, values: [0, 5760], data: testDataByYear.get(2019), @@ -88,7 +88,7 @@ describe('createStackData', () => { expect(actual[1]).toEqual({ year: 2019, basket: 2, - value: 960, + value: 1360, keys: { year: 2019, basket: 2 }, values: [0, 1360], data: testDataByYear.get(2019), @@ -97,7 +97,7 @@ describe('createStackData', () => { expect(actual[2]).toEqual({ year: 2018, basket: 1, - value: 1600, + value: 3040, keys: { year: 2018, basket: 1 }, values: [0, 3040], data: testDataByYear.get(2018), diff --git a/packages/layerchart/src/lib/utils/stack.ts b/packages/layerchart/src/lib/utils/stack.ts index 6e2c80a75..27a09b117 100644 --- a/packages/layerchart/src/lib/utils/stack.ts +++ b/packages/layerchart/src/lib/utils/stack.ts @@ -52,11 +52,13 @@ export function groupStackData( keys[options.stackBy] = series.key; } + const value = sum(groupData, (d: any) => d.value); + return { ...keys, keys, - value: s[1] - s[0], - values: options.stackBy ? [s[0], s[1]] : [0, sum(groupData, (d: any) => d.value)], + value, + values: options.stackBy ? [s[0], s[1]] : [0, value], data: dataByKey.get(keys[options.xKey]), }; }); From 2b59d05108b0a05cb24a3133df772f85d6570176 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 07:29:18 -0400 Subject: [PATCH 088/177] docs: Simplify Bar/Columns stacked examples by removing explicit yDomain (can be properly calculated by Chart now) --- .../layerchart/src/routes/docs/examples/Bars/+page.svelte | 6 ------ .../src/routes/docs/examples/Columns/+page.svelte | 6 ------ 2 files changed, 12 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte index fafdfb75c..c9652485d 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte @@ -836,7 +836,6 @@ d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} @@ -890,7 +889,6 @@ d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} @@ -944,7 +942,6 @@ d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} @@ -970,7 +967,6 @@ d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} @@ -1035,7 +1031,6 @@ d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.2).paddingOuter(0.1)} @@ -1120,7 +1115,6 @@ d.values))} xNice y="year" yScale={scaleBand().paddingInner(0.2).paddingOuter(0.1)} diff --git a/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte b/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte index 1df344588..9c6d590e8 100644 --- a/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Columns/+page.svelte @@ -840,7 +840,6 @@ x="year" xScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} y="values" - yDomain={extent(stackedData.flatMap((d) => d.values))} yNice={4} r="fruit" rScale={scaleOrdinal()} @@ -894,7 +893,6 @@ x="year" xScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} y="values" - yDomain={extent(stackedPercentData.flatMap((d) => d.values))} yNice={4} r="fruit" rScale={scaleOrdinal()} @@ -948,7 +946,6 @@ x="year" xScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} y="values" - yDomain={extent(stackedSeperatedData.flatMap((d) => d.values))} yNice={4} r="fruit" rScale={scaleOrdinal()} @@ -974,7 +971,6 @@ x="year" xScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} y="values" - yDomain={extent(groupedStackedData.flatMap((d) => d.values))} yNice={4} r="fruit" rScale={scaleOrdinal()} @@ -1039,7 +1035,6 @@ x="year" xScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} y="values" - yDomain={extent(stackedData.flatMap((d) => d.values))} yNice={4} r="fruit" rScale={scaleOrdinal()} @@ -1124,7 +1119,6 @@ x="year" xScale={scaleBand().paddingInner(0.4).paddingOuter(0.1)} y="values" - yDomain={extent(stackedData.flatMap((d) => d.values))} yNice={4} r="fruit" rScale={scaleOrdinal()} From bf29d403d37821ecd5a49e75b5ac17d1f320c3c0 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 23:00:58 -0400 Subject: [PATCH 089/177] docs(Tooltip): Fix area stack tooltip example --- .../layerchart/src/routes/docs/components/Tooltip/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index e9265ce66..6b4857cca 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -587,7 +587,7 @@ y={charts.areaStack.snapToDataY ? 'data' : 'pointer'} let:data > - {format(data.date, 'eee, MMMM do')} + {format(data.data.date, 'eee, MMMM do')} {#each keys as key} From 4b7f0beb28af92bc145b1893008f068c70a3dc39 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 28 Aug 2024 23:06:28 -0400 Subject: [PATCH 090/177] fix(Points):Fix points when using array accessor after using `accessor()` within `Chart` which always sets a function in `config.x` / `y` (instead of using LayerCake's built-in) --- .../src/lib/components/Points.svelte | 58 +++++++++---------- 1 file changed, 28 insertions(+), 30 deletions(-) diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index 532a24e39..ee7b2c23a 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -42,47 +42,42 @@ $: pointsData = data ?? $contextData; $: points = pointsData.flatMap((d: any) => { - if (Array.isArray($config.x)) { + const xValue = $x(d); + const yValue = $y(d); + + if (Array.isArray(xValue)) { /* x={["prop1" ,"prop2"]} y="prop3" */ - return $x(d) - .filter(notNull) - .map((xValue: number) => { - const yValue = $y(d); - return { - x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), - y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), - xValue, - yValue: $y(d), - data: d, - }; - }); - } else if (Array.isArray($config.y)) { + return xValue.filter(notNull).map((xValue: number) => { + return { + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue: $y(d), + data: d, + }; + }); + } else if (Array.isArray(yValue)) { /* x="prop1" y={["prop2" ,"prop3"]} */ - return $y(d) - .filter(notNull) - .map((yValue: number) => { - const xValue = $x(d); - return { - x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), - y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), - xValue, - yValue: $y(d), - data: d, - }; - }); + return yValue.filter(notNull).map((yValue: number) => { + return { + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue: $y(d), + data: d, + }; + }); } else { /* x="prop1" y="prop2" */ - const xValue = $x(d); - const yValue = $y(d); return { x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), @@ -94,7 +89,10 @@ }) as { x: number; y: number; xValue: any; yValue: any; data: any }[]; $: _links = pointsData.flatMap((d: any) => { - if (Array.isArray($config.x)) { + const xValue = $x(d); + const yValue = $y(d); + + if (Array.isArray(xValue)) { /* x={["prop1" ,"prop2"]} y="prop3" @@ -111,7 +109,7 @@ y: y, }, }; - } else if (Array.isArray($config.y)) { + } else if (Array.isArray(yValue)) { /* x="prop1" y={["prop2" ,"prop3"]} From 5c986de274a75836e6414c3167072d42cd667b3c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 30 Aug 2024 15:24:48 -0400 Subject: [PATCH 091/177] fix(TooltipControls): Fix display of selected options --- .../src/routes/docs/components/Tooltip/TooltipControls.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/TooltipControls.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/TooltipControls.svelte index be3e7c98d..30f405b66 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/TooltipControls.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/TooltipControls.svelte @@ -18,7 +18,7 @@ }; -
+
options.map((x) => x.name).join(', ')} + formatSelected={({ options }) => options.map((x) => x.label).join(', ')} /> Date: Sat, 31 Aug 2024 22:32:57 -0400 Subject: [PATCH 092/177] feat(Points): Add canvas support --- .changeset/little-geese-laugh.md | 5 + .../src/lib/components/Points.svelte | 117 ++++++++++++++---- 2 files changed, 99 insertions(+), 23 deletions(-) create mode 100644 .changeset/little-geese-laugh.md diff --git a/.changeset/little-geese-laugh.md b/.changeset/little-geese-laugh.md new file mode 100644 index 000000000..e36903b16 --- /dev/null +++ b/.changeset/little-geese-laugh.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Points): Add canvas support diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index ee7b2c23a..6fcaa5295 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -1,5 +1,6 @@ - {#if links} - - {#each _links as link} - + {#each _links as link} + + {/each} + + {/if} + + + {#each points as point} + {@const radialPoint = pointRadial(point.x, point.y)} + {/each} {/if} - - - {#each points as point} - {@const radialPoint = pointRadial(point.x, point.y)} - - {/each} - From df1555d809b03fdc81097c0e4977647d96fef8ba Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 31 Aug 2024 22:33:56 -0400 Subject: [PATCH 093/177] docs(ForceText): Use new Points canvas support instead of individual svg Circle instances --- .../docs/examples/ForceText/+page.svelte | 79 +++++++++++-------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte b/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte index 6b4681018..80495ca98 100644 --- a/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/ForceText/+page.svelte @@ -1,7 +1,7 @@ diff --git a/packages/layerchart/src/routes/docs/components/Bar/+page.ts b/packages/layerchart/src/routes/docs/components/Bar/+page.ts new file mode 100644 index 000000000..6f60ad2a9 --- /dev/null +++ b/packages/layerchart/src/routes/docs/components/Bar/+page.ts @@ -0,0 +1,14 @@ +import api from '$lib/components/Bar.svelte?raw&sveld'; +import source from '$lib/components/Bar.svelte?raw'; +import pageSource from './+page.svelte?raw'; + +export async function load() { + return { + meta: { + api, + source, + pageSource, + related: ['components/Bars', 'examples/Bars', 'examples/Columns'], + }, + }; +} diff --git a/packages/layerchart/src/routes/docs/components/Bars/+page.ts b/packages/layerchart/src/routes/docs/components/Bars/+page.ts index 9e2876d8d..f979343fe 100644 --- a/packages/layerchart/src/routes/docs/components/Bars/+page.ts +++ b/packages/layerchart/src/routes/docs/components/Bars/+page.ts @@ -8,7 +8,7 @@ export async function load() { api, source, pageSource, - related: ['examples/Bars', 'examples/Columns', 'examples/Histogram'], + related: ['components/Bar', 'examples/Bars', 'examples/Columns', 'examples/Histogram'], }, }; } From bc51494760ddc824ecf5114fcb755a4b13306f36 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 1 Sep 2024 15:50:59 -0400 Subject: [PATCH 097/177] Provider better AreaChart custom tooltip example --- .../docs/components/AreaChart/+page.svelte | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 9dd6e930f..a1d5f661e 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -11,7 +11,7 @@ Rule, } from 'layerchart'; import { PeriodType } from 'svelte-ux'; - import { format } from '@layerstack/utils'; + import { format, formatDate } from '@layerstack/utils'; import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; @@ -214,12 +214,27 @@
- - - {format(x(data), PeriodType.DayTime)} - - - + + + {y(data)} + + + + {formatDate(x(data), PeriodType.Day)} From 70b99206cb624b998dd82cea568364f457bf61c6 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 1 Sep 2024 18:48:43 -0400 Subject: [PATCH 098/177] fix(Area): Pass `x` override to internal Spline --- .changeset/spotty-moles-rhyme.md | 5 +++++ packages/layerchart/src/lib/components/Area.svelte | 10 +++++++++- 2 files changed, 14 insertions(+), 1 deletion(-) create mode 100644 .changeset/spotty-moles-rhyme.md diff --git a/.changeset/spotty-moles-rhyme.md b/.changeset/spotty-moles-rhyme.md new file mode 100644 index 000000000..ac9454b6e --- /dev/null +++ b/.changeset/spotty-moles-rhyme.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Area): Pass `x` override to internal Spline diff --git a/packages/layerchart/src/lib/components/Area.svelte b/packages/layerchart/src/lib/components/Area.svelte index 1b5a07bbc..7d1705226 100644 --- a/packages/layerchart/src/lib/components/Area.svelte +++ b/packages/layerchart/src/lib/components/Area.svelte @@ -75,7 +75,15 @@ {#if line} - + {/if} From fa81232e8c509041683aa537121f199860191105 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 1 Sep 2024 18:51:03 -0400 Subject: [PATCH 099/177] feat(AreaChart): Add stackSeries support --- .../lib/components/charts/AreaChart.svelte | 37 ++++++++++++++++--- .../docs/components/AreaChart/+page.svelte | 25 +++++++++++++ 2 files changed, 57 insertions(+), 5 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 4a8c5a081..ba2148931 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -1,6 +1,7 @@ d.value)} + y={y ?? + (stackSeries ? (d) => series.map((s, i) => d.stackData[i][1]) : series.map((s) => s.value))} yDomain={[0, null]} yNice padding={{ left: 16, bottom: 16 }} @@ -85,9 +106,10 @@ - {#each series as s} + {#each series as s, i} d.stackData[i][0] : undefined} + y1={stackSeries ? (d) => d.stackData[i][1] : s.value} line={{ class: 'stroke-2', stroke: s.color }} fill={s.color} fill-opacity={0.3} @@ -101,7 +123,12 @@ {#each series as s, i} - + d.stackData[i][1] : s.value} + points={{ fill: s.color }} + lines={i == 0} + {...props.highlight} + /> {/each} diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index a1d5f661e..d398d5a8e 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -201,6 +201,31 @@
+

Stack series

+ + +
+ +
+
+

Labels

From 9d615a12315b8bf9e2504c16493cc70efcc45c64 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 1 Sep 2024 19:59:31 -0400 Subject: [PATCH 100/177] Cleanup and fix CI build --- .../lib/components/charts/AreaChart.svelte | 28 ++++++++++++------- 1 file changed, 18 insertions(+), 10 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index ba2148931..154a88219 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -48,20 +48,28 @@ labels?: Partial>; } = {}; - // TODO: Detect if value is specified as non-string an throw error (or add `key` property series?) - $: seriesKeys = series.map((s) => s.value); - $: stackData = stack().keys(seriesKeys)(chartDataArray(data)) as any[]; - - $: chartData = chartDataArray(data).map((d, i) => { - if (stackSeries) { + let chartData = chartDataArray(data) as Array; + + $: if (stackSeries) { + const seriesKeys = series.map((s) => { + if (typeof s.value === 'string') { + return s.value; + } else { + throw new Error( + `Unsupported series type: ${s.value}. 'stackSeries' currently requires string values` + ); + } + }); + + const stackData = stack().keys(seriesKeys)(chartDataArray(data)) as any[]; + + chartData = chartData.map((d, i) => { return { ...d, stackData: stackData.map((sd) => sd[i]), }; - } else { - return d; - } - }); + }); + } Date: Sun, 1 Sep 2024 20:11:45 -0400 Subject: [PATCH 101/177] feat(AreaChart): Add total to tooltip when using `stackSeries` --- .../src/lib/components/charts/AreaChart.svelte | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 154a88219..c3c37da33 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -2,6 +2,7 @@ import { type ComponentProps } from 'svelte'; import { scaleLinear, scaleTime } from 'd3-scale'; import { stack } from 'd3-shape'; + import { sum } from 'd3-array'; import { format } from '@layerstack/utils'; import Area from '../Area.svelte'; @@ -70,6 +71,8 @@ }; }); } + + // TODO: Should we stack the series the same as how they are defined (so the first is on top), or update the Tooltip to make the stack {/each} + + {#if stackSeries} + + + { + const valueAccessor = accessor(s.value); + return valueAccessor(data); + })} + format="integer" + valueAlign="right" + /> + {/if} From 3e7e26d17330703f23ea6cc11fbd50034f1ea469 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 1 Sep 2024 22:42:40 -0400 Subject: [PATCH 102/177] chore!: Remove `AreaStack` as use cases fully supported by `Area` --- .changeset/neat-schools-bake.md | 5 + .../src/lib/components/AreaStack.svelte | 54 ----- .../src/lib/components/Highlight.svelte | 2 - .../layerchart/src/lib/components/index.ts | 1 - .../layerchart/src/routes/_NavMenu.svelte | 2 - .../docs/components/AreaStack/+page.svelte | 4 - .../routes/docs/components/AreaStack/+page.ts | 14 -- .../docs/components/Tooltip/+page.svelte | 19 +- .../routes/docs/examples/Area/+page.svelte | 116 ++++++++++- .../docs/examples/AreaStack/+page.svelte | 184 ------------------ .../routes/docs/examples/AreaStack/+page.ts | 9 - 11 files changed, 135 insertions(+), 275 deletions(-) create mode 100644 .changeset/neat-schools-bake.md delete mode 100644 packages/layerchart/src/lib/components/AreaStack.svelte delete mode 100644 packages/layerchart/src/routes/docs/components/AreaStack/+page.svelte delete mode 100644 packages/layerchart/src/routes/docs/components/AreaStack/+page.ts delete mode 100644 packages/layerchart/src/routes/docs/examples/AreaStack/+page.svelte delete mode 100644 packages/layerchart/src/routes/docs/examples/AreaStack/+page.ts diff --git a/.changeset/neat-schools-bake.md b/.changeset/neat-schools-bake.md new file mode 100644 index 000000000..967f68487 --- /dev/null +++ b/.changeset/neat-schools-bake.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +chore!: Remove `AreaStack` as use cases fully supported by `Area` diff --git a/packages/layerchart/src/lib/components/AreaStack.svelte b/packages/layerchart/src/lib/components/AreaStack.svelte deleted file mode 100644 index 1bd1650e4..000000000 --- a/packages/layerchart/src/lib/components/AreaStack.svelte +++ /dev/null @@ -1,54 +0,0 @@ - - -{#if line} - - {#each lineData as seriesData} - d[1]} - stroke={$rGet(seriesData)} - {curve} - {defined} - {tweened} - {...line} - /> - {/each} - -{/if} - - - - {#each chartDataArray($data) as seriesData} - d[0]} - y1={(d) => d[1]} - fill={$rGet(seriesData)} - {curve} - {defined} - {opacity} - {tweened} - /> - {/each} - - diff --git a/packages/layerchart/src/lib/components/Highlight.svelte b/packages/layerchart/src/lib/components/Highlight.svelte index 086693b82..52790e757 100644 --- a/packages/layerchart/src/lib/components/Highlight.svelte +++ b/packages/layerchart/src/lib/components/Highlight.svelte @@ -61,8 +61,6 @@ /** Set to false to disable spring transitions */ export let motion = true; - // TODO: Fix circle points being backwards for stack (see AreaStack) - const _x = accessor(x); const _y = accessor(y); diff --git a/packages/layerchart/src/lib/components/index.ts b/packages/layerchart/src/lib/components/index.ts index 566681db9..b0805d696 100644 --- a/packages/layerchart/src/lib/components/index.ts +++ b/packages/layerchart/src/lib/components/index.ts @@ -5,7 +5,6 @@ export * from './charts/index.js'; export { default as Arc } from './Arc.svelte'; export { default as Area } from './Area.svelte'; -export { default as AreaStack } from './AreaStack.svelte'; export { default as Axis } from './Axis.svelte'; export { default as Bar } from './Bar.svelte'; export { default as Bars } from './Bars.svelte'; diff --git a/packages/layerchart/src/routes/_NavMenu.svelte b/packages/layerchart/src/routes/_NavMenu.svelte index d87537d55..ab8b36693 100644 --- a/packages/layerchart/src/routes/_NavMenu.svelte +++ b/packages/layerchart/src/routes/_NavMenu.svelte @@ -14,7 +14,6 @@ 'Cartesian & Polar': [ 'Arc', 'Area', - 'AreaStack', { label: 'Bar Chart (Vertical)', value: 'Columns' }, { label: 'Bar Chart (Horizontal)', value: 'Bars' }, 'Candlestick', @@ -71,7 +70,6 @@ Primitives: ['Arc', 'Bar', 'Circle', 'Group', 'Line', 'Point', 'Rect', 'Text'], Marks: [ 'Area', - 'AreaStack', 'Bars', 'Calendar', 'Hull', diff --git a/packages/layerchart/src/routes/docs/components/AreaStack/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaStack/+page.svelte deleted file mode 100644 index f5e63b239..000000000 --- a/packages/layerchart/src/routes/docs/components/AreaStack/+page.svelte +++ /dev/null @@ -1,4 +0,0 @@ - diff --git a/packages/layerchart/src/routes/docs/components/AreaStack/+page.ts b/packages/layerchart/src/routes/docs/components/AreaStack/+page.ts deleted file mode 100644 index de7cfd68b..000000000 --- a/packages/layerchart/src/routes/docs/components/AreaStack/+page.ts +++ /dev/null @@ -1,14 +0,0 @@ -import api from '$lib/components/AreaStack.svelte?raw&sveld'; -import source from '$lib/components/AreaStack.svelte?raw'; -import pageSource from './+page.svelte?raw'; - -export async function load() { - return { - meta: { - api, - source, - pageSource, - related: ['examples/AreaStack'], - }, - }; -} diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index 6b4857cca..6a566039e 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -1,10 +1,10 @@ @@ -436,6 +441,113 @@
+

Stack

+ + +
+ d.data.date} + xScale={scaleTime()} + y={[0, 1]} + yNice + r="key" + rScale={scaleOrdinal()} + rDomain={Object.keys(fruitColors)} + rRange={Object.values(fruitColors)} + padding={{ left: 16, bottom: 24 }} + tooltip={{ mode: 'bisect-x' }} + let:data + let:rGet + let:rScale + > + + + format(d, PeriodType.Day, { variant: 'short' })} + rule + /> + + {#each stackData as seriesData} + {@const color = rGet(seriesData)} + d[0]} + y1={(d) => d[1]} + line={{ stroke: color, 'stroke-width': 2 }} + fill={color} + fill-opacity={0.2} + /> + {/each} + + + + + + {formatDate(data.data.date, 'eee, MMMM do')} + + {#each keys as key} + + {/each} + + + +
+
+ +

Stack with gradient

+ + +
+ d.data.date} + xScale={scaleTime()} + y={[0, 1]} + yNice + padding={{ left: 16, bottom: 24 }} + > + + + format(d, PeriodType.Day, { variant: 'short' })} + rule + /> + {@const primaryColors = [ + 'hsl(var(--color-danger-500))', + 'hsl(var(--color-success-500))', + 'hsl(var(--color-info-500))', + ]} + {@const secondaryColors = [ + 'hsl(var(--color-danger-500) / 10%)', + 'hsl(var(--color-success-500) / 10%)', + 'hsl(var(--color-info-500) / 10%)', + ]} + + {#each chartDataArray(stackData) as seriesData, index} + {@const primaryColor = primaryColors[index]} + {@const secondaryColor = secondaryColors[index]} + + + d[0]} + y1={(d) => d[1]} + fill={url} + fill-opacity={0.5} + line={{ stroke: primaryColor }} + /> + + {/each} + + +
+
+

Clip tween on mount

diff --git a/packages/layerchart/src/routes/docs/examples/AreaStack/+page.svelte b/packages/layerchart/src/routes/docs/examples/AreaStack/+page.svelte deleted file mode 100644 index d1f5c9569..000000000 --- a/packages/layerchart/src/routes/docs/examples/AreaStack/+page.svelte +++ /dev/null @@ -1,184 +0,0 @@ - - -

Examples

- -

Basic

- - -
- d.data.date} - xScale={scaleTime()} - y={[0, 1]} - yNice - r="key" - rScale={scaleOrdinal()} - rDomain={keys} - rRange={['hsl(var(--color-danger))', 'hsl(var(--color-success))', 'hsl(var(--color-info))']} - padding={{ left: 16, bottom: 24 }} - > - - - formatDate(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - - -
-
- -

With Tooltip and Highlight

- - -
- d.data.date} - xScale={scaleTime()} - y={[0, 1]} - yNice - r="key" - rScale={scaleOrdinal()} - rDomain={keys} - rRange={['hsl(var(--color-danger))', 'hsl(var(--color-success))', 'hsl(var(--color-info))']} - padding={{ left: 16, bottom: 24 }} - tooltip={{ mode: 'bisect-x' }} - > - - - formatDate(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - - - - {format(data.data.date, 'eee, MMMM do')} - - {#each keys as key} - - {/each} - - - -
-
- - - - -

Slot with gradient

- - -
- d.data.date} - xScale={scaleTime()} - y={[0, 1]} - yNice - padding={{ left: 16, bottom: 24 }} - > - - - formatDate(d, PeriodType.Day, { variant: 'short' })} - rule - /> - - {@const primaryColorScale = scaleOrdinal([ - 'hsl(var(--color-danger-500))', - 'hsl(var(--color-success-500))', - 'hsl(var(--color-info-500))', - ])} - {@const secondaryColorScale = scaleOrdinal([ - 'hsl(var(--color-danger-500) / 10%)', - 'hsl(var(--color-success-500) / 10%)', - 'hsl(var(--color-info-500) / 10%)', - ])} - - {#each chartDataArray(data) as seriesData, index} - {@const primaryColor = primaryColorScale(String(index))} - {@const secondaryColor = secondaryColorScale(String(index))} - - - d[0]} - y1={(d) => d[1]} - fill={url} - fill-opacity={0.5} - line={{ stroke: primaryColor }} - /> - - {/each} - - - -
-
diff --git a/packages/layerchart/src/routes/docs/examples/AreaStack/+page.ts b/packages/layerchart/src/routes/docs/examples/AreaStack/+page.ts deleted file mode 100644 index 48dcda64e..000000000 --- a/packages/layerchart/src/routes/docs/examples/AreaStack/+page.ts +++ /dev/null @@ -1,9 +0,0 @@ -import pageSource from './+page.svelte?raw'; - -export async function load() { - return { - meta: { - pageSource, - }, - }; -} From bd6687b9c65f96f853d45cac1c2475484e26520b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 2 Sep 2024 09:29:39 -0400 Subject: [PATCH 103/177] Remove using `accessor()` before passing x/y accessors to LayerCake to allow introspection of values via `config` (otherwise are always functions) --- .changeset/tasty-pigs-eat.md | 5 ----- packages/layerchart/src/lib/components/Chart.svelte | 4 ++-- 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 .changeset/tasty-pigs-eat.md diff --git a/.changeset/tasty-pigs-eat.md b/.changeset/tasty-pigs-eat.md deleted file mode 100644 index c68fd8b88..000000000 --- a/.changeset/tasty-pigs-eat.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -'layerchart': patch ---- - -feat(Chart): Use `accessor()` util before passsing x/y accessors to LayerCake (i.e. support `x="keys[0]"`) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index 04ea297e7..efe646061 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -257,9 +257,9 @@ Date: Mon, 2 Sep 2024 09:33:13 -0400 Subject: [PATCH 104/177] feat(Area): Simplify usage when `y` accessor set to `[0,1]` --- .../layerchart/src/lib/components/Area.svelte | 36 +++++++++++++++---- .../src/lib/components/Spline.svelte | 11 ++++-- .../docs/components/Tooltip/+page.svelte | 2 -- .../routes/docs/examples/Area/+page.svelte | 11 +----- 4 files changed, 40 insertions(+), 20 deletions(-) diff --git a/packages/layerchart/src/lib/components/Area.svelte b/packages/layerchart/src/lib/components/Area.svelte index 7d1705226..261f3aee4 100644 --- a/packages/layerchart/src/lib/components/Area.svelte +++ b/packages/layerchart/src/lib/components/Area.svelte @@ -15,7 +15,7 @@ import { accessor, type Accessor } from '../utils/common.js'; import { isScaleBand } from '../utils/scales.js'; - const { data: contextData, xScale, yScale, xGet, yGet, yRange } = chartContext(); + const { data: contextData, xScale, yScale, x: contextX, y, yRange, config } = chartContext(); /** Override data instead of using context */ export let data: any = undefined; @@ -59,13 +59,37 @@ $: { const path = radial ? areaRadial() - .angle((d) => (x ? $xScale(_x(d)) : $xGet(d))) + .angle((d) => $xScale(x ? _x(d) : $contextX(d))) .innerRadius((d) => (y0 ? $yScale(_y0(d)) : max($yRange))) - .outerRadius((d) => (y1 ? $yScale(_y1(d)) : $yGet(d))) + .outerRadius((d) => $yScale(y1 ? _y1(d) : $y(d))) : d3Area() - .x((d) => (x ? $xScale(_x(d)) : $xGet(d)) + xOffset) - .y0((d) => (y0 ? $yScale(_y0(d)) : max($yRange)) + yOffset) - .y1((d) => (y1 ? $yScale(_y1(d)) : $yGet(d)) + yOffset); + .x((d) => $xScale(x ? _x(d) : $contextX(d)) + xOffset) + .y0((d) => { + let value = max($yRange)!; + if (y0) { + value = $yScale(_y0(d)); + } else if (Array.isArray($config.y) && $config.y[0] === 0) { + // Use first value if `y` defined as an array (ex. ``) + value = $yScale($y(d)[0]); + } + + return value + yOffset; + }) + + .y1((d) => { + let value = max($yRange)!; + if (y1) { + value = $yScale(_y1(d)); + } else if (Array.isArray($config.y) && $config.y[1] === 1) { + // Use second value if `y` defined as an array (ex. ``) + value = $yScale($y(d)[1]); + } else { + // Expect single value defined for `y` (ex. ``) + value = $yScale($y(d)); + } + + return value + yOffset; + }); if (curve) path.curve(curve); if (defined) path.defined(defined); diff --git a/packages/layerchart/src/lib/components/Spline.svelte b/packages/layerchart/src/lib/components/Spline.svelte index 83760c7d6..7543e9661 100644 --- a/packages/layerchart/src/lib/components/Spline.svelte +++ b/packages/layerchart/src/lib/components/Spline.svelte @@ -9,6 +9,7 @@ import type { CurveFactory, CurveFactoryLineOnly, Line } from 'd3-shape'; // import { interpolateString } from 'd3-interpolate'; import { interpolatePath } from 'd3-interpolate-path'; + import { max } from 'd3-array'; import { cls } from '@layerstack/tailwind'; import { chartContext } from './ChartContext.svelte'; @@ -51,12 +52,18 @@ export let defined: Parameters['defined']>[0] | undefined = undefined; function getScaleValue(data: any, scale: typeof $xScale | typeof $yScale, accessor: Function) { + let value = accessor(data); + + if (Array.isArray(value)) { + value = max(value); + } + if (scale.domain().length) { // If scale is defined with domain, map value - return scale(accessor(data)); + return scale(value); } else { // Use raw value - return accessor(data); + return value; } } diff --git a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte index 6a566039e..f202d9ec0 100644 --- a/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Tooltip/+page.svelte @@ -580,8 +580,6 @@ {@const color = rGet(seriesData)} d[0]} - y1={(d) => d[1]} line={{ stroke: color, 'stroke-width': 2 }} fill={color} fill-opacity={0.2} diff --git a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte index caada1deb..a0ff7e07f 100644 --- a/packages/layerchart/src/routes/docs/examples/Area/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Area/+page.svelte @@ -474,8 +474,6 @@ {@const color = rGet(seriesData)} d[0]} - y1={(d) => d[1]} line={{ stroke: color, 'stroke-width': 2 }} fill={color} fill-opacity={0.2} @@ -533,14 +531,7 @@ {@const secondaryColor = secondaryColors[index]} - d[0]} - y1={(d) => d[1]} - fill={url} - fill-opacity={0.5} - line={{ stroke: primaryColor }} - /> + {/each} From 131689f74647caaf256072be03d366c7b37dabd8 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 2 Sep 2024 09:40:16 -0400 Subject: [PATCH 105/177] fix(AreaChart): Reverse series order so tooltip items match stacks --- .../layerchart/src/lib/components/charts/AreaChart.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index c3c37da33..45aedd5ba 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -71,8 +71,6 @@ }; }); } - - // TODO: Should we stack the series the same as how they are defined (so the first is on top), or update the Tooltip to make the stack {format(x(data))} - {#each series as s} + + {@const seriesItems = stackSeries ? [...series].reverse() : series} + {#each seriesItems as s} {@const valueAccessor = accessor(s.value)} Date: Mon, 2 Sep 2024 16:50:16 -0400 Subject: [PATCH 106/177] Add type hack until LayerCake can support `Accessor` or similar. Fix CI build --- packages/layerchart/src/lib/components/Chart.svelte | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index efe646061..3bf57f9c9 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -37,6 +37,8 @@ import TransformContext from './TransformContext.svelte'; import { geoFitObjectTransform } from '$lib/utils/geo.js'; + type LayerCakeProps = ComponentProps; + type DomainType = | (number | string | Date | null | undefined)[] | Function @@ -253,13 +255,17 @@ onMount(() => { isMounted = true; }); + + // TODO: Hack until LayerCake has better typings (`Accessor`) + $: _x = x as LayerCakeProps['x']; + $: _y = y as LayerCakeProps['y']; Date: Mon, 2 Sep 2024 17:19:54 -0400 Subject: [PATCH 107/177] feat(BarChart): Add `stackSeries` support --- .../lib/components/charts/AreaChart.svelte | 7 +- .../src/lib/components/charts/BarChart.svelte | 63 +++++++++++++--- .../docs/components/BarChart/+page.svelte | 71 ++++++++++++++++++- 3 files changed, 128 insertions(+), 13 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 45aedd5ba..2b2dd1993 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -26,9 +26,6 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; - /** Stack instead of overlap series */ - export let stackSeries = false; - export let series: { label?: string; value: Accessor; @@ -36,6 +33,9 @@ props?: Partial>; }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; + /** Stack instead of overlap series */ + export let stackSeries = false; + export let labels: ComponentProps | boolean = false; // Default xScale based on first data's `x` value @@ -50,7 +50,6 @@ } = {}; let chartData = chartDataArray(data) as Array; - $: if (stackSeries) { const seriesKeys = series.map((s) => { if (typeof s.value === 'string') { diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index eebcdced2..989cdb528 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -1,6 +1,8 @@ s.value)} + data={chartData} + x={x ?? + (stackSeries ? (d) => series.map((s, i) => d.stackData[i][1]) : series.map((s) => s.value))} {xScale} {xDomain} xNice={orientation === 'horizontal'} - y={y ?? series.map((d) => d.value)} + y={y ?? + (stackSeries ? (d) => series.map((s, i) => d.stackData[i][1]) : series.map((s) => s.value))} {yScale} {yDomain} yNice={orientation === 'vertical'} @@ -98,10 +128,10 @@ - {#each series as s} + {#each series as s, i} d.stackData[i] : s.value} + y={isVertical ? (stackSeries ? (d) => d.stackData[i] : s.value) : undefined} radius={4} strokeWidth={1} fill={s.color} @@ -126,15 +156,32 @@ {format(isVertical ? x(data) : y(data))} - {#each series as s} + + {@const seriesItems = stackSeries ? [...series].reverse() : series} + {#each seriesItems as s} {@const valueAccessor = accessor(s.value)} {/each} + + {#if stackSeries} + + + { + const valueAccessor = accessor(s.value); + return valueAccessor(data); + })} + format="integer" + valueAlign="right" + /> + {/if} diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index 8740f2918..1c07a34ac 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -5,7 +5,7 @@ import Preview from '$lib/docs/Preview.svelte'; import Blockquote from '$lib/docs/Blockquote.svelte'; - import { createDateSeries } from '$lib/utils/genData.js'; + import { createDateSeries, wideData } from '$lib/utils/genData.js'; export let data; @@ -227,6 +227,75 @@ +

Stack series

+ + +
+ +
+
+ +

Stack series (horizontal)

+ + +
+ +
+
+

Labels

From 36565d9e3eb819ea050274e74a573419c86ec359 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 08:00:06 -0400 Subject: [PATCH 108/177] fix(Point): Restoring passing `class` to svg circle after supporting canvas --- packages/layerchart/src/lib/components/Points.svelte | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index ec47a66ec..6c4f2548b 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -219,6 +219,7 @@ cy={radial ? radialPoint[1] : point.y} {r} fill={$config.r ? $rGet(point.data) : null} + class={className} {...$$restProps} /> {/each} From d56f7c39f80faca214886fc695ceca044aa1fcc3 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 08:53:26 -0400 Subject: [PATCH 109/177] feat(Chart): Add `radial` prop to enable radial instead of cartesian coordinates at the context level instead of requiring each component to opt-in (Area, Points, Spline). --- .../layerchart/src/lib/components/Area.svelte | 16 +++++++++---- .../src/lib/components/Chart.svelte | 9 ++++++- .../src/lib/components/ChartContext.svelte | 24 +++++++++++++------ .../src/lib/components/Points.svelte | 10 ++++---- .../src/lib/components/Spline.svelte | 11 ++++----- .../docs/examples/RadialLine/+page.svelte | 12 +++++----- 6 files changed, 50 insertions(+), 32 deletions(-) diff --git a/packages/layerchart/src/lib/components/Area.svelte b/packages/layerchart/src/lib/components/Area.svelte index 261f3aee4..adaab3a69 100644 --- a/packages/layerchart/src/lib/components/Area.svelte +++ b/packages/layerchart/src/lib/components/Area.svelte @@ -15,7 +15,16 @@ import { accessor, type Accessor } from '../utils/common.js'; import { isScaleBand } from '../utils/scales.js'; - const { data: contextData, xScale, yScale, x: contextX, y, yRange, config } = chartContext(); + const { + data: contextData, + xScale, + yScale, + x: contextX, + y, + yRange, + config, + radial, + } = chartContext(); /** Override data instead of using context */ export let data: any = undefined; @@ -23,9 +32,6 @@ /** Pass `` explicitly instead of calculating from data / context */ export let pathData: string | undefined | null = undefined; - /** Use radial instead of cartesian area generator, mapping `x` to `angle` and `y0`/`y1 to `innerRadius`/`outerRadius. Radial lines are positioned relative to the origin, use transform (ex. ``) to change the origin */ - export let radial = false; - /** Override x accessor */ export let x: Accessor = undefined; @@ -57,7 +63,7 @@ : false; $: tweened_d = motionStore('', { tweened: tweenedOptions }); $: { - const path = radial + const path = $radial ? areaRadial() .angle((d) => $xScale(x ? _x(d) : $contextX(d))) .innerRadius((d) => (y0 ? $yScale(_y0(d)) : max($yRange))) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index 3bf57f9c9..3bed0ae35 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -187,6 +187,10 @@ /** y value guaranteed to be visible in yDomain. Useful with optional negative values since `yDomain={[0, null]}` would ignore negative values */ yBaseline?: typeof xBaseline; + /* Props passed to ChartContext */ + /** Use radial instead of cartesian coordinates, mapping `x` to `angle` and `y`` to radial. Radial lines are positioned relative to the origin, use transform (ex. ``) to change the origin */ + radial?: typeof radial; + /** Props passed to GeoContext */ geo?: typeof geo; @@ -235,6 +239,9 @@ */ $: yReverse = yScale ? !isScaleBand(yScale) : true; + /** Use radial instead of cartesian coordinates, mapping `x` to `angle` and `y`` to radial. Radial lines are positioned relative to the origin, use transform (ex. ``) to change the origin */ + export let radial = false; + /** Props passed to GeoContext */ export let geo: Partial> | undefined = undefined; @@ -296,7 +303,7 @@ ? geoFitObjectTransform(geo.projection(), [width, height], geo.fitGeojson) : undefined} - + {#key isMounted} ; export type ChartContext = LayerCakeContext & { - // TODO: consider extending with additional values + // Additional context values + radial: Readable; }; export function chartContext() { @@ -99,13 +100,22 @@ - + diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index 6c4f2548b..b87778882 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -24,6 +24,7 @@ containerWidth, containerHeight, config, + radial, } = context; type Offset = number | ((value: number, context: any) => number) | undefined; @@ -35,9 +36,6 @@ export let offsetX: Offset = undefined; export let offsetY: Offset = undefined; - /** Use radial instead of cartesian line generator, mapping `x` to `angle` and `y` to `radius`. Radial points are positioned relative to the origin, use transform (ex. ``) to change the origin */ - export let radial = false; - /** Enable showing links between related points (array x/y accessors) */ export let links: boolean | Partial> = false; @@ -62,7 +60,7 @@ return offset(value, context); } else if (offset != null) { return offset; - } else if (isScaleBand(scale) && !radial) { + } else if (isScaleBand(scale) && !$radial) { return scale.bandwidth() / 2; } else { return 0; @@ -215,8 +213,8 @@ {#each points as point} {@const radialPoint = pointRadial(point.x, point.y)} ` explicitly instead of calculating from data / context */ export let pathData: string | undefined | null = undefined; - /** Use radial instead of cartesian line generator, mapping `x` to `angle` and `y` to `radius`. Radial lines are positioned relative to the origin, use transform (ex. ``) to change the origin */ - export let radial = false; - - /** Override `x` accessor from Chart context. Applies to `angle` when `radial=true` */ + /** Override `x` accessor from Chart context */ export let x: Accessor = undefined; - /** Override `y` accessor from Chart context. Applies to `radius` when `radial=true` */ + /** Override `y` accessor from Chart context */ export let y: Accessor = undefined; /** Interpolate path data using d3-interpolate-path. Works best without `draw` enabled */ @@ -78,7 +75,7 @@ $: tweenedOptions = tweened ? { interpolate: interpolatePath, ...tweened } : false; $: tweened_d = motionStore('', { tweened: tweenedOptions }); $: { - const path = radial + const path = $radial ? lineRadial() .angle((d) => getScaleValue(d, $xScale, x ? _x : $contextX)) .radius((d) => getScaleValue(d, $yScale, y ? _y : $contextY)) diff --git a/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte b/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte index ec95ac0a4..0589ed494 100644 --- a/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte @@ -45,6 +45,7 @@ yRange={({ height }) => [0, height / 2]} yPadding={[0, 10]} padding={{ top: 32, bottom: 8 }} + radial > @@ -55,8 +56,8 @@ format={(d) => ''} /> - - + +
@@ -74,19 +75,18 @@ xRange={[0, 2 * Math.PI]} y={['minmin', 'maxmax']} yRange={({ height }) => [height / 5, height / 2]} + radial > - d.avg} radial curve={curveCatmullRom} class="stroke-primary" /> + d.avg} curve={curveCatmullRom} class="stroke-primary" /> d.min} y1={(d) => d.max} curve={curveCatmullRomClosed} class="fill-primary/20" /> d.minmin} y1={(d) => d.maxmax} curve={curveCatmullRomClosed} @@ -114,6 +114,7 @@ yPadding={[0, 20]} zDomain={[1940, 2024]} zRange={[0.1, 0.2]} + radial let:zScale > @@ -121,7 +122,6 @@ {#each flatGroup(data.dailyTemperatures, (d) => d.year) as [year, yearData]} Date: Wed, 4 Sep 2024 09:15:39 -0400 Subject: [PATCH 110/177] feat(Svg): Add `center` to conveniently center children, useful for radial layouts without requiring `Group` wrapper. Remove exta `g` element when no transform is applied --- .changeset/polite-cooks-tease.md | 5 + .../src/lib/components/layout/Svg.svelte | 17 +- .../routes/docs/components/Arc/+page.svelte | 122 ++++---- .../docs/components/LineChart/+page.svelte | 50 +++- .../src/routes/docs/examples/Arc/+page.svelte | 270 +++++++++--------- .../examples/ForceDisjointGraph/+page.svelte | 22 +- .../docs/examples/ForceLattice/+page.svelte | 22 +- .../docs/examples/ForceTree/+page.svelte | 40 ++- .../docs/examples/RadialLine/+page.svelte | 94 +++--- .../docs/examples/Sunburst/+page.svelte | 50 ++-- 10 files changed, 364 insertions(+), 328 deletions(-) create mode 100644 .changeset/polite-cooks-tease.md diff --git a/.changeset/polite-cooks-tease.md b/.changeset/polite-cooks-tease.md new file mode 100644 index 000000000..ecd4ccca8 --- /dev/null +++ b/.changeset/polite-cooks-tease.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +feat(Svg): Add `center` to conveniently center children, useful for radial layouts without requiring `Group` wrapper diff --git a/packages/layerchart/src/lib/components/layout/Svg.svelte b/packages/layerchart/src/lib/components/layout/Svg.svelte index 1fc570842..d4a2fe7ed 100644 --- a/packages/layerchart/src/lib/components/layout/Svg.svelte +++ b/packages/layerchart/src/lib/components/layout/Svg.svelte @@ -31,11 +31,18 @@ /** Shorthand to set the contents of `` for accessibility. You can also set arbitrary HTML via the "title" slot but this is a convenient shorthand. If you use the "title" slot, this prop is ignored. */ export let title: string | undefined = undefined; + /** + * Translate children to center, useful for radial layouts + */ + export let center: boolean | 'x' | 'y' = false; + const { containerWidth, containerHeight, width, height, padding } = chartContext(); const { mode, scale, translate } = transformContext(); - let transform = ''; + let transform = center + ? `translate(${center === 'x' || center === true ? $width / 2 : 0}, ${center === 'y' || center === true ? $height / 2 : 0})` + : ''; $: if (mode === 'canvas') { const center = { x: $width / 2, y: $height / 2 }; const newTranslate = { @@ -79,8 +86,12 @@ class="layercake-layout-svg_g" transform="translate({$padding.left}, {$padding.top})" > - + {#if transform} + + + + {:else} - + {/if} diff --git a/packages/layerchart/src/routes/docs/components/Arc/+page.svelte b/packages/layerchart/src/routes/docs/components/Arc/+page.svelte index 54fe676aa..3ac5928f1 100644 --- a/packages/layerchart/src/routes/docs/components/Arc/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Arc/+page.svelte @@ -1,6 +1,6 @@
- - - {#key spring} - - - - - - {/key} - + + {#key spring} + + + + + + {/key}
@@ -117,44 +115,42 @@
- - - - - - + - - - - - - - + + + + + +
diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index 378fd6c93..af2c874aa 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -1,5 +1,15 @@

Examples

+

Radar

+ + +
+ d.name)} + y="value" + yPadding={[0, 10]} + padding={{ top: 32, bottom: 8 }} + radial + props={{ + spline: { + class: 'stroke-primary fill-primary/20', + }, + axisLeft: { + ticks: [0, 5, 10], + format: (d) => '', + }, + }} + > + + + + +
+
+

Basic

diff --git a/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte b/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte index b80175614..e990ee4ba 100644 --- a/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Arc/+page.svelte @@ -51,30 +51,28 @@
- - - - - - - - - + + + + + + + @@ -86,35 +84,33 @@
- - - - - - + + + +
@@ -129,36 +125,34 @@
- - - - {#each { length: segments } as _, segmentIndex} - {@const segmentAngle = (2 * Math.PI) / segments} - {@const startAngle = segmentIndex * segmentAngle} - {@const endAngle = (segmentIndex + 1) * segmentAngle} - - {/each} - - - - + + + {#each { length: segments } as _, segmentIndex} + {@const segmentAngle = (2 * Math.PI) / segments} + {@const startAngle = segmentIndex * segmentAngle} + {@const endAngle = (segmentIndex + 1) * segmentAngle} + + {/each} + + +
@@ -169,30 +163,28 @@
- - - {#each { length: layerCount } as _, layerIndex} - {@const layer = layerIndex + 1} - {#each { length: divisions } as _, segmentIndex} - {@const segmentAngle = (2 * Math.PI) / divisions} - {@const startAngle = segmentIndex * segmentAngle} - {@const endAngle = (segmentIndex + 1) * segmentAngle} - {@const color = wheelSegmentColor(startAngle, layer)} - tooltip?.show(e, color)} - on:pointerleave={(e) => tooltip?.hide()} - /> - {/each} + + {#each { length: layerCount } as _, layerIndex} + {@const layer = layerIndex + 1} + {#each { length: divisions } as _, segmentIndex} + {@const segmentAngle = (2 * Math.PI) / divisions} + {@const startAngle = segmentIndex * segmentAngle} + {@const endAngle = (segmentIndex + 1) * segmentAngle} + {@const color = wheelSegmentColor(startAngle, layer)} + tooltip?.show(e, color)} + on:pointerleave={(e) => tooltip?.hide()} + /> {/each} - + {/each} {data} @@ -213,40 +205,38 @@
- - - {#if show} - - - - {/if} - + + {#if show} + + + + {/if}
diff --git a/packages/layerchart/src/routes/docs/examples/ForceDisjointGraph/+page.svelte b/packages/layerchart/src/routes/docs/examples/ForceDisjointGraph/+page.svelte index 3a2c88e68..b488e5ad9 100644 --- a/packages/layerchart/src/routes/docs/examples/ForceDisjointGraph/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/ForceDisjointGraph/+page.svelte @@ -4,7 +4,7 @@ import { scaleOrdinal } from 'd3-scale'; import { schemeCategory10 } from 'd3-scale-chromatic'; - import { Chart, Circle, ForceSimulation, Group, Link, Svg } from 'layerchart'; + import { Chart, Circle, ForceSimulation, Link, Svg } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; @@ -26,7 +26,7 @@
- + - - {#key nodes} - {#each links as link} - - {/each} - {/key} - - {#each nodes as node} - + {#key nodes} + {#each links as link} + {/each} - + {/key} + + {#each nodes as node} + + {/each} diff --git a/packages/layerchart/src/routes/docs/examples/ForceLattice/+page.svelte b/packages/layerchart/src/routes/docs/examples/ForceLattice/+page.svelte index c89e68727..5bf98a343 100644 --- a/packages/layerchart/src/routes/docs/examples/ForceLattice/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/ForceLattice/+page.svelte @@ -2,7 +2,7 @@ import { forceManyBody, forceLink } from 'd3-force'; import { curveLinear } from 'd3-shape'; - import { Chart, Circle, ForceSimulation, Group, Link, Svg } from 'layerchart'; + import { Chart, Circle, ForceSimulation, Link, Svg } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; @@ -25,7 +25,7 @@
- + - - {#key nodes} - {#each links as link} - - {/each} - {/key} - - {#each nodes as node} - + {#key nodes} + {#each links as link} + {/each} - + {/key} + + {#each nodes as node} + + {/each} diff --git a/packages/layerchart/src/routes/docs/examples/ForceTree/+page.svelte b/packages/layerchart/src/routes/docs/examples/ForceTree/+page.svelte index 5993831fd..acb6e8fa2 100644 --- a/packages/layerchart/src/routes/docs/examples/ForceTree/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/ForceTree/+page.svelte @@ -2,7 +2,7 @@ import { hierarchy } from 'd3-hierarchy'; import { forceX, forceY, forceManyBody, forceLink } from 'd3-force'; - import { Chart, Circle, ForceSimulation, Group, Link, Svg, Tooltip } from 'layerchart'; + import { Chart, Circle, ForceSimulation, Link, Svg, Tooltip } from 'layerchart'; import { cls } from '@layerstack/tailwind'; import Preview from '$lib/docs/Preview.svelte'; @@ -24,7 +24,7 @@
- + - - {#key nodes} - {#each links as link} - - {/each} - {/key} - - {#each nodes as node} - tooltip.show(e, node)} - on:pointerleave={tooltip.hide} - /> + {#key nodes} + {#each links as link} + {/each} - + {/key} + + {#each nodes as node} + tooltip.show(e, node)} + on:pointerleave={tooltip.hide} + /> + {/each} diff --git a/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte b/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte index 0589ed494..88c5907a7 100644 --- a/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte @@ -5,7 +5,7 @@ import { Field, PeriodType, ToggleGroup, ToggleOption } from 'svelte-ux'; import { cls } from '@layerstack/tailwind'; - import { Area, Axis, Chart, Group, Points, Spline, Svg } from 'layerchart'; + import { Area, Axis, Chart, Points, Spline, Svg } from 'layerchart'; import Preview from '$lib/docs/Preview.svelte'; @@ -47,18 +47,16 @@ padding={{ top: 32, bottom: 8 }} radial > - - - ''} - /> - - - - + + ''} + /> + + +
@@ -77,24 +75,22 @@ yRange={({ height }) => [height / 5, height / 2]} radial > - - - d.avg} curve={curveCatmullRom} class="stroke-primary" /> - d.min} - y1={(d) => d.max} - curve={curveCatmullRomClosed} - class="fill-primary/20" - /> - d.minmin} - y1={(d) => d.maxmax} - curve={curveCatmullRomClosed} - class="fill-primary/20" - /> - - v + '° F'} /> - + + d.avg} curve={curveCatmullRom} class="stroke-primary" /> + d.min} + y1={(d) => d.max} + curve={curveCatmullRomClosed} + class="fill-primary/20" + /> + d.minmin} + y1={(d) => d.maxmax} + curve={curveCatmullRomClosed} + class="fill-primary/20" + /> + + v + '° F'} />
@@ -117,25 +113,23 @@ radial let:zScale > - - - {#each flatGroup(data.dailyTemperatures, (d) => d.year) as [year, yearData]} - - {/each} - - v + '° F'} /> - + + {#each flatGroup(data.dailyTemperatures, (d) => d.year) as [year, yearData]} + + {/each} + + v + '° F'} />
diff --git a/packages/layerchart/src/routes/docs/examples/Sunburst/+page.svelte b/packages/layerchart/src/routes/docs/examples/Sunburst/+page.svelte index 558cc9317..c65689615 100644 --- a/packages/layerchart/src/routes/docs/examples/Sunburst/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Sunburst/+page.svelte @@ -5,7 +5,7 @@ import * as chromatic from 'd3-scale-chromatic'; import { hsl } from 'd3-color'; - import { Arc, Bounds, Chart, Group, Partition, Svg, Tooltip, findAncestor } from 'layerchart'; + import { Arc, Bounds, Chart, Partition, Svg, Tooltip, findAncestor } from 'layerchart'; import { Breadcrumb, Button, Field, ToggleGroup, ToggleOption } from 'svelte-ux'; import { format, sortFunc, compoundSortFunc } from '@layerstack/utils'; @@ -73,7 +73,7 @@
- + ({ @@ -87,30 +87,28 @@ let:yScale > - - {#each nodes as node} - {@const nodeColor = getNodeColor(node, colorBy)} - { - selected = node; - }} - on:pointermove={(e) => tooltip.show(e, node)} - on:pointerleave={tooltip.hide} - > - - - {/each} - + {#each nodes as node} + {@const nodeColor = getNodeColor(node, colorBy)} + { + selected = node; + }} + on:pointermove={(e) => tooltip.show(e, node)} + on:pointerleave={tooltip.hide} + > + + + {/each} From 4df34196a6617f6267bbd78a52313744abfc2a69 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 09:23:09 -0400 Subject: [PATCH 111/177] Rename `axisBottom` / `axisLeft` to `xAxis` / `yAxis` and begin to support radial LineChart --- .../lib/components/charts/AreaChart.svelte | 8 ++--- .../src/lib/components/charts/BarChart.svelte | 8 ++--- .../lib/components/charts/LineChart.svelte | 31 ++++++++++++++----- .../lib/components/charts/ScatterChart.svelte | 8 ++--- .../docs/components/BarChart/+page.svelte | 16 +++++----- .../docs/components/LineChart/+page.svelte | 2 +- 6 files changed, 44 insertions(+), 29 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 2b2dd1993..10fa7cddd 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -42,8 +42,8 @@ $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear(); export let props: { - axisLeft?: Partial>; - axisBottom?: Partial>; + xAxis?: Partial>; + yAxis?: Partial>; area?: Partial>; highlight?: Partial>; labels?: Partial>; @@ -101,13 +101,13 @@ grid rule format={(value) => format(value, undefined, { variant: 'short' })} - {...props.axisLeft} + {...props.yAxis} /> format(value, undefined, { variant: 'short' })} - {...props.axisBottom} + {...props.xAxis} /> diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 989cdb528..2eb57415f 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -51,8 +51,8 @@ $: yDomain = isVertical ? [0, null] : undefined; export let props: { - axisLeft?: Partial>; - axisBottom?: Partial>; + xAxis?: Partial>; + yAxis?: Partial>; bars?: Partial>; highlight?: Partial>; labels?: Partial>; @@ -114,14 +114,14 @@ grid={isVertical} rule format={(value) => format(value, undefined, { variant: 'short' })} - {...props.axisLeft} + {...props.yAxis} /> format(value, undefined, { variant: 'short' })} - {...props.axisBottom} + {...props.xAxis} /> diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 0f19dc540..3626efaef 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -1,6 +1,7 @@
@@ -289,8 +289,8 @@ ]} stackSeries props={{ - axisBottom: { format: 'metric' }, - axisLeft: { format: 'none' }, + xAxis: { format: 'metric' }, + yAxis: { format: 'none' }, }} />
diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index af2c874aa..836c92a08 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -56,7 +56,7 @@ spline: { class: 'stroke-primary fill-primary/20', }, - axisLeft: { + yAxis: { ticks: [0, 5, 10], format: (d) => '', }, From 1efcd32916a6c4b5c851d5393044277fd270c835 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:30:26 -0400 Subject: [PATCH 112/177] fix(Chart): Default domain sorting to `false` (instead of LayerCake `true`) --- .changeset/fresh-houses-run.md | 5 +++++ packages/layerchart/src/lib/components/Chart.svelte | 5 +++++ .../src/routes/docs/components/Tooltip/+page.svelte | 3 --- .../layerchart/src/routes/docs/examples/DotPlot/+page.svelte | 1 - .../src/routes/docs/examples/RadialLine/+page.svelte | 1 - 5 files changed, 10 insertions(+), 5 deletions(-) create mode 100644 .changeset/fresh-houses-run.md diff --git a/.changeset/fresh-houses-run.md b/.changeset/fresh-houses-run.md new file mode 100644 index 000000000..c0f53451c --- /dev/null +++ b/.changeset/fresh-houses-run.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +fix(Chart): Default domain sorting to `false` (instead of LayerCake's `true`) to simplify bandScale use cases diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index 3bed0ae35..e166340f3 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -268,6 +268,7 @@ $: _y = y as LayerCakeProps['y']; + d.name))]} padding={{ left: 36, bottom: 36 }} tooltip={{ mode: charts.dateTime.mode, @@ -671,7 +670,6 @@ xScale={scaleTime()} y="name" yScale={scaleBand()} - yDomain={[...new Set(timeSeries.map((d) => d.name))]} padding={{ left: 36, bottom: 36 }} tooltip={{ mode: charts.duration.mode, @@ -723,7 +721,6 @@ xScale={scaleTime()} y="name" yScale={scaleBand()} - yDomain={[...new Set(overlapTimeSeries.map((d) => d.name))]} padding={{ left: 36, bottom: 36 }} tooltip={{ mode: charts.multiDuration.mode, diff --git a/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte b/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte index db243d7a6..3936fb807 100644 --- a/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/DotPlot/+page.svelte @@ -39,7 +39,6 @@ xScale={scaleTime()} y="name" yScale={scaleBand()} - yDomain={[...new Set(data.map((d) => d.name))]} padding={{ left: 36, bottom: 36 }} tooltip={{ mode: 'band' }} > diff --git a/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte b/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte index 88c5907a7..8d20134aa 100644 --- a/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/RadialLine/+page.svelte @@ -39,7 +39,6 @@ data={pitchData} x="name" xScale={scaleBand()} - xDomain={pitchData.map((d) => d.name)} xRange={[0, 2 * Math.PI]} y="value" yRange={({ height }) => [0, height / 2]} From 27ea02b029caed2ea5ff3b07769db5e7cc262589 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:31:32 -0400 Subject: [PATCH 113/177] feat(Voronoi): Support radial coordinates. Issue #112 --- .changeset/empty-pianos-add.md | 5 +++++ .../layerchart/src/lib/components/Voronoi.svelte | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .changeset/empty-pianos-add.md diff --git a/.changeset/empty-pianos-add.md b/.changeset/empty-pianos-add.md new file mode 100644 index 000000000..30594e304 --- /dev/null +++ b/.changeset/empty-pianos-add.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Voronoi): Support radial coordinates. Issue #112 diff --git a/packages/layerchart/src/lib/components/Voronoi.svelte b/packages/layerchart/src/lib/components/Voronoi.svelte index 5c16fe422..6a9ae4c92 100644 --- a/packages/layerchart/src/lib/components/Voronoi.svelte +++ b/packages/layerchart/src/lib/components/Voronoi.svelte @@ -5,13 +5,14 @@ import type { GeoPermissibleObjects } from 'd3-geo'; // @ts-expect-error import { geoVoronoi } from 'd3-geo-voronoi'; + import { pointRadial } from 'd3-shape'; import { cls } from '@layerstack/tailwind'; import { chartContext } from './ChartContext.svelte'; import GeoPath from './GeoPath.svelte'; import { geoContext, type GeoContext } from './GeoContext.svelte'; - const { flatData, xGet, yGet, x: xContext, y: yContext, width, height } = chartContext(); + const { flatData, xGet, yGet, x: xContext, y: yContext, width, height, radial } = chartContext(); const geo = geoContext() as GeoContext | undefined; /** Override data instead of using context */ @@ -46,7 +47,14 @@ const x = Array.isArray(xValue) ? min(xValue) : xValue; const y = Array.isArray(yValue) ? min(yValue) : yValue; - const point = [x, y]; + let point: [number, number]; + if ($radial) { + const radialPoint = pointRadial(x, y); + // Assume radial is also centered + point = [radialPoint[0] + $width / 2, radialPoint[1] + $height / 2]; + } else { + point = [x, y]; + } // @ts-expect-error point.data = d; return point; From d7907ab4232661c7d208a6b7f0dcede94c4db222 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:32:39 -0400 Subject: [PATCH 114/177] feat(Highlight): Support radial coordiantes for `points` and `lines`. Issue #112 --- .changeset/hot-houses-stare.md | 5 +++ .../src/lib/components/Highlight.svelte | 33 +++++++++++++++++-- 2 files changed, 35 insertions(+), 3 deletions(-) create mode 100644 .changeset/hot-houses-stare.md diff --git a/.changeset/hot-houses-stare.md b/.changeset/hot-houses-stare.md new file mode 100644 index 000000000..468ae04be --- /dev/null +++ b/.changeset/hot-houses-stare.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Highlight): Support radial coordiantes for `points` and `lines`. Issue #112 diff --git a/packages/layerchart/src/lib/components/Highlight.svelte b/packages/layerchart/src/lib/components/Highlight.svelte index 52790e757..2146bb943 100644 --- a/packages/layerchart/src/lib/components/Highlight.svelte +++ b/packages/layerchart/src/lib/components/Highlight.svelte @@ -1,7 +1,7 @@ From f4f62a6afd183e5d60ff630a8b98dd0bd58894db Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:33:32 -0400 Subject: [PATCH 115/177] feat(Labels): Support `center` placement (useful with Points) --- .changeset/new-readers-sparkle.md | 5 +++++ packages/layerchart/src/lib/components/Labels.svelte | 10 ++++++---- 2 files changed, 11 insertions(+), 4 deletions(-) create mode 100644 .changeset/new-readers-sparkle.md diff --git a/.changeset/new-readers-sparkle.md b/.changeset/new-readers-sparkle.md new file mode 100644 index 000000000..9c97e9cd3 --- /dev/null +++ b/.changeset/new-readers-sparkle.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Labels): Support `center` placement (useful with Points) diff --git a/packages/layerchart/src/lib/components/Labels.svelte b/packages/layerchart/src/lib/components/Labels.svelte index 873929e6e..3dfb59fd5 100644 --- a/packages/layerchart/src/lib/components/Labels.svelte +++ b/packages/layerchart/src/lib/components/Labels.svelte @@ -8,8 +8,8 @@ import { chartContext } from './ChartContext.svelte'; import Points from './Points.svelte'; - export let placement: 'inside' | 'outside' = 'outside'; - export let offset = 4; + export let placement: 'inside' | 'outside' | 'center' = 'outside'; + export let offset = placement === 'center' ? 0 : 4; export let format: FormatType | undefined = undefined; const { yScale } = chartContext(); @@ -55,7 +55,8 @@ y: point.y + (placement === 'outside' ? offset : -offset), capHeight: '.6rem', textAnchor: 'middle', - verticalAnchor: placement === 'outside' ? 'start' : 'end', + verticalAnchor: + placement === 'center' ? 'middle' : placement === 'outside' ? 'start' : 'end', }; } else { // top @@ -65,7 +66,8 @@ y: point.y + (placement === 'outside' ? -offset : offset), capHeight: '.6rem', textAnchor: 'middle', - verticalAnchor: placement === 'outside' ? 'end' : 'start', + verticalAnchor: + placement === 'center' ? 'middle' : placement === 'outside' ? 'end' : 'start', }; } } From 525267bc496ab846d75b5ca37ee98797cbb75e5a Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:34:13 -0400 Subject: [PATCH 116/177] fix(Points): Fix passing fill and stroke for Svg (after supporting Canvas) --- packages/layerchart/src/lib/components/Points.svelte | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index b87778882..0965d141a 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -216,7 +216,8 @@ cx={$radial ? radialPoint[0] : point.x} cy={$radial ? radialPoint[1] : point.y} {r} - fill={$config.r ? $rGet(point.data) : null} + fill={fill ?? ($config.r ? $rGet(point.data) : null)} + {stroke} class={className} {...$$restProps} /> From 966dac0f2ed42914849a7bfada9e3d1e18caa62b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:35:47 -0400 Subject: [PATCH 117/177] feat(LineChart): Support passing `points` prop to easily add Points (similar to `labels`) --- .../lib/components/charts/LineChart.svelte | 23 ++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 3626efaef..46991c79b 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -1,4 +1,6 @@ @@ -107,15 +112,27 @@ - + {#if points} {#each series as s, i} - + {console.log({ s })} + {/each} - + {/if} {#if labels} {/if} + + + {#each series as s, i} + + {/each} + From 53befbf03a196f38f014b9362b8d0c9ba3e570c7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 21:36:28 -0400 Subject: [PATCH 118/177] docs(LineChart): Add more examples (Radar, Points with Labels) --- .../lib/components/charts/LineChart.svelte | 2 +- .../docs/components/LineChart/+page.svelte | 97 +++++++++++++------ 2 files changed, 68 insertions(+), 31 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 46991c79b..6e3a1fbf8 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -63,7 +63,7 @@ yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice padding={{ left: 16, bottom: 16 }} - tooltip={{ mode: 'bisect-x' }} + tooltip={{ mode: radial ? 'voronoi' : 'bisect-x' }} {radial} {...$$restProps} let:x diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index 836c92a08..695b05e24 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -39,36 +39,6 @@

Examples

-

Radar

- - -
- d.name)} - y="value" - yPadding={[0, 10]} - padding={{ top: 32, bottom: 8 }} - radial - props={{ - spline: { - class: 'stroke-primary fill-primary/20', - }, - yAxis: { - ticks: [0, 5, 10], - format: (d) => '', - }, - }} - > - - - - -
-
-

Basic

@@ -153,6 +123,73 @@
+

Points

+ + +
+ +
+
+ +

Labels with Points

+ + +
+ +
+
+ +

Labels within points

+ + +
+ +
+
+ +

Radar

+ + +
+ '', + grid: { + class: 'stroke-surface-content/20 fill-surface-200/50', + }, + }, + highlight: { + lines: false, + }, + }} + /> +
+
+

Custom tooltip

From 1d547d5a201635d0f2ed5830c5ff5200d030a9ee Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 23:38:05 -0400 Subject: [PATCH 119/177] feat(AreaChart): Support radial and better handle y0/y1 with series --- .../lib/components/charts/AreaChart.svelte | 29 ++++++++++---- .../lib/components/charts/LineChart.svelte | 5 +-- .../docs/components/AreaChart/+page.svelte | 38 +++++++++++++++++++ .../routes/docs/components/AreaChart/+page.ts | 38 +++++++++++++++++++ .../docs/components/LineChart/+page.svelte | 2 +- 5 files changed, 101 insertions(+), 11 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 10fa7cddd..a0c13be37 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -26,6 +26,9 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; + /** Use radial instead of cartesian coordinates, mapping `x` to `angle` and `y`` to radial. Radial lines are positioned relative to the origin, use transform (ex. ``) to change the origin */ + export let radial = false; + export let series: { label?: string; value: Accessor; @@ -76,12 +79,15 @@ data={chartData} {x} {xScale} + xRange={$$props.xRange ?? (radial ? [0, 2 * Math.PI] : undefined)} y={y ?? (stackSeries ? (d) => series.map((s, i) => d.stackData[i][1]) : series.map((s) => s.value))} yDomain={[0, null]} + yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice - padding={{ left: 16, bottom: 16 }} - tooltip={{ mode: 'bisect-x' }} + {radial} + padding={radial ? undefined : { left: 16, bottom: 16 }} + tooltip={{ mode: radial ? 'voronoi' : 'bisect-x' }} {...$$restProps} let:x let:xScale @@ -94,17 +100,18 @@ > {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }} - + format(value, undefined, { variant: 'short' })} {...props.yAxis} /> format(value, undefined, { variant: 'short' })} {...props.xAxis} @@ -116,8 +123,16 @@ {#each series as s, i} d.stackData[i][0] : undefined} - y1={stackSeries ? (d) => d.stackData[i][1] : s.value} + y0={stackSeries + ? (d) => d.stackData[i][0] + : Array.isArray(s.value) + ? s.value[0] + : undefined} + y1={stackSeries + ? (d) => d.stackData[i][1] + : Array.isArray(s.value) + ? s.value[1] + : s.value} line={{ class: 'stroke-2', stroke: s.color }} fill={s.color} fill-opacity={0.3} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 6e3a1fbf8..82d77984e 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -62,9 +62,9 @@ yDomain={[0, null]} yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice - padding={{ left: 16, bottom: 16 }} - tooltip={{ mode: radial ? 'voronoi' : 'bisect-x' }} {radial} + padding={radial ? undefined : { left: 16, bottom: 16 }} + tooltip={{ mode: radial ? 'voronoi' : 'bisect-x' }} {...$$restProps} let:x let:xScale @@ -114,7 +114,6 @@ {#if points} {#each series as s, i} - {console.log({ s })} +

Radial

+ + +
+ [height / 5, height / 2]} + radial + props={{ + area: { line: false, 'fill-opacity': 1 }, + xAxis: { format: PeriodType.Month }, + yAxis: { ticks: 4, format: (v) => v + '° F' }, + highlight: { points: false }, + }} + series={[ + { label: 'min/max', value: ['min', 'max'], color: 'hsl(var(--color-primary) / 20%)' }, + { + label: 'minmin/maxmax', + value: ['minmin', 'maxmax'], + color: 'hsl(var(--color-primary) / 20%)', + }, + ]} + > + + + + +
+
+

Custom tooltip

diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.ts b/packages/layerchart/src/routes/docs/components/AreaChart/+page.ts index 2dea85711..e152576a2 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.ts +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.ts @@ -1,3 +1,4 @@ +import { csvParse, autoType } from 'd3-dsv'; import { parse } from '@layerstack/utils'; import api from '$lib/components/charts/AreaChart.svelte?raw&sveld'; @@ -5,12 +6,49 @@ import source from '$lib/components/charts/AreaChart.svelte?raw'; import pageSource from './+page.svelte?raw'; import type { AppleStockData } from '$static/data/examples/date/apple-stock.js'; +import { ascending, flatGroup, max, mean, min } from 'd3-array'; +import { celsiusToFahrenheit } from '$lib/utils/math.js'; export async function load() { return { appleStock: await fetch('/data/examples/date/apple-stock.json').then(async (r) => parse(await r.text()) ), + dailyTemperatures: await fetch('/data/examples/dailyTemperatures.csv').then(async (r) => { + return csvParse<{ dayOfYear: number; year: number; value: number | 'NA' }>( + await r.text(), + // @ts-expect-error + autoType + ) + .filter((d) => d.value !== 'NA') + .map((d) => { + const origDate = new Date(d.year, 0, d.dayOfYear); + return { + ...d, + date: new Date(Date.UTC(2000, origDate.getUTCMonth(), origDate.getUTCDate())), + value: d.value !== 'NA' ? celsiusToFahrenheit(d.value) : 'NA', + }; + }); + }), + sfoTemperatures: await fetch('/data/examples/sfoTemperatures.csv').then(async (r) => { + return flatGroup( + csvParse<{ date: Date; tavg: number; tmax: number; tmin: number }>( + await r.text(), + // @ts-expect-error + autoType + ), + (d) => new Date(Date.UTC(2000, d.date.getUTCMonth(), d.date.getUTCDate())) // group by day of year + ) + .sort(([a], [b]) => ascending(a, b)) // sort chronologically + .map(([date, v]) => ({ + date, + avg: mean(v, (d) => d.tavg || NaN), + min: mean(v, (d) => d.tmin || NaN), + max: mean(v, (d) => d.tmax || NaN), + minmin: min(v, (d) => d.tmin || NaN), + maxmax: max(v, (d) => d.tmax || NaN), + })); + }), meta: { api, source, diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index 695b05e24..4eeef05d3 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -167,7 +167,7 @@ x="name" xScale={scaleBand()} y="value" - padding={{ top: 32, bottom: 8 }} + padding={{ top: 8 }} yPadding={[0, 10]} radial points From ce8fd2012c906958c0be38f2eebea359dfb51bd8 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 4 Sep 2024 23:42:36 -0400 Subject: [PATCH 120/177] Fix overlooked axisBottom => xAxis --- .../src/routes/docs/components/AreaChart/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 42be3a8de..3345d344c 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -76,7 +76,7 @@ x="date" y="value" yDomain={null} - props={{ axisBottom: { rule: false } }} + props={{ xAxis: { rule: false } }} > {@const thresholdValue = 0} From 1a012260747af0138ad28e0f0a4444652decc2b8 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 6 Sep 2024 07:04:22 -0400 Subject: [PATCH 121/177] fix(Highlight): Handle non-zero y values when drawing lines (ex. radial line chart with inner radius) --- .changeset/eight-llamas-pump.md | 5 +++++ packages/layerchart/src/lib/components/Highlight.svelte | 8 ++++---- 2 files changed, 9 insertions(+), 4 deletions(-) create mode 100644 .changeset/eight-llamas-pump.md diff --git a/.changeset/eight-llamas-pump.md b/.changeset/eight-llamas-pump.md new file mode 100644 index 000000000..b534e24a8 --- /dev/null +++ b/.changeset/eight-llamas-pump.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Highlight): Handle non-zero y values when drawing lines (ex. radial line chart with inner radius) diff --git a/packages/layerchart/src/lib/components/Highlight.svelte b/packages/layerchart/src/lib/components/Highlight.svelte index 2146bb943..d6e33871e 100644 --- a/packages/layerchart/src/lib/components/Highlight.svelte +++ b/packages/layerchart/src/lib/components/Highlight.svelte @@ -101,7 +101,7 @@ ..._lines, ...xCoord.filter(notNull).map((xItem, i) => ({ x1: xItem + xOffset, - y1: 0, + y1: min($yRange) as unknown as number, x2: xItem + xOffset, y2: max($yRange) as unknown as number, })), @@ -111,7 +111,7 @@ ..._lines, { x1: xCoord + xOffset, - y1: 0, + y1: min($yRange) as unknown as number, x2: xCoord + xOffset, y2: max($yRange) as unknown as number, }, @@ -149,7 +149,7 @@ _lines = [ ..._lines, ...yCoord.filter(notNull).map((yItem, i) => ({ - x1: 0, + x1: min($xRange) as unknown as number, y1: yItem + yOffset, x2: max($xRange) as unknown as number, y2: yItem + yOffset, @@ -159,7 +159,7 @@ _lines = [ ..._lines, { - x1: 0, + x1: min($xRange) as unknown as number, y1: yCoord + yOffset, x2: max($xRange) as unknown as number, y2: yCoord + yOffset, From 708f8b5d2405a0c7abb2719d6152c5754ec035b7 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 6 Sep 2024 08:04:10 -0400 Subject: [PATCH 122/177] fix(Highlight): Handle null value points --- .changeset/seven-cars-happen.md | 5 +++++ packages/layerchart/src/lib/components/Highlight.svelte | 5 +++-- 2 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changeset/seven-cars-happen.md diff --git a/.changeset/seven-cars-happen.md b/.changeset/seven-cars-happen.md new file mode 100644 index 000000000..2aa4d8037 --- /dev/null +++ b/.changeset/seven-cars-happen.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Highlight): Handle null value points diff --git a/packages/layerchart/src/lib/components/Highlight.svelte b/packages/layerchart/src/lib/components/Highlight.svelte index d6e33871e..baa11d5f6 100644 --- a/packages/layerchart/src/lib/components/Highlight.svelte +++ b/packages/layerchart/src/lib/components/Highlight.svelte @@ -213,7 +213,6 @@ .filter((d) => d.point); // remove if no point found (ex. Histogram); _points = seriesPointsData.map((seriesPoint, i) => { - console.log({ seriesPoint }); return { x: $xScale(seriesPoint.point[1]) + xOffset, y: yCoord + yOffset, @@ -271,7 +270,7 @@ }; }); } - } else { + } else if (xCoord != null && yCoord != null) { _points = [ { x: xCoord + xOffset, @@ -279,6 +278,8 @@ fill: $config.r ? $rGet(highlightData) : null, }, ]; + } else { + _points = []; } if ($radial) { From 0e75096a1e4be39eb031c6a6961e7e455bf31109 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 6 Sep 2024 08:59:05 -0400 Subject: [PATCH 123/177] fix(Spline): Handle null data via defined by default --- .changeset/late-cheetahs-smell.md | 5 +++ .../src/lib/components/Spline.svelte | 16 +++++---- .../docs/components/LineChart/+page.svelte | 33 +++++++++++++++++++ 3 files changed, 47 insertions(+), 7 deletions(-) create mode 100644 .changeset/late-cheetahs-smell.md diff --git a/.changeset/late-cheetahs-smell.md b/.changeset/late-cheetahs-smell.md new file mode 100644 index 000000000..ec4c0d5e7 --- /dev/null +++ b/.changeset/late-cheetahs-smell.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Spline): Handle null data via defined by default diff --git a/packages/layerchart/src/lib/components/Spline.svelte b/packages/layerchart/src/lib/components/Spline.svelte index 43d3151f9..f94a42a1e 100644 --- a/packages/layerchart/src/lib/components/Spline.svelte +++ b/packages/layerchart/src/lib/components/Spline.svelte @@ -64,8 +64,8 @@ } } - const _x = accessor(x); - const _y = accessor(y); + const xAccessor = x ? accessor(x) : $contextX; + const yAccessor = y ? accessor(y) : $contextY; $: xOffset = isScaleBand($xScale) ? $xScale.bandwidth() / 2 : 0; $: yOffset = isScaleBand($yScale) ? $yScale.bandwidth() / 2 : 0; @@ -77,13 +77,15 @@ $: { const path = $radial ? lineRadial() - .angle((d) => getScaleValue(d, $xScale, x ? _x : $contextX)) - .radius((d) => getScaleValue(d, $yScale, y ? _y : $contextY)) + .angle((d) => getScaleValue(d, $xScale, xAccessor)) + .radius((d) => getScaleValue(d, $yScale, yAccessor)) : d3Line() - .x((d) => getScaleValue(d, $xScale, x ? _x : $contextX) + xOffset) - .y((d) => getScaleValue(d, $yScale, y ? _y : $contextY) + yOffset); + .x((d) => getScaleValue(d, $xScale, xAccessor) + xOffset) + .y((d) => getScaleValue(d, $yScale, yAccessor) + yOffset); + + path.defined(defined ?? ((d) => xAccessor(d) != null && yAccessor(d) != null)); + if (curve) path.curve(curve); - if (defined) path.defined(defined); d = pathData ?? path(data ?? $contextData) ?? ''; tweened_d.set(d); diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index 4eeef05d3..4fd4652fa 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -17,6 +17,12 @@ import { createDateSeries } from '$lib/utils/genData.js'; const dateSeriesData = createDateSeries({ count: 30, min: 50, max: 100, value: 'integer' }); + $: dateSeriesDataWithNulls = dateSeriesData.map((d) => { + return { + ...d, + value: Math.random() < 0.2 ? null : d.value, + }; + }); const keys = ['apples', 'bananas', 'oranges']; const multiSeriesData = createDateSeries({ @@ -190,6 +196,33 @@
+

Null gaps

+ + +
+ +
+
+ +

Null with dashed lines

+ + +
+ + + {#each series as s} + d.value !== null)} + y={s.value} + class="stroke-2 [stroke-dasharray:3,3]" + stroke={s.color} + /> + {/each} + + +
+
+

Custom tooltip

From f2bd001c0d54465985987c2b63a56cab0d10813d Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 6 Sep 2024 08:59:43 -0400 Subject: [PATCH 124/177] fix(Area): Handle null data via defined by default --- .changeset/rotten-baboons-design.md | 5 ++++ .../layerchart/src/lib/components/Area.svelte | 25 +++++++++++-------- .../docs/components/AreaChart/+page.svelte | 17 +++++++++++++ 3 files changed, 36 insertions(+), 11 deletions(-) create mode 100644 .changeset/rotten-baboons-design.md diff --git a/.changeset/rotten-baboons-design.md b/.changeset/rotten-baboons-design.md new file mode 100644 index 000000000..f359e1f4f --- /dev/null +++ b/.changeset/rotten-baboons-design.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Area): Handle null data via defined by default diff --git a/packages/layerchart/src/lib/components/Area.svelte b/packages/layerchart/src/lib/components/Area.svelte index adaab3a69..115992fc9 100644 --- a/packages/layerchart/src/lib/components/Area.svelte +++ b/packages/layerchart/src/lib/components/Area.svelte @@ -3,7 +3,7 @@ import type { tweened as tweenedStore } from 'svelte/motion'; import { type Area, area as d3Area, areaRadial } from 'd3-shape'; import type { CurveFactory } from 'd3-shape'; - import { max } from 'd3-array'; + import { max, min } from 'd3-array'; import { interpolatePath } from 'd3-interpolate-path'; import { cls } from '@layerstack/tailwind'; @@ -21,6 +21,7 @@ yScale, x: contextX, y, + yDomain, yRange, config, radial, @@ -51,9 +52,9 @@ /** Enable showing line */ export let line: boolean | Partial> = false; - const _x = accessor(x); - const _y0 = accessor(y0); - const _y1 = accessor(y1); + const xAccessor = x ? accessor(x) : $contextX; + const y0Accessor = y0 ? accessor(y0) : (d: any) => min($yDomain); + const y1Accessor = y1 ? accessor(y1) : $y; $: xOffset = isScaleBand($xScale) ? $xScale.bandwidth() / 2 : 0; $: yOffset = isScaleBand($yScale) ? $yScale.bandwidth() / 2 : 0; @@ -65,15 +66,15 @@ $: { const path = $radial ? areaRadial() - .angle((d) => $xScale(x ? _x(d) : $contextX(d))) - .innerRadius((d) => (y0 ? $yScale(_y0(d)) : max($yRange))) - .outerRadius((d) => $yScale(y1 ? _y1(d) : $y(d))) + .angle((d) => $xScale(xAccessor(d))) + .innerRadius((d) => $yScale(y0Accessor(d))) + .outerRadius((d) => $yScale(y1Accessor(d))) : d3Area() - .x((d) => $xScale(x ? _x(d) : $contextX(d)) + xOffset) + .x((d) => $xScale(xAccessor(d)) + xOffset) .y0((d) => { let value = max($yRange)!; if (y0) { - value = $yScale(_y0(d)); + value = $yScale(y0Accessor(d)); } else if (Array.isArray($config.y) && $config.y[0] === 0) { // Use first value if `y` defined as an array (ex. ``) value = $yScale($y(d)[0]); @@ -85,7 +86,7 @@ .y1((d) => { let value = max($yRange)!; if (y1) { - value = $yScale(_y1(d)); + value = $yScale(y1Accessor(d)); } else if (Array.isArray($config.y) && $config.y[1] === 1) { // Use second value if `y` defined as an array (ex. ``) value = $yScale($y(d)[1]); @@ -96,8 +97,10 @@ return value + yOffset; }); + + path.defined(defined ?? ((d) => xAccessor(d) != null && y1Accessor(d) != null)); + if (curve) path.curve(curve); - if (defined) path.defined(defined); const d = pathData ?? path(data ?? $contextData); tweened_d.set(d ?? ''); diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 3345d344c..788f36a00 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -22,6 +22,13 @@ export let data; const dateSeriesData = createDateSeries({ count: 30, min: 50, max: 100, value: 'integer' }); + $: dateSeriesDataWithNulls = dateSeriesData.map((d) => { + return { + ...d, + value: Math.random() < 0.2 ? null : d.value, + }; + }); + const negativeDateSeriesData = createDateSeries({ count: 30, min: -20, @@ -272,6 +279,16 @@ +

Null gaps

+ + +
+ +
+
+ + +

Custom tooltip

From 0d4fbfe4dab1f676dec220bc0f565af189673254 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 6 Sep 2024 14:56:34 -0400 Subject: [PATCH 125/177] Rename `before-marks`/`after-marks` to `below-marks`/`above-marks` to be more explicit --- .../layerchart/src/lib/components/charts/AreaChart.svelte | 4 ++-- .../layerchart/src/lib/components/charts/BarChart.svelte | 4 ++-- .../layerchart/src/lib/components/charts/LineChart.svelte | 4 ++-- .../layerchart/src/lib/components/charts/PieChart.svelte | 4 ++-- .../src/lib/components/charts/ScatterChart.svelte | 4 ++-- .../src/routes/docs/components/AreaChart/+page.svelte | 2 +- .../src/routes/docs/components/BarChart/+page.svelte | 6 +++--- .../src/routes/docs/components/LineChart/+page.svelte | 2 +- 8 files changed, 15 insertions(+), 15 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index a0c13be37..e2d6a122c 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -118,7 +118,7 @@ /> - + {#each series as s, i} @@ -142,7 +142,7 @@ {/each} - + {#each series as s, i} diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 2eb57415f..c321bb8fb 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -125,7 +125,7 @@ /> - + {#each series as s, i} @@ -141,7 +141,7 @@ {/each} - + diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index 82d77984e..63c3cd184 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -95,7 +95,7 @@ /> - + {#each series as s} @@ -110,7 +110,7 @@ {/each} - + {#if points} {#each series as s, i} diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index 7161326e2..f74a9faad 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -113,7 +113,7 @@ {@const slotProps = { label, value, x, xScale, y, yScale, width, height, padding, tooltip }} - + - + diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index 5627b6755..942e941d2 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -73,13 +73,13 @@ /> - + - + diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index 788f36a00..c91e1b2fa 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -272,7 +272,7 @@ }, ]} > - + diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index 45440f6cc..702935858 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -96,7 +96,7 @@ }, ]} > - + @@ -135,7 +135,7 @@ }, ]} > - + @@ -198,7 +198,7 @@ }, ]} > - + diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index 4fd4652fa..30145f9b0 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -209,7 +209,7 @@
- + {#each series as s} d.value !== null)} From 8ff333bb9de3a4a33d102567069fcdcede97a7fa Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 01:02:08 -0400 Subject: [PATCH 126/177] Add pengiun example dataset --- .../docs/components/ScatterChart/+page.ts | 7 + .../static/data/examples/penguins.csv | 345 ++++++++++++++++++ .../static/data/examples/penguins.d.ts | 10 + 3 files changed, 362 insertions(+) create mode 100644 packages/layerchart/static/data/examples/penguins.csv create mode 100644 packages/layerchart/static/data/examples/penguins.d.ts diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts index ccd26bdfd..caeed1dcc 100644 --- a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.ts @@ -1,9 +1,16 @@ +import { autoType, csvParse } from 'd3-dsv'; + import api from '$lib/components/charts/ScatterChart.svelte?raw&sveld'; import source from '$lib/components/charts/ScatterChart.svelte?raw'; import pageSource from './+page.svelte?raw'; +import type { PenguinsData } from '$static/data/examples/penguins.js'; + export async function load() { return { + penguins: (await fetch('/data/examples/penguins.csv').then(async (r) => + csvParse(await r.text(), autoType) + )) as PenguinsData, meta: { api, source, diff --git a/packages/layerchart/static/data/examples/penguins.csv b/packages/layerchart/static/data/examples/penguins.csv new file mode 100644 index 000000000..af24f5270 --- /dev/null +++ b/packages/layerchart/static/data/examples/penguins.csv @@ -0,0 +1,345 @@ +species,island,bill_length_mm,bill_depth_mm,flipper_length_mm,body_mass_g,sex,year +Adelie,Torgersen,39.1,18.7,181,3750,male,2007 +Adelie,Torgersen,39.5,17.4,186,3800,female,2007 +Adelie,Torgersen,40.3,18,195,3250,female,2007 +Adelie,Torgersen,NA,NA,NA,NA,NA,2007 +Adelie,Torgersen,36.7,19.3,193,3450,female,2007 +Adelie,Torgersen,39.3,20.6,190,3650,male,2007 +Adelie,Torgersen,38.9,17.8,181,3625,female,2007 +Adelie,Torgersen,39.2,19.6,195,4675,male,2007 +Adelie,Torgersen,34.1,18.1,193,3475,NA,2007 +Adelie,Torgersen,42,20.2,190,4250,NA,2007 +Adelie,Torgersen,37.8,17.1,186,3300,NA,2007 +Adelie,Torgersen,37.8,17.3,180,3700,NA,2007 +Adelie,Torgersen,41.1,17.6,182,3200,female,2007 +Adelie,Torgersen,38.6,21.2,191,3800,male,2007 +Adelie,Torgersen,34.6,21.1,198,4400,male,2007 +Adelie,Torgersen,36.6,17.8,185,3700,female,2007 +Adelie,Torgersen,38.7,19,195,3450,female,2007 +Adelie,Torgersen,42.5,20.7,197,4500,male,2007 +Adelie,Torgersen,34.4,18.4,184,3325,female,2007 +Adelie,Torgersen,46,21.5,194,4200,male,2007 +Adelie,Biscoe,37.8,18.3,174,3400,female,2007 +Adelie,Biscoe,37.7,18.7,180,3600,male,2007 +Adelie,Biscoe,35.9,19.2,189,3800,female,2007 +Adelie,Biscoe,38.2,18.1,185,3950,male,2007 +Adelie,Biscoe,38.8,17.2,180,3800,male,2007 +Adelie,Biscoe,35.3,18.9,187,3800,female,2007 +Adelie,Biscoe,40.6,18.6,183,3550,male,2007 +Adelie,Biscoe,40.5,17.9,187,3200,female,2007 +Adelie,Biscoe,37.9,18.6,172,3150,female,2007 +Adelie,Biscoe,40.5,18.9,180,3950,male,2007 +Adelie,Dream,39.5,16.7,178,3250,female,2007 +Adelie,Dream,37.2,18.1,178,3900,male,2007 +Adelie,Dream,39.5,17.8,188,3300,female,2007 +Adelie,Dream,40.9,18.9,184,3900,male,2007 +Adelie,Dream,36.4,17,195,3325,female,2007 +Adelie,Dream,39.2,21.1,196,4150,male,2007 +Adelie,Dream,38.8,20,190,3950,male,2007 +Adelie,Dream,42.2,18.5,180,3550,female,2007 +Adelie,Dream,37.6,19.3,181,3300,female,2007 +Adelie,Dream,39.8,19.1,184,4650,male,2007 +Adelie,Dream,36.5,18,182,3150,female,2007 +Adelie,Dream,40.8,18.4,195,3900,male,2007 +Adelie,Dream,36,18.5,186,3100,female,2007 +Adelie,Dream,44.1,19.7,196,4400,male,2007 +Adelie,Dream,37,16.9,185,3000,female,2007 +Adelie,Dream,39.6,18.8,190,4600,male,2007 +Adelie,Dream,41.1,19,182,3425,male,2007 +Adelie,Dream,37.5,18.9,179,2975,NA,2007 +Adelie,Dream,36,17.9,190,3450,female,2007 +Adelie,Dream,42.3,21.2,191,4150,male,2007 +Adelie,Biscoe,39.6,17.7,186,3500,female,2008 +Adelie,Biscoe,40.1,18.9,188,4300,male,2008 +Adelie,Biscoe,35,17.9,190,3450,female,2008 +Adelie,Biscoe,42,19.5,200,4050,male,2008 +Adelie,Biscoe,34.5,18.1,187,2900,female,2008 +Adelie,Biscoe,41.4,18.6,191,3700,male,2008 +Adelie,Biscoe,39,17.5,186,3550,female,2008 +Adelie,Biscoe,40.6,18.8,193,3800,male,2008 +Adelie,Biscoe,36.5,16.6,181,2850,female,2008 +Adelie,Biscoe,37.6,19.1,194,3750,male,2008 +Adelie,Biscoe,35.7,16.9,185,3150,female,2008 +Adelie,Biscoe,41.3,21.1,195,4400,male,2008 +Adelie,Biscoe,37.6,17,185,3600,female,2008 +Adelie,Biscoe,41.1,18.2,192,4050,male,2008 +Adelie,Biscoe,36.4,17.1,184,2850,female,2008 +Adelie,Biscoe,41.6,18,192,3950,male,2008 +Adelie,Biscoe,35.5,16.2,195,3350,female,2008 +Adelie,Biscoe,41.1,19.1,188,4100,male,2008 +Adelie,Torgersen,35.9,16.6,190,3050,female,2008 +Adelie,Torgersen,41.8,19.4,198,4450,male,2008 +Adelie,Torgersen,33.5,19,190,3600,female,2008 +Adelie,Torgersen,39.7,18.4,190,3900,male,2008 +Adelie,Torgersen,39.6,17.2,196,3550,female,2008 +Adelie,Torgersen,45.8,18.9,197,4150,male,2008 +Adelie,Torgersen,35.5,17.5,190,3700,female,2008 +Adelie,Torgersen,42.8,18.5,195,4250,male,2008 +Adelie,Torgersen,40.9,16.8,191,3700,female,2008 +Adelie,Torgersen,37.2,19.4,184,3900,male,2008 +Adelie,Torgersen,36.2,16.1,187,3550,female,2008 +Adelie,Torgersen,42.1,19.1,195,4000,male,2008 +Adelie,Torgersen,34.6,17.2,189,3200,female,2008 +Adelie,Torgersen,42.9,17.6,196,4700,male,2008 +Adelie,Torgersen,36.7,18.8,187,3800,female,2008 +Adelie,Torgersen,35.1,19.4,193,4200,male,2008 +Adelie,Dream,37.3,17.8,191,3350,female,2008 +Adelie,Dream,41.3,20.3,194,3550,male,2008 +Adelie,Dream,36.3,19.5,190,3800,male,2008 +Adelie,Dream,36.9,18.6,189,3500,female,2008 +Adelie,Dream,38.3,19.2,189,3950,male,2008 +Adelie,Dream,38.9,18.8,190,3600,female,2008 +Adelie,Dream,35.7,18,202,3550,female,2008 +Adelie,Dream,41.1,18.1,205,4300,male,2008 +Adelie,Dream,34,17.1,185,3400,female,2008 +Adelie,Dream,39.6,18.1,186,4450,male,2008 +Adelie,Dream,36.2,17.3,187,3300,female,2008 +Adelie,Dream,40.8,18.9,208,4300,male,2008 +Adelie,Dream,38.1,18.6,190,3700,female,2008 +Adelie,Dream,40.3,18.5,196,4350,male,2008 +Adelie,Dream,33.1,16.1,178,2900,female,2008 +Adelie,Dream,43.2,18.5,192,4100,male,2008 +Adelie,Biscoe,35,17.9,192,3725,female,2009 +Adelie,Biscoe,41,20,203,4725,male,2009 +Adelie,Biscoe,37.7,16,183,3075,female,2009 +Adelie,Biscoe,37.8,20,190,4250,male,2009 +Adelie,Biscoe,37.9,18.6,193,2925,female,2009 +Adelie,Biscoe,39.7,18.9,184,3550,male,2009 +Adelie,Biscoe,38.6,17.2,199,3750,female,2009 +Adelie,Biscoe,38.2,20,190,3900,male,2009 +Adelie,Biscoe,38.1,17,181,3175,female,2009 +Adelie,Biscoe,43.2,19,197,4775,male,2009 +Adelie,Biscoe,38.1,16.5,198,3825,female,2009 +Adelie,Biscoe,45.6,20.3,191,4600,male,2009 +Adelie,Biscoe,39.7,17.7,193,3200,female,2009 +Adelie,Biscoe,42.2,19.5,197,4275,male,2009 +Adelie,Biscoe,39.6,20.7,191,3900,female,2009 +Adelie,Biscoe,42.7,18.3,196,4075,male,2009 +Adelie,Torgersen,38.6,17,188,2900,female,2009 +Adelie,Torgersen,37.3,20.5,199,3775,male,2009 +Adelie,Torgersen,35.7,17,189,3350,female,2009 +Adelie,Torgersen,41.1,18.6,189,3325,male,2009 +Adelie,Torgersen,36.2,17.2,187,3150,female,2009 +Adelie,Torgersen,37.7,19.8,198,3500,male,2009 +Adelie,Torgersen,40.2,17,176,3450,female,2009 +Adelie,Torgersen,41.4,18.5,202,3875,male,2009 +Adelie,Torgersen,35.2,15.9,186,3050,female,2009 +Adelie,Torgersen,40.6,19,199,4000,male,2009 +Adelie,Torgersen,38.8,17.6,191,3275,female,2009 +Adelie,Torgersen,41.5,18.3,195,4300,male,2009 +Adelie,Torgersen,39,17.1,191,3050,female,2009 +Adelie,Torgersen,44.1,18,210,4000,male,2009 +Adelie,Torgersen,38.5,17.9,190,3325,female,2009 +Adelie,Torgersen,43.1,19.2,197,3500,male,2009 +Adelie,Dream,36.8,18.5,193,3500,female,2009 +Adelie,Dream,37.5,18.5,199,4475,male,2009 +Adelie,Dream,38.1,17.6,187,3425,female,2009 +Adelie,Dream,41.1,17.5,190,3900,male,2009 +Adelie,Dream,35.6,17.5,191,3175,female,2009 +Adelie,Dream,40.2,20.1,200,3975,male,2009 +Adelie,Dream,37,16.5,185,3400,female,2009 +Adelie,Dream,39.7,17.9,193,4250,male,2009 +Adelie,Dream,40.2,17.1,193,3400,female,2009 +Adelie,Dream,40.6,17.2,187,3475,male,2009 +Adelie,Dream,32.1,15.5,188,3050,female,2009 +Adelie,Dream,40.7,17,190,3725,male,2009 +Adelie,Dream,37.3,16.8,192,3000,female,2009 +Adelie,Dream,39,18.7,185,3650,male,2009 +Adelie,Dream,39.2,18.6,190,4250,male,2009 +Adelie,Dream,36.6,18.4,184,3475,female,2009 +Adelie,Dream,36,17.8,195,3450,female,2009 +Adelie,Dream,37.8,18.1,193,3750,male,2009 +Adelie,Dream,36,17.1,187,3700,female,2009 +Adelie,Dream,41.5,18.5,201,4000,male,2009 +Gentoo,Biscoe,46.1,13.2,211,4500,female,2007 +Gentoo,Biscoe,50,16.3,230,5700,male,2007 +Gentoo,Biscoe,48.7,14.1,210,4450,female,2007 +Gentoo,Biscoe,50,15.2,218,5700,male,2007 +Gentoo,Biscoe,47.6,14.5,215,5400,male,2007 +Gentoo,Biscoe,46.5,13.5,210,4550,female,2007 +Gentoo,Biscoe,45.4,14.6,211,4800,female,2007 +Gentoo,Biscoe,46.7,15.3,219,5200,male,2007 +Gentoo,Biscoe,43.3,13.4,209,4400,female,2007 +Gentoo,Biscoe,46.8,15.4,215,5150,male,2007 +Gentoo,Biscoe,40.9,13.7,214,4650,female,2007 +Gentoo,Biscoe,49,16.1,216,5550,male,2007 +Gentoo,Biscoe,45.5,13.7,214,4650,female,2007 +Gentoo,Biscoe,48.4,14.6,213,5850,male,2007 +Gentoo,Biscoe,45.8,14.6,210,4200,female,2007 +Gentoo,Biscoe,49.3,15.7,217,5850,male,2007 +Gentoo,Biscoe,42,13.5,210,4150,female,2007 +Gentoo,Biscoe,49.2,15.2,221,6300,male,2007 +Gentoo,Biscoe,46.2,14.5,209,4800,female,2007 +Gentoo,Biscoe,48.7,15.1,222,5350,male,2007 +Gentoo,Biscoe,50.2,14.3,218,5700,male,2007 +Gentoo,Biscoe,45.1,14.5,215,5000,female,2007 +Gentoo,Biscoe,46.5,14.5,213,4400,female,2007 +Gentoo,Biscoe,46.3,15.8,215,5050,male,2007 +Gentoo,Biscoe,42.9,13.1,215,5000,female,2007 +Gentoo,Biscoe,46.1,15.1,215,5100,male,2007 +Gentoo,Biscoe,44.5,14.3,216,4100,NA,2007 +Gentoo,Biscoe,47.8,15,215,5650,male,2007 +Gentoo,Biscoe,48.2,14.3,210,4600,female,2007 +Gentoo,Biscoe,50,15.3,220,5550,male,2007 +Gentoo,Biscoe,47.3,15.3,222,5250,male,2007 +Gentoo,Biscoe,42.8,14.2,209,4700,female,2007 +Gentoo,Biscoe,45.1,14.5,207,5050,female,2007 +Gentoo,Biscoe,59.6,17,230,6050,male,2007 +Gentoo,Biscoe,49.1,14.8,220,5150,female,2008 +Gentoo,Biscoe,48.4,16.3,220,5400,male,2008 +Gentoo,Biscoe,42.6,13.7,213,4950,female,2008 +Gentoo,Biscoe,44.4,17.3,219,5250,male,2008 +Gentoo,Biscoe,44,13.6,208,4350,female,2008 +Gentoo,Biscoe,48.7,15.7,208,5350,male,2008 +Gentoo,Biscoe,42.7,13.7,208,3950,female,2008 +Gentoo,Biscoe,49.6,16,225,5700,male,2008 +Gentoo,Biscoe,45.3,13.7,210,4300,female,2008 +Gentoo,Biscoe,49.6,15,216,4750,male,2008 +Gentoo,Biscoe,50.5,15.9,222,5550,male,2008 +Gentoo,Biscoe,43.6,13.9,217,4900,female,2008 +Gentoo,Biscoe,45.5,13.9,210,4200,female,2008 +Gentoo,Biscoe,50.5,15.9,225,5400,male,2008 +Gentoo,Biscoe,44.9,13.3,213,5100,female,2008 +Gentoo,Biscoe,45.2,15.8,215,5300,male,2008 +Gentoo,Biscoe,46.6,14.2,210,4850,female,2008 +Gentoo,Biscoe,48.5,14.1,220,5300,male,2008 +Gentoo,Biscoe,45.1,14.4,210,4400,female,2008 +Gentoo,Biscoe,50.1,15,225,5000,male,2008 +Gentoo,Biscoe,46.5,14.4,217,4900,female,2008 +Gentoo,Biscoe,45,15.4,220,5050,male,2008 +Gentoo,Biscoe,43.8,13.9,208,4300,female,2008 +Gentoo,Biscoe,45.5,15,220,5000,male,2008 +Gentoo,Biscoe,43.2,14.5,208,4450,female,2008 +Gentoo,Biscoe,50.4,15.3,224,5550,male,2008 +Gentoo,Biscoe,45.3,13.8,208,4200,female,2008 +Gentoo,Biscoe,46.2,14.9,221,5300,male,2008 +Gentoo,Biscoe,45.7,13.9,214,4400,female,2008 +Gentoo,Biscoe,54.3,15.7,231,5650,male,2008 +Gentoo,Biscoe,45.8,14.2,219,4700,female,2008 +Gentoo,Biscoe,49.8,16.8,230,5700,male,2008 +Gentoo,Biscoe,46.2,14.4,214,4650,NA,2008 +Gentoo,Biscoe,49.5,16.2,229,5800,male,2008 +Gentoo,Biscoe,43.5,14.2,220,4700,female,2008 +Gentoo,Biscoe,50.7,15,223,5550,male,2008 +Gentoo,Biscoe,47.7,15,216,4750,female,2008 +Gentoo,Biscoe,46.4,15.6,221,5000,male,2008 +Gentoo,Biscoe,48.2,15.6,221,5100,male,2008 +Gentoo,Biscoe,46.5,14.8,217,5200,female,2008 +Gentoo,Biscoe,46.4,15,216,4700,female,2008 +Gentoo,Biscoe,48.6,16,230,5800,male,2008 +Gentoo,Biscoe,47.5,14.2,209,4600,female,2008 +Gentoo,Biscoe,51.1,16.3,220,6000,male,2008 +Gentoo,Biscoe,45.2,13.8,215,4750,female,2008 +Gentoo,Biscoe,45.2,16.4,223,5950,male,2008 +Gentoo,Biscoe,49.1,14.5,212,4625,female,2009 +Gentoo,Biscoe,52.5,15.6,221,5450,male,2009 +Gentoo,Biscoe,47.4,14.6,212,4725,female,2009 +Gentoo,Biscoe,50,15.9,224,5350,male,2009 +Gentoo,Biscoe,44.9,13.8,212,4750,female,2009 +Gentoo,Biscoe,50.8,17.3,228,5600,male,2009 +Gentoo,Biscoe,43.4,14.4,218,4600,female,2009 +Gentoo,Biscoe,51.3,14.2,218,5300,male,2009 +Gentoo,Biscoe,47.5,14,212,4875,female,2009 +Gentoo,Biscoe,52.1,17,230,5550,male,2009 +Gentoo,Biscoe,47.5,15,218,4950,female,2009 +Gentoo,Biscoe,52.2,17.1,228,5400,male,2009 +Gentoo,Biscoe,45.5,14.5,212,4750,female,2009 +Gentoo,Biscoe,49.5,16.1,224,5650,male,2009 +Gentoo,Biscoe,44.5,14.7,214,4850,female,2009 +Gentoo,Biscoe,50.8,15.7,226,5200,male,2009 +Gentoo,Biscoe,49.4,15.8,216,4925,male,2009 +Gentoo,Biscoe,46.9,14.6,222,4875,female,2009 +Gentoo,Biscoe,48.4,14.4,203,4625,female,2009 +Gentoo,Biscoe,51.1,16.5,225,5250,male,2009 +Gentoo,Biscoe,48.5,15,219,4850,female,2009 +Gentoo,Biscoe,55.9,17,228,5600,male,2009 +Gentoo,Biscoe,47.2,15.5,215,4975,female,2009 +Gentoo,Biscoe,49.1,15,228,5500,male,2009 +Gentoo,Biscoe,47.3,13.8,216,4725,NA,2009 +Gentoo,Biscoe,46.8,16.1,215,5500,male,2009 +Gentoo,Biscoe,41.7,14.7,210,4700,female,2009 +Gentoo,Biscoe,53.4,15.8,219,5500,male,2009 +Gentoo,Biscoe,43.3,14,208,4575,female,2009 +Gentoo,Biscoe,48.1,15.1,209,5500,male,2009 +Gentoo,Biscoe,50.5,15.2,216,5000,female,2009 +Gentoo,Biscoe,49.8,15.9,229,5950,male,2009 +Gentoo,Biscoe,43.5,15.2,213,4650,female,2009 +Gentoo,Biscoe,51.5,16.3,230,5500,male,2009 +Gentoo,Biscoe,46.2,14.1,217,4375,female,2009 +Gentoo,Biscoe,55.1,16,230,5850,male,2009 +Gentoo,Biscoe,44.5,15.7,217,4875,NA,2009 +Gentoo,Biscoe,48.8,16.2,222,6000,male,2009 +Gentoo,Biscoe,47.2,13.7,214,4925,female,2009 +Gentoo,Biscoe,NA,NA,NA,NA,NA,2009 +Gentoo,Biscoe,46.8,14.3,215,4850,female,2009 +Gentoo,Biscoe,50.4,15.7,222,5750,male,2009 +Gentoo,Biscoe,45.2,14.8,212,5200,female,2009 +Gentoo,Biscoe,49.9,16.1,213,5400,male,2009 +Chinstrap,Dream,46.5,17.9,192,3500,female,2007 +Chinstrap,Dream,50,19.5,196,3900,male,2007 +Chinstrap,Dream,51.3,19.2,193,3650,male,2007 +Chinstrap,Dream,45.4,18.7,188,3525,female,2007 +Chinstrap,Dream,52.7,19.8,197,3725,male,2007 +Chinstrap,Dream,45.2,17.8,198,3950,female,2007 +Chinstrap,Dream,46.1,18.2,178,3250,female,2007 +Chinstrap,Dream,51.3,18.2,197,3750,male,2007 +Chinstrap,Dream,46,18.9,195,4150,female,2007 +Chinstrap,Dream,51.3,19.9,198,3700,male,2007 +Chinstrap,Dream,46.6,17.8,193,3800,female,2007 +Chinstrap,Dream,51.7,20.3,194,3775,male,2007 +Chinstrap,Dream,47,17.3,185,3700,female,2007 +Chinstrap,Dream,52,18.1,201,4050,male,2007 +Chinstrap,Dream,45.9,17.1,190,3575,female,2007 +Chinstrap,Dream,50.5,19.6,201,4050,male,2007 +Chinstrap,Dream,50.3,20,197,3300,male,2007 +Chinstrap,Dream,58,17.8,181,3700,female,2007 +Chinstrap,Dream,46.4,18.6,190,3450,female,2007 +Chinstrap,Dream,49.2,18.2,195,4400,male,2007 +Chinstrap,Dream,42.4,17.3,181,3600,female,2007 +Chinstrap,Dream,48.5,17.5,191,3400,male,2007 +Chinstrap,Dream,43.2,16.6,187,2900,female,2007 +Chinstrap,Dream,50.6,19.4,193,3800,male,2007 +Chinstrap,Dream,46.7,17.9,195,3300,female,2007 +Chinstrap,Dream,52,19,197,4150,male,2007 +Chinstrap,Dream,50.5,18.4,200,3400,female,2008 +Chinstrap,Dream,49.5,19,200,3800,male,2008 +Chinstrap,Dream,46.4,17.8,191,3700,female,2008 +Chinstrap,Dream,52.8,20,205,4550,male,2008 +Chinstrap,Dream,40.9,16.6,187,3200,female,2008 +Chinstrap,Dream,54.2,20.8,201,4300,male,2008 +Chinstrap,Dream,42.5,16.7,187,3350,female,2008 +Chinstrap,Dream,51,18.8,203,4100,male,2008 +Chinstrap,Dream,49.7,18.6,195,3600,male,2008 +Chinstrap,Dream,47.5,16.8,199,3900,female,2008 +Chinstrap,Dream,47.6,18.3,195,3850,female,2008 +Chinstrap,Dream,52,20.7,210,4800,male,2008 +Chinstrap,Dream,46.9,16.6,192,2700,female,2008 +Chinstrap,Dream,53.5,19.9,205,4500,male,2008 +Chinstrap,Dream,49,19.5,210,3950,male,2008 +Chinstrap,Dream,46.2,17.5,187,3650,female,2008 +Chinstrap,Dream,50.9,19.1,196,3550,male,2008 +Chinstrap,Dream,45.5,17,196,3500,female,2008 +Chinstrap,Dream,50.9,17.9,196,3675,female,2009 +Chinstrap,Dream,50.8,18.5,201,4450,male,2009 +Chinstrap,Dream,50.1,17.9,190,3400,female,2009 +Chinstrap,Dream,49,19.6,212,4300,male,2009 +Chinstrap,Dream,51.5,18.7,187,3250,male,2009 +Chinstrap,Dream,49.8,17.3,198,3675,female,2009 +Chinstrap,Dream,48.1,16.4,199,3325,female,2009 +Chinstrap,Dream,51.4,19,201,3950,male,2009 +Chinstrap,Dream,45.7,17.3,193,3600,female,2009 +Chinstrap,Dream,50.7,19.7,203,4050,male,2009 +Chinstrap,Dream,42.5,17.3,187,3350,female,2009 +Chinstrap,Dream,52.2,18.8,197,3450,male,2009 +Chinstrap,Dream,45.2,16.6,191,3250,female,2009 +Chinstrap,Dream,49.3,19.9,203,4050,male,2009 +Chinstrap,Dream,50.2,18.8,202,3800,male,2009 +Chinstrap,Dream,45.6,19.4,194,3525,female,2009 +Chinstrap,Dream,51.9,19.5,206,3950,male,2009 +Chinstrap,Dream,46.8,16.5,189,3650,female,2009 +Chinstrap,Dream,45.7,17,195,3650,female,2009 +Chinstrap,Dream,55.8,19.8,207,4000,male,2009 +Chinstrap,Dream,43.5,18.1,202,3400,female,2009 +Chinstrap,Dream,49.6,18.2,193,3775,male,2009 +Chinstrap,Dream,50.8,19,210,4100,male,2009 +Chinstrap,Dream,50.2,18.7,198,3775,female,2009 \ No newline at end of file diff --git a/packages/layerchart/static/data/examples/penguins.d.ts b/packages/layerchart/static/data/examples/penguins.d.ts new file mode 100644 index 000000000..61e70451d --- /dev/null +++ b/packages/layerchart/static/data/examples/penguins.d.ts @@ -0,0 +1,10 @@ +export type PenguinsData = { + species: string; + island: string; + bill_length_mm: number | 'NA'; + bill_depth_mm: number | 'NA'; + flipper_length_mm: number | 'NA'; + body_mass_g: number | 'NA'; + sex: 'male' | 'female' | 'NA'; + year: number; +}[]; From adea4cfabf4002360ae604553e96054d34dbe090 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 01:02:44 -0400 Subject: [PATCH 127/177] feat(TooltipHeader): Support color swatch --- .../components/tooltip/TooltipHeader.svelte | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte index 49e20fc6d..7ecf23b32 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipHeader.svelte @@ -1,9 +1,27 @@
+ {#if color} +
+ {/if}
From 7ef6800fc3752e3c34b40e3eb0ba31c5753c794b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 01:07:23 -0400 Subject: [PATCH 128/177] feat(Chart): Expose `config` as slot prop --- .changeset/cold-taxis-sit.md | 5 +++++ packages/layerchart/src/lib/components/Chart.svelte | 3 ++- packages/layerchart/src/lib/components/ChartContext.svelte | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) create mode 100644 .changeset/cold-taxis-sit.md diff --git a/.changeset/cold-taxis-sit.md b/.changeset/cold-taxis-sit.md new file mode 100644 index 000000000..8e084c953 --- /dev/null +++ b/.changeset/cold-taxis-sit.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Chart): Expose `config` as slot prop diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index e166340f3..a29ca45a2 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -308,7 +308,7 @@ ? geoFitObjectTransform(geo.projection(), [width, height], geo.fitGeojson) : undefined} - + {#key isMounted} diff --git a/packages/layerchart/src/lib/components/ChartContext.svelte b/packages/layerchart/src/lib/components/ChartContext.svelte index 424f36e4f..966022b90 100644 --- a/packages/layerchart/src/lib/components/ChartContext.svelte +++ b/packages/layerchart/src/lib/components/ChartContext.svelte @@ -135,4 +135,4 @@ export let data: TData[] | HierarchyNode | SankeyGraph = []; // Same as `ComponentProps>` but causes circular reference - + From 2fa18f9dd78ecf7cc3acb0d27cd765425b8911ff Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 01:07:30 -0400 Subject: [PATCH 129/177] feat(ScatterChart): Support series (with data) --- .../lib/components/charts/ScatterChart.svelte | 44 ++++++++++++++--- .../docs/components/ScatterChart/+page.svelte | 48 +++++++++++++++---- 2 files changed, 77 insertions(+), 15 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte index 942e941d2..c83d665ec 100644 --- a/packages/layerchart/src/lib/components/charts/ScatterChart.svelte +++ b/packages/layerchart/src/lib/components/charts/ScatterChart.svelte @@ -14,6 +14,7 @@ import { accessor, chartDataArray, type Accessor } from '../../utils/common.js'; interface $$Props extends ComponentProps> { + series?: typeof series; labels?: typeof labels; } @@ -21,6 +22,14 @@ export let x: Accessor = undefined; export let y: Accessor = undefined; + export let series: { + key: string; + label?: string; + data: TData[]; + color?: string; + props?: Partial>; + }[] = [{ key: 'default', data: chartDataArray(data), color: 'hsl(var(--color-primary))' }]; + export let labels: ComponentProps | boolean = false; // Default xScale based on first data's `x` value @@ -33,10 +42,14 @@ highlight?: Partial>; labels?: Partial>; } = {}; + + let chartData = series + .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d }))) + .filter((d) => d) as Array; - {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip }} + {@const slotProps = { x, xScale, y, yScale, width, height, padding, tooltip, series }} + {@const activeSeries = tooltip.data + ? (series.find((s) => s.key === tooltip.data.seriesKey) ?? series[0]) + : null} + @@ -76,13 +94,22 @@ - + {#each series as s} + + {/each} - + {#if labels} @@ -96,9 +123,14 @@ - {format(x(data))} + {#if activeSeries?.key !== 'default'} + + {activeSeries?.label ?? activeSeries?.key} + + {/if} - + + diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte index 38592e32f..52c1b9a32 100644 --- a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte @@ -1,36 +1,66 @@

Examples

Basic

- + +
+ +
+
+ +

Series

+ +
- + { + return { + key: species, + data, + color: [ + 'hsl(var(--color-primary))', + 'hsl(var(--color-secondary))', + 'hsl(var(--color-success))', + ][i], + }; + })} + />

Labels

- +
- +

Custom tooltip

- +
- + Custom chart - +
- + From 44259310168a372a7b6db628f9adc374338335c9 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 18:03:18 -0400 Subject: [PATCH 130/177] fix(ChartContext): Subscribe to chart config before passing to slot prop --- packages/layerchart/src/lib/components/ChartContext.svelte | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/components/ChartContext.svelte b/packages/layerchart/src/lib/components/ChartContext.svelte index 966022b90..e68f21bc7 100644 --- a/packages/layerchart/src/lib/components/ChartContext.svelte +++ b/packages/layerchart/src/lib/components/ChartContext.svelte @@ -133,6 +133,8 @@ // Added to try to pass TData downward export let data: TData[] | HierarchyNode | SankeyGraph = []; // Same as `ComponentProps>` but causes circular reference + + $: config = chartContext.config; - + From d24c5c4b4304a83362843f4f282a342373df1ef6 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 18:05:06 -0400 Subject: [PATCH 131/177] docs(ScatterChart): Set custom tooltip example chart height to match other examples --- .../src/routes/docs/components/ScatterChart/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte index 52c1b9a32..69c0860d8 100644 --- a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte @@ -59,7 +59,7 @@

Custom tooltip

-
+
Date: Sat, 7 Sep 2024 18:38:21 -0400 Subject: [PATCH 132/177] fix(Points): Remove incorrect points for null/undefined values --- .changeset/slimy-points-sing.md | 5 ++ .../src/lib/components/Points.svelte | 68 ++++++++++--------- 2 files changed, 40 insertions(+), 33 deletions(-) create mode 100644 .changeset/slimy-points-sing.md diff --git a/.changeset/slimy-points-sing.md b/.changeset/slimy-points-sing.md new file mode 100644 index 000000000..34a0aaf1d --- /dev/null +++ b/.changeset/slimy-points-sing.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(Points): Remove incorrect points for null/undefined values diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index 0965d141a..ce4299a8b 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -69,52 +69,54 @@ $: pointsData = data ?? $contextData; - $: points = pointsData.flatMap((d: any) => { - const xValue = $x(d); - const yValue = $y(d); + $: points = pointsData + .flatMap((d: any) => { + const xValue = $x(d); + const yValue = $y(d); - if (Array.isArray(xValue)) { - /* + if (Array.isArray(xValue)) { + /* x={["prop1" ,"prop2"]} y="prop3" */ - return xValue.filter(notNull).map((xValue: number) => { - return { - x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), - y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), - xValue, - yValue: $y(d), - data: d, - }; - }); - } else if (Array.isArray(yValue)) { - /* + return xValue.filter(notNull).map((xValue: number) => { + return { + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue: $y(d), + data: d, + }; + }); + } else if (Array.isArray(yValue)) { + /* x="prop1" y={["prop2" ,"prop3"]} */ - return yValue.filter(notNull).map((yValue: number) => { + return yValue.filter(notNull).map((yValue: number) => { + return { + x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), + y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + xValue, + yValue: $y(d), + data: d, + }; + }); + } else if (xValue != null && yValue != null) { + /* + x="prop1" + y="prop2" + */ return { x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), xValue, - yValue: $y(d), + yValue, data: d, }; - }); - } else { - /* - x="prop1" - y="prop2" - */ - return { - x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), - y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), - xValue, - yValue, - data: d, - }; - } - }) as Point[]; + } + }) + .filter((p: Point) => p) as Point[]; $: _links = pointsData.flatMap((d: any) => { const xValue = $x(d); From 7c0fc281723d7fa7ebfb31a3083228654fc0769d Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 22:48:58 -0400 Subject: [PATCH 133/177] feat(AreaChart): Support series data and points prop --- .../lib/components/charts/AreaChart.svelte | 38 ++++++++++++++++--- 1 file changed, 32 insertions(+), 6 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index e2d6a122c..043758276 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -10,6 +10,7 @@ import Chart from '../Chart.svelte'; import Highlight from '../Highlight.svelte'; import Labels from '../Labels.svelte'; + import Points from '../Points.svelte'; import Svg from '../layout/Svg.svelte'; import * as Tooltip from '../tooltip/index.js'; @@ -18,6 +19,7 @@ interface $$Props extends ComponentProps> { series?: typeof series; labels?: typeof labels; + points?: typeof points; props?: typeof props; stackSeries?: typeof stackSeries; } @@ -30,29 +32,37 @@ export let radial = false; export let series: { + key: string; label?: string; value: Accessor; + data?: TData[]; color?: string; props?: Partial>; - }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; + }[] = [{ key: 'default', value: y, color: 'hsl(var(--color-primary))' }]; /** Stack instead of overlap series */ export let stackSeries = false; export let labels: ComponentProps | boolean = false; - - // Default xScale based on first data's `x` value - $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear(); + export let points: ComponentProps | boolean = false; export let props: { xAxis?: Partial>; yAxis?: Partial>; area?: Partial>; + points?: Partial>; highlight?: Partial>; labels?: Partial>; } = {}; - let chartData = chartDataArray(data) as Array; + $: allSeriesData = series + .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d }))) + .filter((d) => d) as Array; + + $: chartData = (allSeriesData.length ? allSeriesData : chartDataArray(data)) as Array< + TData & { stackData?: any } + >; + $: if (stackSeries) { const seriesKeys = series.map((s) => { if (typeof s.value === 'string') { @@ -73,6 +83,9 @@ }; }); } + + // Default xScale based on first data's `x` value + $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear(); {#each series as s, i} d.stackData[i][0] : Array.isArray(s.value) @@ -144,6 +158,18 @@ + {#if points} + {#each series as s, i} + + {/each} + {/if} + {#each series as s, i} Date: Sat, 7 Sep 2024 23:29:09 -0400 Subject: [PATCH 134/177] feat(AreaChart): Allow series.key as fallback for label and value, and simplify examples --- .../lib/components/charts/AreaChart.svelte | 26 +++----- .../docs/components/AreaChart/+page.svelte | 62 ++++++++++++------- 2 files changed, 48 insertions(+), 40 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 043758276..8a0add9af 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -34,7 +34,7 @@ export let series: { key: string; label?: string; - value: Accessor; + value?: Accessor; data?: TData[]; color?: string; props?: Partial>; @@ -64,15 +64,7 @@ >; $: if (stackSeries) { - const seriesKeys = series.map((s) => { - if (typeof s.value === 'string') { - return s.value; - } else { - throw new Error( - `Unsupported series type: ${s.value}. 'stackSeries' currently requires string values` - ); - } - }); + const seriesKeys = series.map((s) => s.key); const stackData = stack().keys(seriesKeys)(chartDataArray(data)) as any[]; @@ -94,7 +86,9 @@ {xScale} xRange={$$props.xRange ?? (radial ? [0, 2 * Math.PI] : undefined)} y={y ?? - (stackSeries ? (d) => series.map((s, i) => d.stackData[i][1]) : series.map((s) => s.value))} + (stackSeries + ? (d) => series.map((s, i) => d.stackData[i][1]) + : series.map((s) => s.value ?? s.key))} yDomain={[0, null]} yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice @@ -146,7 +140,7 @@ ? (d) => d.stackData[i][1] : Array.isArray(s.value) ? s.value[1] - : s.value} + : (s.value ?? s.key)} line={{ class: 'stroke-2', stroke: s.color }} fill={s.color} fill-opacity={0.3} @@ -173,7 +167,7 @@ {#each series as s, i} d.stackData[i][1] : s.value} + y={stackSeries ? (d) => d.stackData[i][1] : (s.value ?? s.key)} points={{ fill: s.color }} lines={i == 0} {...props.highlight} @@ -193,9 +187,9 @@ {@const seriesItems = stackSeries ? [...series].reverse() : series} {#each seriesItems as s} - {@const valueAccessor = accessor(s.value)} + {@const valueAccessor = accessor(s.value ?? s.key)} { - const valueAccessor = accessor(s.value); + const valueAccessor = accessor(s.value ?? s.key); return valueAccessor(data); })} format="integer" diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index c91e1b2fa..cdc9d07d6 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -18,6 +18,7 @@ import { createDateSeries } from '$lib/utils/genData.js'; import { scaleUtc } from 'd3-scale'; import { curveCatmullRom } from 'd3-shape'; + import { group } from 'd3-array'; export let data; @@ -45,6 +46,7 @@ keys, }); const multiSeriesFlatData = pivotLonger(multiSeriesData, keys, 'fruit', 'value'); + const multiSeriesDataByFruit = group(multiSeriesFlatData, (d) => d.fruit);

Examples

@@ -137,15 +139,13 @@ data={multiSeriesData} x="date" series={[ - { label: 'apples', value: 'apples', color: 'hsl(var(--color-danger))' }, + { key: 'apples', color: 'hsl(var(--color-danger))' }, { - label: 'bananas', - value: 'bananas', + key: 'bananas', color: 'hsl(var(--color-success))', }, { - label: 'oranges', - value: 'oranges', + key: 'oranges', color: 'hsl(var(--color-warning))', }, ]} @@ -155,22 +155,25 @@

Series (highlight on hover)

- +
{#each series as s} {@const color = - tooltip.data == null || tooltip.data.fruit === s.value + tooltip.data == null || tooltip.data.fruit === s.key ? s.color : 'hsl(var(--color-surface-content) / 20%)'} - {@const activeSeries = [...series].find((s) => s.value === tooltip.data?.fruit)} + {@const activeSeries = [...series].find((s) => s.key === tooltip.data?.fruit)} - {@const activeSeries = [...series].find((s) => s.value === tooltip.data?.fruit)} + {@const activeSeries = [...series].find((s) => s.key === tooltip.data?.fruit)} {format(x(data))} @@ -221,15 +223,13 @@ data={multiSeriesData} x="date" series={[ - { label: 'apples', value: 'apples', color: 'hsl(var(--color-danger))' }, + { key: 'apples', color: 'hsl(var(--color-danger))' }, { - label: 'bananas', - value: 'bananas', + key: 'bananas', color: 'hsl(var(--color-success))', }, { - label: 'oranges', - value: 'oranges', + key: 'oranges', color: 'hsl(var(--color-warning))', }, ]} @@ -246,6 +246,14 @@
+

Points

+ + +
+ +
+
+

Radial

@@ -264,8 +272,14 @@ highlight: { points: false }, }} series={[ - { label: 'min/max', value: ['min', 'max'], color: 'hsl(var(--color-primary) / 20%)' }, { + key: 'min_max', + label: 'min/max', + value: ['min', 'max'], + color: 'hsl(var(--color-primary) / 20%)', + }, + { + key: 'minmin_maxmax', label: 'minmin/maxmax', value: ['minmin', 'maxmax'], color: 'hsl(var(--color-primary) / 20%)', @@ -283,7 +297,7 @@
- +
From 3e9b7c379c6f9b4e86033bb6c233b45cf7122fbb Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 7 Sep 2024 23:57:41 -0400 Subject: [PATCH 135/177] feat(LineChart): Support series.data and s.key. Cleanup/refine docs --- .../lib/components/charts/AreaChart.svelte | 3 +- .../lib/components/charts/LineChart.svelte | 46 +- .../docs/components/AreaChart/+page.svelte | 6 +- .../docs/components/LineChart/+page.svelte | 595 +++--------------- .../routes/docs/components/LineChart/+page.ts | 18 + 5 files changed, 130 insertions(+), 538 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 8a0add9af..df27ac466 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -35,6 +35,7 @@ key: string; label?: string; value?: Accessor; + /** Provider series data, else uses chart data (with value/key accessor) */ data?: TData[]; color?: string; props?: Partial>; @@ -153,7 +154,7 @@ {#if points} - {#each series as s, i} + {#each series as s} ; + value?: Accessor; + /** Provider series data, else uses chart data (with value/key accessor) */ + data?: TData[]; color?: string; props?: Partial>; - }[] = [{ value: y, color: 'hsl(var(--color-primary))' }]; + }[] = [{ key: 'default', value: y, color: 'hsl(var(--color-primary))' }]; export let labels: ComponentProps | boolean = false; export let points: ComponentProps | boolean = false; - // Default xScale based on first data's `x` value - $: xScale = accessor(x)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear(); - export let props: { xAxis?: Partial>; yAxis?: Partial>; @@ -51,20 +51,31 @@ labels?: Partial>; points?: Partial>; } = {}; + + $: allSeriesData = series + .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d }))) + .filter((d) => d) as Array; + + $: chartData = (allSeriesData.length ? allSeriesData : chartDataArray(data)) as Array< + TData & { stackData?: any } + >; + + // Default xScale based on first data's `x` value + $: xScale = accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear(); d.value)} + y={y ?? series.map((s) => s.value ?? s.key)} yDomain={[0, null]} yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice {radial} padding={radial ? undefined : { left: 16, bottom: 16 }} - tooltip={{ mode: radial ? 'voronoi' : 'bisect-x' }} + tooltip={{ mode: 'bisect-x' }} {...$$restProps} let:x let:xScale @@ -100,8 +111,8 @@ {#each series as s} {#if points} - {#each series as s, i} + {#each series as s} {#each series as s, i} - + {/each} @@ -139,9 +157,9 @@ {format(x(data))} {#each series as s} - {@const valueAccessor = accessor(s.value)} + {@const valueAccessor = accessor(s.value ?? s.key)} {@const value = y(data)} - {format(x(data), PeriodType.DayTime)} + {format(x(data), PeriodType.Day)} - {formatDate(x(data), PeriodType.Day)} + {format(x(data), PeriodType.Day)}
diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index 30145f9b0..3e6ce7d39 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -1,21 +1,16 @@

Examples

@@ -193,6 +202,41 @@
+

Radar with series data

+ + +
+ +
+
+

Radial with series data

From 861c81a7a4a59d080cb484e2fa7d599485af6a88 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 8 Sep 2024 15:15:08 -0400 Subject: [PATCH 137/177] =?UTF-8?q?fix(cartesianToPolar):=20Correctly=20ca?= =?UTF-8?q?lculate=20angle/radians=20between=200=20and=202=CF=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .changeset/twenty-queens-remember.md | 5 +++++ packages/layerchart/src/lib/utils/math.ts | 13 +++++++++++-- 2 files changed, 16 insertions(+), 2 deletions(-) create mode 100644 .changeset/twenty-queens-remember.md diff --git a/.changeset/twenty-queens-remember.md b/.changeset/twenty-queens-remember.md new file mode 100644 index 000000000..3f0d4d459 --- /dev/null +++ b/.changeset/twenty-queens-remember.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +fix(cartesianToPolar): Correctly calculate angle/radians between 0 and 2Ï€ diff --git a/packages/layerchart/src/lib/utils/math.ts b/packages/layerchart/src/lib/utils/math.ts index 19b627c25..f968bec88 100644 --- a/packages/layerchart/src/lib/utils/math.ts +++ b/packages/layerchart/src/lib/utils/math.ts @@ -26,12 +26,21 @@ export function polarToCartesian(angle: number, radius: number) { } /** - * Convert cartesian to polar coordinate system. Angle in radians + * Convert cartesian to polar coordinate system. Angle in radians with 0 at the 12 o'clock position */ export function cartesianToPolar(x: number, y: number) { + let radians = Math.atan2(y, x); + + radians += Math.PI / 2; + + // Ensure the result is between 0 and 2Ï€ + if (radians < 0) { + radians += 2 * Math.PI; + } + return { radius: Math.sqrt(x ** 2 + y ** 2), - angle: Math.atan(y / x), + radians, }; } From ba5c2625ec6955960e458646c5b66e7059011d7e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 8 Sep 2024 15:19:10 -0400 Subject: [PATCH 138/177] feat(tooltip): Update bisect-x mode to support radial coordinates --- .changeset/rude-students-lick.md | 5 +++++ .../src/lib/components/tooltip/TooltipContext.svelte | 12 ++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) create mode 100644 .changeset/rude-students-lick.md diff --git a/.changeset/rude-students-lick.md b/.changeset/rude-students-lick.md new file mode 100644 index 000000000..f61938ec7 --- /dev/null +++ b/.changeset/rude-students-lick.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(tooltip): Update bisect-x mode to support radial coordinates diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte index 814374bee..b9b22bc7d 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipContext.svelte @@ -45,6 +45,7 @@ import { localPoint } from '$lib/utils/event.js'; import { isScaleBand, scaleInvert } from '$lib/utils/scales.js'; + import { cartesianToPolar } from '$lib/utils/math.js'; import { quadtreeRects } from '$lib/utils/quadtree.js'; const { @@ -62,6 +63,7 @@ containerWidth, containerHeight, padding, + radial, } = chartContext(); /* @@ -191,8 +193,14 @@ if (tooltipData == null) { switch (mode) { case 'bisect-x': { - // `x` value at pointer coordinate - const xValueAtPoint = scaleInvert($xScale, localX - $padding.left); + let xValueAtPoint: any; + if ($radial) { + // Assume radial is always centered + const { radians } = cartesianToPolar(localX - $width / 2, localY - $height / 2); + xValueAtPoint = scaleInvert($xScale, radians); + } else { + xValueAtPoint = scaleInvert($xScale, localX - $padding.left); + } const index = bisectX($flatData, xValueAtPoint, 1); const previousValue = $flatData[index - 1]; From 576c2ee03284fa27a52f3d31c12948f8ba2c0949 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 8 Sep 2024 19:02:45 -0400 Subject: [PATCH 139/177] Use `scaleTime()` (default) instead of `scaleUtc()` to fix axis formatting and simplify examples --- .../src/routes/docs/components/AreaChart/+page.svelte | 2 -- .../src/routes/docs/components/LineChart/+page.svelte | 3 +-- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index dfa7d0e6e..4bf75b00a 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -16,7 +16,6 @@ import Preview from '$lib/docs/Preview.svelte'; import { createDateSeries } from '$lib/utils/genData.js'; - import { scaleUtc } from 'd3-scale'; import { curveCatmullRom } from 'd3-shape'; import { group } from 'd3-array'; @@ -261,7 +260,6 @@ [height / 5, height / 2]} radial diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index eb7eb6c0a..136089a95 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -1,6 +1,6 @@

Examples

@@ -237,7 +252,80 @@
-

Radial with series data

+

Gradient encoding

+ + +
+ + + + + + + +
+
+ +

Gradient threshold

+ + +
+ + + {@const thresholdOffset = (yScale(50) / (height + padding.bottom)) * 100 + '%'} + + + + + +
+
+ +

Large series

+ + +
+ v + '° F' }, + highlight: { points: false }, + }} + series={flatGroup(data.dailyTemperatures, (d) => d.year).map(([year, data]) => { + return { + key: year, + data, + color: + year === 2024 + ? 'hsl(var(--color-primary))' + : year === 2023 + ? 'hsl(var(--color-primary) / 50%)' + : 'hsl(var(--color-surface-content))', + props: { opacity: [2023, 2024].includes(year) ? 1 : 0.1 }, + }; + })} + tooltip={{ mode: 'manual' }} + /> +
+
+ +

Radial large series

diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.ts b/packages/layerchart/src/routes/docs/components/LineChart/+page.ts index dabf6013d..204bda6c9 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.ts +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.ts @@ -19,7 +19,7 @@ export async function load() { // @ts-expect-error autoType ) - .filter((d) => d.value !== 'NA') + .filter((d) => d.value !== 'NA' && d.dayOfYear <= 365 /* Ignore 366th day */) .map((d) => { const origDate = new Date(d.year, 0, d.dayOfYear); return { @@ -29,6 +29,9 @@ export async function load() { }; }); }), + dailyTemperature: await fetch('/data/examples/date/daily-temperature.json').then(async (r) => + parse<{ date: Date; value: number }[]>(await r.text()) + ), meta: { api, source, From 10961c5bee57cbe71ff5bfd2bbc93fa24312965e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 9 Sep 2024 23:25:14 -0400 Subject: [PATCH 142/177] docs(LineChart): Improve gradient encoding tooltip/highlight --- .../docs/components/LineChart/+page.svelte | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte index c966eb526..dc4b1fa29 100644 --- a/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/LineChart/+page.svelte @@ -266,6 +266,22 @@ + + + {#if tooltip.data} + + {/if} + + + + + {@const value = y(data)} + {format(x(data))} + + + + +
@@ -279,8 +295,8 @@ {@const thresholdOffset = (yScale(50) / (height + padding.bottom)) * 100 + '%'} Date: Tue, 10 Sep 2024 08:27:21 -0400 Subject: [PATCH 143/177] refactor(Chart): No longer expose layout components (Svg, Canvas) from Chart module export --- .../src/lib/components/Chart.svelte | 67 ++++++------------- .../components/tooltip/TooltipContext.svelte | 2 +- 2 files changed, 23 insertions(+), 46 deletions(-) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index a29ca45a2..a6c3aa1a5 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -1,40 +1,17 @@ - - {#key curve} - - - - - - - - - - + + + $y(d)[0]} y1={(d) => min($yDomain)} {curve} {defined} /> + - + + - -{/key} + + + min($yDomain)} y1={(d) => $y(d)[1]} {curve} {defined} /> + - - + + + + +{/key} diff --git a/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte b/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte index 176bb2e00..b27d059a4 100644 --- a/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Threshold/+page.svelte @@ -55,15 +55,15 @@ format={(d) => formatDate(d, PeriodType.Day, { variant: 'short' })} rule /> - - - - + + + - - - + + + + @@ -91,15 +91,15 @@ format={(d) => formatDate(d, PeriodType.Day, { variant: 'short' })} rule /> - - - - + + + - - - + + + + @@ -138,14 +138,14 @@ rule /> - - - + + - - - + + + + From f73f35bf7870af847f749a373ef3267c0bb442db Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Wed, 11 Sep 2024 11:55:20 -0400 Subject: [PATCH 149/177] fix(Points): Fix array values --- packages/layerchart/src/lib/components/Points.svelte | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index ce4299a8b..6a2a5d2ff 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -84,7 +84,7 @@ x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), xValue, - yValue: $y(d), + yValue, data: d, }; }); @@ -98,7 +98,7 @@ x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), xValue, - yValue: $y(d), + yValue, data: d, }; }); From cf0adc4aff8ab8c70feb71fb9b86a4990eab1746 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Thu, 12 Sep 2024 21:18:57 -0400 Subject: [PATCH 150/177] docs(PieChart): Tweak arc example --- .../routes/docs/components/PieChart/+page.svelte | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index d8b1de45f..62056a0b9 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -20,15 +20,22 @@
-

Arc (range)

+

Donut (innerRadius)

- +
-

Donut (innerRadius)

+

Arc (range)

@@ -36,8 +43,9 @@ {data} label="fruit" value="value" + range={[-90, 90]} innerRadius={-20} - cornerRadius={5} + cornerRadius={10} padAngle={0.02} />
From 87524d077fdaa3ec1a16192e7a8478912fde04f3 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 13 Sep 2024 08:07:34 -0400 Subject: [PATCH 151/177] feat(PieChart): Add Group to enable shifting all arcs (useful for arc / partial circle). Refine arc example --- .../src/lib/components/charts/PieChart.svelte | 70 ++++++++++--------- .../docs/components/PieChart/+page.svelte | 4 +- 2 files changed, 40 insertions(+), 34 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index f74a9faad..26b76c7ed 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -6,6 +6,7 @@ import Arc from '../Arc.svelte'; import Chart from '../Chart.svelte'; + import Group from '../Group.svelte'; import Pie from '../Pie.svelte'; import Svg from '../layout/Svg.svelte'; import * as Tooltip from '../tooltip/index.js'; @@ -86,6 +87,7 @@ export let props: { pie?: Partial>; + group?: Partial>; arc?: Partial>; } = {}; @@ -126,39 +128,41 @@ {...props.pie} let:arcs > - {#if separateTracks} - {@const sumValue = Number(sum(chartData, valueAccessor))} - {#each chartData as d, i} - - {/each} - {:else} - {#each arcs as arc} - - {/each} - {/if} + + {#if separateTracks} + {@const sumValue = Number(sum(chartData, valueAccessor))} + {#each chartData as d, i} + + {/each} + {:else} + {#each arcs as arc} + + {/each} + {/if} + diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index 62056a0b9..bdf9ed1d6 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -38,15 +38,17 @@

Arc (range)

-
+
From 60e492ace88d6dc63f5fb84252155383c1ddbed8 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 13 Sep 2024 08:18:24 -0400 Subject: [PATCH 152/177] docs(TranslucentGlobe): Update Tooltip --- .../src/routes/docs/examples/TranslucentGlobe/+page.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/layerchart/src/routes/docs/examples/TranslucentGlobe/+page.svelte b/packages/layerchart/src/routes/docs/examples/TranslucentGlobe/+page.svelte index bfa3e49aa..c2d8f6d31 100644 --- a/packages/layerchart/src/routes/docs/examples/TranslucentGlobe/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/TranslucentGlobe/+page.svelte @@ -125,9 +125,9 @@ {/each} - -
{data.properties.name}
-
+ + {data.properties.name} +
From d99a09afd5ce022f76d32f57af43436848b94804 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 14 Sep 2024 15:48:08 -0400 Subject: [PATCH 153/177] feat(Chart): Support x1/y1 derived scales, useful for grouped bar charts, and replace Bar/Bars groupBy/etc with these new scales --- .changeset/flat-ties-trade.md | 5 + .changeset/witty-goats-breathe.md | 5 + .../layerchart/src/lib/components/Bar.svelte | 20 ++-- .../layerchart/src/lib/components/Bars.svelte | 21 +++-- .../src/lib/components/Chart.svelte | 57 ++++++++++-- .../src/lib/components/ChartContext.svelte | 92 +++++++++++++++++-- packages/layerchart/src/lib/utils/rect.ts | 56 ++++++----- packages/layerchart/src/lib/utils/scales.ts | 32 ++++++- .../routes/docs/examples/Bars/+page.svelte | 74 +++++++-------- .../routes/docs/examples/Columns/+page.svelte | 76 +++++++-------- 10 files changed, 292 insertions(+), 146 deletions(-) create mode 100644 .changeset/flat-ties-trade.md create mode 100644 .changeset/witty-goats-breathe.md diff --git a/.changeset/flat-ties-trade.md b/.changeset/flat-ties-trade.md new file mode 100644 index 000000000..4eee48aff --- /dev/null +++ b/.changeset/flat-ties-trade.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +breaking(Bar/Bars): Replace groupBy/groupPadding with Chart-level x1/y1 derived scales diff --git a/.changeset/witty-goats-breathe.md b/.changeset/witty-goats-breathe.md new file mode 100644 index 000000000..e02810250 --- /dev/null +++ b/.changeset/witty-goats-breathe.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Chart): Support x1/y1 derived scales, useful for grouped bar charts diff --git a/packages/layerchart/src/lib/components/Bar.svelte b/packages/layerchart/src/lib/components/Bar.svelte index 0e1853166..a0fa1d8e0 100644 --- a/packages/layerchart/src/lib/components/Bar.svelte +++ b/packages/layerchart/src/lib/components/Bar.svelte @@ -22,6 +22,16 @@ */ export let y: Accessor = $yContext; + /** + * Override `x1` from context. Useful for multiple Bar instances + */ + export let x1: Accessor = undefined; + + /** + * Override `y1` from context. Useful for multiple Bar instances + */ + export let y1: Accessor = undefined; + export let fill: string | undefined = undefined; export let stroke = 'black'; export let strokeWidth = 0; @@ -40,9 +50,6 @@ | 'bottom-right' = 'all'; export let inset = 0; - export let groupBy: string | undefined = undefined; - export let groupPaddingInner = 0.2; - export let groupPaddingOuter = 0; export let spring: ComponentProps['spring'] = undefined; export let tweened: ComponentProps['tweened'] = undefined; @@ -52,12 +59,9 @@ $: getDimensions = createDimensionGetter(chartContext(), { x, y, - groupBy, + x1, + y1, inset, - groupPadding: { - inner: groupPaddingInner, - outer: groupPaddingOuter, - }, }); $: dimensions = $getDimensions(bar) ?? { x: 0, y: 0, width: 0, height: 0 }; diff --git a/packages/layerchart/src/lib/components/Bars.svelte b/packages/layerchart/src/lib/components/Bars.svelte index af96f75c6..9120da20a 100644 --- a/packages/layerchart/src/lib/components/Bars.svelte +++ b/packages/layerchart/src/lib/components/Bars.svelte @@ -18,6 +18,16 @@ */ export let y: Accessor = undefined; + /** + * Override `x1` from context. Useful for multiple Bar instances + */ + export let x1: Accessor = undefined; + + /** + * Override `y1` from context. Useful for multiple Bar instances + */ + export let y1: Accessor = undefined; + export let stroke = 'black'; export let strokeWidth = 0; export let radius = 0; @@ -27,12 +37,6 @@ export let spring: ComponentProps['spring'] = undefined; export let tweened: ComponentProps['tweened'] = undefined; - - // See: https://svelte.dev/repl/7000c5ce05b84cd98ccbfb2768b4be3d?version=3.38.3 - - export let groupBy: string | undefined = undefined; - export let groupPaddingInner = 0.2; - export let groupPaddingOuter = 0; @@ -42,6 +46,8 @@ bar={item} {x} {y} + {x1} + {y1} fill={$config.r ? $rGet(item) : null} {stroke} {strokeWidth} @@ -49,9 +55,6 @@ {inset} {spring} {tweened} - {groupBy} - {groupPaddingInner} - {groupPaddingOuter} {...$$restProps} /> {/each} diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index a6c3aa1a5..e7c1505c9 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -11,17 +11,11 @@ import TransformContext from './TransformContext.svelte'; import { accessor, type Accessor } from '$lib/utils/common.js'; - import { isScaleBand, type AnyScale } from '$lib/utils/scales.js'; + import { isScaleBand, type AnyScale, type DomainType } from '$lib/utils/scales.js'; import { geoFitObjectTransform } from '$lib/utils/geo.js'; type LayerCakeProps = ComponentProps; - type DomainType = - | (number | string | Date | null | undefined)[] - | Function - // 'null' useful for Brush component - | null; - interface $$Props { /** Whether this chart should be rendered server side. @default false */ ssr?: boolean; @@ -62,6 +56,10 @@ z?: Accessor; /** The r accessor. The key in each row of data that corresponds to the r-field. This can be a string, an accessor function, a number or an array of any combination of those types. This property gets converted to a function when you access it through the context. */ r?: Accessor; + /** The x1 accessor. The key in each row of data that corresponds to the x1-field. This can be a string, an accessor function, a number or an array of any combination of those types. This property gets converted to a function when you access it through the context. */ + x1?: Accessor; + /** The y1 accessor. The key in each row of data that corresponds to the y1-field. This can be a string, an accessor function, a number or an array of any combination of those types. This property gets converted to a function when you access it through the context. */ + y1?: Accessor; /** Set a min or max. For linear scales, if you want to inherit the value from the data's extent, set that value to `null`. This value can also be an array because sometimes your scales are [piecewise](https://github.com/d3/d3-scale#continuous_domain) or are a list of discrete values such as in [ordinal scales](https://github.com/d3/d3-scale#ordinal-scales), useful for color series. Set it to a function that receives the computed domain and lets you return a modified domain, useful for sorting values. */ xDomain?: DomainType; @@ -71,6 +69,10 @@ zDomain?: DomainType; /** Set a min or max. For linear scales, if you want to inherit the value from the data's extent, set that value to `null`. This value can also be an array because sometimes your scales are [piecewise](https://github.com/d3/d3-scale#continuous_domain) or are a list of discrete values such as in [ordinal scales](https://github.com/d3/d3-scale#ordinal-scales), useful for color series. Set it to a function that receives the computed domain and lets you return a modified domain, useful for sorting values. */ rDomain?: DomainType; + /** Set a min or max. For linear scales, if you want to inherit the value from the data's extent, set that value to `null`. This value can also be an array because sometimes your scales are [piecewise](https://github.com/d3/d3-scale#continuous_domain) or are a list of discrete values such as in [ordinal scales](https://github.com/d3/d3-scale#ordinal-scales), useful for color series. Set it to a function that receives the computed domain and lets you return a modified domain, useful for sorting values. */ + x1Domain?: DomainType; + /** Set a min or max. For linear scales, if you want to inherit the value from the data's extent, set that value to `null`. This value can also be an array because sometimes your scales are [piecewise](https://github.com/d3/d3-scale#continuous_domain) or are a list of discrete values such as in [ordinal scales](https://github.com/d3/d3-scale#ordinal-scales), useful for color series. Set it to a function that receives the computed domain and lets you return a modified domain, useful for sorting values. */ + y1Domain?: DomainType; /** Applies D3's [scale.nice()](https://github.com/d3/d3-scale#continuous_nice) to the x domain. @default false */ xNice?: boolean | number; @@ -98,6 +100,10 @@ zScale?: AnyScale; /** The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if you want to override the default or you want to extra options. @default scaleSqrt */ rScale?: AnyScale; + /** The D3 scale that should be used for the x1-dimension. Pass in an instantiated D3 scale if you want to override the default or you want to extra options. @default scaleLinear */ + x1Scale?: AnyScale; + /** The D3 scale that should be used for the y1-dimension. Pass in an instantiated D3 scale if you want to override the default or you want to extra options. @default scaleLinear */ + y1Scale?: AnyScale; /** Override the default x range of `[0, width]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `xReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ xRange?: @@ -119,6 +125,16 @@ | number[] | string[] | ((args: { width: number; height: number }) => number[] | string[]); + /** Override the default x1 range of `[0, width]` by setting an array or function with argument `({ xScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ + x1Range?: + | number[] + | string[] + | ((args: { xScale: AnyScale; width: number; height: number }) => number[] | string[]); + /** Override the default y1 range of `[0, width]` by setting an array or function with argument `({ yScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ + y1Range?: + | number[] + | string[] + | ((args: { yScale: AnyScale; width: number; height: number }) => number[] | string[]); /** Reverse the default x range. By default this is `false` and the range is `[0, width]`. Ignored if you set the xRange prop. @default false */ xReverse?: boolean; @@ -187,6 +203,16 @@ export let y: Accessor = undefined; export let yScale: AnyScale | undefined = undefined; + export let x1: $$Props['x1'] = undefined; + export let x1Scale: $$Props['x1Scale'] = undefined; + export let x1Domain: $$Props['x1Domain'] = undefined; + export let x1Range: $$Props['x1Range'] = undefined; + + export let y1: $$Props['y1'] = undefined; + export let y1Scale: $$Props['y1Scale'] = undefined; + export let y1Domain: $$Props['y1Domain'] = undefined; + export let y1Range: $$Props['y1Range'] = undefined; + /** * x value guaranteed to be visible in xDomain. Useful with optional negative values since `xDomain={[0, null]}` would ignore negative values */ @@ -285,7 +311,22 @@ ? geoFitObjectTransform(geo.projection(), [width, height], geo.fitGeojson) : undefined} - + {#key isMounted} and exposing with a strongly type context getter --> diff --git a/packages/layerchart/src/lib/utils/rect.ts b/packages/layerchart/src/lib/utils/rect.ts index 023468957..0ed03af01 100644 --- a/packages/layerchart/src/lib/utils/rect.ts +++ b/packages/layerchart/src/lib/utils/rect.ts @@ -1,7 +1,7 @@ import { derived } from 'svelte/store'; import { max, min } from 'd3-array'; -import { groupScaleBand, isScaleBand } from './scales.js'; +import { isScaleBand } from './scales.js'; import type { ChartContext } from '../components/ChartContext.svelte'; import { accessor, type Accessor } from './common.js'; @@ -10,43 +10,55 @@ type DimensionGetterOptions = { x?: Accessor; /** Override `y` accessor from context */ y?: Accessor; - groupBy?: string; + /** Override `x1` accessor from context */ + x1?: Accessor; + /** Override `y1` accessor from context */ + y1?: Accessor; inset?: number; - groupPadding?: { inner?: number; outer?: number }; }; -// TOOD: Pass in overrides for `x` and `y` accessors export function createDimensionGetter( context: ChartContext, options?: DimensionGetterOptions ) { - const { flatData, xGet, yGet, xScale, yScale, x: xAccessor, y: yAccessor } = context; + const { + xScale, + yScale, + x: xAccessor, + y: yAccessor, + x1: x1Accessor, + y1: y1Accessor, + x1Scale, + y1Scale, + } = context; - const groupBy = options?.groupBy; const inset = options?.inset ?? 0; return derived( - [flatData, xGet, yGet, xScale, yScale, xAccessor, yAccessor], - ([$flatData, $xGet, $yGet, $xScale, $yScale, $xAccessor, $yAccessor]) => { + [xScale, x1Scale, yScale, y1Scale, xAccessor, yAccessor, x1Accessor, y1Accessor], + ([$xScale, $x1Scale, $yScale, $y1Scale, $xAccessor, $yAccessor, $x1Accessor, $y1Accessor]) => { // Use `xscale.domain()` instead of `$xDomain` to include `nice()` being applied const [minXDomain, maxXDomain] = $xScale.domain(); const [minYDomain, maxYDomain] = $yScale.domain(); + const _x = accessor(options?.x ?? $xAccessor); + const _y = accessor(options?.y ?? $yAccessor); + const _x1 = accessor(options?.x1 ?? $x1Accessor); + const _y1 = accessor(options?.y1 ?? $y1Accessor); + // @ts-expect-error return function getter(item) { if (isScaleBand($yScale)) { // Horizontal band - const y1Scale = groupBy - ? groupScaleBand($yScale, $flatData, groupBy, options?.groupPadding) - : null; - // @ts-expect-error - const y = firstValue($yGet(item)) + (y1Scale ? y1Scale(item[groupBy]) : 0) + inset / 2; + const y = + firstValue($yScale(_y(item)) ?? 0) + ($y1Scale ? $y1Scale(_y1(item)) : 0) + inset / 2; const height = Math.max( 0, - $yScale.bandwidth ? (y1Scale ? y1Scale.bandwidth() : $yScale.bandwidth()) - inset : 0 + $yScale.bandwidth + ? ($y1Scale ? ($y1Scale.bandwidth?.() ?? 0) : $yScale.bandwidth()) - inset + : 0 ); - const _x = accessor(options?.x ?? $xAccessor); const xValue = _x(item); let left = 0; @@ -77,19 +89,15 @@ export function createDimensionGetter( }; } else { // Vertical band or linear - const x1Scale = - groupBy && isScaleBand($xScale) - ? groupScaleBand($xScale, $flatData, groupBy, options?.groupPadding) - : null; - - // @ts-expect-error - const x = firstValue($xGet(item)) + (x1Scale ? x1Scale(item[groupBy]) : 0) + inset / 2; + const x = + firstValue($xScale(_x(item))) + ($x1Scale ? $x1Scale(_x1(item)) : 0) + inset / 2; const width = Math.max( 0, - $xScale.bandwidth ? (x1Scale ? x1Scale.bandwidth() : $xScale.bandwidth()) - inset : 0 + $xScale.bandwidth + ? ($x1Scale ? ($x1Scale.bandwidth?.() ?? 0) : $xScale.bandwidth()) - inset + : 0 ); - const _y = accessor(options?.y ?? $yAccessor); const yValue = _y(item); let top = 0; diff --git a/packages/layerchart/src/lib/utils/scales.ts b/packages/layerchart/src/lib/utils/scales.ts index 6de57bccc..2b09a41fb 100644 --- a/packages/layerchart/src/lib/utils/scales.ts +++ b/packages/layerchart/src/lib/utils/scales.ts @@ -5,15 +5,23 @@ import { type MotionOptions, motionStore } from '$lib/stores/motionStore.js'; import { scaleBand, type ScaleBand } from 'd3-scale'; import { unique } from 'svelte-ux/utils/array'; -export type AnyScale = { +export interface AnyScale { (value: Input): Output; invert?: (value: Output) => Input; domain(): Domain[]; + domain(domain: Iterable): this; range(): Range[]; + range(range: Iterable): this; bandwidth?: Function; ticks?: Function; tickFormat?: Function; -}; + copy(): Function; +} + +export type DomainType = + | (number | string | Date | null | undefined)[] + // 'null' useful for Brush component + | null; /** * Implemenation for missing `scaleBand().invert()` @@ -52,6 +60,26 @@ export function scaleInvert(scale: AnyScale, value: number) { } } +/** Create new copy of scale with domain and range */ +export function createScale( + scale: AnyScale, + domain: DomainType, + range: any[] | Function, + context?: Record +) { + const scaleCopy = scale.copy() as AnyScale; + if (domain) { + scaleCopy.domain(domain); + } + + if (typeof range === 'function') { + scaleCopy.range(range(context)); + } else { + scaleCopy.range(range); + } + return scaleCopy; +} + /** Create a `scaleBand()` within another scaleBand()'s bandwidth (typically a x1 of an x0 scale, used for grouping) */ export function groupScaleBand( scale: ScaleBand, diff --git a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte index c9652485d..e9c36f5b6 100644 --- a/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Bars/+page.svelte @@ -1,7 +1,7 @@ - + From 5a17a87f0ee9e00fe36ddf271d1e8aa1d6c93443 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 15 Sep 2024 23:09:13 -0400 Subject: [PATCH 157/177] feat(ChartContext): Default x1Domain / y1Domain to extent of chart data base on x1/y1 accessor (similar to other scales) --- .../src/lib/components/ChartContext.svelte | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/packages/layerchart/src/lib/components/ChartContext.svelte b/packages/layerchart/src/lib/components/ChartContext.svelte index b6c7e3b9b..b47e476cd 100644 --- a/packages/layerchart/src/lib/components/ChartContext.svelte +++ b/packages/layerchart/src/lib/components/ChartContext.svelte @@ -112,10 +112,12 @@

Examples

@@ -23,15 +16,20 @@
+ yScale.domain()} padding={{ top: 24, bottom: 24, left: 24, right: 24 }} tooltip={{ mode: 'bisect-x' }} let:height + let:y1Scale > - efficiencyScale(d.efficiency)} class="stroke-2 stroke-secondary" /> + y1Scale(d.efficiency)} class="stroke-2 stroke-secondary" /> - efficiencyScale(d.efficiency)} /> + y1Scale(d.efficiency)} /> From 58b43a057020646fd239d9ff530970ac8b7259fa Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Tue, 17 Sep 2024 23:42:31 -0400 Subject: [PATCH 159/177] breaking: Add new color `cScale` (and related `c` accessor, domain, range, etc) and replace `rScale` usage (which should be used for radius, etc) --- .changeset/red-roses-drive.md | 5 ++ .../layerchart/src/lib/components/Bars.svelte | 4 +- .../src/lib/components/Calendar.svelte | 4 +- .../src/lib/components/Chart.svelte | 35 +++++++- .../src/lib/components/ChartContext.svelte | 88 ++++++++++++++++--- .../src/lib/components/Highlight.svelte | 14 +-- .../src/lib/components/Legend.svelte | 6 +- .../layerchart/src/lib/components/Pie.svelte | 4 +- .../src/lib/components/Points.svelte | 4 +- .../src/lib/components/charts/PieChart.svelte | 18 ++-- .../lib/components/tooltip/TooltipItem.svelte | 2 +- .../docs/components/Calendar/+page.svelte | 30 +++---- .../docs/components/Legend/+page.svelte | 12 +-- .../routes/docs/components/Pie/+page.svelte | 74 ++++++---------- .../docs/components/Tooltip/+page.svelte | 12 +-- .../routes/docs/examples/Area/+page.svelte | 60 ++++++------- .../routes/docs/examples/Bars/+page.svelte | 76 ++++++++-------- .../docs/examples/Candlestick/+page.svelte | 8 +- .../routes/docs/examples/Columns/+page.svelte | 76 ++++++++-------- .../routes/docs/examples/Line/+page.svelte | 36 ++++---- .../routes/docs/examples/Scatter/+page.svelte | 8 +- 21 files changed, 329 insertions(+), 247 deletions(-) create mode 100644 .changeset/red-roses-drive.md diff --git a/.changeset/red-roses-drive.md b/.changeset/red-roses-drive.md new file mode 100644 index 000000000..8d75f660d --- /dev/null +++ b/.changeset/red-roses-drive.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +breaking: Add new color `cScale` (and related `c` accessor, domain, range, etc) and replace `rScale` usage (which should be used for radius, etc) diff --git a/packages/layerchart/src/lib/components/Bars.svelte b/packages/layerchart/src/lib/components/Bars.svelte index 9120da20a..d2518ae6e 100644 --- a/packages/layerchart/src/lib/components/Bars.svelte +++ b/packages/layerchart/src/lib/components/Bars.svelte @@ -6,7 +6,7 @@ import Rect from './Rect.svelte'; import { chartDataArray, type Accessor } from '../utils/common.js'; - const { data, rGet, config } = chartContext(); + const { data, cGet, config } = chartContext(); /** * Override `x` from context. Useful for multiple Bar instances @@ -48,7 +48,7 @@ {y} {x1} {y1} - fill={$config.r ? $rGet(item) : null} + fill={$config.c ? $cGet(item) : null} {stroke} {strokeWidth} {radius} diff --git a/packages/layerchart/src/lib/components/Calendar.svelte b/packages/layerchart/src/lib/components/Calendar.svelte index 52e08491d..924c5ee8d 100644 --- a/packages/layerchart/src/lib/components/Calendar.svelte +++ b/packages/layerchart/src/lib/components/Calendar.svelte @@ -27,7 +27,7 @@ */ export let tooltip: TooltipContextValue | undefined = undefined; - const { width, height, x, rGet, data, config } = chartContext(); + const { width, height, x, cGet, data, config } = chartContext(); $: yearDays = timeDays(start, end); $: yearMonths = timeMonths(start, end); @@ -50,7 +50,7 @@ return { x: timeWeek.count(timeYear(date), date) * cellWidth, y: date.getDay() * cellHeight, - color: $config.r ? $rGet(cellData) : 'transparent', + color: $config.c ? $cGet(cellData) : 'transparent', data: cellData, }; }); diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index dcb9583fe..6d00142cd 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -60,6 +60,8 @@ x1?: Accessor; /** The y1 accessor. The key in each row of data that corresponds to the y1-field. This can be a string, an accessor function, a number or an array of any combination of those types. This property gets converted to a function when you access it through the context. */ y1?: Accessor; + /** The c (color) accessor. The key in each row of data that corresponds to the color. This can be a string or an accessor function. This property gets converted to a function when you access it through the context. */ + c?: Accessor; /** Set a min or max. For linear scales, if you want to inherit the value from the data's extent, set that value to `null`. This value can also be an array because sometimes your scales are [piecewise](https://github.com/d3/d3-scale#continuous_domain) or are a list of discrete values such as in [ordinal scales](https://github.com/d3/d3-scale#ordinal-scales), useful for color series. Set it to a function that receives the computed domain and lets you return a modified domain, useful for sorting values. */ xDomain?: DomainType; @@ -73,6 +75,8 @@ x1Domain?: DomainType; /** Set a min or max. For linear scales, if you want to inherit the value from the data's extent, set that value to `null`. This value can also be an array because sometimes your scales are [piecewise](https://github.com/d3/d3-scale#continuous_domain) or are a list of discrete values such as in [ordinal scales](https://github.com/d3/d3-scale#ordinal-scales), useful for color series. Set it to a function that receives the computed domain and lets you return a modified domain, useful for sorting values. */ y1Domain?: DomainType; + /** Set the list of color values. */ + cDomain?: DomainType; /** Applies D3's [scale.nice()](https://github.com/d3/d3-scale#continuous_nice) to the x domain. @default false */ xNice?: boolean | number; @@ -104,6 +108,8 @@ x1Scale?: AnyScale; /** The D3 scale that should be used for the y1-dimension. Pass in an instantiated D3 scale if you want to override the default or you want to extra options. @default scaleLinear */ y1Scale?: AnyScale; + /** The D3 scale that should be used for the color dimension. Pass in an instantiated D3 scale if you want to override the default or you want to extra options. @default scaleOrdinal */ + cScale?: AnyScale; /** Override the default x range of `[0, width]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `xReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ xRange?: @@ -125,16 +131,18 @@ | number[] | string[] | ((args: { width: number; height: number }) => number[] | string[]); - /** Override the default x1 range of `[0, width]` by setting an array or function with argument `({ xScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ + /** Set the x1 range by setting an array or function with argument `({ xScale, width, height})` that returns an array. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ x1Range?: | number[] | string[] | ((args: { xScale: AnyScale; width: number; height: number }) => number[] | string[]); - /** Override the default y1 range of `[0, width]` by setting an array or function with argument `({ yScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ + /** Set the y1 range by setting an array or function with argument `({ yScale, width, height})` that returns an array. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ y1Range?: | number[] | string[] | ((args: { yScale: AnyScale; width: number; height: number }) => number[] | string[]); + /** Override the default y1 range of `[0, width]` by setting an array or function with argument `({ yScale, width, height})` that returns an array. Setting this prop overrides `x1Reverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshhold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */ + cRange?: string[]; /** Reverse the default x range. By default this is `false` and the range is `[0, width]`. Ignored if you set the xRange prop. @default false */ xReverse?: boolean; @@ -213,6 +221,11 @@ export let y1Domain: $$Props['y1Domain'] = undefined; export let y1Range: $$Props['y1Range'] = undefined; + export let c: $$Props['c'] = undefined; + export let cScale: $$Props['cScale'] = undefined; + export let cDomain: $$Props['cDomain'] = undefined; + export let cRange: $$Props['cRange'] = undefined; + /** * x value guaranteed to be visible in xDomain. Useful with optional negative values since `xDomain={[0, null]}` would ignore negative values */ @@ -322,11 +335,22 @@ {y1Scale} {y1Domain} {y1Range} + {c} + {cScale} + {cDomain} + {cRange} let:data let:flatData let:config + let:x1 let:x1Scale + let:x1Get + let:y1 let:y1Scale + let:y1Get + let:c + let:cScale + let:cGet on:resize > {#key isMounted} @@ -387,8 +411,15 @@ {r} {rScale} {rGet} + {x1} {x1Scale} + {x1Get} + {y1} {y1Scale} + {y1Get} + {c} + {cScale} + {cGet} {padding} {data} {flatData} diff --git a/packages/layerchart/src/lib/components/ChartContext.svelte b/packages/layerchart/src/lib/components/ChartContext.svelte index b47e476cd..063a36ade 100644 --- a/packages/layerchart/src/lib/components/ChartContext.svelte +++ b/packages/layerchart/src/lib/components/ChartContext.svelte @@ -10,7 +10,7 @@ setContext, type ComponentProps, } from 'svelte'; - import { writable, type Readable } from 'svelte/store'; + import { derived, writable, type Readable } from 'svelte/store'; export const chartContextKey = Symbol(); @@ -33,6 +33,7 @@ r: Readable<(d: TData) => any>; x1: Readable<(d: TData) => any>; y1: Readable<(d: TData) => any>; + c: Readable<(d: TData) => any>; custom: Readable; data: Readable | SankeyGraph>; xNice: Readable; @@ -65,12 +66,14 @@ rDomain: Readable; x1Domain: Readable; y1Domain: Readable; + cDomain: Readable; xRange: Readable; yRange: Readable; zRange: Readable; rRange: Readable; x1Range: Readable; y1Range: Readable; + cRange: Readable; config: Readable; xScale: Readable; xGet: Readable; @@ -81,7 +84,11 @@ rScale: Readable; rGet: Readable; x1Scale: Readable; + x1Get: Readable; y1Scale: Readable; + y1Get: Readable; + cScale: Readable; + cGet: Readable; }; export type ChartEvents = { @@ -112,6 +119,8 @@ {#if highlightData} diff --git a/packages/layerchart/src/lib/components/Legend.svelte b/packages/layerchart/src/lib/components/Legend.svelte index 22f0f61f2..46df8600a 100644 --- a/packages/layerchart/src/lib/components/Legend.svelte +++ b/packages/layerchart/src/lib/components/Legend.svelte @@ -9,7 +9,7 @@ import ColorRamp from './ColorRamp.svelte'; import { cls } from '@layerstack/tailwind'; - const { rScale } = chartContext() ?? {}; + const { cScale } = chartContext() ?? {}; type AnyScale = any; type Placement = @@ -41,9 +41,9 @@ tick?: string; } = {}; - $: if (scale == null && rScale) { + $: if (scale == null && cScale) { // Read scale from chart context - scale = $rScale; + scale = $cScale; } let xScale: AnyScale; diff --git a/packages/layerchart/src/lib/components/Pie.svelte b/packages/layerchart/src/lib/components/Pie.svelte index 95ce88769..b356b4f05 100644 --- a/packages/layerchart/src/lib/components/Pie.svelte +++ b/packages/layerchart/src/lib/components/Pie.svelte @@ -67,7 +67,7 @@ */ export let tooltip: TooltipContextValue | undefined = undefined; - const { data: contextData, x, y, xRange, rGet, config, width, height } = chartContext(); + const { data: contextData, x, y, xRange, c, cScale, config, width, height } = chartContext(); // @ts-expect-error $: resolved_endAngle = endAngle ?? degreesToRadians($config.xRange ? max($xRange) : max(range)); @@ -108,7 +108,7 @@ {outerRadius} {cornerRadius} {offset} - fill={$config.r ? $rGet(arc.data) : null} + fill={$config.c ? $cScale?.($c(arc.data)) : null} data={arc.data} {tooltip} /> diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index 6a2a5d2ff..e8c507457 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -19,7 +19,7 @@ y, yScale, yGet, - rGet, + cGet, padding, containerWidth, containerHeight, @@ -218,7 +218,7 @@ cx={$radial ? radialPoint[0] : point.x} cy={$radial ? radialPoint[1] : point.y} {r} - fill={fill ?? ($config.r ? $rGet(point.data) : null)} + fill={fill ?? ($config.c ? $cGet(point.data) : null)} {stroke} class={className} {...$$restProps} diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index 26b76c7ed..c0468d5f1 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -97,15 +97,15 @@ x={value} y={label} r={label} - rScale={colorScale} - rDomain={colorKeys} - rRange={colors} + cScale={colorScale} + cDomain={colorKeys} + cRange={colors} {...$$restProps} let:x let:xScale let:y - let:r - let:rScale + let:c + let:cScale let:yScale let:width let:height @@ -139,8 +139,8 @@ {innerRadius} {cornerRadius} {padAngle} - fill={rScale(r(d))} - track={{ fill: rScale(r(d)), 'fill-opacity': 0.1 }} + fill={cScale(c(d))} + track={{ fill: cScale(c(d)), 'fill-opacity': 0.1 }} {tooltip} data={d} {...props.arc} @@ -155,7 +155,7 @@ {innerRadius} {cornerRadius} {padAngle} - fill={rScale(r(arc.data))} + fill={cScale(c(arc.data))} data={arc.data} {tooltip} {...props.arc} @@ -175,7 +175,7 @@ diff --git a/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte b/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte index 64364df3a..f380163bd 100644 --- a/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte +++ b/packages/layerchart/src/lib/components/tooltip/TooltipItem.svelte @@ -1,6 +1,6 @@ - - - {#if separateTracks} - {@const sumValue = Number(sum(chartData, valueAccessor))} - {#each chartData as d, i} - - {/each} + {#each series as s, i} + + + {#if s.data && !Array.isArray(s.data)} + {:else} - {#each arcs as arc} - - {/each} + + {#each arcs as arc} + + {/each} + {/if} - + {/each} diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index bdf9ed1d6..e8bb097b8 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -1,13 +1,18 @@

Examples

@@ -38,30 +43,136 @@

Arc (range)

-
+
-

Separate tracks

+

Series data

+ + +
+ { + return { key, data }; + })} + outerRadius={-25} + innerRadius={-20} + cornerRadius={5} + padAngle={0.01} + /> +
+
+ +

Series data (individual tracks)

+ + +
+ { + return { + key: d.fruit, + data: d, + }; + })} + outerRadius={-25} + innerRadius={-20} + cornerRadius={10} + /> +
+
+ +

Series data (arc)

{ + return { + key: d.fruit, + data: d, + }; + })} + range={[-90, 90]} + outerRadius={-25} + innerRadius={-20} + cornerRadius={10} + props={{ group: { y: 190 } }} + /> +
+
+ +

Series data (track color)

+ + +
+ { + return { + key: d.fruit, + data: d, + }; + })} + props={{ + arc: { + track: { fill: 'hsl(var(--color-surface-content) / 10%)' }, + }, + }} + outerRadius={-25} + innerRadius={-20} + cornerRadius={10} + /> +
+
+ +

Series data (individual tracks and total)

+ + +
+ { + return { + key: d.label, + data: d, + total: d.total, + color: d.color, + }; + })} + outerRadius={-25} + innerRadius={-20} + cornerRadius={10} + /> +
+
+ +

Series data (single value)

+ + +
+ +

Customize colors

+ + +
+ +
+
+ - - {#if s.data && !Array.isArray(s.data)} + {@const singleArc = s.data?.length === 1 || chartData.length === 1} + + {#if singleArc} + {@const d = s.data?.[0] || chartData[0]} {:else} diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index e8bb097b8..ed632c7ef 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -9,9 +9,9 @@ const data = dataByYear.get(2019); const exerciseData = [ - { label: 'move', value: 400, total: 1000, color: '#ef4444' }, - { label: 'exercise', value: 20, total: 30, color: '#a3e635' }, - { label: 'stand', value: 10, total: 12, color: '#22d3ee' }, + { label: 'move', value: 400, maxValue: 1000, color: '#ef4444' }, + { label: 'exercise', value: 20, maxValue: 30, color: '#a3e635' }, + { label: 'stand', value: 10, maxValue: 12, color: '#22d3ee' }, ]; @@ -58,6 +58,39 @@
+

Single value

+ + +
+ +
+
+ +

Single value (arc)

+ + +
+ +
+
+

Series data

@@ -65,9 +98,7 @@ { - return { key, data }; - })} + series={Array.from(dataByYear, ([key, data]) => ({ key, data }))} outerRadius={-25} innerRadius={-20} cornerRadius={5} @@ -83,12 +114,7 @@ { - return { - key: d.fruit, - data: d, - }; - })} + series={data?.map((d) => ({ key: d.fruit, data: [d] }))} outerRadius={-25} innerRadius={-20} cornerRadius={10} @@ -103,12 +129,7 @@ { - return { - key: d.fruit, - data: d, - }; - })} + series={data?.map((d) => ({ key: d.fruit, data: [d] }))} range={[-90, 90]} outerRadius={-25} innerRadius={-20} @@ -125,12 +146,7 @@ { - return { - key: d.fruit, - data: d, - }; - })} + series={data?.map((d) => ({ key: d.fruit, data: [d] }))} props={{ arc: { track: { fill: 'hsl(var(--color-surface-content) / 10%)' }, @@ -143,7 +159,7 @@
-

Series data (individual tracks and total)

+

Series data (individual tracks, max value, and color)

@@ -153,8 +169,8 @@ series={exerciseData.map((d) => { return { key: d.label, - data: d, - total: d.total, + data: [d], + maxValue: d.maxValue, color: d.color, }; })} @@ -165,21 +181,6 @@
-

Series data (single value)

- - -
- -
-
-

Inner component props (Arc class)

From dc94fbacca65cf504ac0dcf76e30adaed8ef723e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 21:06:38 -0400 Subject: [PATCH 164/177] refactor(Chart): Handle radial default xRange/yRange within Chart instead of in each chart (AreaChart/LineChart) --- packages/layerchart/src/lib/components/Chart.svelte | 5 +++++ packages/layerchart/src/lib/components/Highlight.svelte | 2 -- .../layerchart/src/lib/components/charts/AreaChart.svelte | 2 -- .../layerchart/src/lib/components/charts/LineChart.svelte | 2 -- 4 files changed, 5 insertions(+), 6 deletions(-) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index 6d00142cd..fa86ecdad 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -208,8 +208,11 @@ export let data: TData[] | HierarchyNode | SankeyGraph = []; export let x: Accessor = undefined; + export let xRange: $$Props['xRange'] = undefined; + export let y: Accessor = undefined; export let yScale: AnyScale | undefined = undefined; + export let yRange: $$Props['yRange'] = undefined; export let x1: $$Props['x1'] = undefined; export let x1Scale: $$Props['x1Scale'] = undefined; @@ -289,9 +292,11 @@ {data} x={_x} {xDomain} + xRange={xRange ?? (radial ? [0, 2 * Math.PI] : undefined)} y={_y} {yScale} {yDomain} + yRange={yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} {yReverse} xDomainSort={false} yDomainSort={false} diff --git a/packages/layerchart/src/lib/components/Highlight.svelte b/packages/layerchart/src/lib/components/Highlight.svelte index ff1cbaac1..4da0041ee 100644 --- a/packages/layerchart/src/lib/components/Highlight.svelte +++ b/packages/layerchart/src/lib/components/Highlight.svelte @@ -308,8 +308,6 @@ // TODO: How to handle _areas } } - - $: console.log({ _points }); {#if highlightData} diff --git a/packages/layerchart/src/lib/components/charts/AreaChart.svelte b/packages/layerchart/src/lib/components/charts/AreaChart.svelte index 66db01e92..3fd989284 100644 --- a/packages/layerchart/src/lib/components/charts/AreaChart.svelte +++ b/packages/layerchart/src/lib/components/charts/AreaChart.svelte @@ -85,13 +85,11 @@ data={chartData} {x} {xScale} - xRange={$$props.xRange ?? (radial ? [0, 2 * Math.PI] : undefined)} y={y ?? (stackSeries ? (d) => series.map((s, i) => d.stackData[i][1]) : series.map((s) => s.value ?? s.key))} yBaseline={0} - yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice {radial} padding={radial ? undefined : { left: 16, bottom: 16 }} diff --git a/packages/layerchart/src/lib/components/charts/LineChart.svelte b/packages/layerchart/src/lib/components/charts/LineChart.svelte index b1601d5c2..086bd6f6f 100644 --- a/packages/layerchart/src/lib/components/charts/LineChart.svelte +++ b/packages/layerchart/src/lib/components/charts/LineChart.svelte @@ -67,10 +67,8 @@ data={chartData} {x} {xScale} - xRange={$$props.xRange ?? (radial ? [0, 2 * Math.PI] : undefined)} y={y ?? series.map((s) => s.value ?? s.key)} yBaseline={0} - yRange={$$props.yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} yNice {radial} padding={radial ? undefined : { left: 16, bottom: 16 }} From 36ad32cdeca27967136041ecf4d8e9f42d778d8e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 21:19:07 -0400 Subject: [PATCH 165/177] Add another workaround for LayerCake typings to fix `svelte-check` --- packages/layerchart/src/lib/components/Chart.svelte | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/layerchart/src/lib/components/Chart.svelte b/packages/layerchart/src/lib/components/Chart.svelte index fa86ecdad..addfcfce9 100644 --- a/packages/layerchart/src/lib/components/Chart.svelte +++ b/packages/layerchart/src/lib/components/Chart.svelte @@ -282,9 +282,14 @@ isMounted = true; }); - // TODO: Hack until LayerCake has better typings (`Accessor`) + // TODO: Hacks until LayerCake has better typings (`Accessor`) $: _x = x as LayerCakeProps['x']; $: _y = y as LayerCakeProps['y']; + $: _yRange = + yRange ?? + ((radial + ? ({ height }: { height: number }) => [0, height / 2] + : undefined) as LayerCakeProps['yRange']); @@ -296,7 +301,7 @@ y={_y} {yScale} {yDomain} - yRange={yRange ?? (radial ? ({ height }) => [0, height / 2] : undefined)} + yRange={_yRange} {yReverse} xDomainSort={false} yDomainSort={false} From 6fa8be9b2fd0365e1c16d7de9e9647423c67e6e4 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 21:48:11 -0400 Subject: [PATCH 166/177] breaking(Pie): Remove `placement` prop and instead rely Svg `center` or use `Group` for positioning --- .changeset/poor-hats-roll.md | 5 ++ .../layerchart/src/lib/components/Pie.svelte | 50 ++++++------------- .../src/lib/components/charts/PieChart.svelte | 17 +++---- .../routes/docs/components/Pie/+page.svelte | 48 ++++++++++-------- .../docs/components/PieChart/+page.svelte | 9 ++-- 5 files changed, 59 insertions(+), 70 deletions(-) create mode 100644 .changeset/poor-hats-roll.md diff --git a/.changeset/poor-hats-roll.md b/.changeset/poor-hats-roll.md new file mode 100644 index 000000000..e3a64622f --- /dev/null +++ b/.changeset/poor-hats-roll.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +breaking(Pie): Remove `placement` prop and instead rely Svg `center` or use `Group` for positioning diff --git a/packages/layerchart/src/lib/components/Pie.svelte b/packages/layerchart/src/lib/components/Pie.svelte index b356b4f05..50761308f 100644 --- a/packages/layerchart/src/lib/components/Pie.svelte +++ b/packages/layerchart/src/lib/components/Pie.svelte @@ -5,7 +5,6 @@ import Arc from './Arc.svelte'; import { chartContext } from './ChartContext.svelte'; - import Group from './Group.svelte'; import { degreesToRadians } from '$lib/utils/math.js'; import { motionStore } from '$lib/stores/motionStore.js'; import type { TooltipContextValue } from './tooltip/TooltipContext.svelte'; @@ -52,8 +51,6 @@ export let cornerRadius = 0; export let padAngle = 0; - export let placement: 'left' | 'center' | 'right' | 'none' = 'center'; - export let spring: boolean | Parameters[1] = undefined; export let tweened: boolean | Parameters[1] = undefined; @@ -82,36 +79,21 @@ .value($x); $: arcs = pie(data ?? (Array.isArray($contextData) ? $contextData : [])); - - $: radius = Math.min($width / 2, $height / 2); - $: coords = { - x: - placement === 'left' - ? radius - : placement === 'center' - ? $width / 2 - : placement === 'right' - ? $width - radius - : 0, - y: placement === 'none' ? 0 : $height / 2, - }; - - - {#each arcs as arc} - - {/each} - - + + {#each arcs as arc} + + {/each} + diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index 759aa6164..0202c0352 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -31,7 +31,6 @@ outerRadius?: typeof outerRadius; cornerRadius?: typeof cornerRadius; padAngle?: typeof padAngle; - placement?: typeof placement; props?: typeof props; series?: typeof series; // labels?: typeof labels; @@ -84,8 +83,6 @@ export let cornerRadius = 0; export let padAngle = 0; - export let placement: 'left' | 'center' | 'right' | 'none' = 'center'; - export let props: { pie?: Partial>; group?: Partial>; @@ -130,14 +127,13 @@ > {@const slotProps = { label, value, x, xScale, y, yScale, width, height, padding, tooltip }} - + - {#each series as s, i} - - {@const singleArc = s.data?.length === 1 || chartData.length === 1} - + + {#each series as s, i} + {@const singleArc = s.data?.length === 1 || chartData.length === 1} {#if singleArc} {@const d = s.data?.[0] || chartData[0]} @@ -182,8 +177,8 @@ {/each} {/if} - - {/each} + {/each} + diff --git a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte index 807c4ac45..8f4b33c57 100644 --- a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte @@ -38,7 +38,7 @@
- + @@ -50,7 +50,7 @@
- + @@ -62,7 +62,7 @@
- + @@ -74,7 +74,7 @@
- + @@ -86,7 +86,7 @@
- + @@ -100,7 +100,7 @@
- + @@ -112,7 +112,7 @@
- + @@ -124,7 +124,7 @@
- + @@ -136,7 +136,7 @@
- + @@ -148,7 +148,7 @@
- + @@ -161,7 +161,7 @@
- + @@ -173,7 +173,7 @@
- + @@ -185,7 +185,7 @@
- + {#each arcs as arc, index}
- + {#each arcs as arc, index} {@const colors = keyClasses[index]} @@ -249,7 +249,7 @@
- + @@ -273,7 +273,7 @@
- + {#each arcs as arc, index} {@const colors = keyClasses[index]} @@ -333,20 +333,22 @@
- + - + + +
-

center (default)

+

center

- + @@ -357,9 +359,11 @@
- + - + + +
diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index ed632c7ef..be7d5641f 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -61,7 +61,7 @@

Single value

-
+
Single value (arc) -
+
@@ -134,7 +137,7 @@ outerRadius={-25} innerRadius={-20} cornerRadius={10} - props={{ group: { y: 190 } }} + props={{ group: { y: 70 } }} />
From be7a6deb109c96e5755eb3511d98693f3a85f884 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 22:14:48 -0400 Subject: [PATCH 167/177] fix(PieChart): Support passing explicit (>0) outerRadius for single arc variant. --- .../layerchart/src/lib/components/charts/PieChart.svelte | 2 +- .../src/routes/docs/components/PieChart/+page.svelte | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/PieChart.svelte b/packages/layerchart/src/lib/components/charts/PieChart.svelte index 0202c0352..7fd9b65fb 100644 --- a/packages/layerchart/src/lib/components/charts/PieChart.svelte +++ b/packages/layerchart/src/lib/components/charts/PieChart.svelte @@ -141,7 +141,7 @@ domain={[0, s.maxValue ?? maxValue ?? sum(chartData, valueAccessor)]} {range} {innerRadius} - outerRadius={i * (outerRadius ?? 0)} + outerRadius={(outerRadius ?? 0) < 0 ? i * (outerRadius ?? 0) : outerRadius} {cornerRadius} {padAngle} fill={s.color ?? cScale(c(d))} diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index be7d5641f..05e72b360 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -77,18 +77,18 @@

Single value (arc)

-
+
From 05aa8483c3c9b68974385fc775d065a87e8b7e6e Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 22:17:13 -0400 Subject: [PATCH 168/177] docs(Pie): Fix accidental search/replace --- .../layerchart/src/routes/docs/components/Pie/+page.svelte | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte index 8f4b33c57..0c2a7ad5f 100644 --- a/packages/layerchart/src/routes/docs/components/Pie/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/Pie/+page.svelte @@ -223,7 +223,7 @@ x={centroid[0]} y={centroid[1]} dy={-8} - textAnchoc="middle" + textAnchor="middle" verticalAnchoc="middle" class={cls('text-base', colors.content)} /> @@ -232,7 +232,7 @@ x={centroid[0]} y={centroid[1]} dy={8} - textAnchoc="middle" + textAnchor="middle" verticalAnchoc="middle" class={cls('text-sm opacity-50', colors.content)} /> @@ -301,7 +301,7 @@ value={formatUtil(arc.data.value / dataSum, 'percent')} x={centroid[0]} y={centroid[1]} - textAnchoc="middle" + textAnchor="middle" verticalAnchoc="middle" class={cls('text-base', colors.content)} /> From 967fb7bad70394fba4371890c005abd21908fc6b Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 22:22:35 -0400 Subject: [PATCH 169/177] docs(AreaChart): Use thresholdValue for Area y0 for better readability --- .../src/routes/docs/components/AreaChart/+page.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte index fa495dd19..3869d422d 100644 --- a/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/AreaChart/+page.svelte @@ -94,7 +94,7 @@ let:url > 0} + y0={(d) => thresholdValue} line={{ stroke: url, class: 'stroke-2' }} fill={url} fill-opacity={0.2} From 8de38b05192f73bcba5071ca63253aa126d05008 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Fri, 20 Sep 2024 22:48:04 -0400 Subject: [PATCH 170/177] feat(Points): Integrate with rScale. Add support with ScatterChart --- .changeset/short-colts-smash.md | 5 +++ .../src/lib/components/Points.svelte | 14 +++++--- .../lib/components/charts/ScatterChart.svelte | 20 ++++++++++-- .../docs/components/ScatterChart/+page.svelte | 32 +++++++++++++++++++ 4 files changed, 64 insertions(+), 7 deletions(-) create mode 100644 .changeset/short-colts-smash.md diff --git a/.changeset/short-colts-smash.md b/.changeset/short-colts-smash.md new file mode 100644 index 000000000..483148598 --- /dev/null +++ b/.changeset/short-colts-smash.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Points): Integrate with rScale diff --git a/packages/layerchart/src/lib/components/Points.svelte b/packages/layerchart/src/lib/components/Points.svelte index e8c507457..001e184f7 100644 --- a/packages/layerchart/src/lib/components/Points.svelte +++ b/packages/layerchart/src/lib/components/Points.svelte @@ -20,6 +20,7 @@ yScale, yGet, cGet, + rGet, padding, containerWidth, containerHeight, @@ -43,7 +44,7 @@ export let stroke: string | undefined = undefined; export let strokeWidth: number | string | undefined = undefined; - type Point = { x: number; y: number; xValue: any; yValue: any; data: any }; + type Point = { x: number; y: number; r: number; xValue: any; yValue: any; data: any }; /** Render to canvas */ export let render: ((ctx: CanvasRenderingContext2D, points: Point[]) => any) | undefined = @@ -83,6 +84,7 @@ return { x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + r: $config.r ? $rGet(d) : r, xValue, yValue, data: d, @@ -97,6 +99,7 @@ return { x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + r: $config.r ? $rGet(d) : r, xValue, yValue, data: d, @@ -110,6 +113,7 @@ return { x: $xScale(xValue) + getOffset($xScale(xValue), offsetX, $xScale), y: $yScale(yValue) + getOffset($yScale(yValue), offsetY, $yScale), + r: $config.r ? $rGet(d) : r, xValue, yValue, data: d, @@ -131,11 +135,11 @@ const y = $yGet(d) + getOffset($yGet(d), offsetY, $yScale); return { source: { - x: xMin + getOffset(xMin, offsetX, $xScale) + r, + x: xMin + getOffset(xMin, offsetX, $xScale) + ($config.r ? $rGet(d) : r), y, }, target: { - x: xMax + getOffset(xMax, offsetX, $xScale) - r, + x: xMax + getOffset(xMax, offsetX, $xScale) - ($config.r ? $rGet(d) : r), y: y, }, }; @@ -178,7 +182,7 @@ } else { points.forEach((point) => { $ctx.beginPath(); - $ctx.arc(point.x, point.y, r, 0, 2 * Math.PI, false); + $ctx.arc(point.x, point.y, point.r, 0, 2 * Math.PI, false); $ctx.lineWidth = Number(strokeWidth ?? 0); $ctx.strokeStyle = @@ -217,7 +221,7 @@ {/if} - - + + + {#if config.r} + + {/if} diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte index 69c0860d8..6235d9858 100644 --- a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte @@ -26,6 +26,14 @@
+

Radius via rScale

+ + +
+ +
+
+

Series

@@ -48,6 +56,30 @@
+

Series with radius

+ + +
+ { + return { + key: species, + data, + color: [ + 'hsl(var(--color-primary))', + 'hsl(var(--color-secondary))', + 'hsl(var(--color-success))', + ][i], + }; + })} + /> +
+
+

Labels

From 6b4b164beb4b2afe9266efa6b3ab9d32e5554055 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sat, 21 Sep 2024 18:39:12 -0400 Subject: [PATCH 171/177] docs(PieChart): Add "Single value gradient with text" example --- .../docs/components/PieChart/+page.svelte | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte index 05e72b360..65127dfe9 100644 --- a/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/PieChart/+page.svelte @@ -1,5 +1,5 @@

Examples

@@ -26,6 +30,20 @@
+

Single dimension

+ + +
+ 0} + axis={false} + props={{ highlight: { lines: false } }} + /> +
+
+

Radius via rScale

diff --git a/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte b/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte index deefcdd60..6466f95f6 100644 --- a/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte +++ b/packages/layerchart/src/routes/docs/examples/Sparkbar/+page.svelte @@ -22,7 +22,7 @@

Basic

-
+
@@ -37,7 +37,7 @@

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam pretium, ligula ac sollicitudin ullamcorper, leo justo pretium tellus, at gravida ex quam et orci. - + @@ -52,7 +52,7 @@

Basic negative data

-
+
@@ -64,7 +64,7 @@

With Tooltip and Highlight

-
+
With Tooltip and Highlight (fixed position) -
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam pretium, ligula ac sollicitudin ullamcorper, leo justo pretium tellus, at gravida ex quam et orci. - + Basic
-
+
@@ -31,7 +31,7 @@

Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam pretium, ligula ac sollicitudin ullamcorper, leo justo pretium tellus, at gravida ex quam et orci. - + @@ -45,7 +45,7 @@

Basic zero axis

-
+
@@ -56,7 +56,7 @@

With Tooltip and Highlight

-
+
@@ -75,7 +75,7 @@

With Tooltip and Highlight (fixed position)

-
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam pretium, ligula ac sollicitudin ullamcorper, leo justo pretium tellus, at gravida ex quam et orci. - + Date: Sun, 22 Sep 2024 21:20:57 -0400 Subject: [PATCH 173/177] feat(Bars): Support passing `data` override --- .changeset/chilly-years-vanish.md | 5 +++++ packages/layerchart/src/lib/components/Bars.svelte | 9 +++++++-- 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 .changeset/chilly-years-vanish.md diff --git a/.changeset/chilly-years-vanish.md b/.changeset/chilly-years-vanish.md new file mode 100644 index 000000000..50a93e40a --- /dev/null +++ b/.changeset/chilly-years-vanish.md @@ -0,0 +1,5 @@ +--- +'layerchart': patch +--- + +feat(Bars): Support passing `data` override diff --git a/packages/layerchart/src/lib/components/Bars.svelte b/packages/layerchart/src/lib/components/Bars.svelte index d2518ae6e..ea5507690 100644 --- a/packages/layerchart/src/lib/components/Bars.svelte +++ b/packages/layerchart/src/lib/components/Bars.svelte @@ -6,7 +6,12 @@ import Rect from './Rect.svelte'; import { chartDataArray, type Accessor } from '../utils/common.js'; - const { data, cGet, config } = chartContext(); + const { data: contextData, cGet, config } = chartContext(); + + /** + * Override `data` from context. Useful for multiple Bar instances + */ + export let data: any = undefined; /** * Override `x` from context. Useful for multiple Bar instances @@ -41,7 +46,7 @@ - {#each chartDataArray($data) as item} + {#each chartDataArray(data ?? $contextData) as item} Date: Sun, 22 Sep 2024 21:27:46 -0400 Subject: [PATCH 174/177] feat(BarChart): Support passing series (long) data --- .../src/lib/components/charts/BarChart.svelte | 19 +++- .../docs/components/BarChart/+page.svelte | 101 +++++++++++++++++- .../docs/components/ScatterChart/+page.svelte | 34 +++--- 3 files changed, 135 insertions(+), 19 deletions(-) diff --git a/packages/layerchart/src/lib/components/charts/BarChart.svelte b/packages/layerchart/src/lib/components/charts/BarChart.svelte index 06ca2fbea..8d21617d7 100644 --- a/packages/layerchart/src/lib/components/charts/BarChart.svelte +++ b/packages/layerchart/src/lib/components/charts/BarChart.svelte @@ -98,7 +98,11 @@ } = {}; $: allSeriesData = series - .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d }))) + .flatMap((s) => + s.data?.map((d) => { + return { seriesKey: s.key, ...d }; + }) + ) .filter((d) => d) as Array; $: chartData = (allSeriesData.length ? allSeriesData : chartDataArray(data)) as Array< @@ -181,8 +185,17 @@ {#each series as s, i} d.stackData[i] : (s.value ?? s.key)) : undefined} - y={isVertical ? (stackSeries ? (d) => d.stackData[i] : (s.value ?? s.key)) : undefined} + data={s.data} + x={!isVertical + ? stackSeries + ? (d) => d.stackData[i] + : (s.value ?? (s.data ? undefined : s.key)) + : undefined} + y={isVertical + ? stackSeries + ? (d) => d.stackData[i] + : (s.value ?? (s.data ? undefined : s.key)) + : undefined} x1={isVertical && groupSeries ? (d) => s.value ?? s.key : undefined} y1={!isVertical && groupSeries ? (d) => s.value ?? s.key : undefined} radius={4} diff --git a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte index 9bea96b1d..fabd06940 100644 --- a/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/BarChart/+page.svelte @@ -1,14 +1,16 @@

Examples

@@ -72,6 +75,30 @@
+

Series data

+ + +
+ +
+
+

Series (diverging)

@@ -282,6 +309,40 @@
+

Group series (series / long data)

+ + +
+ +
+
+

Stack series

@@ -345,6 +406,42 @@
+ + +

Labels

diff --git a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte index 2272a4a8e..54a4cdfd3 100644 --- a/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte +++ b/packages/layerchart/src/routes/docs/components/ScatterChart/+page.svelte @@ -30,20 +30,6 @@
-

Single dimension

- - -
- 0} - axis={false} - props={{ highlight: { lines: false } }} - /> -
-
-

Radius via rScale

@@ -106,6 +92,26 @@
+

Single dimension

+ + +
+ 0} + axis={false} + props={{ highlight: { lines: false } }} + > + + + {format(x(data))} + + + +
+
+

Custom tooltip

From 0008ee6f5f4c0894f921cb7c3126e8c96bd50312 Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Sun, 22 Sep 2024 21:35:17 -0400 Subject: [PATCH 175/177] Add changeset for new simplified charts (AreaChart, BarChart, LineChart, PieChart, and ScatterChart) --- .changeset/cool-needles-divide.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/cool-needles-divide.md diff --git a/.changeset/cool-needles-divide.md b/.changeset/cool-needles-divide.md new file mode 100644 index 000000000..b3b2e5047 --- /dev/null +++ b/.changeset/cool-needles-divide.md @@ -0,0 +1,5 @@ +--- +'layerchart': minor +--- + +Add simplified charts to streamline creating common chart types with recommended conventions and granular extensibility (AreaChart, BarChart, LineChart, PieChart, and ScatterChart) From 79079d57e2c35bb8f8df569ec16782e3bb70fc7c Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 23 Sep 2024 08:06:04 -0400 Subject: [PATCH 176/177] Tweak changeset --- .changeset/cool-needles-divide.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/cool-needles-divide.md b/.changeset/cool-needles-divide.md index b3b2e5047..ccc3f07d5 100644 --- a/.changeset/cool-needles-divide.md +++ b/.changeset/cool-needles-divide.md @@ -2,4 +2,4 @@ 'layerchart': minor --- -Add simplified charts to streamline creating common chart types with recommended conventions and granular extensibility (AreaChart, BarChart, LineChart, PieChart, and ScatterChart) +feat: Add simplified charts to streamline creating common chart types with recommended conventions and granular extensibility (AreaChart, BarChart, LineChart, PieChart, and ScatterChart) From 12118feb964e8db82f448c03cdc956e764abb2df Mon Sep 17 00:00:00 2001 From: Sean Lynch Date: Mon, 23 Sep 2024 08:19:42 -0400 Subject: [PATCH 177/177] fix(Svg): Fix center reactivity with width/height changes --- packages/layerchart/src/lib/components/layout/Svg.svelte | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/layerchart/src/lib/components/layout/Svg.svelte b/packages/layerchart/src/lib/components/layout/Svg.svelte index d4a2fe7ed..35f014c57 100644 --- a/packages/layerchart/src/lib/components/layout/Svg.svelte +++ b/packages/layerchart/src/lib/components/layout/Svg.svelte @@ -40,7 +40,7 @@ const { mode, scale, translate } = transformContext(); - let transform = center + $: transform = center ? `translate(${center === 'x' || center === true ? $width / 2 : 0}, ${center === 'y' || center === true ? $height / 2 : 0})` : ''; $: if (mode === 'canvas') {