layerchart 2.0.0-next.2 → 2.0.0-next.20
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/AnnotationLine.svelte +17 -29
- package/dist/components/AnnotationLine.svelte.d.ts +4 -2
- package/dist/components/AnnotationPoint.svelte +11 -13
- package/dist/components/AnnotationPoint.svelte.d.ts +4 -2
- package/dist/components/AnnotationRange.svelte +3 -3
- package/dist/components/Arc.svelte +2 -2
- package/dist/components/Axis.svelte +52 -24
- package/dist/components/Axis.svelte.d.ts +14 -3
- package/dist/components/Bar.svelte +7 -4
- package/dist/components/Bar.svelte.d.ts +4 -1
- package/dist/components/Bars.svelte +9 -6
- package/dist/components/Bars.svelte.d.ts +3 -3
- package/dist/components/Blur.svelte +20 -12
- package/dist/components/Blur.svelte.d.ts +2 -5
- 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/ClipPath.svelte +14 -9
- 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/GeoEdgeFade.svelte +4 -3
- package/dist/components/GeoEdgeFade.svelte.d.ts +2 -2
- 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/Graticule.svelte +3 -2
- package/dist/components/Grid.svelte +8 -7
- package/dist/components/Grid.svelte.d.ts +2 -1
- package/dist/components/Group.svelte +45 -5
- package/dist/components/Group.svelte.d.ts +32 -4
- package/dist/components/Highlight.svelte +1 -1
- package/dist/components/Hull.svelte +4 -4
- package/dist/components/Hull.svelte.d.ts +2 -2
- package/dist/components/Labels.svelte +6 -4
- package/dist/components/Labels.svelte.d.ts +2 -2
- package/dist/components/Legend.svelte +8 -5
- package/dist/components/Legend.svelte.d.ts +3 -3
- 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/Rule.svelte +3 -2
- package/dist/components/Spline.svelte +30 -18
- package/dist/components/Spline.svelte.d.ts +12 -4
- package/dist/components/Text.svelte +60 -48
- package/dist/components/Text.svelte.d.ts +6 -0
- package/dist/components/Treemap.svelte +63 -26
- package/dist/components/Treemap.svelte.d.ts +11 -11
- package/dist/components/Voronoi.svelte +55 -36
- package/dist/components/Voronoi.svelte.d.ts +5 -3
- package/dist/components/charts/ArcChart.svelte +2 -2
- package/dist/components/charts/AreaChart.svelte +9 -10
- package/dist/components/charts/BarChart.svelte +63 -53
- package/dist/components/charts/DefaultTooltip.svelte +1 -1
- package/dist/components/charts/LineChart.svelte +8 -5
- package/dist/components/charts/PieChart.svelte +2 -2
- package/dist/components/charts/ScatterChart.svelte +0 -2
- package/dist/components/charts/utils.svelte.d.ts +3 -3
- package/dist/components/charts/utils.svelte.js +7 -3
- package/dist/components/index.d.ts +4 -0
- package/dist/components/index.js +4 -0
- 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 +25 -8
- package/dist/components/tooltip/TooltipContext.svelte.d.ts +1 -1
- 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 +3 -1
- 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/TilesetField.svelte +20 -19
- package/dist/docs/TilesetField.svelte.d.ts +5 -22
- package/dist/docs/ViewSourceButton.svelte +7 -4
- package/dist/docs/ViewSourceButton.svelte.d.ts +7 -21
- package/dist/utils/arcText.svelte.js +4 -4
- 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/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 +4 -4
- package/dist/utils/ticks.js +106 -159
- package/dist/utils/ticks.test.js +6 -16
- package/dist/utils/treemap.d.ts +1 -1
- package/package.json +25 -22
- package/dist/utils/object.js +0 -2
|
@@ -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
|
*
|
|
@@ -50,26 +52,30 @@
|
|
|
50
52
|
};
|
|
51
53
|
|
|
52
54
|
export type VoronoiProps = VoronoiPropsWithoutHTML &
|
|
53
|
-
Without<Omit<
|
|
55
|
+
Without<Omit<GroupProps, 'children'>, VoronoiPropsWithoutHTML>;
|
|
54
56
|
</script>
|
|
55
57
|
|
|
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';
|
|
63
65
|
import { cls } from '@layerstack/tailwind';
|
|
64
66
|
|
|
65
67
|
import GeoPath from './GeoPath.svelte';
|
|
68
|
+
import Group, { type GroupProps } from './Group.svelte';
|
|
66
69
|
import Spline from './Spline.svelte';
|
|
67
70
|
import { getChartContext } from './Chart.svelte';
|
|
68
71
|
import { getGeoContext } from './GeoContext.svelte';
|
|
72
|
+
import CircleClipPath from './CircleClipPath.svelte';
|
|
73
|
+
|
|
69
74
|
import { layerClass } from '../utils/attributes.js';
|
|
70
75
|
|
|
71
76
|
let {
|
|
72
77
|
data,
|
|
78
|
+
r,
|
|
73
79
|
classes = {},
|
|
74
80
|
onclick,
|
|
75
81
|
onpointerenter,
|
|
@@ -108,54 +114,67 @@
|
|
|
108
114
|
// Width and/or height can sometimes be negative (when loading data remotely and updately)
|
|
109
115
|
const boundWidth = $derived(Math.max(ctx.width, 0));
|
|
110
116
|
const boundHeight = $derived(Math.max(ctx.height, 0));
|
|
117
|
+
|
|
118
|
+
const disableClip = $derived(r === 0 || r == null || r === Infinity);
|
|
111
119
|
</script>
|
|
112
120
|
|
|
113
|
-
<
|
|
121
|
+
<Group {...restProps} class={cls(layerClass('voronoi-g'), classes.root, className)}>
|
|
114
122
|
{#if geo.projection}
|
|
115
123
|
{@const polygons = geoVoronoi().polygons(points)}
|
|
116
124
|
{#each polygons.features as feature}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
onpointermove={(e) => onpointermove?.(e, { data: feature.properties.site.data, feature })}
|
|
127
|
-
onpointerdown={(e) => onpointerdown?.(e, { data: feature.properties.site.data, feature })}
|
|
128
|
-
{onpointerleave}
|
|
129
|
-
ontouchmove={(e) => {
|
|
130
|
-
// Prevent touch to not interfere with pointer
|
|
131
|
-
e.preventDefault();
|
|
132
|
-
}}
|
|
133
|
-
/>
|
|
134
|
-
{/each}
|
|
135
|
-
{:else}
|
|
136
|
-
{@const voronoi = Delaunay.from(points).voronoi([0, 0, boundWidth, boundHeight])}
|
|
137
|
-
{#each points as point, i}
|
|
138
|
-
{@const pathData = voronoi.renderCell(i)}
|
|
139
|
-
<!-- Wait to render Spline until pathData is available to fix path artifacts from injected tweened points in Spline -->
|
|
140
|
-
{#if pathData}
|
|
141
|
-
<Spline
|
|
142
|
-
{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}
|
|
143
134
|
class={cls(
|
|
144
|
-
layerClass('voronoi-path'),
|
|
135
|
+
layerClass('voronoi-geo-path'),
|
|
145
136
|
'fill-transparent stroke-transparent',
|
|
146
137
|
classes.path
|
|
147
138
|
)}
|
|
148
|
-
onclick={(e) => onclick?.(e, { data:
|
|
149
|
-
onpointerenter={(e) =>
|
|
150
|
-
|
|
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 })}
|
|
151
144
|
{onpointerleave}
|
|
152
|
-
onpointerdown={(e) => onpointerdown?.(e, { data: point.data, point })}
|
|
153
145
|
ontouchmove={(e) => {
|
|
154
146
|
// Prevent touch to not interfere with pointer
|
|
155
147
|
e.preventDefault();
|
|
156
148
|
}}
|
|
157
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>
|
|
158
177
|
{/if}
|
|
159
178
|
{/each}
|
|
160
179
|
{/if}
|
|
161
|
-
</
|
|
180
|
+
</Group>
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Without } from '../utils/types.js';
|
|
2
|
-
import type { SVGAttributes } from 'svelte/elements';
|
|
3
2
|
export type VoronoiPropsWithoutHTML = {
|
|
4
3
|
/**
|
|
5
4
|
* Override data instead of using context
|
|
6
5
|
*/
|
|
7
6
|
data?: any;
|
|
7
|
+
/** Radius to clip voronoi cells. `0` or `undefined` to disables clipping */
|
|
8
|
+
r?: number;
|
|
8
9
|
/**
|
|
9
10
|
* Classes to apply to the root and path elements
|
|
10
11
|
*
|
|
@@ -35,8 +36,9 @@ export type VoronoiPropsWithoutHTML = {
|
|
|
35
36
|
feature?: GeoPermissibleObjects;
|
|
36
37
|
}) => void;
|
|
37
38
|
};
|
|
38
|
-
export type VoronoiProps = VoronoiPropsWithoutHTML & Without<Omit<
|
|
39
|
-
import type
|
|
39
|
+
export type VoronoiProps = VoronoiPropsWithoutHTML & Without<Omit<GroupProps, 'children'>, VoronoiPropsWithoutHTML>;
|
|
40
|
+
import { type GeoPermissibleObjects } from 'd3-geo';
|
|
41
|
+
import { type GroupProps } from './Group.svelte';
|
|
40
42
|
declare const Voronoi: import("svelte").Component<VoronoiProps, {}, "">;
|
|
41
43
|
type Voronoi = ReturnType<typeof Voronoi>;
|
|
42
44
|
export default 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),
|
|
@@ -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
|
};
|
|
@@ -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
|
};
|
|
@@ -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
|
};
|
|
@@ -377,7 +381,6 @@
|
|
|
377
381
|
{@render childrenProp(snippetProps)}
|
|
378
382
|
{:else}
|
|
379
383
|
{@render belowContext?.(snippetProps)}
|
|
380
|
-
<!-- TODO: Always use `Svg` until `Pattern` supports `Canvas` (issue #307) -->
|
|
381
384
|
|
|
382
385
|
<Layer
|
|
383
386
|
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),
|
|
@@ -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
|
};
|
|
@@ -4,12 +4,12 @@ import type { SeriesData } from './types.js';
|
|
|
4
4
|
import type Legend from '../Legend.svelte';
|
|
5
5
|
export declare class HighlightKey<TData, SeriesComponent extends Component> {
|
|
6
6
|
current: string | null;
|
|
7
|
-
set(seriesKey: typeof this.current)
|
|
7
|
+
set: (seriesKey: typeof this.current) => void;
|
|
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>[];
|
|
@@ -2,9 +2,9 @@ import { SelectionState } from '@layerstack/svelte-state';
|
|
|
2
2
|
import { scaleOrdinal } from 'd3-scale';
|
|
3
3
|
export class HighlightKey {
|
|
4
4
|
current = $state(null);
|
|
5
|
-
set(seriesKey) {
|
|
5
|
+
set = (seriesKey) => {
|
|
6
6
|
this.current = seriesKey;
|
|
7
|
-
}
|
|
7
|
+
};
|
|
8
8
|
}
|
|
9
9
|
export class SeriesState {
|
|
10
10
|
#series = $state.raw([]);
|
|
@@ -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';
|
package/dist/components/index.js
CHANGED
|
@@ -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';
|