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
|
@@ -88,23 +88,30 @@
|
|
|
88
88
|
? 'start'
|
|
89
89
|
: 'middle',
|
|
90
90
|
});
|
|
91
|
-
</script>
|
|
92
91
|
|
|
93
|
-
|
|
94
|
-
cx={point.x}
|
|
95
|
-
cy={point.y}
|
|
96
|
-
{r}
|
|
97
|
-
onpointermove={(e) => {
|
|
92
|
+
function onPointerMove(e: PointerEvent | MouseEvent | TouchEvent) {
|
|
98
93
|
if (details) {
|
|
99
94
|
e.stopPropagation();
|
|
100
95
|
ctx.tooltip.show(e, { annotation: { label, details } });
|
|
101
96
|
}
|
|
102
|
-
}
|
|
103
|
-
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
function onPointerLeave(e: PointerEvent | MouseEvent | TouchEvent) {
|
|
104
100
|
if (details) {
|
|
101
|
+
e.stopPropagation();
|
|
105
102
|
ctx.tooltip.hide();
|
|
106
103
|
}
|
|
107
|
-
}
|
|
104
|
+
}
|
|
105
|
+
</script>
|
|
106
|
+
|
|
107
|
+
<Circle
|
|
108
|
+
cx={point.x}
|
|
109
|
+
cy={point.y}
|
|
110
|
+
{r}
|
|
111
|
+
onmousemove={onPointerMove}
|
|
112
|
+
ontouchmove={onPointerMove}
|
|
113
|
+
onmouseleave={onPointerLeave}
|
|
114
|
+
ontouchend={onPointerLeave}
|
|
108
115
|
{...props?.circle}
|
|
109
116
|
class={cls('stroke-surface-100', props?.circle?.class)}
|
|
110
117
|
/>
|
|
@@ -118,13 +118,13 @@
|
|
|
118
118
|
</script>
|
|
119
119
|
|
|
120
120
|
{#if fill || className}
|
|
121
|
-
<Rect {...rect} {fill} class={cls(props?.rect?.class, className)} />
|
|
121
|
+
<Rect {...rect} {...props?.rect} {fill} class={cls(props?.rect?.class, className)} />
|
|
122
122
|
{/if}
|
|
123
123
|
|
|
124
124
|
{#if gradient}
|
|
125
125
|
<LinearGradient {...gradient}>
|
|
126
126
|
{#snippet children({ gradient })}
|
|
127
|
-
<Rect {...rect}
|
|
127
|
+
<Rect {...rect} {...props?.rect} fill={gradient} />
|
|
128
128
|
{/snippet}
|
|
129
129
|
</LinearGradient>
|
|
130
130
|
{/if}
|
|
@@ -132,7 +132,7 @@
|
|
|
132
132
|
{#if pattern}
|
|
133
133
|
<Pattern {...pattern}>
|
|
134
134
|
{#snippet children({ pattern })}
|
|
135
|
-
<Rect {...rect}
|
|
135
|
+
<Rect {...rect} {...props?.rect} fill={pattern} />
|
|
136
136
|
{/snippet}
|
|
137
137
|
</Pattern>
|
|
138
138
|
{/if}
|
|
@@ -401,13 +401,13 @@
|
|
|
401
401
|
<Spline
|
|
402
402
|
pathData={trackArc()}
|
|
403
403
|
stroke="none"
|
|
404
|
-
bind:
|
|
404
|
+
bind:pathRef={trackRef}
|
|
405
405
|
{...extractLayerProps(track, 'arc-track')}
|
|
406
406
|
/>
|
|
407
407
|
{/if}
|
|
408
408
|
|
|
409
409
|
<Spline
|
|
410
|
-
bind:
|
|
410
|
+
bind:pathRef={ref}
|
|
411
411
|
pathData={arc()}
|
|
412
412
|
transform="translate({xOffset}, {yOffset})"
|
|
413
413
|
{fill}
|
|
@@ -43,6 +43,18 @@
|
|
|
43
43
|
*/
|
|
44
44
|
ticks?: TicksConfig;
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* Width or height of each tick in pxiels (responsive reduce)
|
|
48
|
+
*/
|
|
49
|
+
tickSpacing?: number;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Whether to render tick labels on multiple lines for additional context
|
|
53
|
+
*
|
|
54
|
+
* @default false
|
|
55
|
+
*/
|
|
56
|
+
tickMultiline?: boolean;
|
|
57
|
+
|
|
46
58
|
/**
|
|
47
59
|
* Length of the tick line
|
|
48
60
|
* @default 4
|
|
@@ -59,7 +71,7 @@
|
|
|
59
71
|
/**
|
|
60
72
|
* Format tick labels
|
|
61
73
|
*/
|
|
62
|
-
format?: FormatType;
|
|
74
|
+
format?: FormatType | FormatConfig;
|
|
63
75
|
|
|
64
76
|
/**
|
|
65
77
|
* Props to apply to each tick label
|
|
@@ -114,7 +126,7 @@
|
|
|
114
126
|
import { extent } from 'd3-array';
|
|
115
127
|
import { pointRadial } from 'd3-shape';
|
|
116
128
|
|
|
117
|
-
import {
|
|
129
|
+
import { type FormatType, type FormatConfig } from '@layerstack/utils';
|
|
118
130
|
import { cls } from '@layerstack/tailwind';
|
|
119
131
|
|
|
120
132
|
import Group, { type GroupProps } from './Group.svelte';
|
|
@@ -126,7 +138,7 @@
|
|
|
126
138
|
import { getChartContext } from './Chart.svelte';
|
|
127
139
|
import { extractLayerProps, layerClass } from '../utils/attributes.js';
|
|
128
140
|
import { type MotionProp } from '../utils/motion.svelte.js';
|
|
129
|
-
import { resolveTickVals, type TicksConfig } from '../utils/ticks.js';
|
|
141
|
+
import { resolveTickFormat, resolveTickVals, type TicksConfig } from '../utils/ticks.js';
|
|
130
142
|
|
|
131
143
|
let {
|
|
132
144
|
placement,
|
|
@@ -136,6 +148,12 @@
|
|
|
136
148
|
rule = false,
|
|
137
149
|
grid = false,
|
|
138
150
|
ticks,
|
|
151
|
+
tickSpacing = ['top', 'bottom', 'angle'].includes(placement)
|
|
152
|
+
? 80
|
|
153
|
+
: ['left', 'right', 'radius'].includes(placement)
|
|
154
|
+
? 50
|
|
155
|
+
: undefined,
|
|
156
|
+
tickMultiline = false,
|
|
139
157
|
tickLength = 4,
|
|
140
158
|
tickMarks = true,
|
|
141
159
|
format,
|
|
@@ -169,7 +187,36 @@
|
|
|
169
187
|
const xRangeMinMax = $derived(extent<number>(ctx.xRange)) as [number, number];
|
|
170
188
|
const yRangeMinMax = $derived(extent<number>(ctx.yRange)) as [number, number];
|
|
171
189
|
|
|
172
|
-
const
|
|
190
|
+
const ctxSize = $derived(
|
|
191
|
+
orientation === 'vertical'
|
|
192
|
+
? ctx.height
|
|
193
|
+
: orientation === 'horizontal'
|
|
194
|
+
? ctx.width
|
|
195
|
+
: orientation === 'radius'
|
|
196
|
+
? ctx.height / 2
|
|
197
|
+
: orientation === 'angle'
|
|
198
|
+
? ctx.width
|
|
199
|
+
: null
|
|
200
|
+
);
|
|
201
|
+
|
|
202
|
+
const tickCount = $derived(
|
|
203
|
+
typeof ticks === 'number'
|
|
204
|
+
? ticks
|
|
205
|
+
: tickSpacing && ctxSize
|
|
206
|
+
? Math.round(ctxSize / tickSpacing)
|
|
207
|
+
: undefined
|
|
208
|
+
);
|
|
209
|
+
const tickVals = $derived(resolveTickVals(scale, ticks, tickCount));
|
|
210
|
+
const tickFormat = $derived(
|
|
211
|
+
resolveTickFormat({
|
|
212
|
+
scale,
|
|
213
|
+
ticks,
|
|
214
|
+
count: tickCount,
|
|
215
|
+
formatType: format,
|
|
216
|
+
multiline: tickMultiline,
|
|
217
|
+
placement,
|
|
218
|
+
})
|
|
219
|
+
);
|
|
173
220
|
|
|
174
221
|
function getCoords(tick: any) {
|
|
175
222
|
switch (placement) {
|
|
@@ -217,14 +264,14 @@
|
|
|
217
264
|
return {
|
|
218
265
|
textAnchor: 'middle',
|
|
219
266
|
verticalAnchor: 'end',
|
|
220
|
-
dy: -tickLength
|
|
267
|
+
dy: -tickLength,
|
|
221
268
|
};
|
|
222
269
|
|
|
223
270
|
case 'bottom':
|
|
224
271
|
return {
|
|
225
272
|
textAnchor: 'middle',
|
|
226
273
|
verticalAnchor: 'start',
|
|
227
|
-
dy: tickLength,
|
|
274
|
+
dy: tickLength,
|
|
228
275
|
};
|
|
229
276
|
|
|
230
277
|
case 'left':
|
|
@@ -232,7 +279,6 @@
|
|
|
232
279
|
textAnchor: 'end',
|
|
233
280
|
verticalAnchor: 'middle',
|
|
234
281
|
dx: -tickLength,
|
|
235
|
-
dy: -2, // manually adjusted until Text supports custom styles
|
|
236
282
|
};
|
|
237
283
|
|
|
238
284
|
case 'right':
|
|
@@ -240,7 +286,6 @@
|
|
|
240
286
|
textAnchor: 'start',
|
|
241
287
|
verticalAnchor: 'middle',
|
|
242
288
|
dx: tickLength,
|
|
243
|
-
dy: -2, // manually adjusted until Text supports custom styles
|
|
244
289
|
};
|
|
245
290
|
|
|
246
291
|
case 'angle':
|
|
@@ -255,7 +300,7 @@
|
|
|
255
300
|
? 'end'
|
|
256
301
|
: 'start',
|
|
257
302
|
verticalAnchor: 'middle',
|
|
258
|
-
dx: Math.sin(xValue) *
|
|
303
|
+
dx: Math.sin(xValue) * tickLength,
|
|
259
304
|
dy: -Math.cos(xValue) * (tickLength + 4), // manually adjusted until Text supports custom styles
|
|
260
305
|
};
|
|
261
306
|
|
|
@@ -264,7 +309,6 @@
|
|
|
264
309
|
textAnchor: 'middle',
|
|
265
310
|
verticalAnchor: 'middle',
|
|
266
311
|
dx: 2,
|
|
267
|
-
dy: -2, // manually adjusted until Text supports custom styles
|
|
268
312
|
};
|
|
269
313
|
}
|
|
270
314
|
}
|
|
@@ -317,13 +361,15 @@
|
|
|
317
361
|
});
|
|
318
362
|
|
|
319
363
|
const resolvedLabelProps = $derived({
|
|
320
|
-
value: typeof label === 'function' ? '' :
|
|
364
|
+
value: typeof label === 'function' ? '' : label,
|
|
321
365
|
x: resolvedLabelX,
|
|
322
366
|
y: resolvedLabelY,
|
|
323
367
|
textAnchor: resolvedLabelTextAnchor,
|
|
324
368
|
verticalAnchor: resolvedLabelVerticalAnchor,
|
|
325
369
|
rotate: orientation === 'vertical' && labelPlacement === 'middle' ? -90 : 0,
|
|
326
|
-
|
|
370
|
+
// complement 10px text (until Text supports custom styles)
|
|
371
|
+
capHeight: '7px',
|
|
372
|
+
lineHeight: '11px',
|
|
327
373
|
...labelProps,
|
|
328
374
|
class: cls(
|
|
329
375
|
layerClass('axis-label'),
|
|
@@ -356,7 +402,7 @@
|
|
|
356
402
|
<Text {...resolvedLabelProps} />
|
|
357
403
|
{/if}
|
|
358
404
|
|
|
359
|
-
{#each tickVals as tick, index (tick.
|
|
405
|
+
{#each tickVals as tick, index (tick.valueOf())}
|
|
360
406
|
{@const tickCoords = getCoords(tick)}
|
|
361
407
|
{@const [radialTickCoordsX, radialTickCoordsY] = pointRadial(tickCoords.x, tickCoords.y)}
|
|
362
408
|
{@const [radialTickMarkCoordsX, radialTickMarkCoordsY] = pointRadial(
|
|
@@ -366,9 +412,12 @@
|
|
|
366
412
|
{@const resolvedTickLabelProps = {
|
|
367
413
|
x: orientation === 'angle' ? radialTickCoordsX : tickCoords.x,
|
|
368
414
|
y: orientation === 'angle' ? radialTickCoordsY : tickCoords.y,
|
|
369
|
-
value:
|
|
415
|
+
value: tickFormat(tick, index),
|
|
370
416
|
...getDefaultTickLabelProps(tick),
|
|
371
417
|
motion,
|
|
418
|
+
// complement 10px text (until Text supports custom styles)
|
|
419
|
+
capHeight: '7px',
|
|
420
|
+
lineHeight: '11px',
|
|
372
421
|
...tickLabelProps,
|
|
373
422
|
class: cls(
|
|
374
423
|
layerClass('axis-tick-label'),
|
|
@@ -36,6 +36,16 @@ export type AxisPropsWithoutHTML<In extends Transition = Transition> = {
|
|
|
36
36
|
* Control the number of ticks
|
|
37
37
|
*/
|
|
38
38
|
ticks?: TicksConfig;
|
|
39
|
+
/**
|
|
40
|
+
* Width or height of each tick in pxiels (responsive reduce)
|
|
41
|
+
*/
|
|
42
|
+
tickSpacing?: number;
|
|
43
|
+
/**
|
|
44
|
+
* Whether to render tick labels on multiple lines for additional context
|
|
45
|
+
*
|
|
46
|
+
* @default false
|
|
47
|
+
*/
|
|
48
|
+
tickMultiline?: boolean;
|
|
39
49
|
/**
|
|
40
50
|
* Length of the tick line
|
|
41
51
|
* @default 4
|
|
@@ -50,7 +60,7 @@ export type AxisPropsWithoutHTML<In extends Transition = Transition> = {
|
|
|
50
60
|
/**
|
|
51
61
|
* Format tick labels
|
|
52
62
|
*/
|
|
53
|
-
format?: FormatType;
|
|
63
|
+
format?: FormatType | FormatConfig;
|
|
54
64
|
/**
|
|
55
65
|
* Props to apply to each tick label
|
|
56
66
|
*/
|
|
@@ -92,7 +102,7 @@ export type AxisPropsWithoutHTML<In extends Transition = Transition> = {
|
|
|
92
102
|
export type AxisProps<In extends Transition = Transition> = AxisPropsWithoutHTML<In> & Without<GroupProps, AxisPropsWithoutHTML<In>>;
|
|
93
103
|
import { type ComponentProps, type Snippet } from 'svelte';
|
|
94
104
|
import type { SVGAttributes } from 'svelte/elements';
|
|
95
|
-
import { type FormatType } from '@layerstack/utils';
|
|
105
|
+
import { type FormatType, type FormatConfig } from '@layerstack/utils';
|
|
96
106
|
import { type GroupProps } from './Group.svelte';
|
|
97
107
|
import Rule from './Rule.svelte';
|
|
98
108
|
import Text from './Text.svelte';
|
|
@@ -14,9 +14,9 @@
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* The default children snippet which provides
|
|
17
|
-
* the id
|
|
17
|
+
* the id for the filter.
|
|
18
18
|
*/
|
|
19
|
-
children?: Snippet
|
|
19
|
+
children?: Snippet;
|
|
20
20
|
};
|
|
21
21
|
</script>
|
|
22
22
|
|
|
@@ -42,7 +42,9 @@
|
|
|
42
42
|
|
|
43
43
|
{#if children}
|
|
44
44
|
<g filter="url(#{id})" class={layerClass('blur-g')}>
|
|
45
|
-
{@render children(
|
|
45
|
+
{@render children()}
|
|
46
46
|
</g>
|
|
47
47
|
{/if}
|
|
48
|
+
{:else if children}
|
|
49
|
+
{@render children()}
|
|
48
50
|
{/if}
|
|
@@ -11,12 +11,9 @@ export type BlurProps = {
|
|
|
11
11
|
stdDeviation?: number;
|
|
12
12
|
/**
|
|
13
13
|
* The default children snippet which provides
|
|
14
|
-
* the id
|
|
14
|
+
* the id for the filter.
|
|
15
15
|
*/
|
|
16
|
-
children?: Snippet
|
|
17
|
-
id: string;
|
|
18
|
-
url: string;
|
|
19
|
-
}]>;
|
|
16
|
+
children?: Snippet;
|
|
20
17
|
};
|
|
21
18
|
import type { Snippet } from 'svelte';
|
|
22
19
|
declare const Blur: import("svelte").Component<BlurProps, {}, "">;
|
|
@@ -319,7 +319,7 @@
|
|
|
319
319
|
_range.width < RESET_THRESHOLD ||
|
|
320
320
|
_range.height < RESET_THRESHOLD
|
|
321
321
|
) {
|
|
322
|
-
// Clicked on frame, or pointer delta was
|
|
322
|
+
// Clicked on frame, or pointer delta was less than threshold (default: 1px)
|
|
323
323
|
if (ignoreResetClick) {
|
|
324
324
|
logger.debug('ignoring frame click reset');
|
|
325
325
|
} else {
|
|
@@ -36,14 +36,14 @@
|
|
|
36
36
|
/**
|
|
37
37
|
* Props to pass to the `<text>` element for month labels.
|
|
38
38
|
*/
|
|
39
|
-
monthLabel?: Partial<ComponentProps<typeof Text>>;
|
|
39
|
+
monthLabel?: boolean | Partial<ComponentProps<typeof Text>>;
|
|
40
40
|
|
|
41
41
|
/**
|
|
42
42
|
* Tooltip context to setup mouse events to show tooltip for related data
|
|
43
43
|
*/
|
|
44
44
|
tooltipContext?: TooltipContextValue;
|
|
45
45
|
|
|
46
|
-
children?: Snippet<[{ cells: CalendarCell[] }]>;
|
|
46
|
+
children?: Snippet<[{ cells: CalendarCell[]; cellSize: [number, number] }]>;
|
|
47
47
|
} & Omit<
|
|
48
48
|
RectPropsWithoutHTML,
|
|
49
49
|
'children' | 'x' | 'y' | 'width' | 'height' | 'fill' | 'onpointermove' | 'onpointerleave'
|
|
@@ -57,7 +57,7 @@
|
|
|
57
57
|
import { type ComponentProps, type Snippet } from 'svelte';
|
|
58
58
|
import { timeDays, timeMonths, timeWeek, timeYear } from 'd3-time';
|
|
59
59
|
import { index } from 'd3-array';
|
|
60
|
-
import { format } from '
|
|
60
|
+
import { format } from '@layerstack/utils';
|
|
61
61
|
|
|
62
62
|
import Rect, { type RectPropsWithoutHTML } from './Rect.svelte';
|
|
63
63
|
import type { TooltipContextValue } from './tooltip/TooltipContext.svelte';
|
|
@@ -74,9 +74,9 @@
|
|
|
74
74
|
start,
|
|
75
75
|
cellSize: cellSizeProp,
|
|
76
76
|
monthPath = false,
|
|
77
|
+
monthLabel = true,
|
|
77
78
|
tooltipContext: tooltip,
|
|
78
79
|
children,
|
|
79
|
-
monthLabel,
|
|
80
80
|
...restProps
|
|
81
81
|
}: CalendarPropsWithoutHTML = $props();
|
|
82
82
|
|
|
@@ -117,7 +117,7 @@
|
|
|
117
117
|
</script>
|
|
118
118
|
|
|
119
119
|
{#if children}
|
|
120
|
-
{@render children({ cells })}
|
|
120
|
+
{@render children({ cells, cellSize })}
|
|
121
121
|
{:else}
|
|
122
122
|
{#each cells as cell}
|
|
123
123
|
<Rect
|
|
@@ -136,11 +136,15 @@
|
|
|
136
136
|
{#if monthPath}
|
|
137
137
|
{#each yearMonths as date}
|
|
138
138
|
<MonthPath {date} {cellSize} {...extractLayerProps(monthPath, 'calendar-month-path')} />
|
|
139
|
+
{/each}
|
|
140
|
+
{/if}
|
|
139
141
|
|
|
142
|
+
{#if monthLabel}
|
|
143
|
+
{#each yearMonths as date}
|
|
140
144
|
<Text
|
|
141
145
|
x={timeWeek.count(timeYear.floor(date), timeWeek.ceil(date)) * cellSize[0]}
|
|
142
146
|
y={-4}
|
|
143
|
-
value={format(date, '
|
|
147
|
+
value={format(date, 'month', { variant: 'short' })}
|
|
144
148
|
{...extractLayerProps(monthLabel, 'calendar-month-label', 'text-xs')}
|
|
145
149
|
/>
|
|
146
150
|
{/each}
|
|
@@ -30,13 +30,14 @@ export type CalendarPropsWithoutHTML = {
|
|
|
30
30
|
/**
|
|
31
31
|
* Props to pass to the `<text>` element for month labels.
|
|
32
32
|
*/
|
|
33
|
-
monthLabel?: Partial<ComponentProps<typeof Text>>;
|
|
33
|
+
monthLabel?: boolean | Partial<ComponentProps<typeof Text>>;
|
|
34
34
|
/**
|
|
35
35
|
* Tooltip context to setup mouse events to show tooltip for related data
|
|
36
36
|
*/
|
|
37
37
|
tooltipContext?: TooltipContextValue;
|
|
38
38
|
children?: Snippet<[{
|
|
39
39
|
cells: CalendarCell[];
|
|
40
|
+
cellSize: [number, number];
|
|
40
41
|
}]>;
|
|
41
42
|
} & Omit<RectPropsWithoutHTML, 'children' | 'x' | 'y' | 'width' | 'height' | 'fill' | 'onpointermove' | 'onpointerleave'>;
|
|
42
43
|
export type CalendarProps = CalendarPropsWithoutHTML & Without<SVGAttributes<SVGRectElement>, CalendarPropsWithoutHTML>;
|
|
@@ -844,12 +844,12 @@
|
|
|
844
844
|
if (verbose === true) {
|
|
845
845
|
if (width <= 0 && isMounted === true) {
|
|
846
846
|
console.warn(
|
|
847
|
-
|
|
847
|
+
`[LayerChart] Target div has zero or negative width (${width}). Did you forget to set an explicit width in CSS on the container?`
|
|
848
848
|
);
|
|
849
849
|
}
|
|
850
850
|
if (height <= 0 && isMounted === true) {
|
|
851
851
|
console.warn(
|
|
852
|
-
|
|
852
|
+
`[LayerChart] Target div has zero or negative height (${height}). Did you forget to set an explicit height in CSS on the container?`
|
|
853
853
|
);
|
|
854
854
|
}
|
|
855
855
|
}
|
|
@@ -82,7 +82,7 @@
|
|
|
82
82
|
type = 'rounded',
|
|
83
83
|
radius = 20,
|
|
84
84
|
curve = curveLinear,
|
|
85
|
-
|
|
85
|
+
pathRef = $bindable(),
|
|
86
86
|
pathData: pathDataProp,
|
|
87
87
|
marker,
|
|
88
88
|
markerStart,
|
|
@@ -137,7 +137,7 @@
|
|
|
137
137
|
|
|
138
138
|
<Spline
|
|
139
139
|
pathData={motionPath.current}
|
|
140
|
-
bind:
|
|
140
|
+
bind:pathRef
|
|
141
141
|
marker-start={markerStartId ? `url(#${markerStartId})` : undefined}
|
|
142
142
|
marker-mid={markerMidId ? `url(#${markerMidId})` : undefined}
|
|
143
143
|
marker-end={markerEndId ? `url(#${markerEndId})` : undefined}
|
|
@@ -46,6 +46,6 @@ import { type CurveFactory } from 'd3-shape';
|
|
|
46
46
|
import { type ConnectorCoords, type ConnectorSweep, type ConnectorType } from '../utils/connectorUtils.js';
|
|
47
47
|
import { type SplineProps, type SplinePropsWithoutHTML } from './Spline.svelte';
|
|
48
48
|
import type { Without } from '../utils/types.js';
|
|
49
|
-
declare const Connector: import("svelte").Component<ConnectorProps, {}, "
|
|
49
|
+
declare const Connector: import("svelte").Component<ConnectorProps, {}, "pathRef">;
|
|
50
50
|
type Connector = ReturnType<typeof Connector>;
|
|
51
51
|
export default Connector;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script lang="ts" module>
|
|
2
|
+
import type { CommonStyleProps, Without } from '../utils/types.js';
|
|
3
|
+
|
|
4
|
+
export type EllipsePropsWithoutHTML = {
|
|
5
|
+
/**
|
|
6
|
+
* The center x position of the ellipse.
|
|
7
|
+
*
|
|
8
|
+
* @default 0
|
|
9
|
+
*/
|
|
10
|
+
cx?: number;
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* The initial center x position of the ellipse.
|
|
14
|
+
*
|
|
15
|
+
* @default cx
|
|
16
|
+
*/
|
|
17
|
+
initialCx?: number;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* The center y position of the ellipse.
|
|
21
|
+
*
|
|
22
|
+
* @default 0
|
|
23
|
+
*/
|
|
24
|
+
cy?: number;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* The initial center y position of the ellipse.
|
|
28
|
+
*
|
|
29
|
+
* @default cy
|
|
30
|
+
*/
|
|
31
|
+
initialCy?: number;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* The radius of the ellipse on the x-axis.
|
|
35
|
+
*
|
|
36
|
+
* @default 1
|
|
37
|
+
*/
|
|
38
|
+
rx?: number;
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The initial radius of the ellipse on the x-axis.
|
|
42
|
+
*
|
|
43
|
+
* @default rx
|
|
44
|
+
*/
|
|
45
|
+
initialRx?: number;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The radius of the ellipse on the y-axis.
|
|
49
|
+
*
|
|
50
|
+
* @default 1
|
|
51
|
+
*/
|
|
52
|
+
ry?: number;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The initial radius of the ellipse on the y-axis.
|
|
56
|
+
*
|
|
57
|
+
* @default ry
|
|
58
|
+
*/
|
|
59
|
+
initialRy?: number;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* A bindable reference to the `<ellipse>` element
|
|
63
|
+
*
|
|
64
|
+
* @bindable
|
|
65
|
+
*/
|
|
66
|
+
ref?: SVGEllipseElement;
|
|
67
|
+
|
|
68
|
+
motion?: MotionProp;
|
|
69
|
+
} & CommonStyleProps;
|
|
70
|
+
|
|
71
|
+
export type EllipseProps = EllipsePropsWithoutHTML &
|
|
72
|
+
Without<SVGAttributes<Element>, EllipsePropsWithoutHTML>;
|
|
73
|
+
</script>
|
|
74
|
+
|
|
75
|
+
<script lang="ts">
|
|
76
|
+
import { cls } from '@layerstack/tailwind';
|
|
77
|
+
import { merge } from 'lodash-es';
|
|
78
|
+
|
|
79
|
+
import { getRenderContext } from './Chart.svelte';
|
|
80
|
+
import { createMotion, type MotionProp } from '../utils/motion.svelte.js';
|
|
81
|
+
import { registerCanvasComponent } from './layout/Canvas.svelte';
|
|
82
|
+
import { renderEllipse, type ComputedStylesOptions } from '../utils/canvas.js';
|
|
83
|
+
import type { SVGAttributes } from 'svelte/elements';
|
|
84
|
+
import { createKey } from '../utils/key.svelte.js';
|
|
85
|
+
import { layerClass } from '../utils/attributes.js';
|
|
86
|
+
|
|
87
|
+
let {
|
|
88
|
+
cx = 0,
|
|
89
|
+
initialCx: initialCxProp,
|
|
90
|
+
cy = 0,
|
|
91
|
+
initialCy: initialCyProp,
|
|
92
|
+
rx = 1,
|
|
93
|
+
initialRx: initialRxProp,
|
|
94
|
+
ry = 1,
|
|
95
|
+
initialRy: initialRyProp,
|
|
96
|
+
motion,
|
|
97
|
+
fill,
|
|
98
|
+
fillOpacity,
|
|
99
|
+
stroke,
|
|
100
|
+
strokeWidth,
|
|
101
|
+
opacity,
|
|
102
|
+
class: className,
|
|
103
|
+
ref: refProp = $bindable(),
|
|
104
|
+
...restProps
|
|
105
|
+
}: EllipseProps = $props();
|
|
106
|
+
|
|
107
|
+
let ref = $state<SVGEllipseElement>();
|
|
108
|
+
|
|
109
|
+
$effect.pre(() => {
|
|
110
|
+
refProp = ref;
|
|
111
|
+
});
|
|
112
|
+
|
|
113
|
+
const initialCx = initialCxProp ?? cx;
|
|
114
|
+
const initialCy = initialCyProp ?? cy;
|
|
115
|
+
const initialRx = initialRxProp ?? rx;
|
|
116
|
+
const initialRy = initialRyProp ?? ry;
|
|
117
|
+
|
|
118
|
+
const renderCtx = getRenderContext();
|
|
119
|
+
|
|
120
|
+
const motionCx = createMotion(initialCx, () => cx, motion);
|
|
121
|
+
const motionCy = createMotion(initialCy, () => cy, motion);
|
|
122
|
+
const motionRx = createMotion(initialRx, () => rx, motion);
|
|
123
|
+
const motionRy = createMotion(initialRy, () => ry, motion);
|
|
124
|
+
|
|
125
|
+
function render(
|
|
126
|
+
ctx: CanvasRenderingContext2D,
|
|
127
|
+
styleOverrides: ComputedStylesOptions | undefined
|
|
128
|
+
) {
|
|
129
|
+
renderEllipse(
|
|
130
|
+
ctx,
|
|
131
|
+
{ cx: motionCx.current, cy: motionCy.current, rx: motionRx.current, ry: motionRy.current },
|
|
132
|
+
styleOverrides
|
|
133
|
+
? merge({ styles: { strokeWidth } }, styleOverrides)
|
|
134
|
+
: {
|
|
135
|
+
styles: { fill, fillOpacity, stroke, strokeWidth, opacity },
|
|
136
|
+
classes: className,
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// TODO: Use objectId to work around Svelte 4 reactivity issue (even when memoizing gradients)
|
|
142
|
+
const fillKey = createKey(() => fill);
|
|
143
|
+
const strokeKey = createKey(() => stroke);
|
|
144
|
+
|
|
145
|
+
if (renderCtx === 'canvas') {
|
|
146
|
+
registerCanvasComponent({
|
|
147
|
+
name: 'Ellipse',
|
|
148
|
+
render,
|
|
149
|
+
events: {
|
|
150
|
+
click: restProps.onclick,
|
|
151
|
+
pointerdown: restProps.onpointerdown,
|
|
152
|
+
pointerenter: restProps.onpointerenter,
|
|
153
|
+
pointermove: restProps.onpointermove,
|
|
154
|
+
pointerleave: restProps.onpointerleave,
|
|
155
|
+
},
|
|
156
|
+
deps: () => [
|
|
157
|
+
motionCx.current,
|
|
158
|
+
motionCy.current,
|
|
159
|
+
motionRx.current,
|
|
160
|
+
motionRy.current,
|
|
161
|
+
fillKey.current,
|
|
162
|
+
fillOpacity,
|
|
163
|
+
strokeKey.current,
|
|
164
|
+
strokeWidth,
|
|
165
|
+
opacity,
|
|
166
|
+
className,
|
|
167
|
+
],
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
</script>
|
|
171
|
+
|
|
172
|
+
{#if renderCtx === 'svg'}
|
|
173
|
+
<ellipse
|
|
174
|
+
bind:this={ref}
|
|
175
|
+
cx={motionCx.current}
|
|
176
|
+
cy={motionCy.current}
|
|
177
|
+
rx={motionRx.current}
|
|
178
|
+
ry={motionRy.current}
|
|
179
|
+
{fill}
|
|
180
|
+
fill-opacity={fillOpacity}
|
|
181
|
+
{stroke}
|
|
182
|
+
stroke-width={strokeWidth}
|
|
183
|
+
{opacity}
|
|
184
|
+
class={cls(layerClass('ellipse'), fill == null && 'fill-surface-content', className)}
|
|
185
|
+
{...restProps}
|
|
186
|
+
/>
|
|
187
|
+
{/if}
|