layerchart 2.0.0-next.50 → 2.0.0-next.52

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.
Files changed (70) hide show
  1. package/dist/components/Arc.svelte +12 -4
  2. package/dist/components/Arc.svelte.d.ts +4 -0
  3. package/dist/components/ArcLabel.svelte +259 -0
  4. package/dist/components/ArcLabel.svelte.d.ts +73 -0
  5. package/dist/components/ArcLabel.svelte.test.d.ts +1 -0
  6. package/dist/components/ArcLabel.svelte.test.js +235 -0
  7. package/dist/components/Axis.svelte +25 -0
  8. package/dist/components/Axis.svelte.d.ts +10 -0
  9. package/dist/components/Circle.svelte +82 -59
  10. package/dist/components/CircleLegend.svelte +389 -0
  11. package/dist/components/CircleLegend.svelte.d.ts +114 -0
  12. package/dist/components/Ellipse.svelte +83 -64
  13. package/dist/components/GeoLegend.svelte +404 -0
  14. package/dist/components/GeoLegend.svelte.d.ts +106 -0
  15. package/dist/components/GeoRaster.svelte +311 -0
  16. package/dist/components/GeoRaster.svelte.d.ts +61 -0
  17. package/dist/components/Grid.svelte +15 -0
  18. package/dist/components/Grid.svelte.d.ts +5 -0
  19. package/dist/components/Image.svelte +2 -2
  20. package/dist/components/Labels.svelte +46 -11
  21. package/dist/components/Labels.svelte.d.ts +7 -3
  22. package/dist/components/Legend.svelte +58 -3
  23. package/dist/components/Legend.svelte.d.ts +7 -0
  24. package/dist/components/Line.svelte +82 -62
  25. package/dist/components/Points.svelte +2 -2
  26. package/dist/components/Polygon.svelte +92 -56
  27. package/dist/components/Rect.svelte +113 -64
  28. package/dist/components/Rule.svelte +2 -0
  29. package/dist/components/Sankey.svelte +0 -2
  30. package/dist/components/Text.svelte +83 -52
  31. package/dist/components/__screenshots__/ArcLabel.svelte.test.ts/ArcLabel-defaults-placement-to-centroid--x-y-at-the-centroid--middle-anchors--1.png +0 -0
  32. package/dist/components/__screenshots__/ArcLabel.svelte.test.ts/ArcLabel-defaults-placement-to-centroid--x-y-at-the-centroid--middle-anchors--2.png +0 -0
  33. package/dist/components/charts/ArcChart.svelte +39 -2
  34. package/dist/components/charts/ArcChart.svelte.d.ts +12 -1
  35. package/dist/components/charts/PieChart.svelte +40 -2
  36. package/dist/components/charts/PieChart.svelte.d.ts +10 -0
  37. package/dist/components/index.d.ts +8 -0
  38. package/dist/components/index.js +8 -0
  39. package/dist/components/layers/Canvas.svelte +65 -48
  40. package/dist/components/layers/Canvas.svelte.d.ts +10 -0
  41. package/dist/contexts/canvas.d.ts +3 -0
  42. package/dist/server/ContextCapture.svelte +30 -0
  43. package/dist/server/ContextCapture.svelte.d.ts +8 -0
  44. package/dist/server/ServerChart.svelte +26 -0
  45. package/dist/server/ServerChart.svelte.d.ts +11 -0
  46. package/dist/server/TestBarChart.svelte +35 -0
  47. package/dist/server/TestBarChart.svelte.d.ts +14 -0
  48. package/dist/server/TestLineChart.svelte +35 -0
  49. package/dist/server/TestLineChart.svelte.d.ts +14 -0
  50. package/dist/server/captureStore.d.ts +8 -0
  51. package/dist/server/captureStore.js +18 -0
  52. package/dist/server/index.d.ts +137 -0
  53. package/dist/server/index.js +141 -0
  54. package/dist/server/renderChart.ssr.test.d.ts +1 -0
  55. package/dist/server/renderChart.ssr.test.js +205 -0
  56. package/dist/server/renderTree.d.ts +8 -0
  57. package/dist/server/renderTree.js +29 -0
  58. package/dist/states/__screenshots__/chart.svelte.test.ts/ChartState-geo-projection-skips-markInfo-should-not-derive-x-y-accessors-from-marks-when-geo-projection-is-active-1.png +0 -0
  59. package/dist/states/__screenshots__/chart.svelte.test.ts/ChartState-geo-projection-skips-markInfo-should-not-derive-x-y-accessors-from-marks-when-geo-projection-is-active-2.png +0 -0
  60. package/dist/states/chart.svelte.d.ts +5 -1
  61. package/dist/states/chart.svelte.js +18 -3
  62. package/dist/states/chart.svelte.test.js +110 -0
  63. package/dist/states/geo.svelte.d.ts +5 -1
  64. package/dist/states/geo.svelte.js +80 -68
  65. package/dist/utils/arcText.svelte.d.ts +7 -1
  66. package/dist/utils/arcText.svelte.js +8 -4
  67. package/dist/utils/canvas.js +29 -10
  68. package/dist/utils/canvas.svelte.test.js +2 -2
  69. package/dist/utils/motion.svelte.js +14 -0
  70. package/package.json +7 -1
