layerchart 2.0.0-next.3 → 2.0.0-next.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/AnnotationPoint.svelte +16 -9
- package/dist/components/AnnotationRange.svelte +3 -3
- package/dist/components/Arc.svelte +2 -2
- package/dist/components/Axis.svelte +63 -14
- package/dist/components/Axis.svelte.d.ts +12 -2
- package/dist/components/Blur.svelte +5 -3
- package/dist/components/Blur.svelte.d.ts +2 -5
- package/dist/components/BrushContext.svelte +1 -1
- package/dist/components/Calendar.svelte +10 -6
- package/dist/components/Calendar.svelte.d.ts +2 -1
- package/dist/components/Chart.svelte +2 -2
- package/dist/components/Connector.svelte +2 -2
- package/dist/components/Connector.svelte.d.ts +1 -1
- package/dist/components/Ellipse.svelte +187 -0
- package/dist/components/Ellipse.svelte.d.ts +64 -0
- package/dist/components/ForceSimulation.svelte +168 -50
- package/dist/components/ForceSimulation.svelte.d.ts +80 -21
- package/dist/components/GeoPath.svelte +12 -5
- package/dist/components/GeoPoint.svelte +1 -2
- package/dist/components/GeoSpline.svelte +4 -4
- package/dist/components/GeoSpline.svelte.d.ts +1 -1
- package/dist/components/Group.svelte +2 -2
- package/dist/components/Highlight.svelte +2 -2
- package/dist/components/Hull.svelte +1 -1
- package/dist/components/Labels.svelte +3 -2
- package/dist/components/Labels.svelte.d.ts +2 -2
- package/dist/components/Legend.svelte +19 -12
- package/dist/components/Legend.svelte.d.ts +5 -5
- package/dist/components/MonthPath.svelte +14 -11
- package/dist/components/MonthPath.svelte.d.ts +4 -3
- package/dist/components/Polygon.svelte +285 -0
- package/dist/components/Polygon.svelte.d.ts +115 -0
- package/dist/components/RadialGradient.svelte +1 -3
- package/dist/components/Spline.svelte +30 -18
- package/dist/components/Spline.svelte.d.ts +12 -4
- package/dist/components/Text.svelte +62 -60
- package/dist/components/Text.svelte.d.ts +6 -0
- package/dist/components/TransformControls.svelte +16 -20
- package/dist/components/Treemap.svelte +63 -26
- package/dist/components/Treemap.svelte.d.ts +11 -11
- package/dist/components/Voronoi.svelte +51 -33
- package/dist/components/Voronoi.svelte.d.ts +3 -1
- package/dist/components/charts/ArcChart.svelte +5 -3
- package/dist/components/charts/AreaChart.svelte +11 -11
- package/dist/components/charts/BarChart.svelte +64 -53
- package/dist/components/charts/DefaultTooltip.svelte +1 -1
- package/dist/components/charts/LineChart.svelte +10 -6
- package/dist/components/charts/PieChart.svelte +5 -3
- package/dist/components/charts/ScatterChart.svelte +2 -3
- package/dist/components/charts/utils.svelte.d.ts +2 -2
- package/dist/components/charts/utils.svelte.js +5 -1
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +5 -1
- package/dist/components/layout/Canvas.svelte +67 -49
- package/dist/components/layout/Canvas.svelte.d.ts +6 -0
- package/dist/components/layout/Layer.svelte +6 -4
- package/dist/components/layout/Layer.svelte.d.ts +6 -4
- package/dist/components/tooltip/Tooltip.svelte +14 -7
- package/dist/components/tooltip/TooltipContext.svelte +78 -34
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +3 -3
- package/dist/components/tooltip/TooltipHeader.svelte +5 -4
- package/dist/components/tooltip/TooltipHeader.svelte.d.ts +3 -3
- package/dist/components/tooltip/TooltipItem.svelte +5 -4
- package/dist/components/tooltip/TooltipItem.svelte.d.ts +3 -3
- package/dist/components/tooltip/TooltipList.svelte +1 -1
- package/dist/components/tooltip/tooltipMetaContext.d.ts +2 -2
- package/dist/docs/Blockquote.svelte +6 -4
- package/dist/docs/Blockquote.svelte.d.ts +4 -19
- package/dist/docs/Code.svelte +20 -12
- package/dist/docs/Code.svelte.d.ts +9 -23
- package/dist/docs/Header1.svelte +4 -2
- package/dist/docs/Header1.svelte.d.ts +4 -28
- package/dist/docs/Json.svelte +11 -3
- package/dist/docs/Json.svelte.d.ts +9 -21
- package/dist/docs/Layout.svelte +10 -7
- package/dist/docs/Layout.svelte.d.ts +4 -19
- package/dist/docs/Link.svelte +7 -3
- package/dist/docs/Link.svelte.d.ts +4 -38
- package/dist/docs/Preview.svelte +6 -3
- package/dist/docs/TilesetField.svelte +20 -19
- package/dist/docs/TilesetField.svelte.d.ts +5 -22
- package/dist/docs/ViewSourceButton.svelte +9 -6
- package/dist/docs/ViewSourceButton.svelte.d.ts +7 -21
- package/dist/utils/arcText.svelte.js +4 -4
- package/dist/utils/array.d.ts +11 -0
- package/dist/utils/array.js +23 -0
- package/dist/utils/array.test.d.ts +1 -0
- package/dist/utils/array.test.js +200 -0
- package/dist/utils/canvas.d.ts +77 -0
- package/dist/utils/canvas.js +105 -41
- package/dist/utils/genData.d.ts +14 -0
- package/dist/utils/genData.js +24 -6
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.js +1 -0
- package/dist/utils/path.d.ts +10 -0
- package/dist/utils/path.js +30 -0
- package/dist/utils/scales.svelte.d.ts +3 -2
- package/dist/utils/scales.svelte.js +7 -3
- package/dist/utils/shape.d.ts +43 -0
- package/dist/utils/shape.js +59 -0
- package/dist/utils/string.d.ts +49 -0
- package/dist/utils/string.js +4 -2
- package/dist/utils/ticks.d.ts +15 -4
- package/dist/utils/ticks.js +140 -159
- package/dist/utils/ticks.test.js +6 -16
- package/dist/utils/treemap.d.ts +1 -1
- package/package.json +27 -25
- package/dist/utils/object.js +0 -2
|
@@ -10,47 +10,47 @@ export type TreemapProps<T> = {
|
|
|
10
10
|
*
|
|
11
11
|
* @default 0
|
|
12
12
|
*/
|
|
13
|
-
padding?: number;
|
|
13
|
+
padding?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
14
14
|
/**
|
|
15
15
|
* The inner padding between nodes.
|
|
16
16
|
*
|
|
17
17
|
* @default 0
|
|
18
18
|
*/
|
|
19
|
-
paddingInner?: number;
|
|
19
|
+
paddingInner?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
20
20
|
/**
|
|
21
21
|
* The outer padding between nodes.
|
|
22
22
|
*
|
|
23
23
|
* @default 0
|
|
24
24
|
*/
|
|
25
|
-
paddingOuter?: number;
|
|
25
|
+
paddingOuter?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
26
26
|
/**
|
|
27
27
|
* The top padding between nodes.
|
|
28
28
|
*
|
|
29
29
|
* @default 0
|
|
30
30
|
*/
|
|
31
|
-
paddingTop?: number;
|
|
31
|
+
paddingTop?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
32
32
|
/**
|
|
33
33
|
* The bottom padding between nodes.
|
|
34
34
|
*
|
|
35
35
|
* @default 0
|
|
36
36
|
*/
|
|
37
|
-
paddingBottom?: number;
|
|
37
|
+
paddingBottom?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
38
38
|
/**
|
|
39
39
|
* The left padding between nodes.
|
|
40
40
|
*
|
|
41
41
|
*/
|
|
42
|
-
paddingLeft?: number;
|
|
42
|
+
paddingLeft?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
43
43
|
/**
|
|
44
44
|
* The right padding between nodes.
|
|
45
45
|
*
|
|
46
46
|
*/
|
|
47
|
-
paddingRight?: number;
|
|
47
|
+
paddingRight?: number | ((node: HierarchyRectangularNode<T>) => number);
|
|
48
48
|
/**
|
|
49
|
-
*
|
|
49
|
+
* Modify tiling function for approapriate aspect ratio when treemap is zoomed in
|
|
50
50
|
*
|
|
51
|
-
* @default
|
|
51
|
+
* @default false
|
|
52
52
|
*/
|
|
53
|
-
|
|
53
|
+
maintainAspectRatio?: boolean;
|
|
54
54
|
hierarchy?: HierarchyNode<T>;
|
|
55
55
|
children?: Snippet<[{
|
|
56
56
|
nodes: HierarchyRectangularNode<T>[];
|
|
@@ -62,7 +62,7 @@ declare class __sveltets_Render<T> {
|
|
|
62
62
|
props(): TreemapProps<T>;
|
|
63
63
|
events(): {};
|
|
64
64
|
slots(): {};
|
|
65
|
-
bindings(): "
|
|
65
|
+
bindings(): "";
|
|
66
66
|
exports(): {};
|
|
67
67
|
}
|
|
68
68
|
interface $$IsomorphicComponent {
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import type { Without } from '../utils/types.js';
|
|
3
|
-
import type { SVGAttributes } from 'svelte/elements';
|
|
4
3
|
|
|
5
4
|
export type VoronoiPropsWithoutHTML = {
|
|
6
5
|
/**
|
|
@@ -8,6 +7,9 @@
|
|
|
8
7
|
*/
|
|
9
8
|
data?: any;
|
|
10
9
|
|
|
10
|
+
/** Radius to clip voronoi cells. `0` or `undefined` to disables clipping */
|
|
11
|
+
r?: number;
|
|
12
|
+
|
|
11
13
|
/**
|
|
12
14
|
* Classes to apply to the root and path elements
|
|
13
15
|
*
|
|
@@ -56,7 +58,7 @@
|
|
|
56
58
|
<script lang="ts">
|
|
57
59
|
import { min } from 'd3-array';
|
|
58
60
|
import { Delaunay } from 'd3-delaunay';
|
|
59
|
-
import type
|
|
61
|
+
import { type GeoPermissibleObjects } from 'd3-geo';
|
|
60
62
|
// @ts-expect-error
|
|
61
63
|
import { geoVoronoi } from 'd3-geo-voronoi';
|
|
62
64
|
import { pointRadial } from 'd3-shape';
|
|
@@ -67,10 +69,13 @@
|
|
|
67
69
|
import Spline from './Spline.svelte';
|
|
68
70
|
import { getChartContext } from './Chart.svelte';
|
|
69
71
|
import { getGeoContext } from './GeoContext.svelte';
|
|
72
|
+
import CircleClipPath from './CircleClipPath.svelte';
|
|
73
|
+
|
|
70
74
|
import { layerClass } from '../utils/attributes.js';
|
|
71
75
|
|
|
72
76
|
let {
|
|
73
77
|
data,
|
|
78
|
+
r,
|
|
74
79
|
classes = {},
|
|
75
80
|
onclick,
|
|
76
81
|
onpointerenter,
|
|
@@ -109,53 +114,66 @@
|
|
|
109
114
|
// Width and/or height can sometimes be negative (when loading data remotely and updately)
|
|
110
115
|
const boundWidth = $derived(Math.max(ctx.width, 0));
|
|
111
116
|
const boundHeight = $derived(Math.max(ctx.height, 0));
|
|
117
|
+
|
|
118
|
+
const disableClip = $derived(r === 0 || r == null || r === Infinity);
|
|
112
119
|
</script>
|
|
113
120
|
|
|
114
121
|
<Group {...restProps} class={cls(layerClass('voronoi-g'), classes.root, className)}>
|
|
115
122
|
{#if geo.projection}
|
|
116
123
|
{@const polygons = geoVoronoi().polygons(points)}
|
|
117
124
|
{#each polygons.features as feature}
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
onpointermove={(e) => onpointermove?.(e, { data: feature.properties.site.data, feature })}
|
|
128
|
-
onpointerdown={(e) => onpointerdown?.(e, { data: feature.properties.site.data, feature })}
|
|
129
|
-
{onpointerleave}
|
|
130
|
-
ontouchmove={(e) => {
|
|
131
|
-
// Prevent touch to not interfere with pointer
|
|
132
|
-
e.preventDefault();
|
|
133
|
-
}}
|
|
134
|
-
/>
|
|
135
|
-
{/each}
|
|
136
|
-
{:else}
|
|
137
|
-
{@const voronoi = Delaunay.from(points).voronoi([0, 0, boundWidth, boundHeight])}
|
|
138
|
-
{#each points as point, i}
|
|
139
|
-
{@const pathData = voronoi.renderCell(i)}
|
|
140
|
-
<!-- Wait to render Spline until pathData is available to fix path artifacts from injected tweened points in Spline -->
|
|
141
|
-
{#if pathData}
|
|
142
|
-
<Spline
|
|
143
|
-
{pathData}
|
|
125
|
+
{@const point = r ? geo.projection?.(feature.properties.sitecoordinates) : null}
|
|
126
|
+
<CircleClipPath
|
|
127
|
+
cx={point?.[0]}
|
|
128
|
+
cy={point?.[1]}
|
|
129
|
+
r={r ?? 0}
|
|
130
|
+
disabled={point == null || disableClip}
|
|
131
|
+
>
|
|
132
|
+
<GeoPath
|
|
133
|
+
geojson={feature}
|
|
144
134
|
class={cls(
|
|
145
|
-
layerClass('voronoi-path'),
|
|
135
|
+
layerClass('voronoi-geo-path'),
|
|
146
136
|
'fill-transparent stroke-transparent',
|
|
147
137
|
classes.path
|
|
148
138
|
)}
|
|
149
|
-
onclick={(e) => onclick?.(e, { data:
|
|
150
|
-
onpointerenter={(e) =>
|
|
151
|
-
|
|
139
|
+
onclick={(e) => onclick?.(e, { data: feature.properties.site.data, feature })}
|
|
140
|
+
onpointerenter={(e) =>
|
|
141
|
+
onpointerenter?.(e, { data: feature.properties.site.data, feature })}
|
|
142
|
+
onpointermove={(e) => onpointermove?.(e, { data: feature.properties.site.data, feature })}
|
|
143
|
+
onpointerdown={(e) => onpointerdown?.(e, { data: feature.properties.site.data, feature })}
|
|
152
144
|
{onpointerleave}
|
|
153
|
-
onpointerdown={(e) => onpointerdown?.(e, { data: point.data, point })}
|
|
154
145
|
ontouchmove={(e) => {
|
|
155
146
|
// Prevent touch to not interfere with pointer
|
|
156
147
|
e.preventDefault();
|
|
157
148
|
}}
|
|
158
149
|
/>
|
|
150
|
+
</CircleClipPath>
|
|
151
|
+
{/each}
|
|
152
|
+
{:else}
|
|
153
|
+
{@const voronoi = Delaunay.from(points).voronoi([0, 0, boundWidth, boundHeight])}
|
|
154
|
+
{#each points as point, i}
|
|
155
|
+
{@const pathData = voronoi.renderCell(i)}
|
|
156
|
+
<!-- Wait to render Spline until pathData is available to fix path artifacts from injected tweened points in Spline -->
|
|
157
|
+
{#if pathData}
|
|
158
|
+
<CircleClipPath cx={point[0]} cy={point[1]} r={r ?? 0} disabled={disableClip}>
|
|
159
|
+
<Spline
|
|
160
|
+
{pathData}
|
|
161
|
+
class={cls(
|
|
162
|
+
layerClass('voronoi-path'),
|
|
163
|
+
'fill-transparent stroke-transparent',
|
|
164
|
+
classes.path
|
|
165
|
+
)}
|
|
166
|
+
onclick={(e) => onclick?.(e, { data: point.data, point })}
|
|
167
|
+
onpointerenter={(e) => onpointerenter?.(e, { data: point.data, point })}
|
|
168
|
+
onpointermove={(e) => onpointermove?.(e, { data: point.data, point })}
|
|
169
|
+
{onpointerleave}
|
|
170
|
+
onpointerdown={(e) => onpointerdown?.(e, { data: point.data, point })}
|
|
171
|
+
ontouchmove={(e) => {
|
|
172
|
+
// Prevent touch to not interfere with pointer
|
|
173
|
+
e.preventDefault();
|
|
174
|
+
}}
|
|
175
|
+
/>
|
|
176
|
+
</CircleClipPath>
|
|
159
177
|
{/if}
|
|
160
178
|
{/each}
|
|
161
179
|
{/if}
|
|
@@ -4,6 +4,8 @@ export type VoronoiPropsWithoutHTML = {
|
|
|
4
4
|
* Override data instead of using context
|
|
5
5
|
*/
|
|
6
6
|
data?: any;
|
|
7
|
+
/** Radius to clip voronoi cells. `0` or `undefined` to disables clipping */
|
|
8
|
+
r?: number;
|
|
7
9
|
/**
|
|
8
10
|
* Classes to apply to the root and path elements
|
|
9
11
|
*
|
|
@@ -35,7 +37,7 @@ export type VoronoiPropsWithoutHTML = {
|
|
|
35
37
|
}) => void;
|
|
36
38
|
};
|
|
37
39
|
export type VoronoiProps = VoronoiPropsWithoutHTML & Without<Omit<GroupProps, 'children'>, VoronoiPropsWithoutHTML>;
|
|
38
|
-
import type
|
|
40
|
+
import { type GeoPermissibleObjects } from 'd3-geo';
|
|
39
41
|
import { type GroupProps } from './Group.svelte';
|
|
40
42
|
declare const Voronoi: import("svelte").Component<VoronoiProps, {}, "">;
|
|
41
43
|
type Voronoi = ReturnType<typeof Voronoi>;
|
|
@@ -264,8 +264,8 @@
|
|
|
264
264
|
placement: 'bottom',
|
|
265
265
|
variant: 'swatches',
|
|
266
266
|
onclick: (e, item) => {
|
|
267
|
-
selectedKeys.
|
|
268
|
-
selectedSeries.
|
|
267
|
+
selectedKeys.toggle(item.value);
|
|
268
|
+
selectedSeries.toggle(item.value);
|
|
269
269
|
},
|
|
270
270
|
onpointerenter: (e, item) => (highlightKey.current = item.value),
|
|
271
271
|
onpointerleave: (e) => (highlightKey.current = null),
|
|
@@ -384,7 +384,9 @@
|
|
|
384
384
|
]}
|
|
385
385
|
padding={{ bottom: legend === true ? 32 : 0 }}
|
|
386
386
|
{...restProps}
|
|
387
|
-
tooltip={tooltip === false
|
|
387
|
+
tooltip={tooltip === false
|
|
388
|
+
? false
|
|
389
|
+
: { ...props.tooltip?.context, ...(typeof tooltip === 'object' ? tooltip : null) }}
|
|
388
390
|
>
|
|
389
391
|
{#snippet children({ context })}
|
|
390
392
|
{@const snippetProps = {
|
|
@@ -69,7 +69,6 @@
|
|
|
69
69
|
import { onMount, type ComponentProps } from 'svelte';
|
|
70
70
|
import { scaleLinear, scaleTime } from 'd3-scale';
|
|
71
71
|
import { stack, stackOffsetDiverging, stackOffsetExpand, stackOffsetNone } from 'd3-shape';
|
|
72
|
-
import { format } from '@layerstack/utils';
|
|
73
72
|
import { cls } from '@layerstack/tailwind';
|
|
74
73
|
|
|
75
74
|
import Area from '../Area.svelte';
|
|
@@ -136,7 +135,14 @@
|
|
|
136
135
|
|
|
137
136
|
const series = $derived(
|
|
138
137
|
seriesProp === undefined
|
|
139
|
-
? [
|
|
138
|
+
? [
|
|
139
|
+
{
|
|
140
|
+
key: 'default',
|
|
141
|
+
label: typeof y === 'string' ? y : 'value',
|
|
142
|
+
value: y,
|
|
143
|
+
color: 'var(--color-primary)',
|
|
144
|
+
},
|
|
145
|
+
]
|
|
140
146
|
: seriesProp
|
|
141
147
|
);
|
|
142
148
|
|
|
@@ -398,13 +404,7 @@
|
|
|
398
404
|
if (axisDirection === 'y') {
|
|
399
405
|
return {
|
|
400
406
|
placement: radial ? 'radius' : 'left',
|
|
401
|
-
format:
|
|
402
|
-
if (seriesLayout === 'stackExpand') {
|
|
403
|
-
return format(value, 'percentRound');
|
|
404
|
-
} else {
|
|
405
|
-
return format(value, undefined, { variant: 'short' });
|
|
406
|
-
}
|
|
407
|
-
},
|
|
407
|
+
format: seriesLayout === 'stackExpand' ? 'percentRound' : undefined,
|
|
408
408
|
...(typeof axis === 'object' ? axis : null),
|
|
409
409
|
...props.yAxis,
|
|
410
410
|
};
|
|
@@ -412,7 +412,6 @@
|
|
|
412
412
|
|
|
413
413
|
return {
|
|
414
414
|
placement: radial ? 'angle' : 'bottom',
|
|
415
|
-
format: (value) => format(value, undefined, { variant: 'short' }),
|
|
416
415
|
...(typeof axis === 'object' ? axis : null),
|
|
417
416
|
...props.xAxis,
|
|
418
417
|
};
|
|
@@ -444,10 +443,11 @@
|
|
|
444
443
|
tooltip={tooltip === false
|
|
445
444
|
? false
|
|
446
445
|
: {
|
|
447
|
-
mode: '
|
|
446
|
+
mode: 'quadtree-x',
|
|
448
447
|
onclick: onTooltipClick,
|
|
449
448
|
debug,
|
|
450
449
|
...props.tooltip?.context,
|
|
450
|
+
...(typeof tooltip === 'object' ? tooltip : null),
|
|
451
451
|
}}
|
|
452
452
|
brush={brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')
|
|
453
453
|
? {
|
|
@@ -84,9 +84,8 @@
|
|
|
84
84
|
|
|
85
85
|
<script lang="ts" generics="TData">
|
|
86
86
|
import { onMount, type ComponentProps } from 'svelte';
|
|
87
|
-
import { scaleBand, scaleLinear } from 'd3-scale';
|
|
87
|
+
import { scaleBand, scaleLinear, scaleTime } from 'd3-scale';
|
|
88
88
|
import { stack, stackOffsetDiverging, stackOffsetExpand, stackOffsetNone } from 'd3-shape';
|
|
89
|
-
import { format } from '@layerstack/utils';
|
|
90
89
|
import { cls } from '@layerstack/tailwind';
|
|
91
90
|
|
|
92
91
|
import Axis from '../Axis.svelte';
|
|
@@ -109,7 +108,7 @@
|
|
|
109
108
|
import { asAny } from '../../utils/types.js';
|
|
110
109
|
import type { Insets } from '../../utils/rect.svelte.js';
|
|
111
110
|
import type { SeriesData, SimplifiedChartProps, SimplifiedChartPropsObject } from './types.js';
|
|
112
|
-
import type
|
|
111
|
+
import { isScaleTime, type AnyScale } from '../../utils/scales.svelte.js';
|
|
113
112
|
import { createLegendProps, SeriesState } from './utils.svelte.js';
|
|
114
113
|
import { setTooltipMetaContext } from '../tooltip/tooltipMetaContext.js';
|
|
115
114
|
import DefaultTooltip from './DefaultTooltip.svelte';
|
|
@@ -160,6 +159,14 @@
|
|
|
160
159
|
? [
|
|
161
160
|
{
|
|
162
161
|
key: 'default',
|
|
162
|
+
label:
|
|
163
|
+
orientation === 'vertical'
|
|
164
|
+
? typeof yProp === 'string'
|
|
165
|
+
? yProp
|
|
166
|
+
: 'value'
|
|
167
|
+
: typeof xProp === 'string'
|
|
168
|
+
? xProp
|
|
169
|
+
: 'value',
|
|
163
170
|
value: orientation === 'vertical' ? yProp : xProp,
|
|
164
171
|
},
|
|
165
172
|
]
|
|
@@ -171,15 +178,56 @@
|
|
|
171
178
|
const isStackSeries = $derived(seriesLayout.startsWith('stack'));
|
|
172
179
|
const isGroupSeries = $derived(seriesLayout === 'group');
|
|
173
180
|
|
|
181
|
+
const chartData: Array<TData & { stackData?: any }> = $derived.by(() => {
|
|
182
|
+
let _chartData = (
|
|
183
|
+
seriesState.allSeriesData.length ? seriesState.allSeriesData : chartDataArray(data)
|
|
184
|
+
) as Array<TData & { stackData?: any }>;
|
|
185
|
+
if (isStackSeries) {
|
|
186
|
+
const seriesKeys = seriesState.visibleSeries.map((s) => s.key);
|
|
187
|
+
|
|
188
|
+
const offset =
|
|
189
|
+
seriesLayout === 'stackExpand'
|
|
190
|
+
? stackOffsetExpand
|
|
191
|
+
: seriesLayout === 'stackDiverging'
|
|
192
|
+
? stackOffsetDiverging
|
|
193
|
+
: stackOffsetNone;
|
|
194
|
+
const stackData = stack()
|
|
195
|
+
.keys(seriesKeys)
|
|
196
|
+
.value((d, key) => {
|
|
197
|
+
const s = series.find((d) => d.key === key)!;
|
|
198
|
+
return accessor(s.value ?? s.key)(d as any);
|
|
199
|
+
})
|
|
200
|
+
.offset(offset)(chartDataArray(data)) as any[];
|
|
201
|
+
|
|
202
|
+
_chartData = _chartData.map((d, i) => {
|
|
203
|
+
return {
|
|
204
|
+
...d,
|
|
205
|
+
stackData: stackData.map((sd) => sd[i]),
|
|
206
|
+
};
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
return _chartData;
|
|
210
|
+
});
|
|
211
|
+
|
|
174
212
|
const xScale = $derived(
|
|
175
|
-
xScaleProp ??
|
|
213
|
+
xScaleProp ??
|
|
214
|
+
(isVertical
|
|
215
|
+
? scaleBand().padding(bandPadding)
|
|
216
|
+
: accessor(xProp)(chartData[0]) instanceof Date // TODO: also check for Array<Date> instances (ex. x={['start', 'end']})
|
|
217
|
+
? scaleTime()
|
|
218
|
+
: scaleLinear())
|
|
176
219
|
);
|
|
177
|
-
const xBaseline = $derived(isVertical ? undefined : 0);
|
|
220
|
+
const xBaseline = $derived(isVertical || isScaleTime(xScale) ? undefined : 0);
|
|
178
221
|
|
|
179
222
|
const yScale = $derived(
|
|
180
|
-
yScaleProp ??
|
|
223
|
+
yScaleProp ??
|
|
224
|
+
(isVertical
|
|
225
|
+
? accessor(yProp)(chartData[0]) instanceof Date // TODO: also check for Array<Date> instances (ex. y={['start', 'end']})
|
|
226
|
+
? scaleTime()
|
|
227
|
+
: scaleLinear()
|
|
228
|
+
: scaleBand().padding(bandPadding))
|
|
181
229
|
);
|
|
182
|
-
const yBaseline = $derived(isVertical ? 0 : undefined);
|
|
230
|
+
const yBaseline = $derived(isVertical || isScaleTime(yScale) ? 0 : undefined);
|
|
183
231
|
|
|
184
232
|
const x1Scale = $derived(
|
|
185
233
|
isGroupSeries && isVertical ? scaleBand().padding(groupPadding) : undefined
|
|
@@ -214,37 +262,6 @@
|
|
|
214
262
|
return d && typeof d === 'object' && 'stackData' in d;
|
|
215
263
|
}
|
|
216
264
|
|
|
217
|
-
const chartData: Array<TData & { stackData?: any }> = $derived.by(() => {
|
|
218
|
-
let _chartData = (
|
|
219
|
-
seriesState.allSeriesData.length ? seriesState.allSeriesData : chartDataArray(data)
|
|
220
|
-
) as Array<TData & { stackData?: any }>;
|
|
221
|
-
if (isStackSeries) {
|
|
222
|
-
const seriesKeys = seriesState.visibleSeries.map((s) => s.key);
|
|
223
|
-
|
|
224
|
-
const offset =
|
|
225
|
-
seriesLayout === 'stackExpand'
|
|
226
|
-
? stackOffsetExpand
|
|
227
|
-
: seriesLayout === 'stackDiverging'
|
|
228
|
-
? stackOffsetDiverging
|
|
229
|
-
: stackOffsetNone;
|
|
230
|
-
const stackData = stack()
|
|
231
|
-
.keys(seriesKeys)
|
|
232
|
-
.value((d, key) => {
|
|
233
|
-
const s = series.find((d) => d.key === key)!;
|
|
234
|
-
return accessor(s.value ?? s.key)(d as any);
|
|
235
|
-
})
|
|
236
|
-
.offset(offset)(chartDataArray(data)) as any[];
|
|
237
|
-
|
|
238
|
-
_chartData = _chartData.map((d, i) => {
|
|
239
|
-
return {
|
|
240
|
-
...d,
|
|
241
|
-
stackData: stackData.map((sd) => sd[i]),
|
|
242
|
-
};
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
return _chartData;
|
|
246
|
-
});
|
|
247
|
-
|
|
248
265
|
function getBarsProps(s: SeriesData<TData, typeof Bars>, i: number): ComponentProps<typeof Bars> {
|
|
249
266
|
const isFirst = i == 0;
|
|
250
267
|
const isLast = i == seriesState.visibleSeries.length - 1;
|
|
@@ -278,7 +295,12 @@
|
|
|
278
295
|
y: isVertical ? valueAccessor : undefined,
|
|
279
296
|
x1: isVertical && isGroupSeries ? (d) => s.value ?? s.key : undefined,
|
|
280
297
|
y1: !isVertical && isGroupSeries ? (d) => s.value ?? s.key : undefined,
|
|
281
|
-
rounded:
|
|
298
|
+
rounded:
|
|
299
|
+
isStackLayout && i !== seriesState.visibleSeries.length - 1
|
|
300
|
+
? 'none'
|
|
301
|
+
: Array.isArray(xProp) || Array.isArray(yProp)
|
|
302
|
+
? 'all'
|
|
303
|
+
: 'edge',
|
|
282
304
|
radius: 4,
|
|
283
305
|
strokeWidth: 1,
|
|
284
306
|
insets: stackInsets,
|
|
@@ -350,26 +372,14 @@
|
|
|
350
372
|
return {
|
|
351
373
|
placement: radial ? 'radius' : 'left',
|
|
352
374
|
|
|
353
|
-
format:
|
|
354
|
-
if (isVertical && seriesLayout === 'stackExpand') {
|
|
355
|
-
return format(value, 'percentRound');
|
|
356
|
-
} else {
|
|
357
|
-
return format(value, undefined, { variant: 'short' });
|
|
358
|
-
}
|
|
359
|
-
},
|
|
375
|
+
format: isVertical && seriesLayout === 'stackExpand' ? 'percentRound' : undefined,
|
|
360
376
|
...(typeof axis === 'object' ? axis : null),
|
|
361
377
|
...props.yAxis,
|
|
362
378
|
};
|
|
363
379
|
}
|
|
364
380
|
return {
|
|
365
381
|
placement: radial ? 'angle' : 'bottom',
|
|
366
|
-
format:
|
|
367
|
-
if (!isVertical && seriesLayout === 'stackExpand') {
|
|
368
|
-
return format(value, 'percentRound');
|
|
369
|
-
} else {
|
|
370
|
-
return format(value, undefined, { variant: 'short' });
|
|
371
|
-
}
|
|
372
|
-
},
|
|
382
|
+
format: !isVertical && seriesLayout === 'stackExpand' ? 'percentRound' : undefined,
|
|
373
383
|
...(typeof axis === 'object' ? axis : null),
|
|
374
384
|
...props.xAxis,
|
|
375
385
|
};
|
|
@@ -445,6 +455,7 @@
|
|
|
445
455
|
onclick: onTooltipClick,
|
|
446
456
|
debug,
|
|
447
457
|
...props.tooltip?.context,
|
|
458
|
+
...(typeof tooltip === 'object' ? tooltip : null),
|
|
448
459
|
}}
|
|
449
460
|
brush={brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')
|
|
450
461
|
? {
|
|
@@ -70,7 +70,6 @@
|
|
|
70
70
|
<script lang="ts" generics="TData">
|
|
71
71
|
import { onMount, type ComponentProps } from 'svelte';
|
|
72
72
|
import { scaleLinear, scaleTime } from 'd3-scale';
|
|
73
|
-
import { format } from '@layerstack/utils';
|
|
74
73
|
import { cls } from '@layerstack/tailwind';
|
|
75
74
|
|
|
76
75
|
import Axis from '../Axis.svelte';
|
|
@@ -142,7 +141,14 @@
|
|
|
142
141
|
|
|
143
142
|
const series = $derived(
|
|
144
143
|
seriesProp === undefined
|
|
145
|
-
? [
|
|
144
|
+
? [
|
|
145
|
+
{
|
|
146
|
+
key: 'default',
|
|
147
|
+
label: typeof yProp === 'string' ? yProp : 'value',
|
|
148
|
+
value: yProp,
|
|
149
|
+
color: 'var(--color-primary)',
|
|
150
|
+
},
|
|
151
|
+
]
|
|
146
152
|
: seriesProp
|
|
147
153
|
);
|
|
148
154
|
const seriesState = new SeriesState(() => series);
|
|
@@ -284,14 +290,12 @@
|
|
|
284
290
|
if (axisDirection === 'y') {
|
|
285
291
|
return {
|
|
286
292
|
placement: radial ? 'radius' : 'left',
|
|
287
|
-
format: (value) => format(value, undefined, { variant: 'short' }),
|
|
288
293
|
...(typeof axis === 'object' ? axis : null),
|
|
289
294
|
...props.yAxis,
|
|
290
295
|
};
|
|
291
296
|
}
|
|
292
297
|
return {
|
|
293
298
|
placement: radial ? 'angle' : 'bottom',
|
|
294
|
-
format: (value) => format(value, undefined, { variant: 'short' }),
|
|
295
299
|
...(typeof axis === 'object' ? axis : null),
|
|
296
300
|
...props.xAxis,
|
|
297
301
|
};
|
|
@@ -339,10 +343,11 @@
|
|
|
339
343
|
tooltip={tooltip === false
|
|
340
344
|
? false
|
|
341
345
|
: {
|
|
342
|
-
mode: '
|
|
346
|
+
mode: 'quadtree-x',
|
|
343
347
|
onclick: onTooltipClick,
|
|
344
348
|
debug,
|
|
345
349
|
...props.tooltip?.context,
|
|
350
|
+
...(typeof tooltip === 'object' ? tooltip : null),
|
|
346
351
|
}}
|
|
347
352
|
brush={brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')
|
|
348
353
|
? {
|
|
@@ -377,7 +382,6 @@
|
|
|
377
382
|
{@render childrenProp(snippetProps)}
|
|
378
383
|
{:else}
|
|
379
384
|
{@render belowContext?.(snippetProps)}
|
|
380
|
-
<!-- TODO: Always use `Svg` until `Pattern` supports `Canvas` (issue #307) -->
|
|
381
385
|
|
|
382
386
|
<Layer
|
|
383
387
|
type={renderContext}
|
|
@@ -281,9 +281,9 @@
|
|
|
281
281
|
placement: 'bottom',
|
|
282
282
|
variant: 'swatches',
|
|
283
283
|
onclick: (e, item) => {
|
|
284
|
-
selectedKeys.
|
|
284
|
+
selectedKeys.toggle(item.value);
|
|
285
285
|
// TODO: investigate
|
|
286
|
-
// selectedSeries.
|
|
286
|
+
// selectedSeries.toggle(item.value);
|
|
287
287
|
},
|
|
288
288
|
onpointerenter: (e, item) => (highlightKey.current = item.value),
|
|
289
289
|
onpointerleave: (e) => (highlightKey.current = null),
|
|
@@ -409,7 +409,9 @@
|
|
|
409
409
|
]}
|
|
410
410
|
padding={{ bottom: legend === true ? 32 : 0 }}
|
|
411
411
|
{...restProps}
|
|
412
|
-
tooltip={tooltip === false
|
|
412
|
+
tooltip={tooltip === false
|
|
413
|
+
? false
|
|
414
|
+
: { ...props.tooltip?.context, ...(typeof tooltip === 'object' ? tooltip : null) }}
|
|
413
415
|
>
|
|
414
416
|
{#snippet children({ context })}
|
|
415
417
|
{@const snippetProps = {
|
|
@@ -205,14 +205,12 @@
|
|
|
205
205
|
if (axisDirection === 'y') {
|
|
206
206
|
return {
|
|
207
207
|
placement: 'left',
|
|
208
|
-
format: (value) => format(value, undefined, { variant: 'short' }),
|
|
209
208
|
...(typeof axis === 'object' ? axis : null),
|
|
210
209
|
...props.yAxis,
|
|
211
210
|
};
|
|
212
211
|
}
|
|
213
212
|
return {
|
|
214
213
|
placement: 'bottom',
|
|
215
|
-
format: (value) => format(value, undefined, { variant: 'short' }),
|
|
216
214
|
...(typeof axis === 'object' ? axis : null),
|
|
217
215
|
...props.xAxis,
|
|
218
216
|
};
|
|
@@ -255,10 +253,11 @@
|
|
|
255
253
|
tooltip={tooltip === false
|
|
256
254
|
? false
|
|
257
255
|
: {
|
|
258
|
-
mode: '
|
|
256
|
+
mode: 'quadtree',
|
|
259
257
|
onclick: onTooltipClick,
|
|
260
258
|
debug,
|
|
261
259
|
...props.tooltip?.context,
|
|
260
|
+
...(typeof tooltip === 'object' ? tooltip : null),
|
|
262
261
|
}}
|
|
263
262
|
brush={brush && (brush === true || brush.mode == undefined || brush.mode === 'integrated')
|
|
264
263
|
? {
|
|
@@ -8,8 +8,8 @@ export declare class HighlightKey<TData, SeriesComponent extends Component> {
|
|
|
8
8
|
}
|
|
9
9
|
export declare class SeriesState<TData, TComponent extends Component> {
|
|
10
10
|
#private;
|
|
11
|
-
selectedSeries: SelectionState<unknown>;
|
|
12
|
-
selectedKeys: SelectionState<unknown>;
|
|
11
|
+
selectedSeries: SelectionState<unknown, false>;
|
|
12
|
+
selectedKeys: SelectionState<unknown, false>;
|
|
13
13
|
highlightKey: HighlightKey<TData, TComponent>;
|
|
14
14
|
constructor(getSeries: () => SeriesData<TData, TComponent>[]);
|
|
15
15
|
get series(): SeriesData<TData, TComponent>[];
|
|
@@ -13,6 +13,10 @@ export class SeriesState {
|
|
|
13
13
|
highlightKey = new HighlightKey();
|
|
14
14
|
constructor(getSeries) {
|
|
15
15
|
this.#series = getSeries();
|
|
16
|
+
$effect.pre(() => {
|
|
17
|
+
// keep series state in sync with the prop
|
|
18
|
+
this.#series = getSeries();
|
|
19
|
+
});
|
|
16
20
|
}
|
|
17
21
|
get series() {
|
|
18
22
|
return this.#series;
|
|
@@ -40,7 +44,7 @@ export function createLegendProps(opts) {
|
|
|
40
44
|
tickFormat: (key) => opts.seriesState.series.find((s) => s.key === key)?.label ?? key,
|
|
41
45
|
placement: 'bottom',
|
|
42
46
|
variant: 'swatches',
|
|
43
|
-
onclick: (_, item) => opts.seriesState.selectedSeries.
|
|
47
|
+
onclick: (_, item) => opts.seriesState.selectedSeries.toggle(item.value),
|
|
44
48
|
onpointerenter: (_, item) => (opts.seriesState.highlightKey.current = item.value),
|
|
45
49
|
onpointerleave: () => (opts.seriesState.highlightKey.current = null),
|
|
46
50
|
...opts.props,
|
|
@@ -42,6 +42,8 @@ export { default as Connector } from './Connector.svelte';
|
|
|
42
42
|
export * from './Connector.svelte';
|
|
43
43
|
export { default as Dagre } from './Dagre.svelte';
|
|
44
44
|
export * from './Dagre.svelte';
|
|
45
|
+
export { default as Ellipse } from './Ellipse.svelte';
|
|
46
|
+
export * from './Ellipse.svelte';
|
|
45
47
|
export { default as Frame } from './Frame.svelte';
|
|
46
48
|
export * from './Frame.svelte';
|
|
47
49
|
export { default as ForceSimulation } from './ForceSimulation.svelte';
|
|
@@ -102,6 +104,8 @@ export { default as Point } from './Point.svelte';
|
|
|
102
104
|
export * from './Point.svelte';
|
|
103
105
|
export { default as Points } from './Points.svelte';
|
|
104
106
|
export * from './Points.svelte';
|
|
107
|
+
export { default as Polygon } from './Polygon.svelte';
|
|
108
|
+
export * from './Polygon.svelte';
|
|
105
109
|
export { default as RadialGradient } from './RadialGradient.svelte';
|
|
106
110
|
export * from './RadialGradient.svelte';
|
|
107
111
|
export { default as Rect } from './Rect.svelte';
|