layerchart 2.0.0-next.33 → 2.0.0-next.35
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/Axis.svelte +2 -2
- package/dist/components/Bars.svelte +1 -1
- package/dist/components/Chart.svelte +36 -22
- package/dist/components/Chart.svelte.d.ts +5 -5
- package/dist/components/Points.svelte +1 -64
- package/dist/components/Points.svelte.d.ts +1 -8
- package/dist/components/Rule.svelte +156 -73
- package/dist/components/Rule.svelte.d.ts +7 -2
- package/dist/components/charts/AreaChart.svelte +0 -7
- package/dist/components/charts/LineChart.svelte +0 -8
- package/dist/components/charts/ScatterChart.svelte +0 -17
- package/dist/utils/genData.d.ts +8 -8
- package/dist/utils/genData.js +10 -8
- package/dist/utils/scales.svelte.d.ts +6 -1
- package/dist/utils/scales.svelte.js +40 -1
- package/package.json +2 -2
|
@@ -439,8 +439,8 @@
|
|
|
439
439
|
{#if rule !== false}
|
|
440
440
|
{@const ruleProps = extractLayerProps(rule, 'axis-rule')}
|
|
441
441
|
<Rule
|
|
442
|
-
x={placement === 'left'
|
|
443
|
-
y={placement === 'top'
|
|
442
|
+
x={placement === 'left' ? '$left' : placement === 'right' ? '$right' : placement === 'angle'}
|
|
443
|
+
y={placement === 'top' ? '$top' : placement === 'bottom' ? '$bottom' : placement === 'radius'}
|
|
444
444
|
{motion}
|
|
445
445
|
{...ruleProps}
|
|
446
446
|
class={cls('stroke-surface-content/50', classes.rule, ruleProps?.class)}
|
|
@@ -32,8 +32,8 @@
|
|
|
32
32
|
import Bar, { type BarProps, type BarPropsWithoutHTML } from './Bar.svelte';
|
|
33
33
|
import Group from './Group.svelte';
|
|
34
34
|
|
|
35
|
-
import { chartDataArray } from '../utils/common.js';
|
|
36
35
|
import { getChartContext } from './Chart.svelte';
|
|
36
|
+
import { chartDataArray } from '../utils/common.js';
|
|
37
37
|
import { extractLayerProps, layerClass } from '../utils/attributes.js';
|
|
38
38
|
|
|
39
39
|
let {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
-
import {
|
|
2
|
+
import { scaleOrdinal, scaleSqrt } from 'd3-scale';
|
|
3
3
|
import { type Accessor, accessor, chartDataArray } from '../utils/common.js';
|
|
4
4
|
import { printDebug } from '../utils/debug.js';
|
|
5
5
|
import { filterObject } from '../utils/filterObject.js';
|
|
6
6
|
import {
|
|
7
|
+
autoScale,
|
|
7
8
|
createScale,
|
|
8
9
|
getRange,
|
|
9
10
|
isScaleBand,
|
|
@@ -421,21 +422,21 @@
|
|
|
421
422
|
/**
|
|
422
423
|
* The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
|
|
423
424
|
* you want to override the default or you want to extra options.
|
|
424
|
-
* @default
|
|
425
|
+
* @default autoScale
|
|
425
426
|
*/
|
|
426
427
|
xScale?: XScale;
|
|
427
428
|
|
|
428
429
|
/**
|
|
429
430
|
* The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
|
|
430
431
|
* you want to override the default or you want to extra options.
|
|
431
|
-
* @default
|
|
432
|
+
* @default autoScale
|
|
432
433
|
*/
|
|
433
434
|
yScale?: YScale;
|
|
434
435
|
|
|
435
436
|
/**
|
|
436
437
|
* The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
|
|
437
438
|
* you want to override the default or you want to extra options.
|
|
438
|
-
* @default
|
|
439
|
+
* @default autoScale
|
|
439
440
|
*/
|
|
440
441
|
zScale?: AnyScale;
|
|
441
442
|
|
|
@@ -449,14 +450,14 @@
|
|
|
449
450
|
/**
|
|
450
451
|
* The D3 scale that should be used for the x1-dimension. Pass in an instantiated D3 scale if
|
|
451
452
|
* you want to override the default or you want to extra options.
|
|
452
|
-
* @default
|
|
453
|
+
* @default autoScale
|
|
453
454
|
*/
|
|
454
455
|
x1Scale?: AnyScale;
|
|
455
456
|
|
|
456
457
|
/**
|
|
457
458
|
* The D3 scale that should be used for the y1-dimension. Pass in an instantiated D3 scale if
|
|
458
459
|
* you want to override the default or you want to extra options.
|
|
459
|
-
* @default
|
|
460
|
+
* @default autoScale
|
|
460
461
|
*/
|
|
461
462
|
y1Scale?: AnyScale;
|
|
462
463
|
|
|
@@ -717,6 +718,7 @@
|
|
|
717
718
|
z: zProp,
|
|
718
719
|
r: rProp,
|
|
719
720
|
data = [],
|
|
721
|
+
flatData: flatDataProp,
|
|
720
722
|
xDomain: xDomainProp,
|
|
721
723
|
yDomain: yDomainProp,
|
|
722
724
|
zDomain: zDomainProp,
|
|
@@ -730,12 +732,12 @@
|
|
|
730
732
|
zPadding,
|
|
731
733
|
rPadding,
|
|
732
734
|
// @ts-expect-error shh
|
|
733
|
-
xScale: xScaleProp =
|
|
735
|
+
xScale: xScaleProp = autoScale(xDomainProp, flatDataProp ?? data, xProp),
|
|
736
|
+
// @ts-expect-error shh
|
|
737
|
+
yScale: yScaleProp = autoScale(yDomainProp, flatDataProp ?? data, yProp),
|
|
734
738
|
// @ts-expect-error shh
|
|
735
|
-
|
|
736
|
-
zScale: zScaleProp = scaleLinear(),
|
|
739
|
+
zScale: zScaleProp = autoScale(zDomainProp, flatDataProp ?? data, zProp),
|
|
737
740
|
rScale: rScaleProp = scaleSqrt(),
|
|
738
|
-
flatData: flatDataProp,
|
|
739
741
|
padding: paddingProp = {},
|
|
740
742
|
verbose = true,
|
|
741
743
|
debug = false,
|
|
@@ -1009,24 +1011,36 @@
|
|
|
1009
1011
|
const rGet = $derived(createGetter(r, rScale));
|
|
1010
1012
|
|
|
1011
1013
|
const x1Scale = $derived(
|
|
1012
|
-
|
|
1013
|
-
? createScale(
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1014
|
+
x1RangeProp
|
|
1015
|
+
? createScale(
|
|
1016
|
+
// @ts-expect-error shh
|
|
1017
|
+
x1ScaleProp ?? autoScale(x1DomainProp, flatDataProp ?? data, x1Prop),
|
|
1018
|
+
x1Domain,
|
|
1019
|
+
x1RangeProp,
|
|
1020
|
+
{
|
|
1021
|
+
xScale,
|
|
1022
|
+
width,
|
|
1023
|
+
height,
|
|
1024
|
+
}
|
|
1025
|
+
)
|
|
1018
1026
|
: null
|
|
1019
1027
|
);
|
|
1020
1028
|
|
|
1021
1029
|
const x1Get = $derived(createGetter(x1, x1Scale));
|
|
1022
1030
|
|
|
1023
1031
|
const y1Scale = $derived(
|
|
1024
|
-
|
|
1025
|
-
? createScale(
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1032
|
+
y1RangeProp
|
|
1033
|
+
? createScale(
|
|
1034
|
+
// @ts-expect-error shh
|
|
1035
|
+
y1ScaleProp ?? autoScale(y1DomainProp, flatDataProp ?? data, y1Prop),
|
|
1036
|
+
y1Domain,
|
|
1037
|
+
y1RangeProp,
|
|
1038
|
+
{
|
|
1039
|
+
yScale,
|
|
1040
|
+
width,
|
|
1041
|
+
height,
|
|
1042
|
+
}
|
|
1043
|
+
)
|
|
1030
1044
|
: null
|
|
1031
1045
|
);
|
|
1032
1046
|
|
|
@@ -288,19 +288,19 @@ export type ChartPropsWithoutHTML<T, XScale extends AnyScale = AnyScale, YScale
|
|
|
288
288
|
/**
|
|
289
289
|
* The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
|
|
290
290
|
* you want to override the default or you want to extra options.
|
|
291
|
-
* @default
|
|
291
|
+
* @default autoScale
|
|
292
292
|
*/
|
|
293
293
|
xScale?: XScale;
|
|
294
294
|
/**
|
|
295
295
|
* The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
|
|
296
296
|
* you want to override the default or you want to extra options.
|
|
297
|
-
* @default
|
|
297
|
+
* @default autoScale
|
|
298
298
|
*/
|
|
299
299
|
yScale?: YScale;
|
|
300
300
|
/**
|
|
301
301
|
* The D3 scale that should be used for the x-dimension. Pass in an instantiated D3 scale if
|
|
302
302
|
* you want to override the default or you want to extra options.
|
|
303
|
-
* @default
|
|
303
|
+
* @default autoScale
|
|
304
304
|
*/
|
|
305
305
|
zScale?: AnyScale;
|
|
306
306
|
/**
|
|
@@ -312,13 +312,13 @@ export type ChartPropsWithoutHTML<T, XScale extends AnyScale = AnyScale, YScale
|
|
|
312
312
|
/**
|
|
313
313
|
* The D3 scale that should be used for the x1-dimension. Pass in an instantiated D3 scale if
|
|
314
314
|
* you want to override the default or you want to extra options.
|
|
315
|
-
* @default
|
|
315
|
+
* @default autoScale
|
|
316
316
|
*/
|
|
317
317
|
x1Scale?: AnyScale;
|
|
318
318
|
/**
|
|
319
319
|
* The D3 scale that should be used for the y1-dimension. Pass in an instantiated D3 scale if
|
|
320
320
|
* you want to override the default or you want to extra options.
|
|
321
|
-
* @default
|
|
321
|
+
* @default autoScale
|
|
322
322
|
*/
|
|
323
323
|
y1Scale?: AnyScale;
|
|
324
324
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
2
|
import type { CommonStyleProps, Without } from '../utils/types.js';
|
|
3
|
-
import type {
|
|
3
|
+
import type { Snippet } from 'svelte';
|
|
4
4
|
|
|
5
5
|
export type Point = { x: number; y: number; r: number; xValue: any; yValue: any; data: any };
|
|
6
6
|
type Offset = number | ((value: number, context: any) => number) | undefined;
|
|
@@ -37,13 +37,6 @@
|
|
|
37
37
|
*/
|
|
38
38
|
offsetY?: Offset;
|
|
39
39
|
|
|
40
|
-
/**
|
|
41
|
-
* Enable showing links between related points (array x/y accessors)
|
|
42
|
-
*
|
|
43
|
-
* @default false
|
|
44
|
-
*/
|
|
45
|
-
links?: boolean | Partial<ComponentProps<typeof Link>>;
|
|
46
|
-
|
|
47
40
|
children?: Snippet<[{ points: Point[] }]>;
|
|
48
41
|
} & CommonStyleProps;
|
|
49
42
|
|
|
@@ -71,7 +64,6 @@
|
|
|
71
64
|
r = 5,
|
|
72
65
|
offsetX,
|
|
73
66
|
offsetY,
|
|
74
|
-
links = false,
|
|
75
67
|
fill,
|
|
76
68
|
fillOpacity,
|
|
77
69
|
stroke,
|
|
@@ -136,66 +128,11 @@
|
|
|
136
128
|
return [];
|
|
137
129
|
}) as Point[]
|
|
138
130
|
);
|
|
139
|
-
|
|
140
|
-
const _links = $derived(
|
|
141
|
-
pointsData.flatMap((d: any) => {
|
|
142
|
-
const xValue = xAccessor(d);
|
|
143
|
-
const yValue = yAccessor(d);
|
|
144
|
-
|
|
145
|
-
if (Array.isArray(xValue)) {
|
|
146
|
-
/*
|
|
147
|
-
x={["prop1" ,"prop2"]}
|
|
148
|
-
y="prop3"
|
|
149
|
-
*/
|
|
150
|
-
const [xMin, xMax] = extent(ctx.xGet(d)) as unknown as [number, number];
|
|
151
|
-
const y = ctx.yGet(d) + getOffset(ctx.yGet(d), offsetY, ctx.yScale);
|
|
152
|
-
return {
|
|
153
|
-
source: {
|
|
154
|
-
x: xMin + getOffset(xMin, offsetX, ctx.xScale) + (ctx.config.r ? ctx.rGet(d) : r),
|
|
155
|
-
y,
|
|
156
|
-
},
|
|
157
|
-
target: {
|
|
158
|
-
x: xMax + getOffset(xMax, offsetX, ctx.xScale) - (ctx.config.r ? ctx.rGet(d) : r),
|
|
159
|
-
y: y,
|
|
160
|
-
},
|
|
161
|
-
data: d,
|
|
162
|
-
};
|
|
163
|
-
} else if (Array.isArray(yValue)) {
|
|
164
|
-
/*
|
|
165
|
-
x="prop1"
|
|
166
|
-
y={["prop2" ,"prop3"]}
|
|
167
|
-
*/
|
|
168
|
-
const x = ctx.xGet(d) + getOffset(ctx.xGet(d), offsetX, ctx.xScale);
|
|
169
|
-
const [yMin, yMax] = extent(ctx.yGet(d)) as unknown as [number, number];
|
|
170
|
-
return {
|
|
171
|
-
source: {
|
|
172
|
-
x: x,
|
|
173
|
-
y: yMin + getOffset(yMin, offsetY, ctx.yScale),
|
|
174
|
-
},
|
|
175
|
-
target: {
|
|
176
|
-
x: x,
|
|
177
|
-
y: yMax + getOffset(yMax, offsetY, ctx.yScale),
|
|
178
|
-
},
|
|
179
|
-
data: d,
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
})
|
|
183
|
-
);
|
|
184
131
|
</script>
|
|
185
132
|
|
|
186
133
|
{#if children}
|
|
187
134
|
{@render children({ points })}
|
|
188
135
|
{:else}
|
|
189
|
-
{#if links}
|
|
190
|
-
{#each _links as link}
|
|
191
|
-
<Link
|
|
192
|
-
data={link}
|
|
193
|
-
stroke={fill ?? (ctx.config.c ? ctx.cGet(link.data) : null)}
|
|
194
|
-
{...extractLayerProps(links, 'points-link')}
|
|
195
|
-
/>
|
|
196
|
-
{/each}
|
|
197
|
-
{/if}
|
|
198
|
-
|
|
199
136
|
{#each points as point}
|
|
200
137
|
<Circle
|
|
201
138
|
cx={point.x}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { CommonStyleProps, Without } from '../utils/types.js';
|
|
2
|
-
import type {
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
3
|
export type Point = {
|
|
4
4
|
x: number;
|
|
5
5
|
y: number;
|
|
@@ -36,19 +36,12 @@ export type PointsPropsWithoutHTML = {
|
|
|
36
36
|
* The offset of the point in the y direction
|
|
37
37
|
*/
|
|
38
38
|
offsetY?: Offset;
|
|
39
|
-
/**
|
|
40
|
-
* Enable showing links between related points (array x/y accessors)
|
|
41
|
-
*
|
|
42
|
-
* @default false
|
|
43
|
-
*/
|
|
44
|
-
links?: boolean | Partial<ComponentProps<typeof Link>>;
|
|
45
39
|
children?: Snippet<[{
|
|
46
40
|
points: Point[];
|
|
47
41
|
}]>;
|
|
48
42
|
} & CommonStyleProps;
|
|
49
43
|
export type PointsProps = PointsPropsWithoutHTML & Omit<Without<CircleProps, PointsPropsWithoutHTML>, 'ref'>;
|
|
50
44
|
import { type CircleProps } from './Circle.svelte';
|
|
51
|
-
import Link from './Link.svelte';
|
|
52
45
|
import { type Accessor } from '../utils/common.js';
|
|
53
46
|
declare const Points: import("svelte").Component<PointsProps, {}, "">;
|
|
54
47
|
type Points = ReturnType<typeof Points>;
|
|
@@ -3,6 +3,11 @@
|
|
|
3
3
|
import type { SVGAttributes } from 'svelte/elements';
|
|
4
4
|
|
|
5
5
|
export type BaseRulePropsWithoutHTML = {
|
|
6
|
+
/**
|
|
7
|
+
* Override the data from the context.
|
|
8
|
+
*/
|
|
9
|
+
data?: any;
|
|
10
|
+
|
|
6
11
|
/**
|
|
7
12
|
* Create a vertical `x` line
|
|
8
13
|
* - If true or 'left', will draw at chart left (xRange[0])
|
|
@@ -12,7 +17,7 @@
|
|
|
12
17
|
*
|
|
13
18
|
* @default false
|
|
14
19
|
*/
|
|
15
|
-
x?: number | Date | boolean | 'left' | 'right';
|
|
20
|
+
x?: number | Date | boolean | '$left' | '$right' | Accessor;
|
|
16
21
|
|
|
17
22
|
/**
|
|
18
23
|
* Pixel offset to apply to `x` coordinate
|
|
@@ -30,7 +35,7 @@
|
|
|
30
35
|
*
|
|
31
36
|
* @default false
|
|
32
37
|
*/
|
|
33
|
-
y?: number | Date | boolean | 'top' | 'bottom';
|
|
38
|
+
y?: number | Date | boolean | '$top' | '$bottom' | Accessor;
|
|
34
39
|
|
|
35
40
|
/**
|
|
36
41
|
* Pixel offset to apply to `y` coordinate
|
|
@@ -55,13 +60,17 @@
|
|
|
55
60
|
import Group from './Group.svelte';
|
|
56
61
|
import Line, { type LinePropsWithoutHTML } from './Line.svelte';
|
|
57
62
|
import { getChartContext } from './Chart.svelte';
|
|
63
|
+
import { accessor, chartDataArray, type Accessor } from '../utils/common.js';
|
|
58
64
|
import { layerClass } from '../utils/attributes.js';
|
|
65
|
+
import { isScaleBand, isScaleNumeric } from '../utils/scales.svelte.js';
|
|
59
66
|
|
|
60
67
|
let {
|
|
68
|
+
data: dataProp,
|
|
61
69
|
x = false,
|
|
62
70
|
xOffset = 0,
|
|
63
71
|
y = false,
|
|
64
72
|
yOffset = 0,
|
|
73
|
+
stroke: strokeProp,
|
|
65
74
|
class: className,
|
|
66
75
|
children,
|
|
67
76
|
...restProps
|
|
@@ -69,89 +78,163 @@
|
|
|
69
78
|
|
|
70
79
|
const ctx = getChartContext();
|
|
71
80
|
|
|
72
|
-
const
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
81
|
+
const data = $derived(chartDataArray(dataProp ?? ctx.data));
|
|
82
|
+
|
|
83
|
+
const singleX = $derived(
|
|
84
|
+
typeof x === 'number' ||
|
|
85
|
+
x instanceof Date ||
|
|
86
|
+
x === true ||
|
|
87
|
+
x === '$left' ||
|
|
88
|
+
x === '$right' ||
|
|
89
|
+
(isScaleBand(ctx.xScale) && ctx.xDomain.includes(x as any))
|
|
90
|
+
);
|
|
91
|
+
const singleY = $derived(
|
|
92
|
+
typeof y === 'number' ||
|
|
93
|
+
y instanceof Date ||
|
|
94
|
+
y === true ||
|
|
95
|
+
y === '$bottom' ||
|
|
96
|
+
y === '$top' ||
|
|
97
|
+
(isScaleBand(ctx.yScale) && ctx.yDomain.includes(y as any))
|
|
98
|
+
);
|
|
99
|
+
|
|
100
|
+
const xRangeMinMax = $derived(extent<number>(ctx.xRange));
|
|
101
|
+
const yRangeMinMax = $derived(extent<number>(ctx.yRange));
|
|
102
|
+
|
|
103
|
+
const lines = $derived.by(() => {
|
|
104
|
+
const result: {
|
|
105
|
+
x1: number;
|
|
106
|
+
y1: number;
|
|
107
|
+
x2: number;
|
|
108
|
+
y2: number;
|
|
109
|
+
axis: 'x' | 'y';
|
|
110
|
+
stroke?: string;
|
|
111
|
+
}[] = [];
|
|
112
|
+
|
|
113
|
+
// Single x line
|
|
114
|
+
if (singleX) {
|
|
115
|
+
const _x =
|
|
116
|
+
x === true || x === '$left'
|
|
117
|
+
? xRangeMinMax[0]!
|
|
118
|
+
: x === '$right'
|
|
119
|
+
? xRangeMinMax[1]!
|
|
120
|
+
: ctx.xScale(x) + xOffset;
|
|
121
|
+
|
|
122
|
+
result.push({
|
|
123
|
+
x1: _x,
|
|
124
|
+
y1: ctx.yRange[0] || 0,
|
|
125
|
+
x2: _x,
|
|
126
|
+
y2: ctx.yRange[1] || 0,
|
|
127
|
+
axis: 'x',
|
|
128
|
+
});
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// Single y line
|
|
132
|
+
if (singleY) {
|
|
133
|
+
const _y =
|
|
134
|
+
y === true || y === '$bottom'
|
|
135
|
+
? yRangeMinMax[1]!
|
|
136
|
+
: y === '$top'
|
|
137
|
+
? yRangeMinMax[0]!
|
|
138
|
+
: ctx.yScale(y) + yOffset;
|
|
139
|
+
|
|
140
|
+
result.push({
|
|
141
|
+
x1: ctx.xRange[0] || 0,
|
|
142
|
+
y1: _y,
|
|
143
|
+
x2: ctx.xRange[1] || 0,
|
|
144
|
+
y2: _y,
|
|
145
|
+
axis: 'y',
|
|
146
|
+
});
|
|
87
147
|
}
|
|
88
|
-
|
|
148
|
+
|
|
149
|
+
// Data driven lines
|
|
150
|
+
if (!singleX && !singleY) {
|
|
151
|
+
const xAccessor = x !== false ? accessor(x as Accessor) : ctx.x;
|
|
152
|
+
const yAccessor = y !== false ? accessor(y as Accessor) : ctx.y;
|
|
153
|
+
|
|
154
|
+
const xBandOffset = isScaleBand(ctx.xScale) ? ctx.xScale.bandwidth() / 2 : 0;
|
|
155
|
+
const yBandOffset = isScaleBand(ctx.yScale) ? ctx.yScale.bandwidth() / 2 : 0;
|
|
156
|
+
|
|
157
|
+
for (const d of data) {
|
|
158
|
+
const xValue = xAccessor(d);
|
|
159
|
+
const yValue = yAccessor(d);
|
|
160
|
+
|
|
161
|
+
const x1Value = Array.isArray(xValue) ? xValue[0] : isScaleNumeric(ctx.xScale) ? 0 : xValue;
|
|
162
|
+
const x2Value = Array.isArray(xValue) ? xValue[1] : xValue;
|
|
163
|
+
const y1Value = Array.isArray(yValue) ? yValue[0] : isScaleNumeric(ctx.yScale) ? 0 : yValue;
|
|
164
|
+
const y2Value = Array.isArray(yValue) ? yValue[1] : yValue;
|
|
165
|
+
|
|
166
|
+
result.push({
|
|
167
|
+
x1: ctx.xScale(x1Value) + xBandOffset + xOffset,
|
|
168
|
+
y1: ctx.yScale(y1Value) + yBandOffset + yOffset,
|
|
169
|
+
x2: ctx.xScale(x2Value) + xBandOffset + xOffset,
|
|
170
|
+
y2: ctx.yScale(y2Value) + yBandOffset + yOffset,
|
|
171
|
+
axis: Array.isArray(yValue) || isScaleBand(ctx.xScale) ? 'x' : 'y', // TODO: what about single prop like lollipop?
|
|
172
|
+
stroke: (strokeProp ?? ctx.config.c) ? ctx.cGet(d) : null, // use color scale, if available
|
|
173
|
+
});
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Remove lines if out of range of chart (non-0 baseline, brushing, etc)
|
|
178
|
+
return result.filter((line) => {
|
|
179
|
+
return (
|
|
180
|
+
line.x1 >= xRangeMinMax[0]! &&
|
|
181
|
+
line.x2 <= xRangeMinMax[1]! &&
|
|
182
|
+
line.y1 >= yRangeMinMax[0]! &&
|
|
183
|
+
line.y2 <= yRangeMinMax[1]!
|
|
184
|
+
);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
|
|
188
|
+
// $inspect({ lines });
|
|
89
189
|
</script>
|
|
90
190
|
|
|
91
191
|
<Group class={layerClass('rule-g')}>
|
|
92
|
-
{#
|
|
93
|
-
{@const
|
|
94
|
-
x === true || x === 'left'
|
|
95
|
-
? xRangeMinMax[0]
|
|
96
|
-
: x === 'right'
|
|
97
|
-
? xRangeMinMax[1]
|
|
98
|
-
: ctx.xScale(x) + xOffset}
|
|
192
|
+
{#each lines as line}
|
|
193
|
+
{@const stroke = line.stroke}
|
|
99
194
|
|
|
100
195
|
{#if ctx.radial}
|
|
101
|
-
{
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
196
|
+
{#if line.axis === 'x'}
|
|
197
|
+
{@const [x1, y1] = pointRadial(line.x1, line.y1)}
|
|
198
|
+
{@const [x2, y2] = pointRadial(line.x2, line.y2)}
|
|
199
|
+
<Line
|
|
200
|
+
{...restProps}
|
|
201
|
+
{x1}
|
|
202
|
+
{y1}
|
|
203
|
+
{x2}
|
|
204
|
+
{y2}
|
|
205
|
+
{stroke}
|
|
206
|
+
class={cls(
|
|
207
|
+
layerClass('rule-x-radial-line'),
|
|
208
|
+
!stroke && 'stroke-surface-content/10',
|
|
209
|
+
className
|
|
210
|
+
)}
|
|
211
|
+
/>
|
|
212
|
+
{:else if line.axis === 'y'}
|
|
213
|
+
<Circle
|
|
214
|
+
r={line.y1}
|
|
215
|
+
{stroke}
|
|
216
|
+
class={cls(
|
|
217
|
+
layerClass('rule-y-radial-circle'),
|
|
218
|
+
!stroke && 'stroke-surface-content/50',
|
|
219
|
+
'fill-none',
|
|
220
|
+
className
|
|
221
|
+
)}
|
|
222
|
+
/>
|
|
223
|
+
{/if}
|
|
112
224
|
{:else}
|
|
113
225
|
<Line
|
|
114
226
|
{...restProps}
|
|
115
|
-
x1={
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
y2={
|
|
119
|
-
|
|
120
|
-
/>
|
|
121
|
-
{/if}
|
|
122
|
-
{/if}
|
|
123
|
-
|
|
124
|
-
{#if showRule(y, 'y')}
|
|
125
|
-
{#if ctx.radial}
|
|
126
|
-
<Circle
|
|
127
|
-
r={y === true || y === 'bottom'
|
|
128
|
-
? yRangeMinMax[1]
|
|
129
|
-
: y === 'top'
|
|
130
|
-
? yRangeMinMax[0]
|
|
131
|
-
: ctx.yScale(y) + yOffset}
|
|
227
|
+
x1={line.x1}
|
|
228
|
+
y1={line.y1}
|
|
229
|
+
x2={line.x2}
|
|
230
|
+
y2={line.y2}
|
|
231
|
+
{stroke}
|
|
132
232
|
class={cls(
|
|
133
|
-
layerClass('rule-y-
|
|
134
|
-
'
|
|
233
|
+
layerClass(line.axis === 'x' ? 'rule-x-line' : 'rule-y-line'),
|
|
234
|
+
!stroke && 'stroke-surface-content/50',
|
|
135
235
|
className
|
|
136
236
|
)}
|
|
137
237
|
/>
|
|
138
|
-
{:else}
|
|
139
|
-
<Line
|
|
140
|
-
{...restProps}
|
|
141
|
-
x1={ctx.xRange[0] || 0}
|
|
142
|
-
x2={ctx.xRange[1] || 0}
|
|
143
|
-
y1={y === true || y === 'bottom'
|
|
144
|
-
? yRangeMinMax[1]
|
|
145
|
-
: y === 'top'
|
|
146
|
-
? yRangeMinMax[0]
|
|
147
|
-
: ctx.yScale(y) + yOffset}
|
|
148
|
-
y2={y === true || y === 'bottom'
|
|
149
|
-
? yRangeMinMax[1]
|
|
150
|
-
: y === 'top'
|
|
151
|
-
? yRangeMinMax[0]
|
|
152
|
-
: ctx.yScale(y) + yOffset}
|
|
153
|
-
class={cls(layerClass('rule-y-line'), 'stroke-surface-content/50', className)}
|
|
154
|
-
/>
|
|
155
238
|
{/if}
|
|
156
|
-
{/
|
|
239
|
+
{/each}
|
|
157
240
|
</Group>
|
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import type { Without } from '../utils/types.js';
|
|
2
2
|
import type { SVGAttributes } from 'svelte/elements';
|
|
3
3
|
export type BaseRulePropsWithoutHTML = {
|
|
4
|
+
/**
|
|
5
|
+
* Override the data from the context.
|
|
6
|
+
*/
|
|
7
|
+
data?: any;
|
|
4
8
|
/**
|
|
5
9
|
* Create a vertical `x` line
|
|
6
10
|
* - If true or 'left', will draw at chart left (xRange[0])
|
|
@@ -10,7 +14,7 @@ export type BaseRulePropsWithoutHTML = {
|
|
|
10
14
|
*
|
|
11
15
|
* @default false
|
|
12
16
|
*/
|
|
13
|
-
x?: number | Date | boolean | 'left' | 'right';
|
|
17
|
+
x?: number | Date | boolean | '$left' | '$right' | Accessor;
|
|
14
18
|
/**
|
|
15
19
|
* Pixel offset to apply to `x` coordinate
|
|
16
20
|
*
|
|
@@ -26,7 +30,7 @@ export type BaseRulePropsWithoutHTML = {
|
|
|
26
30
|
*
|
|
27
31
|
* @default false
|
|
28
32
|
*/
|
|
29
|
-
y?: number | Date | boolean | 'top' | 'bottom';
|
|
33
|
+
y?: number | Date | boolean | '$top' | '$bottom' | Accessor;
|
|
30
34
|
/**
|
|
31
35
|
* Pixel offset to apply to `y` coordinate
|
|
32
36
|
* @default 0
|
|
@@ -36,6 +40,7 @@ export type BaseRulePropsWithoutHTML = {
|
|
|
36
40
|
export type RulePropsWithoutHTML = BaseRulePropsWithoutHTML & Without<Partial<LinePropsWithoutHTML>, BaseRulePropsWithoutHTML>;
|
|
37
41
|
export type RuleProps = RulePropsWithoutHTML & Without<SVGAttributes<SVGElement>, RulePropsWithoutHTML>;
|
|
38
42
|
import { type LinePropsWithoutHTML } from './Line.svelte';
|
|
43
|
+
import { type Accessor } from '../utils/common.js';
|
|
39
44
|
declare const Rule: import("svelte").Component<RuleProps, {}, "">;
|
|
40
45
|
type Rule = ReturnType<typeof Rule>;
|
|
41
46
|
export default Rule;
|
|
@@ -122,7 +122,6 @@
|
|
|
122
122
|
renderContext = 'svg',
|
|
123
123
|
profile = false,
|
|
124
124
|
debug = false,
|
|
125
|
-
xScale: xScaleProp,
|
|
126
125
|
children: childrenProp,
|
|
127
126
|
aboveContext,
|
|
128
127
|
belowContext,
|
|
@@ -196,11 +195,6 @@
|
|
|
196
195
|
return _chartData;
|
|
197
196
|
});
|
|
198
197
|
|
|
199
|
-
// Default xScale based on first data's `x` value
|
|
200
|
-
const xScale = $derived(
|
|
201
|
-
xScaleProp ?? (accessor(x)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear())
|
|
202
|
-
);
|
|
203
|
-
|
|
204
198
|
function isStackData(d: TData): d is TData & { stackData: any[] } {
|
|
205
199
|
return d && typeof d === 'object' && 'stackData' in d;
|
|
206
200
|
}
|
|
@@ -433,7 +427,6 @@
|
|
|
433
427
|
data={chartData}
|
|
434
428
|
{x}
|
|
435
429
|
{xDomain}
|
|
436
|
-
{xScale}
|
|
437
430
|
y={resolveAccessor(y)}
|
|
438
431
|
yBaseline={0}
|
|
439
432
|
yNice
|
|
@@ -69,7 +69,6 @@
|
|
|
69
69
|
|
|
70
70
|
<script lang="ts" generics="TData">
|
|
71
71
|
import { onMount, type ComponentProps } from 'svelte';
|
|
72
|
-
import { scaleLinear, scaleTime } from 'd3-scale';
|
|
73
72
|
import { cls } from '@layerstack/tailwind';
|
|
74
73
|
|
|
75
74
|
import Axis from '../Axis.svelte';
|
|
@@ -124,7 +123,6 @@
|
|
|
124
123
|
renderContext = 'svg',
|
|
125
124
|
profile = false,
|
|
126
125
|
debug = false,
|
|
127
|
-
xScale: xScaleProp,
|
|
128
126
|
tooltip = true,
|
|
129
127
|
children: childrenProp,
|
|
130
128
|
aboveContext,
|
|
@@ -159,11 +157,6 @@
|
|
|
159
157
|
: chartDataArray(data)) as Array<TData>
|
|
160
158
|
);
|
|
161
159
|
|
|
162
|
-
// Default xScale based on first data's `x` value
|
|
163
|
-
const xScale = $derived(
|
|
164
|
-
xScaleProp ?? (accessor(xProp)(chartData[0]) instanceof Date ? scaleTime() : scaleLinear())
|
|
165
|
-
);
|
|
166
|
-
|
|
167
160
|
function getSplineProps(s: SeriesData<TData, typeof Spline>, i: number) {
|
|
168
161
|
const splineProps: ComponentProps<typeof Spline> = {
|
|
169
162
|
data: s.data,
|
|
@@ -333,7 +326,6 @@
|
|
|
333
326
|
data={chartData}
|
|
334
327
|
x={xProp}
|
|
335
328
|
{xDomain}
|
|
336
|
-
{xScale}
|
|
337
329
|
y={yProp ?? series.map((s) => s.value ?? s.key)}
|
|
338
330
|
yBaseline={0}
|
|
339
331
|
yNice
|
|
@@ -44,7 +44,6 @@
|
|
|
44
44
|
</script>
|
|
45
45
|
|
|
46
46
|
<script lang="ts" generics="TData">
|
|
47
|
-
import { scaleLinear, scaleTime } from 'd3-scale';
|
|
48
47
|
import { format } from '@layerstack/utils';
|
|
49
48
|
import { cls } from '@layerstack/tailwind';
|
|
50
49
|
|
|
@@ -88,8 +87,6 @@
|
|
|
88
87
|
renderContext = 'svg',
|
|
89
88
|
profile = false,
|
|
90
89
|
debug = false,
|
|
91
|
-
xScale: xScaleProp,
|
|
92
|
-
yScale: yScaleProp,
|
|
93
90
|
children: childrenProp,
|
|
94
91
|
aboveContext,
|
|
95
92
|
belowContext,
|
|
@@ -107,18 +104,6 @@
|
|
|
107
104
|
|
|
108
105
|
const seriesState = new SeriesState(() => series);
|
|
109
106
|
|
|
110
|
-
// Default xScale based on first data's `x` value
|
|
111
|
-
const xScale = $derived(
|
|
112
|
-
xScaleProp ??
|
|
113
|
-
(accessor(xProp)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear())
|
|
114
|
-
);
|
|
115
|
-
|
|
116
|
-
// Default yScale based on first data's `y` value
|
|
117
|
-
const yScale = $derived(
|
|
118
|
-
yScaleProp ??
|
|
119
|
-
(accessor(yProp)(chartDataArray(data)[0]) instanceof Date ? scaleTime() : scaleLinear())
|
|
120
|
-
);
|
|
121
|
-
|
|
122
107
|
const chartData = $derived(
|
|
123
108
|
seriesState.visibleSeries
|
|
124
109
|
.flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
|
|
@@ -241,10 +226,8 @@
|
|
|
241
226
|
data={chartData}
|
|
242
227
|
x={xProp}
|
|
243
228
|
{xDomain}
|
|
244
|
-
{xScale}
|
|
245
229
|
y={yProp}
|
|
246
230
|
{yDomain}
|
|
247
|
-
{yScale}
|
|
248
231
|
yNice
|
|
249
232
|
c={yProp}
|
|
250
233
|
cRange={['var(--color-primary)']}
|
package/dist/utils/genData.d.ts
CHANGED
|
@@ -23,21 +23,21 @@ export declare function createSeries<TKey extends string>(options: {
|
|
|
23
23
|
}): ({
|
|
24
24
|
x: number;
|
|
25
25
|
} & { [K in TKey]: number; })[];
|
|
26
|
-
export declare function createDateSeries<TKey extends string>(options
|
|
26
|
+
export declare function createDateSeries<TKey extends string>(options?: {
|
|
27
27
|
count?: number;
|
|
28
|
-
min
|
|
29
|
-
max
|
|
28
|
+
min?: number;
|
|
29
|
+
max?: number;
|
|
30
30
|
keys?: TKey[];
|
|
31
31
|
value?: 'number' | 'integer';
|
|
32
32
|
}): ({
|
|
33
33
|
date: Date;
|
|
34
34
|
} & { [K in TKey]: number; })[];
|
|
35
|
-
export declare function createTimeSeries<TKey extends string>(options
|
|
35
|
+
export declare function createTimeSeries<TKey extends string>(options?: {
|
|
36
36
|
count?: number;
|
|
37
|
-
min
|
|
38
|
-
max
|
|
39
|
-
keys
|
|
40
|
-
value
|
|
37
|
+
min?: number;
|
|
38
|
+
max?: number;
|
|
39
|
+
keys?: TKey[];
|
|
40
|
+
value?: 'number' | 'integer';
|
|
41
41
|
}): ({
|
|
42
42
|
name: string;
|
|
43
43
|
startDate: Date;
|
package/dist/utils/genData.js
CHANGED
|
@@ -43,29 +43,31 @@ export function createSeries(options) {
|
|
|
43
43
|
};
|
|
44
44
|
});
|
|
45
45
|
}
|
|
46
|
-
export function createDateSeries(options) {
|
|
46
|
+
export function createDateSeries(options = {}) {
|
|
47
47
|
const now = timeDay.floor(new Date());
|
|
48
48
|
const count = options.count ?? 10;
|
|
49
|
-
const min = options.min;
|
|
50
|
-
const max = options.max;
|
|
49
|
+
const min = options.min ?? 0;
|
|
50
|
+
const max = options.max ?? 100;
|
|
51
51
|
const keys = options.keys ?? ['value'];
|
|
52
|
+
const valueType = options.value ?? 'number';
|
|
52
53
|
return Array.from({ length: count }).map((_, i) => {
|
|
53
54
|
return {
|
|
54
55
|
date: timeDay.offset(now, -count + i),
|
|
55
56
|
...Object.fromEntries(keys.map((key) => {
|
|
56
57
|
return [
|
|
57
58
|
key,
|
|
58
|
-
|
|
59
|
+
valueType === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max),
|
|
59
60
|
];
|
|
60
61
|
})),
|
|
61
62
|
};
|
|
62
63
|
});
|
|
63
64
|
}
|
|
64
|
-
export function createTimeSeries(options) {
|
|
65
|
+
export function createTimeSeries(options = {}) {
|
|
65
66
|
const count = options.count ?? 10;
|
|
66
|
-
const min = options.min;
|
|
67
|
-
const max = options.max;
|
|
67
|
+
const min = options.min ?? 0;
|
|
68
|
+
const max = options.max ?? 100;
|
|
68
69
|
const keys = options.keys ?? ['value'];
|
|
70
|
+
const valueType = options.value ?? 'number';
|
|
69
71
|
let lastStartDate = timeDay.floor(new Date());
|
|
70
72
|
const timeSeries = Array.from({ length: count }).map((_, i) => {
|
|
71
73
|
const startDate = timeMinute.offset(lastStartDate, getRandomInteger(0, 60));
|
|
@@ -78,7 +80,7 @@ export function createTimeSeries(options) {
|
|
|
78
80
|
...Object.fromEntries(keys.map((key) => {
|
|
79
81
|
return [
|
|
80
82
|
key,
|
|
81
|
-
|
|
83
|
+
valueType === 'integer' ? getRandomInteger(min, max) : getRandomNumber(min, max),
|
|
82
84
|
];
|
|
83
85
|
})),
|
|
84
86
|
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type ScaleBand, type ScaleTime } from 'd3-scale';
|
|
2
2
|
import { type MotionProp, type MotionOptions, type SpringOptions, type TweenOptions } from './motion.svelte.js';
|
|
3
|
-
import type
|
|
3
|
+
import { type Accessor } from './common.js';
|
|
4
4
|
import type { OnlyObjects } from './types.js';
|
|
5
5
|
export type AnyScale<TInput extends SingleDomainType = any, TOutput extends SingleDomainType = any, TScaleArgs extends any[] | readonly any[] = any[]> = {
|
|
6
6
|
(value: TInput): TOutput;
|
|
@@ -25,6 +25,7 @@ export type AnyScale<TInput extends SingleDomainType = any, TOutput extends Sing
|
|
|
25
25
|
};
|
|
26
26
|
export declare function isScaleBand(scale: AnyScale<any, any>): scale is ScaleBand<any>;
|
|
27
27
|
export declare function isScaleTime(scale: AnyScale<any, any>): scale is ScaleTime<any, any>;
|
|
28
|
+
export declare function isScaleNumeric(scale: AnyScale<any, any>): scale is ScaleTime<any, any>;
|
|
28
29
|
export declare function getRange(scale: any): any[];
|
|
29
30
|
export type SingleDomainType = number | string | Date | null | undefined;
|
|
30
31
|
export type DomainType = (number | string | Date | null | undefined)[] | null | undefined;
|
|
@@ -54,6 +55,10 @@ export declare function scaleBandInvert(scale: ScaleBand<any>): (value: number)
|
|
|
54
55
|
export declare function scaleInvert(scale: AnyScale<any, any>, value: number): any;
|
|
55
56
|
/** Create new copy of scale with domain and range */
|
|
56
57
|
export declare function createScale(scale: AnyScale, domain: DomainType, range: any[] | readonly any[] | Function, context?: Record<any, any>): AnyScale<any, any, any[]>;
|
|
58
|
+
/**
|
|
59
|
+
* Auto-detect scale type based on domain values or data values
|
|
60
|
+
*/
|
|
61
|
+
export declare function autoScale(domain?: DomainType, data?: any[], propAccessor?: Accessor<any>): AnyScale;
|
|
57
62
|
/**
|
|
58
63
|
* Create a `scaleBand()` within another scaleBand()'s bandwidth
|
|
59
64
|
* (typically a x1 of an x0 scale, used for grouping)
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { unique } from '@layerstack/utils';
|
|
2
|
-
import { scaleBand } from 'd3-scale';
|
|
2
|
+
import { scaleBand, scaleLinear, scaleTime } from 'd3-scale';
|
|
3
3
|
import { createControlledMotion, } from './motion.svelte.js';
|
|
4
4
|
import { Spring, Tween } from 'svelte/motion';
|
|
5
|
+
import { accessor } from './common.js';
|
|
5
6
|
function isAnyScale(scale) {
|
|
6
7
|
return typeof scale === 'function' && typeof scale.range === 'function';
|
|
7
8
|
}
|
|
@@ -12,6 +13,10 @@ export function isScaleTime(scale) {
|
|
|
12
13
|
const domain = scale.domain();
|
|
13
14
|
return domain[0] instanceof Date || domain[1] instanceof Date;
|
|
14
15
|
}
|
|
16
|
+
export function isScaleNumeric(scale) {
|
|
17
|
+
const domain = scale.domain();
|
|
18
|
+
return typeof domain[0] === 'number' || typeof domain[1] === 'number';
|
|
19
|
+
}
|
|
15
20
|
export function getRange(scale) {
|
|
16
21
|
if (isAnyScale(scale)) {
|
|
17
22
|
return scale.range();
|
|
@@ -87,6 +92,40 @@ export function createScale(scale, domain, range, context) {
|
|
|
87
92
|
}
|
|
88
93
|
return scaleCopy;
|
|
89
94
|
}
|
|
95
|
+
/**
|
|
96
|
+
* Auto-detect scale type based on domain values or data values
|
|
97
|
+
*/
|
|
98
|
+
export function autoScale(domain, data, propAccessor) {
|
|
99
|
+
let values = null;
|
|
100
|
+
if (domain && domain.length > 0) {
|
|
101
|
+
// Determine based on domain values
|
|
102
|
+
values = domain;
|
|
103
|
+
}
|
|
104
|
+
else if (data && data.length > 0 && propAccessor) {
|
|
105
|
+
// Determine based on data values
|
|
106
|
+
const value = accessor(propAccessor)(data[0]);
|
|
107
|
+
// If accessor defined with an array (ex. `x={['start', 'end']}`) use both values
|
|
108
|
+
if (Array.isArray(value)) {
|
|
109
|
+
values = value;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
values = [value];
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
if (values) {
|
|
116
|
+
if (values.some((v) => v instanceof Date)) {
|
|
117
|
+
return scaleTime();
|
|
118
|
+
}
|
|
119
|
+
else if (values.some((v) => typeof v === 'number')) {
|
|
120
|
+
return scaleLinear();
|
|
121
|
+
}
|
|
122
|
+
else if (values.some((v) => typeof v === 'string')) {
|
|
123
|
+
return scaleBand();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
// fallback to linear scale
|
|
127
|
+
return scaleLinear();
|
|
128
|
+
}
|
|
90
129
|
/**
|
|
91
130
|
* Create a `scaleBand()` within another scaleBand()'s bandwidth
|
|
92
131
|
* (typically a x1 of an x0 scale, used for grouping)
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"author": "Sean Lynch <techniq35@gmail.com>",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": "techniq/layerchart",
|
|
7
|
-
"version": "2.0.0-next.
|
|
7
|
+
"version": "2.0.0-next.35",
|
|
8
8
|
"devDependencies": {
|
|
9
9
|
"@changesets/cli": "^2.29.4",
|
|
10
10
|
"@iconify-json/lucide": "^1.2.48",
|
|
@@ -55,7 +55,7 @@
|
|
|
55
55
|
"svelte": "5.34.1",
|
|
56
56
|
"svelte-check": "^4.2.1",
|
|
57
57
|
"svelte-json-tree": "^2.2.0",
|
|
58
|
-
"svelte-ux": "2.0.0-next.
|
|
58
|
+
"svelte-ux": "2.0.0-next.17",
|
|
59
59
|
"svelte2tsx": "^0.7.39",
|
|
60
60
|
"tailwindcss": "^4.1.10",
|
|
61
61
|
"topojson-client": "^3.1.0",
|