@@ -6,6 +6,7 @@
6
6
  import type { SeriesData } from './types.js';
7
7
 
8
8
  import Arc from '../Arc.svelte';
9
+ import ArcLabel, { type ArcLabelConfig } from '../ArcLabel.svelte';
9
10
  import Group from '../Group.svelte';
10
11
  import Pie from '../Pie.svelte';
11
12
 
@@ -28,6 +29,13 @@
28
29
  // Props that don't apply to PieChart
29
30
  'data' | 'axis' | 'brush' | 'grid' | 'highlight' | 'labels' | 'points' | 'rule'
30
31
  > & {
32
+ /**
33
+ * Render text labels on each arc.
34
+ *
35
+ * Pass `true` to enable with default placement (`centroid`), or an object
36
+ * to customize via `ArcLabel` props (placement, format, value accessor, etc).
37
+ */
38
+ labels?: boolean | (ArcLabelConfig & { value?: Accessor });
31
39
  /**
32
40
  * The series data to be used for the chart.
33
41
  */
@@ -214,10 +222,17 @@
214
222
  tooltip: tooltipProp,
215
223
  pie,
216
224
  arc,
225
+ labels = false,
217
226
  context = $bindable(),
218
227
  ...restProps
219
228
  }: PieChartProps<TData> = $props();
220
229
 
230
+ const labelsConfig = $derived.by<(ArcLabelConfig & { value?: Accessor }) | null>(() => {
231
+ if (labels === true) return { placement: 'callout' };
232
+ if (labels) return { placement: 'callout', ...labels };
233
+ return null;
234
+ });
235
+
221
236
  const series = $derived(
222
237
  seriesProp === undefined ? [{ key: 'default', value: value }] : seriesProp
223
238
  );
@@ -231,7 +246,7 @@
231
246
  // Reading context.series.allSeriesData here would create a derived_references_self cycle:
232
247
  // SeriesState.#series → ChartState.props → data={visibleData} → chartData → context.series.allSeriesData → #series
233
248
  const chartData = $derived.by(() => {
234
- const seriesData = series.flatMap((s) => s.data ?? []);
249
+ const seriesData = series.flatMap((s) => ('data' in s ? s.data : undefined) ?? []);
235
250
  return (seriesData.length > 0 ? seriesData : chartDataArray(data)) as Array<TData>;
236
251
  });
237
252
 
@@ -245,7 +260,7 @@
245
260
 
246
261
  // Compute series colors locally to avoid derived_references_self cycle through context.series.allSeriesColors
