layerchart 2.0.0-next.55 → 2.0.0-next.56
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/bench/ComposableLineChart.svelte +1 -1
- package/dist/bench/GeoBench.svelte +1 -8
- package/dist/components/AnnotationRange.svelte +3 -1
- package/dist/components/Arc.svelte +1 -3
- package/dist/components/ArcLabel.svelte.test.js +7 -7
- package/dist/components/Bar.svelte +4 -2
- package/dist/components/BoxPlot.svelte +4 -12
- package/dist/components/Cell.svelte +13 -8
- package/dist/components/Chart.svelte +69 -26
- package/dist/components/ChartChildren.svelte +22 -4
- package/dist/components/Circle.svelte +34 -12
- package/dist/components/ClipPath.svelte +3 -9
- package/dist/components/Ellipse.svelte +27 -6
- package/dist/components/GeoLegend.svelte +1 -3
- package/dist/components/GeoPoint.svelte +25 -3
- package/dist/components/GeoSpline.svelte +1 -4
- package/dist/components/GeoTile.svelte +8 -4
- package/dist/components/Group.svelte +11 -5
- package/dist/components/Highlight.svelte +3 -3
- package/dist/components/Image.svelte +42 -30
- package/dist/components/Labels.svelte +2 -4
- package/dist/components/Line.svelte +7 -6
- package/dist/components/LinearGradient.svelte +8 -4
- package/dist/components/Link.svelte +0 -1
- package/dist/components/Marker.svelte +9 -1
- package/dist/components/Path.svelte +43 -23
- package/dist/components/Pattern.svelte +101 -5
- package/dist/components/Pattern.svelte.d.ts +3 -1
- package/dist/components/Pie.svelte +2 -6
- package/dist/components/RadialGradient.svelte +8 -4
- package/dist/components/Rect.svelte +29 -12
- package/dist/components/Spline.svelte +22 -4
- package/dist/components/Text.svelte +9 -5
- package/dist/components/Trail.svelte +19 -7
- package/dist/components/Vector.svelte +37 -14
- package/dist/components/Violin.svelte +1 -2
- package/dist/components/charts/ArcChart.svelte +8 -5
- package/dist/components/charts/AreaChart.svelte +6 -1
- package/dist/components/charts/BarChart.svelte +3 -1
- package/dist/components/charts/LineChart.svelte +6 -1
- package/dist/components/charts/PieChart.svelte +10 -3
- package/dist/components/tooltip/Tooltip.svelte +2 -8
- package/dist/contexts/chart.d.ts +1 -1
- package/dist/contexts/chart.js +3 -1
- package/dist/server/TestBarChart.svelte +28 -28
- package/dist/server/TestLineChart.svelte +28 -28
- package/dist/server/index.js +1 -1
- package/dist/states/brush.svelte.js +16 -13
- package/dist/states/chart.svelte.test.js +24 -19
- package/dist/states/geo.svelte.js +1 -4
- package/dist/states/series.svelte.js +1 -1
- package/dist/utils/canvas.js +7 -4
- package/dist/utils/trail.js +3 -4
- package/package.json +1 -1
|
@@ -63,11 +63,25 @@
|
|
|
63
63
|
|
|
64
64
|
{#if layerCtx === 'svg'}
|
|
65
65
|
{#if children}
|
|
66
|
-
<Group
|
|
66
|
+
<Group
|
|
67
|
+
{x}
|
|
68
|
+
{y}
|
|
69
|
+
opacity={opacity as number}
|
|
70
|
+
class={className as string}
|
|
71
|
+
{...extractLayerProps(restProps, 'lc-geo-point-group')}
|
|
72
|
+
>
|
|
67
73
|
{@render children({ x, y })}
|
|
68
74
|
</Group>
|
|
69
75
|
{:else}
|
|
70
|
-
<Circle
|
|
76
|
+
<Circle
|
|
77
|
+
cx={x}
|
|
78
|
+
cy={y}
|
|
79
|
+
{opacity}
|
|
80
|
+
{fillOpacity}
|
|
81
|
+
{strokeWidth}
|
|
82
|
+
class={className}
|
|
83
|
+
{...extractLayerProps(restProps, 'lc-geo-point')}
|
|
84
|
+
/>
|
|
71
85
|
{/if}
|
|
72
86
|
{/if}
|
|
73
87
|
|
|
@@ -78,6 +92,14 @@
|
|
|
78
92
|
{@render children({ x, y })}
|
|
79
93
|
<!-- </Group> -->
|
|
80
94
|
{:else}
|
|
81
|
-
<Circle
|
|
95
|
+
<Circle
|
|
96
|
+
cx={x}
|
|
97
|
+
cy={y}
|
|
98
|
+
{opacity}
|
|
99
|
+
{fillOpacity}
|
|
100
|
+
{strokeWidth}
|
|
101
|
+
class={className}
|
|
102
|
+
{...extractLayerProps(restProps, 'lc-geo-point')}
|
|
103
|
+
/>
|
|
82
104
|
{/if}
|
|
83
105
|
{/if}
|
|
@@ -91,10 +91,14 @@
|
|
|
91
91
|
}
|
|
92
92
|
|
|
93
93
|
if (layerCtx === 'canvas') {
|
|
94
|
-
ctx.registerComponent({
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
94
|
+
ctx.registerComponent({
|
|
95
|
+
name: 'GeoTile',
|
|
96
|
+
kind: 'mark',
|
|
97
|
+
canvasRender: {
|
|
98
|
+
render,
|
|
99
|
+
deps: () => [tiles],
|
|
100
|
+
},
|
|
101
|
+
});
|
|
98
102
|
}
|
|
99
103
|
</script>
|
|
100
104
|
|
|
@@ -137,9 +137,7 @@
|
|
|
137
137
|
const dataMode = $derived(hasAnyDataProp(x, y));
|
|
138
138
|
|
|
139
139
|
// Data to iterate over in data mode
|
|
140
|
-
const resolvedData: any[] = $derived(
|
|
141
|
-
dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []
|
|
142
|
-
);
|
|
140
|
+
const resolvedData: any[] = $derived(dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []);
|
|
143
141
|
|
|
144
142
|
// Resolve a single data item to pixel coordinates
|
|
145
143
|
function resolveGroup(d: any) {
|
|
@@ -198,10 +196,18 @@
|
|
|
198
196
|
const initialY = initialYProp ?? (typeof y === 'number' ? y : undefined);
|
|
199
197
|
|
|
200
198
|
const trueX = $derived(
|
|
201
|
-
typeof x === 'number'
|
|
199
|
+
typeof x === 'number'
|
|
200
|
+
? x
|
|
201
|
+
: x == null && (center === 'x' || center === true)
|
|
202
|
+
? chartCtx.width / 2
|
|
203
|
+
: 0
|
|
202
204
|
);
|
|
203
205
|
const trueY = $derived(
|
|
204
|
-
typeof y === 'number'
|
|
206
|
+
typeof y === 'number'
|
|
207
|
+
? y
|
|
208
|
+
: y == null && (center === 'y' || center === true)
|
|
209
|
+
? chartCtx.height / 2
|
|
210
|
+
: 0
|
|
205
211
|
);
|
|
206
212
|
const motionX = createMotion(initialX, () => trueX, motion);
|
|
207
213
|
const motionY = createMotion(initialY, () => trueY, motion);
|
|
@@ -389,9 +389,9 @@
|
|
|
389
389
|
: null;
|
|
390
390
|
// For diverging stacks, use the outer edge (y0 for below-baseline, y1 for above)
|
|
391
391
|
const stackedY1 = stackValue
|
|
392
|
-
?
|
|
393
|
-
|
|
394
|
-
|
|
392
|
+
? ctx.series.stackLayout === 'stackDiverging' && stackValue[1] <= 0
|
|
393
|
+
? stackValue[0]
|
|
394
|
+
: stackValue[1]
|
|
395
395
|
: 0;
|
|
396
396
|
|
|
397
397
|
if (ctx.valueAxis === 'x') {
|
|
@@ -195,16 +195,16 @@
|
|
|
195
195
|
const geo = getGeoContext();
|
|
196
196
|
|
|
197
197
|
// Data to iterate over in data mode
|
|
198
|
-
const resolvedData: any[] = $derived(
|
|
199
|
-
dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []
|
|
200
|
-
);
|
|
198
|
+
const resolvedData: any[] = $derived(dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []);
|
|
201
199
|
|
|
202
200
|
// Resolve a single data item to pixel coordinates and dimensions
|
|
203
201
|
function resolveImage(d: any) {
|
|
204
202
|
const resolvedR = r !== undefined ? resolveDataProp(r, d, null, 0) : undefined;
|
|
205
203
|
const defaultSize = resolvedR !== undefined ? resolvedR * 2 : 16;
|
|
206
|
-
const resolvedWidth =
|
|
207
|
-
|
|
204
|
+
const resolvedWidth =
|
|
205
|
+
width !== undefined ? resolveDataProp(width, d, null, defaultSize) : defaultSize;
|
|
206
|
+
const resolvedHeight =
|
|
207
|
+
height !== undefined ? resolveDataProp(height, d, null, defaultSize) : defaultSize;
|
|
208
208
|
|
|
209
209
|
let resolvedX: number, resolvedY: number;
|
|
210
210
|
if (geo.projection) {
|
|
@@ -247,7 +247,14 @@
|
|
|
247
247
|
const key = keyFn(d, i);
|
|
248
248
|
activeKeys.add(key);
|
|
249
249
|
const resolved = resolveImage(d);
|
|
250
|
-
untrack(() =>
|
|
250
|
+
untrack(() =>
|
|
251
|
+
dataMotionMap.update(key, {
|
|
252
|
+
x: resolved.x,
|
|
253
|
+
y: resolved.y,
|
|
254
|
+
width: resolved.width,
|
|
255
|
+
height: resolved.height,
|
|
256
|
+
})
|
|
257
|
+
);
|
|
251
258
|
}
|
|
252
259
|
untrack(() => dataMotionMap.cleanup(activeKeys));
|
|
253
260
|
});
|
|
@@ -416,29 +423,32 @@
|
|
|
416
423
|
y: typeof y === 'string' ? y : undefined,
|
|
417
424
|
};
|
|
418
425
|
},
|
|
419
|
-
canvasRender:
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
426
|
+
canvasRender:
|
|
427
|
+
layerCtx === 'canvas'
|
|
428
|
+
? {
|
|
429
|
+
render: canvasRender,
|
|
430
|
+
events: {
|
|
431
|
+
click: restProps.onclick,
|
|
432
|
+
pointerdown: restProps.onpointerdown,
|
|
433
|
+
pointerenter: restProps.onpointerenter,
|
|
434
|
+
pointermove: restProps.onpointermove,
|
|
435
|
+
pointerleave: restProps.onpointerleave,
|
|
436
|
+
},
|
|
437
|
+
deps: () => [
|
|
438
|
+
dataMode,
|
|
439
|
+
dataMode ? resolvedItems : null,
|
|
440
|
+
motionX.current,
|
|
441
|
+
motionY.current,
|
|
442
|
+
motionWidth.current,
|
|
443
|
+
motionHeight.current,
|
|
444
|
+
href,
|
|
445
|
+
opacity,
|
|
446
|
+
className,
|
|
447
|
+
restProps.style,
|
|
448
|
+
loadedImageCount,
|
|
449
|
+
],
|
|
450
|
+
}
|
|
451
|
+
: undefined,
|
|
442
452
|
});
|
|
443
453
|
</script>
|
|
444
454
|
|
|
@@ -487,7 +497,9 @@
|
|
|
487
497
|
width={motionWidth.current}
|
|
488
498
|
height={motionHeight.current}
|
|
489
499
|
clip-path={pixelR !== undefined ? `url(#${clipId})` : undefined}
|
|
490
|
-
transform={pixelRotate
|
|
500
|
+
transform={pixelRotate
|
|
501
|
+
? `rotate(${pixelRotate}, ${motionX.current}, ${motionY.current})`
|
|
502
|
+
: undefined}
|
|
491
503
|
{preserveAspectRatio}
|
|
492
504
|
crossorigin={crossOrigin}
|
|
493
505
|
image-rendering={imageRendering}
|
|
@@ -173,8 +173,7 @@
|
|
|
173
173
|
fill: fillValue,
|
|
174
174
|
x: point.x + (placement === 'outside' ? -offset : offset),
|
|
175
175
|
y: point.y,
|
|
176
|
-
textAnchor:
|
|
177
|
-
placement === 'middle' ? 'middle' : placement === 'outside' ? 'end' : 'start',
|
|
176
|
+
textAnchor: placement === 'middle' ? 'middle' : placement === 'outside' ? 'end' : 'start',
|
|
178
177
|
verticalAnchor: 'middle',
|
|
179
178
|
capHeight: '.6rem',
|
|
180
179
|
};
|
|
@@ -185,8 +184,7 @@
|
|
|
185
184
|
fill: fillValue,
|
|
186
185
|
x: point.x + (placement === 'outside' ? offset : -offset),
|
|
187
186
|
y: point.y,
|
|
188
|
-
textAnchor:
|
|
189
|
-
placement === 'middle' ? 'middle' : placement === 'outside' ? 'start' : 'end',
|
|
187
|
+
textAnchor: placement === 'middle' ? 'middle' : placement === 'outside' ? 'start' : 'end',
|
|
190
188
|
verticalAnchor: 'middle',
|
|
191
189
|
capHeight: '.6rem',
|
|
192
190
|
};
|
|
@@ -298,12 +298,13 @@
|
|
|
298
298
|
'lc-line',
|
|
299
299
|
itemClass ?? (typeof className === 'string' ? className : undefined)
|
|
300
300
|
),
|
|
301
|
-
style:
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
301
|
+
style:
|
|
302
|
+
[
|
|
303
|
+
restProps.style as string | undefined,
|
|
304
|
+
dashArrayAttr ? `stroke-dasharray: ${dashArrayAttr}` : undefined,
|
|
305
|
+
]
|
|
306
|
+
.filter(Boolean)
|
|
307
|
+
.join('; ') || undefined,
|
|
307
308
|
};
|
|
308
309
|
}
|
|
309
310
|
|
|
@@ -174,10 +174,14 @@
|
|
|
174
174
|
}
|
|
175
175
|
|
|
176
176
|
if (layerCtx === 'canvas') {
|
|
177
|
-
ctx.registerComponent({
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
177
|
+
ctx.registerComponent({
|
|
178
|
+
name: 'Gradient',
|
|
179
|
+
kind: 'group',
|
|
180
|
+
canvasRender: {
|
|
181
|
+
render,
|
|
182
|
+
deps: () => [x1, y1, x2, y2, stops, className],
|
|
183
|
+
},
|
|
184
|
+
});
|
|
181
185
|
}
|
|
182
186
|
</script>
|
|
183
187
|
|
|
@@ -8,7 +8,15 @@
|
|
|
8
8
|
*
|
|
9
9
|
* Pass `children` to render a custom element/component inside the marker instead.
|
|
10
10
|
*/
|
|
11
|
-
type?:
|
|
11
|
+
type?:
|
|
12
|
+
| 'arrow'
|
|
13
|
+
| 'triangle'
|
|
14
|
+
| 'line'
|
|
15
|
+
| 'circle'
|
|
16
|
+
| 'circle-stroke'
|
|
17
|
+
| 'dot'
|
|
18
|
+
| 'square'
|
|
19
|
+
| 'square-stroke';
|
|
12
20
|
|
|
13
21
|
/**
|
|
14
22
|
* Unique identifier for the marker
|
|
@@ -197,30 +197,50 @@
|
|
|
197
197
|
const strokeKey = layerCtx === 'canvas' ? createKey(() => stroke) : undefined;
|
|
198
198
|
|
|
199
199
|
if (layerCtx === 'canvas') {
|
|
200
|
-
ctx.registerComponent({
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
200
|
+
ctx.registerComponent({
|
|
201
|
+
name: 'Path',
|
|
202
|
+
kind: 'mark',
|
|
203
|
+
canvasRender: {
|
|
204
|
+
render,
|
|
205
|
+
events: {
|
|
206
|
+
get click() {
|
|
207
|
+
return onclick;
|
|
208
|
+
},
|
|
209
|
+
get pointerenter() {
|
|
210
|
+
return onpointerenter;
|
|
211
|
+
},
|
|
212
|
+
get pointermove() {
|
|
213
|
+
return onpointermove;
|
|
214
|
+
},
|
|
215
|
+
get pointerleave() {
|
|
216
|
+
return onpointerleave;
|
|
217
|
+
},
|
|
218
|
+
get pointerdown() {
|
|
219
|
+
return onpointerdown;
|
|
220
|
+
},
|
|
221
|
+
get pointerover() {
|
|
222
|
+
return onpointerover;
|
|
223
|
+
},
|
|
224
|
+
get pointerout() {
|
|
225
|
+
return onpointerout;
|
|
226
|
+
},
|
|
227
|
+
get touchmove() {
|
|
228
|
+
return ontouchmove;
|
|
229
|
+
},
|
|
230
|
+
},
|
|
231
|
+
deps: () => [
|
|
232
|
+
fillKey!.current,
|
|
233
|
+
fillOpacity,
|
|
234
|
+
strokeKey!.current,
|
|
235
|
+
strokeOpacity,
|
|
236
|
+
strokeWidth,
|
|
237
|
+
opacity,
|
|
238
|
+
className,
|
|
239
|
+
tweenedState.current,
|
|
240
|
+
restProps.style,
|
|
241
|
+
],
|
|
211
242
|
},
|
|
212
|
-
|
|
213
|
-
fillKey!.current,
|
|
214
|
-
fillOpacity,
|
|
215
|
-
strokeKey!.current,
|
|
216
|
-
strokeOpacity,
|
|
217
|
-
strokeWidth,
|
|
218
|
-
opacity,
|
|
219
|
-
className,
|
|
220
|
-
tweenedState.current,
|
|
221
|
-
restProps.style,
|
|
222
|
-
],
|
|
223
|
-
} });
|
|
243
|
+
});
|
|
224
244
|
}
|
|
225
245
|
|
|
226
246
|
let startPoint = $state<DOMPoint | undefined>();
|
|
@@ -95,7 +95,9 @@
|
|
|
95
95
|
background?: string;
|
|
96
96
|
|
|
97
97
|
/**
|
|
98
|
-
* Render as a child of the pattern
|
|
98
|
+
* Render as a child of the pattern.
|
|
99
|
+
*
|
|
100
|
+
* Note: only supported on the `<Svg>` layer.
|
|
99
101
|
*/
|
|
100
102
|
patternContent?: Snippet;
|
|
101
103
|
|
|
@@ -250,10 +252,102 @@
|
|
|
250
252
|
}
|
|
251
253
|
|
|
252
254
|
if (layerCtx === 'canvas') {
|
|
253
|
-
chartCtx.registerComponent({
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
255
|
+
chartCtx.registerComponent({
|
|
256
|
+
name: 'Pattern',
|
|
257
|
+
kind: 'group',
|
|
258
|
+
canvasRender: {
|
|
259
|
+
render,
|
|
260
|
+
deps: () => [width, height, shapes, background],
|
|
261
|
+
},
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
function withOpacity(color: string, opacity: number) {
|
|
266
|
+
return opacity === 1 ? color : `color-mix(in srgb, ${color} ${opacity * 100}%, transparent)`;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Build a CSS `background` value from lines/circles/background.
|
|
270
|
+
// Uses repeating-linear-gradient for lines and radial-gradient for circles
|
|
271
|
+
// so CSS variables/classes resolve natively in the HTML layer.
|
|
272
|
+
function createCSSPattern(): string {
|
|
273
|
+
const layers: string[] = [];
|
|
274
|
+
|
|
275
|
+
if (linesProp) {
|
|
276
|
+
const lineDefs = Array.isArray(linesProp)
|
|
277
|
+
? linesProp
|
|
278
|
+
: linesProp === true
|
|
279
|
+
? [{}]
|
|
280
|
+
: [linesProp];
|
|
281
|
+
for (const line of lineDefs) {
|
|
282
|
+
const color = withOpacity(
|
|
283
|
+
line.color ?? 'var(--color-surface-content, currentColor)',
|
|
284
|
+
line.opacity ?? 1
|
|
285
|
+
);
|
|
286
|
+
const sw = line.width ?? 1;
|
|
287
|
+
|
|
288
|
+
let rotate = Math.round(line.rotate ?? 0) % 360;
|
|
289
|
+
if (rotate > 180) rotate = rotate - 360;
|
|
290
|
+
else if (rotate > 90) rotate = rotate - 180;
|
|
291
|
+
else if (rotate < -180) rotate = rotate + 360;
|
|
292
|
+
else if (rotate < -90) rotate = rotate + 180;
|
|
293
|
+
|
|
294
|
+
let angle: number;
|
|
295
|
+
let period: number;
|
|
296
|
+
if (rotate === 0) {
|
|
297
|
+
angle = 0;
|
|
298
|
+
period = height;
|
|
299
|
+
} else if (rotate === 90) {
|
|
300
|
+
angle = 90;
|
|
301
|
+
period = width;
|
|
302
|
+
} else if (rotate > 0) {
|
|
303
|
+
angle = 45;
|
|
304
|
+
period = (width * height) / Math.sqrt(width * width + height * height);
|
|
305
|
+
} else {
|
|
306
|
+
angle = 135;
|
|
307
|
+
period = (width * height) / Math.sqrt(width * width + height * height);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
layers.push(
|
|
311
|
+
`repeating-linear-gradient(${angle}deg, ${color} 0 ${sw}px, transparent ${sw}px ${period}px)`
|
|
312
|
+
);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
if (circlesProp) {
|
|
317
|
+
const circleDefs = Array.isArray(circlesProp)
|
|
318
|
+
? circlesProp
|
|
319
|
+
: circlesProp === true
|
|
320
|
+
? [{}]
|
|
321
|
+
: [circlesProp];
|
|
322
|
+
for (const circle of circleDefs) {
|
|
323
|
+
const color = withOpacity(
|
|
324
|
+
circle.color ?? 'var(--color-surface-content, currentColor)',
|
|
325
|
+
circle.opacity ?? 1
|
|
326
|
+
);
|
|
327
|
+
const r = circle.radius ?? 1;
|
|
328
|
+
|
|
329
|
+
if (circle.stagger) {
|
|
330
|
+
layers.push(
|
|
331
|
+
`radial-gradient(circle at 25% 25%, ${color} ${r}px, transparent ${r}px) 0 0 / ${size}px ${size}px`,
|
|
332
|
+
`radial-gradient(circle at 75% 75%, ${color} ${r}px, transparent ${r}px) 0 0 / ${size}px ${size}px`
|
|
333
|
+
);
|
|
334
|
+
} else {
|
|
335
|
+
layers.push(
|
|
336
|
+
`radial-gradient(circle at center, ${color} ${r}px, transparent ${r}px) 0 0 / ${size}px ${size}px`
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// `background` may be either a plain color or an image value (e.g. `linear-gradient(...)`
|
|
343
|
+
// when used as `<Pattern background={gradient}>`). Images go in the image-layer list
|
|
344
|
+
// tiled at the pattern size (after shape layers so they paint underneath);
|
|
345
|
+
// colors go in the background-color slot.
|
|
346
|
+
const isImage = background != null && /gradient\(|url\(/i.test(background);
|
|
347
|
+
if (isImage) layers.push(`${background} 0 0 / ${width}px ${height}px`);
|
|
348
|
+
|
|
349
|
+
if (layers.length === 0) return background ?? 'transparent';
|
|
350
|
+
return !isImage && background ? `${layers.join(', ')}, ${background}` : layers.join(', ');
|
|
257
351
|
}
|
|
258
352
|
</script>
|
|
259
353
|
|
|
@@ -299,4 +393,6 @@
|
|
|
299
393
|
</defs>
|
|
300
394
|
|
|
301
395
|
{@render children?.({ id, pattern: `url(#${id})` })}
|
|
396
|
+
{:else if layerCtx === 'html'}
|
|
397
|
+
{@render children?.({ id, pattern: createCSSPattern() })}
|
|
302
398
|
{/if}
|
|
@@ -75,7 +75,9 @@ export type PatternPropsWithoutHTML = {
|
|
|
75
75
|
*/
|
|
76
76
|
background?: string;
|
|
77
77
|
/**
|
|
78
|
-
* Render as a child of the pattern
|
|
78
|
+
* Render as a child of the pattern.
|
|
79
|
+
*
|
|
80
|
+
* Note: only supported on the `<Svg>` layer.
|
|
79
81
|
*/
|
|
80
82
|
patternContent?: Snippet;
|
|
81
83
|
children?: Snippet<[{
|
|
@@ -109,9 +109,7 @@
|
|
|
109
109
|
|
|
110
110
|
const endAngle = $derived(
|
|
111
111
|
endAngleProp ??
|
|
112
|
-
degreesToRadians(
|
|
113
|
-
(ctx.config.xRange ? max(ctx.config.xRange as number[]) : max(range))!
|
|
114
|
-
)
|
|
112
|
+
degreesToRadians((ctx.config.xRange ? max(ctx.config.xRange as number[]) : max(range))!)
|
|
115
113
|
);
|
|
116
114
|
|
|
117
115
|
const motionEndAngle = createMotion(0, () => endAngle, motion);
|
|
@@ -120,9 +118,7 @@
|
|
|
120
118
|
let _pie = d3pie<any>()
|
|
121
119
|
.startAngle(
|
|
122
120
|
startAngleProp ??
|
|
123
|
-
degreesToRadians(
|
|
124
|
-
(ctx.config.xRange ? min(ctx.config.xRange as number[]) : min(range))!
|
|
125
|
-
)
|
|
121
|
+
degreesToRadians((ctx.config.xRange ? min(ctx.config.xRange as number[]) : min(range))!)
|
|
126
122
|
)
|
|
127
123
|
.endAngle(motionEndAngle.current)
|
|
128
124
|
.padAngle(padAngle)
|
|
@@ -144,10 +144,14 @@
|
|
|
144
144
|
}
|
|
145
145
|
|
|
146
146
|
if (layerCtx === 'canvas') {
|
|
147
|
-
ctx.registerComponent({
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
147
|
+
ctx.registerComponent({
|
|
148
|
+
name: 'Gradient',
|
|
149
|
+
kind: 'group',
|
|
150
|
+
canvasRender: {
|
|
151
|
+
render,
|
|
152
|
+
deps: () => [stops, cx, cy, fx, fy, ctx.width, ctx.height],
|
|
153
|
+
},
|
|
154
|
+
});
|
|
151
155
|
}
|
|
152
156
|
</script>
|
|
153
157
|
|
|
@@ -313,9 +313,7 @@
|
|
|
313
313
|
const resolved = resolveCorners(corners, Infinity, Infinity);
|
|
314
314
|
return cornersUniform(resolved) ? resolved[0] : undefined;
|
|
315
315
|
});
|
|
316
|
-
const cornersNonUniform = $derived(
|
|
317
|
-
corners !== undefined && cornersUniformValue === undefined
|
|
318
|
-
);
|
|
316
|
+
const cornersNonUniform = $derived(corners !== undefined && cornersUniformValue === undefined);
|
|
319
317
|
|
|
320
318
|
// Normalize rx/ry - if only one is provided, use it for both (SVG behavior)
|
|
321
319
|
// Coerce to number for canvas rendering (SVG allows string like "50%")
|
|
@@ -368,8 +366,14 @@
|
|
|
368
366
|
const staticStrokeWidth = $derived(typeof strokeWidth === 'number' ? strokeWidth : undefined);
|
|
369
367
|
const staticOpacity = $derived(typeof opacity === 'number' ? opacity : undefined);
|
|
370
368
|
const staticClassName = $derived(typeof className === 'string' ? className : undefined);
|
|
369
|
+
// Match SVG's implicit `stroke-width: 1` default: if `stroke` is set but
|
|
370
|
+
// `strokeWidth` is not, render a 1px border so HTML matches SVG/Canvas layers.
|
|
371
371
|
const staticBorderWidth = $derived(
|
|
372
|
-
typeof strokeWidth === 'number'
|
|
372
|
+
typeof strokeWidth === 'number'
|
|
373
|
+
? `${strokeWidth}px`
|
|
374
|
+
: typeof stroke === 'string'
|
|
375
|
+
? '1px'
|
|
376
|
+
: undefined
|
|
373
377
|
);
|
|
374
378
|
const htmlRestProps = $derived(restProps as unknown as HTMLAttributes<HTMLDivElement>);
|
|
375
379
|
|
|
@@ -430,12 +434,13 @@
|
|
|
430
434
|
'lc-rect',
|
|
431
435
|
itemClass ?? (typeof className === 'string' ? className : undefined)
|
|
432
436
|
),
|
|
433
|
-
style:
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
437
|
+
style:
|
|
438
|
+
[
|
|
439
|
+
restProps.style as string | undefined,
|
|
440
|
+
dashArrayAttr ? `stroke-dasharray: ${dashArrayAttr}` : undefined,
|
|
441
|
+
]
|
|
442
|
+
.filter(Boolean)
|
|
443
|
+
.join('; ') || undefined,
|
|
439
444
|
};
|
|
440
445
|
}
|
|
441
446
|
|
|
@@ -596,7 +601,7 @@
|
|
|
596
601
|
opacity={staticOpacity}
|
|
597
602
|
stroke-dasharray={dashArrayAttr}
|
|
598
603
|
class={cls('lc-rect', staticClassName)}
|
|
599
|
-
{...
|
|
604
|
+
{...restProps as unknown as SVGAttributes<SVGPathElement>}
|
|
600
605
|
{onclick}
|
|
601
606
|
{ondblclick}
|
|
602
607
|
{onpointerenter}
|
|
@@ -641,6 +646,12 @@
|
|
|
641
646
|
{@const resolvedStrokeWidth = resolveStyleProp(strokeWidth, item.d)}
|
|
642
647
|
{@const resolvedOpacity = resolveStyleProp(opacity, item.d)}
|
|
643
648
|
{@const resolvedClass = resolveStyleProp(className, item.d)}
|
|
649
|
+
{@const resolvedBorderWidth =
|
|
650
|
+
resolvedStrokeWidth != null
|
|
651
|
+
? `${resolvedStrokeWidth}px`
|
|
652
|
+
: resolvedStroke != null
|
|
653
|
+
? '1px'
|
|
654
|
+
: undefined}
|
|
644
655
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
|
645
656
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
|
646
657
|
<div
|
|
@@ -650,8 +661,9 @@
|
|
|
650
661
|
style:width="{item.width}px"
|
|
651
662
|
style:height="{item.height}px"
|
|
652
663
|
style:background={resolvedFill}
|
|
664
|
+
style:background-origin="border-box"
|
|
653
665
|
style:opacity={resolvedOpacity}
|
|
654
|
-
style:border-width=
|
|
666
|
+
style:border-width={resolvedBorderWidth}
|
|
655
667
|
style:border-style={dashArrayResolved ? 'dashed' : 'solid'}
|
|
656
668
|
style:border-color={resolvedStroke}
|
|
657
669
|
style:border-radius="{rx}px"
|
|
@@ -676,6 +688,7 @@
|
|
|
676
688
|
style:width="{motionWidth.current}px"
|
|
677
689
|
style:height="{motionHeight.current}px"
|
|
678
690
|
style:background={staticFill}
|
|
691
|
+
style:background-origin="border-box"
|
|
679
692
|
style:opacity={staticOpacity}
|
|
680
693
|
style:border-width={staticBorderWidth}
|
|
681
694
|
style:border-style={dashArrayResolved ? 'dashed' : 'solid'}
|
|
@@ -712,6 +725,10 @@
|
|
|
712
725
|
}
|
|
713
726
|
|
|
714
727
|
/* Html layers */
|
|
728
|
+
:global(:where(.lc-layout-html .lc-rect)) {
|
|
729
|
+
/* Match SVG sizing/positioning (visual extent equals `width`×`height`, border on outer edge) */
|
|
730
|
+
box-sizing: border-box;
|
|
731
|
+
}
|
|
715
732
|
:global(:where(.lc-layout-html .lc-rect):not([background])) {
|
|
716
733
|
background: var(--fill-color);
|
|
717
734
|
}
|