247
262
  const allSeriesColors = $derived(
248
- series.map((s) => s.color).filter((c) => c != null) as string[]
263
+ series.map((s) => ('color' in s ? s.color : undefined)).filter((c) => c != null) as string[]
249
264
  );
250
265
 
251
266
  // Custom tickFormat for PieChart legends - uses data labels instead of series labels
@@ -402,6 +417,29 @@
402
417
  index: arcIdx,
403
418
  seriesIndex: seriesIdx,
404
419
  })}
420
+ {:else if labelsConfig}
421
+ <Arc {...arcProps}>
422
+ {#snippet children({
423
+ centroid,
424
+ startAngle,
425
+ endAngle,
426
+ innerRadius: arcInnerRadius,
427
+ outerRadius: arcOuterRadius,
428
+ getArcTextProps,
429
+ })}
430
+ {@const { value: labelValue, ...labelRest } = labelsConfig}
431
+ <ArcLabel
432
+ {centroid}
433
+ {startAngle}
434
+ {endAngle}
435
+ innerRadius={arcInnerRadius}
436
+ outerRadius={arcOuterRadius}
437
+ {getArcTextProps}
438
+ value={accessor(labelValue ?? value)(arcData.data)}
439
+ {...labelRest}
440
+ />
441
+ {/snippet}
442
+ </Arc>
405
443
  {:else}
406
444
  <Arc {...arcProps} />
407
445
  {/if}
@@ -4,6 +4,7 @@ import type { ChartState } from '../../contexts/chart.js';
4
4
  import type { Accessor } from '../../utils/common.js';
5
5
  import type { SeriesData } from './types.js';
6
6
  import Arc from '../Arc.svelte';
7
+ import { type ArcLabelConfig } from '../ArcLabel.svelte';
7
8
  import Group from '../Group.svelte';
8
9
  import Pie from '../Pie.svelte';
9
10
  export type PieChartExtraSnippetProps<TData> = {
@@ -19,6 +20,15 @@ export type PieChartProps<TData> = {
19
20
  */
20
21
  data?: TData[] | readonly TData[];
21
22
  } & Omit<ChartProps<any>, 'data' | 'axis' | 'brush' | 'grid' | 'highlight' | 'labels' | 'points' | 'rule'> & {
23
+ /**
24
+ * Render text labels on each arc.
25
+ *
26
+ * Pass `true` to enable with default placement (`centroid`), or an object
27
+ * to customize via `ArcLabel` props (placement, format, value accessor, etc).
28
+ */
29
+ labels?: boolean | (ArcLabelConfig & {
30
+ value?: Accessor;
31
+ });
22
32
  /**
23
33
  * The series data to be used for the chart.
24
34
  */
@@ -8,6 +8,8 @@ export { default as AnnotationRange } from './AnnotationRange.svelte';
8
8
  export * from './AnnotationRange.svelte';
9
9
  export { default as Arc } from './Arc.svelte';
10
10
  export * from './Arc.svelte';
11
+ export { default as ArcLabel } from './ArcLabel.svelte';
12
+ export * from './ArcLabel.svelte';
11
13
  export { default as Area } from './Area.svelte';
12
14
  export * from './Area.svelte';
13
15
  export { default as Axis } from './Axis.svelte';
@@ -68,6 +70,8 @@ export { default as GeoPath } from './GeoPath.svelte';
68
70
  export * from './GeoPath.svelte';
69
71
  export { default as GeoPoint } from './GeoPoint.svelte';
70
72
  export * from './GeoPoint.svelte';
73
+ export { default as GeoRaster } from './GeoRaster.svelte';
74
+ export * from './GeoRaster.svelte';
71
75
  export { default as GeoSpline } from './GeoSpline.svelte';
72
76
  export * from './GeoSpline.svelte';
73
77
  export { default as GeoTile } from './GeoTile.svelte';
@@ -92,6 +96,10 @@ export { default as Labels } from './Labels.svelte';
92
96
  export * from './Labels.svelte';
93
97
  export { default as Layer } from './layers/Layer.svelte';
94
98
  export * from './layers/Layer.svelte';
99
+ export { default as CircleLegend } from './CircleLegend.svelte';
100
+ export * from './CircleLegend.svelte';
101
+ export { default as GeoLegend } from './GeoLegend.svelte';
102
+ export * from './GeoLegend.svelte';
95
103
  export { default as Legend } from './Legend.svelte';
96
104
  export * from './Legend.svelte';
97
105
  export { default as Line } from './Line.svelte';
@@ -8,6 +8,8 @@ export { default as AnnotationRange } from './AnnotationRange.svelte';
8
8
  export * from './AnnotationRange.svelte';
9
9
  export { default as Arc } from './Arc.svelte';
10
10
  export * from './Arc.svelte';
11
+ export { default as ArcLabel } from './ArcLabel.svelte';
12
+ export * from './ArcLabel.svelte';
11
13
  export { default as Area } from './Area.svelte';
12
14
  export * from './Area.svelte';
13
15
  export { default as Axis } from './Axis.svelte';
@@ -68,6 +70,8 @@ export { default as GeoPath } from './GeoPath.svelte';
68
70
  export * from './GeoPath.svelte';
69
71
  export { default as GeoPoint } from './GeoPoint.svelte';
70
72
  export * from './GeoPoint.svelte';
73
+ export { default as GeoRaster } from './GeoRaster.svelte';
74
+ export * from './GeoRaster.svelte';
71
75
  export { default as GeoSpline } from './GeoSpline.svelte';
72
76
  export * from './GeoSpline.svelte';
73
77
  export { default as GeoTile } from './GeoTile.svelte';
@@ -92,6 +96,10 @@ export { default as Labels } from './Labels.svelte';
92
96
  export * from './Labels.svelte';
93
97
  export { default as Layer } from './layers/Layer.svelte';
94
98
  export * from './layers/Layer.svelte';
99
+ export { default as CircleLegend } from './CircleLegend.svelte';
100
+ export * from './CircleLegend.svelte';
101
+ export { default as GeoLegend } from './GeoLegend.svelte';
102
+ export * from './GeoLegend.svelte';
95
103
  export { default as Legend } from './Legend.svelte';
96
104
  export * from './Legend.svelte';
97
105
  export { default as Line } from './Line.svelte';
@@ -1,5 +1,11 @@
1
1
  <script lang="ts" module>
2
2
  import type { ComponentNode } from '../../contexts/chart.js';
3
+ import type { ChartState } from '../../states/chart.svelte.js';
4
+
5
+ type SSRCaptureTarget = {
6
+ chartState?: ChartState<any, any, any>;
7
+ rootNode?: ComponentNode;
8
+ };
3
9
 
4
10
  export type CanvasPropsWithoutHTML = {
5
11
  /**
@@ -80,6 +86,12 @@
80
86
  */
81
87
  debug?: boolean;
82
88
 
89
+ /** @internal Server-side capture target used by layerchart/server. */
90
+ ssrCapture?: SSRCaptureTarget;
91
+
92
+ /** @internal Server-side capture callback used by layerchart/server. */
93
+ ssrCaptureCallback?: (data: SSRCaptureTarget) => void;
94
+
83
95
  children?: Snippet<
84
96
  [{ ref: HTMLCanvasElement; canvasContext: CanvasRenderingContext2D | undefined }]
85
97
  >;
@@ -87,7 +99,6 @@
87
99
 
88
100
  export type CanvasProps = CanvasPropsWithoutHTML &
89
101
  Without<HTMLCanvasAttributes, CanvasPropsWithoutHTML>;
90
-
91
102
  </script>
92
103
 
93
104
  <script lang="ts">
@@ -107,10 +118,13 @@
107
118
  type CanvasContextValue,
108
119
  type ComponentRender,
109
120
  } from '../../contexts/canvas.js';
121
+ import { renderTree } from '../../server/renderTree.js';
110
122
 
111
123
  let {
112
124
  ref: refProp = $bindable(),
113
125
  canvasContext: canvasContextProp = $bindable(),
126
+ ssrCapture,
127
+ ssrCaptureCallback,
114
128
  willReadFrequently = false,
115
129
  debug = false,
116
130
  zIndex = 0,
@@ -183,9 +197,10 @@
183
197
  // Bubble up to ancestor groups
184
198
  let ancestor = node?.parent;
185
199
  while (ancestor) {
186
- const handler = ancestor.kind === 'group'
187
- ? ancestor.canvasRender?.events?.[eventName] as ((e: Event) => void) | null | undefined
188
- : undefined;
200
+ const handler =
201
+ ancestor.kind === 'group'
202
+ ? (ancestor.canvasRender?.events?.[eventName] as ((e: Event) => void) | null | undefined)
203
+ : undefined;
189
204
  handler?.(e);
190
205
  ancestor = ancestor.parent;
191
206
  }
@@ -225,21 +240,23 @@
225
240
  */
226
241
 
227
242
  // Invalidate/redraw if color scheme changes, either via browser `prefers-color-scheme` (including emulation) or by changing `<html class="dark">` or `<html data-theme="...">`
228
- const { dark } = new MediaQueryPresets();
229
- watch(
230
- () => dark.current,
231
- () => {
232
- canvasContext.invalidate();
233
- }
234
- );
235
- useMutationObserver(
236
- () => document.documentElement,
237
- () => canvasContext.invalidate(),
238
- {
239
- attributes: true,
240
- attributeFilter: ['class', 'data-theme'],
241
- }
242
- );
243
+ if (typeof window !== 'undefined') {
244
+ const { dark } = new MediaQueryPresets();
245
+ watch(
246
+ () => dark.current,
247
+ () => {
248
+ canvasContext.invalidate();
249
+ }
250
+ );
251
+ useMutationObserver(
252
+ () => document.documentElement,
253
+ () => canvasContext.invalidate(),
254
+ {
255
+ attributes: true,
256
+ attributeFilter: ['class', 'data-theme'],
257
+ }
258
+ );
259
+ }
243
260
 
244
261
  onMount(() => {
245
262
  context = ref?.getContext('2d', { willReadFrequently }) as CanvasRenderingContext2D;
@@ -310,33 +327,6 @@
310
327
  pendingInvalidation = false;
311
328
  }
312
329
 
313
- /**
314
- * Recursively render the component tree.
315
- * Group nodes: save → render (translate/opacity) → recurse children → restore
316
- * Leaf nodes: save → render → restore
317
- */
318
- function renderTree(canvasCtx: CanvasRenderingContext2D, node: ComponentNode) {
319
- if (node.kind === 'group' && node.canvasRender) {
320
- // Group: save state, apply transform, render children, restore
321
- canvasCtx.save();
322
- node.canvasRender.render(canvasCtx);
323
- for (const child of node.children) {
324
- renderTree(canvasCtx, child);
325
- }
326
- canvasCtx.restore();
327
- } else if (node.canvasRender) {
328
- // Leaf mark: save, render, restore
329
- canvasCtx.save();
330
- node.canvasRender.render(canvasCtx);
331
- canvasCtx.restore();
332
- } else {
333
- // Non-rendering node (e.g. root, composite-mark): just recurse children
334
- for (const child of node.children) {
335
- renderTree(canvasCtx, child);
336
- }
337
- }
338
- }
339
-
340
330
  function nodeHasEvents(node: ComponentNode) {
341
331
  return node.canvasRender?.events && Object.values(node.canvasRender.events).some((d) => d);
342
332
  }
@@ -345,7 +335,11 @@
345
335
  * Recursively render the hit canvas tree for pointer event detection.
346
336
  * Renders components that have event handlers (or whose ancestor group does), using unique colors.
347
337
  */
348
- function renderHitTree(hitCtx: CanvasRenderingContext2D, node: ComponentNode, ancestorHasEvents = false) {
338
+ function renderHitTree(
339
+ hitCtx: CanvasRenderingContext2D,
340
+ node: ComponentNode,
341
+ ancestorHasEvents = false
342
+ ) {
349
343
  if (node.kind === 'group' && node.canvasRender) {
350
344
  const groupHasEvents = ancestorHasEvents || nodeHasEvents(node);
351
345
  // Group: apply transform, recurse children (scoped by save/restore)
@@ -383,11 +377,33 @@
383
377
 
384
378
  function invalidate() {
385
379
  if (pendingInvalidation) return;
380
+ if (typeof requestAnimationFrame === 'undefined') return;
386
381
  pendingInvalidation = true;
387
382
  frameId = requestAnimationFrame(update);
388
383
  }
389
384
 
390
- return { register, invalidate };
385
+ function getRootNode() {
386
+ return rootNode;
387
+ }
388
+
389
+ return { register, invalidate, getRootNode };
390
+ }
391
+
392
+ function captureSSR() {
393
+ if (typeof window !== 'undefined') return '';
394
+ if (!ssrCapture && !ssrCaptureCallback) return '';
395
+
396
+ const captured: SSRCaptureTarget = {
397
+ chartState: ctx,
398
+ rootNode,
399
+ };
400
+
401
+ if (ssrCapture) {
402
+ Object.assign(ssrCapture, captured);
403
+ }
404
+
405
+ ssrCaptureCallback?.(captured);
406
+ return '';
391
407
  }
392
408
 
393
409
  const canvasContext = createCanvasContext();
@@ -457,6 +473,7 @@
457
473
  <canvas bind:this={hitCanvasElement} class="lc-hit-canvas" class:debug></canvas>
458
474
 
459
475
  {@render children?.({ ref, canvasContext: context })}
476
+ {captureSSR()}
460
477
 
461
478
  <style>
462
479
  @layer base {
@@ -1,3 +1,9 @@
1
+ import type { ComponentNode } from '../../contexts/chart.js';
2
+ import type { ChartState } from '../../states/chart.svelte.js';
3
+ type SSRCaptureTarget = {
4
+ chartState?: ChartState<any, any, any>;
5
+ rootNode?: ComponentNode;
6
+ };
1
7
  export type CanvasPropsWithoutHTML = {
2
8
  /**
3
9
  * The `<canvas>` tag. Useful for bindings.
@@ -67,6 +73,10 @@ export type CanvasPropsWithoutHTML = {
67
73
  * @default false
68
74
  */
69
75
  debug?: boolean;
76
+ /** @internal Server-side capture target used by layerchart/server. */
77
+ ssrCapture?: SSRCaptureTarget;
78
+ /** @internal Server-side capture callback used by layerchart/server. */
79
+ ssrCaptureCallback?: (data: SSRCaptureTarget) => void;
70
80
  children?: Snippet<[
71
81
  {
72
82
  ref: HTMLCanvasElement;
@@ -1,5 +1,6 @@
1
1
  import type { MouseEventHandler, PointerEventHandler, TouchEventHandler } from 'svelte/elements';
2
2
  import type { ComputedStylesOptions } from '../utils/canvas.js';
3
+ import type { ComponentNode } from '../states/chart.svelte.js';
3
4
  export type ComponentRender<T extends Element = Element> = {
4
5
  render: (ctx: CanvasRenderingContext2D, styleOverrides?: ComputedStylesOptions) => any;
5
6
  events?: {
@@ -26,6 +27,8 @@ export type CanvasContextValue = {
26
27
  */
27
28
  register<T extends Element>(component: ComponentRender<T>): () => void;
28
29
  invalidate(): void;
30
+ /** Get the root ComponentNode of the canvas render tree. Used for server-side rendering. */
31
+ getRootNode?: () => ComponentNode;
29
32
  };
30
33
  export declare function getCanvasContext(): CanvasContextValue;
31
34
  export declare function setCanvasContext(context: CanvasContextValue): CanvasContextValue;
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ import { getChartContext } from '../contexts/chart.js';
3
+ import { getCanvasContext } from '../contexts/canvas.js';
4
+ import { setSSRCapture, type CaptureTarget } from './captureStore.js';
5
+
6
+ let {
7
+ capture,
8
+ onCapture,
9
+ }: {
10
+ capture?: CaptureTarget;
11
+ onCapture?: (data: CaptureTarget) => void;
12
+ } = $props();
13
+
14
+ const chartState = getChartContext();
15
+ const canvasCtx = getCanvasContext();
16
+
17
+ const captured = {
18
+ chartState,
19
+ rootNode: canvasCtx.getRootNode?.(),
20
+ };
21
+
22
+ if (typeof window === 'undefined') {
23
+ if (capture) {
24
+ Object.assign(capture, captured);
25
+ }
26
+
27
+ setSSRCapture(captured);
28
+ onCapture?.(captured);
29
+ }
30
+ </script>
@@ -0,0 +1,8 @@
1
+ import { type CaptureTarget } from './captureStore.js';
2
+ type $$ComponentProps = {
3
+ capture?: CaptureTarget;
4
+ onCapture?: (data: CaptureTarget) => void;
5
+ };
6
+ declare const ContextCapture: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type ContextCapture = ReturnType<typeof ContextCapture>;
8
+ export default ContextCapture;
@@ -0,0 +1,26 @@
1
+ <script lang="ts">
2
+ import type { Snippet } from 'svelte';
3
+ import Chart from '../components/Chart.svelte';
4
+ import type { ChartProps } from '../components/Chart.svelte';
5
+ import Canvas from '../components/layers/Canvas.svelte';
6
+ import type { CaptureTarget } from './captureStore.js';
7
+
8
+ let {
9
+ children,
10
+ capture,
11
+ onCapture,
12
+ ...chartProps
13
+ }: {
14
+ children?: Snippet;
15
+ capture?: CaptureTarget;
16
+ onCapture?: (data: CaptureTarget) => void;
17
+ } & Omit<ChartProps<any>, 'children'> = $props();
18
+ </script>
19
+
20
+ <Chart ssr={true} {...chartProps}>
21
+ <Canvas ssrCapture={capture} ssrCaptureCallback={onCapture}>
22
+ {#if children}
23
+ {@render children()}
24
+ {/if}
25
+ </Canvas>
26
+ </Chart>
@@ -0,0 +1,11 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { ChartProps } from '../components/Chart.svelte';
3
+ import type { CaptureTarget } from './captureStore.js';
4
+ type $$ComponentProps = {
5
+ children?: Snippet;
6
+ capture?: CaptureTarget;
7
+ onCapture?: (data: CaptureTarget) => void;
8
+ } & Omit<ChartProps<any>, 'children'>;
9
+ declare const ServerChart: import("svelte").Component<$$ComponentProps, {}, "">;
10
+ type ServerChart = ReturnType<typeof ServerChart>;
11
+ export default ServerChart;
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import { scaleBand } from 'd3-scale';
3
+ import ServerChart from './ServerChart.svelte';
4
+ import type { CaptureTarget } from './captureStore.js';
5
+ import Bars from '../components/Bars.svelte';
6
+
7
+ let {
8
+ data,
9
+ width,
10
+ height,
11
+ capture,
12
+ onCapture
13
+ }: {
14
+ data: { category: string; value: number }[];
15
+ width: number;
16
+ height: number;
17
+ capture?: CaptureTarget;
18
+ onCapture?: (data: CaptureTarget) => void;
19
+ } = $props();
20
+ </script>
21
+
22
+ <ServerChart
23
+ {capture}
24
+ {onCapture}
25
+ {width}
26
+ {height}
27
+ {data}
28
+ x="category"
29
+ xScale={scaleBand().paddingInner(0.2).paddingOuter(0.1)}
30
+ y="value"
31
+ yDomain={[0, null]}
32
+ padding={{ top: 20, right: 20, bottom: 30, left: 40 }}
33
+ >
34
+ <Bars fill="rgb(59, 130, 246)" radius={4} />
35
+ </ServerChart>
@@ -0,0 +1,14 @@
1
+ import type { CaptureTarget } from './captureStore.js';
2
+ type $$ComponentProps = {
3
+ data: {
4
+ category: string;
5
+ value: number;
6
+ }[];
7
+ width: number;
8
+ height: number;
9
+ capture?: CaptureTarget;
10
+ onCapture?: (data: CaptureTarget) => void;
11
+ };
12
+ declare const TestBarChart: import("svelte").Component<$$ComponentProps, {}, "">;
13
+ type TestBarChart = ReturnType<typeof TestBarChart>;
14
+ export default TestBarChart;
@@ -0,0 +1,35 @@
1
+ <script lang="ts">
2
+ import ServerChart from './ServerChart.svelte';
3
+ import type { CaptureTarget } from './captureStore.js';
4
+ import Area from '../components/Area.svelte';
5
+ import Spline from '../components/Spline.svelte';
6
+
7
+ let {
8
+ data,
9
+ width,
10
+ height,
11
+ capture,
12
+ onCapture
13
+ }: {
14
+ data: { date: number; value: number }[];
15
+ width: number;
16
+ height: number;
17
+ capture?: CaptureTarget;
18
+ onCapture?: (data: CaptureTarget) => void;
19
+ } = $props();
20
+ </script>
21
+
22
+ <ServerChart
23
+ {capture}
24
+ {onCapture}
25
+ {width}
26
+ {height}
27
+ {data}
28
+ x="date"
29
+ y="value"
30
+ yDomain={[0, null]}
31
+ padding={{ top: 20, right: 20, bottom: 20, left: 20 }}
32
+ >
33
+ <Area fill="rgba(59, 130, 246, 0.15)" stroke="none" />
34
+ <Spline stroke="rgb(59, 130, 246)" strokeWidth={2} />
35
+ </ServerChart>
@@ -0,0 +1,14 @@
1
+ import type { CaptureTarget } from './captureStore.js';
2
+ type $$ComponentProps = {
3
+ data: {
4
+ date: number;
5
+ value: number;
6
+ }[];
7
+ width: number;
8
+ height: number;
9
+ capture?: CaptureTarget;
10
+ onCapture?: (data: CaptureTarget) => void;
11
+ };
12
+ declare const TestLineChart: import("svelte").Component<$$ComponentProps, {}, "">;
13
+ type TestLineChart = ReturnType<typeof TestLineChart>;
14
+ export default TestLineChart;
@@ -0,0 +1,8 @@
1
+ import type { ChartState, ComponentNode } from '../states/chart.svelte.js';
2
+ export type CaptureTarget = {
3
+ chartState?: ChartState;
4
+ rootNode?: ComponentNode;
5
+ };
6
+ export type SSRCapture = CaptureTarget | null;
7
+ export declare function setSSRCapture(target: SSRCapture): void;
8
+ export declare function getSSRCapture(): SSRCapture;
@@ -0,0 +1,18 @@
1
+ const SSR_CAPTURE_KEY = Symbol.for('layerchart.ssr-capture');
2
+ let _capture = null;
3
+ function getGlobalCaptureStore() {
4
+ return globalThis;
5
+ }
6
+ export function setSSRCapture(target) {
7
+ _capture = target;
8
+ const globalStore = getGlobalCaptureStore();
9
+ if (target == null) {
10
+ delete globalStore[SSR_CAPTURE_KEY];
11
+ }
12
+ else {
13
+ globalStore[SSR_CAPTURE_KEY] = target;
14
+ }
15
+ }
16
+ export function getSSRCapture() {
17
+ return getGlobalCaptureStore()[SSR_CAPTURE_KEY] ?? _capture;
18
+ }