layerchart 0.60.2 → 0.70.0

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 (47) hide show
  1. package/dist/components/Arc.svelte +83 -27
  2. package/dist/components/Area.svelte +51 -12
  3. package/dist/components/Bar.svelte +5 -1
  4. package/dist/components/Circle.svelte +54 -12
  5. package/dist/components/ComputedStyles.svelte +16 -0
  6. package/dist/components/ComputedStyles.svelte.d.ts +20 -0
  7. package/dist/components/GeoPath.svelte +36 -44
  8. package/dist/components/GeoPath.svelte.d.ts +2 -2
  9. package/dist/components/GeoPoint.svelte +27 -13
  10. package/dist/components/GeoTile.svelte +22 -7
  11. package/dist/components/Graticule.svelte.d.ts +4 -4
  12. package/dist/components/Group.svelte +46 -18
  13. package/dist/components/HitCanvas.svelte +7 -21
  14. package/dist/components/Legend.svelte.d.ts +1 -1
  15. package/dist/components/Line.svelte +70 -31
  16. package/dist/components/LinearGradient.svelte +89 -26
  17. package/dist/components/LinearGradient.svelte.d.ts +2 -2
  18. package/dist/components/Points.svelte +23 -41
  19. package/dist/components/Points.svelte.d.ts +2 -1
  20. package/dist/components/RadialGradient.svelte +86 -28
  21. package/dist/components/RadialGradient.svelte.d.ts +2 -2
  22. package/dist/components/Rect.svelte +62 -18
  23. package/dist/components/Rule.svelte +1 -1
  24. package/dist/components/Spline.svelte +95 -57
  25. package/dist/components/Text.svelte +80 -22
  26. package/dist/components/TransformControls.svelte.d.ts +1 -1
  27. package/dist/components/charts/AreaChart.svelte +14 -10
  28. package/dist/components/charts/BarChart.svelte +13 -9
  29. package/dist/components/charts/LineChart.svelte +13 -9
  30. package/dist/components/charts/PieChart.svelte +6 -2
  31. package/dist/components/charts/PieChart.svelte.d.ts +2 -1
  32. package/dist/components/charts/ScatterChart.svelte +14 -10
  33. package/dist/components/layout/Canvas.svelte +93 -11
  34. package/dist/components/layout/Canvas.svelte.d.ts +13 -0
  35. package/dist/components/layout/Svg.svelte +1 -1
  36. package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -1
  37. package/dist/utils/canvas.d.ts +46 -0
  38. package/dist/utils/canvas.js +146 -0
  39. package/dist/utils/common.d.ts +10 -1
  40. package/dist/utils/common.js +13 -0
  41. package/dist/utils/index.d.ts +2 -0
  42. package/dist/utils/index.js +2 -0
  43. package/dist/utils/math.d.ts +2 -0
  44. package/dist/utils/math.js +10 -0
  45. package/dist/utils/path.d.ts +7 -0
  46. package/dist/utils/path.js +17 -3
  47. package/package.json +3 -4
@@ -1,6 +1,12 @@
1
1
  <script lang="ts">
2
+ import { onDestroy } from 'svelte';
2
3
  import { uniqueId } from '@layerstack/utils';
3
4
 
5
+ import { chartContext } from './ChartContext.svelte';
6
+ import { getCanvasContext } from './layout/Canvas.svelte';
7
+ import { getComputedStyles } from '../utils/canvas.js';
8
+ import { parsePercent } from '../utils/math.js';
9
+
4
10
  /** Unique id for linearGradient */
5
11
  export let id: string = uniqueId('radialGradient-');
6
12
 
@@ -25,33 +31,85 @@
25
31
 
26
32
  /** Define the coordinate system for attributes (i.e. gradientUnits) */
27
33
  export let units: 'objectBoundingBox' | 'userSpaceOnUse' = 'objectBoundingBox';
34
+
35
+ const { width, height, padding } = chartContext();
36
+
37
+ const canvasContext = getCanvasContext();
38
+ const renderContext = canvasContext ? 'canvas' : 'svg';
39
+
40
+ let canvasGradient: CanvasGradient;
41
+
42
+ function render(ctx: CanvasRenderingContext2D) {
43
+ // TODO: Set correct values: https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/createRadialGradient. See also: LinearGradient
44
+ const gradient = ctx.createRadialGradient(0, 0, 0, 0, 0, 0);
45
+
46
+ // Use `getComputedStyles()` to convert each stop (if using CSS variables and/or classes) to color values
47
+ stops.forEach((stop, i) => {
48
+ if (Array.isArray(stop)) {
49
+ const { fill } = getComputedStyles(ctx.canvas, {
50
+ styles: { fill: stop[1] },
51
+ classes: $$props.class,
52
+ });
53
+ gradient.addColorStop(parsePercent(stop[0]), fill);
54
+ } else {
55
+ const { fill } = getComputedStyles(ctx.canvas, {
56
+ styles: { fill: stop },
57
+ classes: $$props.class,
58
+ });
59
+ gradient.addColorStop(i / (stops.length - 1), fill);
60
+ }
61
+ });
62
+
63
+ canvasGradient = gradient;
64
+ }
65
+
66
+ let canvasUnregister: ReturnType<typeof canvasContext.register>;
67
+ $: if (renderContext === 'canvas') {
68
+ canvasUnregister = canvasContext.register({ name: 'Gradient', render });
69
+ }
70
+
71
+ $: if (renderContext === 'canvas') {
72
+ // Redraw when props changes (TODO: styles, class, etc)
73
+ stops && cx && cy && fx && fy && $width && $height;
74
+ canvasContext.invalidate();
75
+ }
76
+
77
+ onDestroy(() => {
78
+ if (renderContext === 'canvas') {
79
+ canvasUnregister();
80
+ }
81
+ });
28
82
  </script>
29
83
 
30
- <defs>
31
- <radialGradient
32
- {id}
33
- {cx}
34
- {cy}
35
- {fx}
36
- {fy}
37
- {r}
38
- {spreadMethod}
39
- gradientTransform={transform}
40
- gradientUnits={units}
41
- {...$$restProps}
42
- >
43
- <slot name="stops">
44
- {#if stops}
45
- {#each stops as stop, i}
46
- {#if Array.isArray(stop)}
47
- <stop offset={stop[0]} stop-color={stop[1]} />
48
- {:else}
49
- <stop offset="{i * (100 / (stops.length - 1))}%" stop-color={stop} />
50
- {/if}
51
- {/each}
52
- {/if}
53
- </slot>
54
- </radialGradient>
55
- </defs>
56
-
57
- <slot {id} url="url(#{id})" />
84
+ {#if renderContext === 'canvas'}
85
+ <slot {id} gradient={canvasGradient} />
86
+ {:else if renderContext === 'svg'}
87
+ <defs>
88
+ <radialGradient
89
+ {id}
90
+ {cx}
91
+ {cy}
92
+ {fx}
93
+ {fy}
94
+ {r}
95
+ {spreadMethod}
96
+ gradientTransform={transform}
97
+ gradientUnits={units}
98
+ {...$$restProps}
99
+ >
100
+ <slot name="stops">
101
+ {#if stops}
102
+ {#each stops as stop, i}
103
+ {#if Array.isArray(stop)}
104
+ <stop offset={stop[0]} stop-color={stop[1]} />
105
+ {:else}
106
+ <stop offset="{i * (100 / (stops.length - 1))}%" stop-color={stop} />
107
+ {/if}
108
+ {/each}
109
+ {/if}
110
+ </slot>
111
+ </radialGradient>
112
+ </defs>
113
+
114
+ <slot {id} gradient="url(#{id})" />
115
+ {/if}
@@ -17,11 +17,11 @@ declare const __propDef: {
17
17
  [evt: string]: CustomEvent<any>;
18
18
  };
19
19
  slots: {
20
- stops: {};
21
20
  default: {
22
21
  id: string;
23
- url: string;
22
+ gradient: string;
24
23
  };
24
+ stops: {};
25
25
  };
26
26
  };
27
27
  export type RadialGradientProps = typeof __propDef.props;
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { tick } from 'svelte';
2
+ import { onDestroy, tick } from 'svelte';
3
3
  import { cls } from '@layerstack/tailwind';
4
4
 
5
5
  import {
@@ -8,6 +8,8 @@
8
8
  type SpringOptions,
9
9
  type TweenedOptions,
10
10
  } from '../stores/motionStore.js';
11
+ import { getCanvasContext } from './layout/Canvas.svelte';
12
+ import { renderRect } from '../index.js/utils/canvas.js';
11
13
 
12
14
  export let x = 0;
13
15
  export let initialX = x;
@@ -21,6 +23,11 @@
21
23
  export let height: number;
22
24
  export let initialHeight = height;
23
25
 
26
+ export let fill: string | undefined = undefined;
27
+ export let fillOpacity: number | undefined = undefined;
28
+ export let stroke: string | undefined = undefined;
29
+ export let strokeWidth: number | undefined = undefined;
30
+
24
31
  export let spring: boolean | SpringOptions | { [prop: string]: SpringOptions } = undefined;
25
32
  export let tweened: boolean | TweenedOptions | { [prop: string]: TweenedOptions } = undefined;
26
33
 
@@ -35,22 +42,59 @@
35
42
  tweened_width.set(width);
36
43
  tweened_height.set(height);
37
44
  });
45
+
46
+ const canvasContext = getCanvasContext();
47
+ const renderContext = canvasContext ? 'canvas' : 'svg';
48
+
49
+ function render(ctx: CanvasRenderingContext2D) {
50
+ renderRect(
51
+ ctx,
52
+ { x: $tweened_x, y: $tweened_y, width: $tweened_width, height: $tweened_height },
53
+ {
54
+ styles: { fill, fillOpacity, stroke, strokeWidth },
55
+ classes: $$props.class,
56
+ }
57
+ );
58
+ }
59
+
60
+ let canvasUnregister: ReturnType<typeof canvasContext.register>;
61
+ $: if (renderContext === 'canvas') {
62
+ canvasUnregister = canvasContext.register({ name: 'Rect', render });
63
+ }
64
+
65
+ $: if (renderContext === 'canvas') {
66
+ // Redraw when props changes (TODO: styles, class, etc)
67
+ $tweened_x && $tweened_y && $tweened_width && $tweened_height;
68
+ canvasContext.invalidate();
69
+ }
70
+
71
+ onDestroy(() => {
72
+ if (renderContext === 'canvas') {
73
+ canvasUnregister();
74
+ }
75
+ });
38
76
  </script>
39
77
 
40
- <!-- svelte-ignore a11y-mouse-events-have-key-events -->
41
- <!-- svelte-ignore a11y-no-static-element-interactions -->
42
- <rect
43
- x={$tweened_x}
44
- y={$tweened_y}
45
- width={$tweened_width}
46
- height={$tweened_height}
47
- class={cls($$props.fill == null && 'fill-surface-content')}
48
- {...$$restProps}
49
- on:click
50
- on:pointerenter
51
- on:pointerover
52
- on:pointermove
53
- on:pointerout
54
- on:pointerleave
55
- on:dblclick
56
- />
78
+ {#if renderContext === 'svg'}
79
+ <!-- svelte-ignore a11y-mouse-events-have-key-events -->
80
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
81
+ <rect
82
+ x={$tweened_x}
83
+ y={$tweened_y}
84
+ width={$tweened_width}
85
+ height={$tweened_height}
86
+ class={cls($$props.fill == null && 'fill-surface-content')}
87
+ {fill}
88
+ fill-opacity={fillOpacity}
89
+ {stroke}
90
+ stroke-width={strokeWidth}
91
+ {...$$restProps}
92
+ on:click
93
+ on:pointerenter
94
+ on:pointerover
95
+ on:pointermove
96
+ on:pointerout
97
+ on:pointerleave
98
+ on:dblclick
99
+ />
100
+ {/if}
@@ -67,7 +67,7 @@
67
67
  {x2}
68
68
  {y2}
69
69
  {...$$restProps}
70
- class={cls('test grid stroke-surface-content/10', $$props.class)}
70
+ class={cls('stroke-surface-content/10', $$props.class)}
71
71
  />
72
72
  {:else}
73
73
  <Line
@@ -1,5 +1,5 @@
1
1
  <script lang="ts">
2
- import { tick, type ComponentProps } from 'svelte';
2
+ import { onDestroy, tick, type ComponentProps } from 'svelte';
3
3
  import { writable } from 'svelte/store';
4
4
  import { tweened as tweenedStore } from 'svelte/motion';
5
5
  import { draw as _drawTransition } from 'svelte/transition';
@@ -21,6 +21,8 @@
21
21
  import { accessor, type Accessor } from '../utils/common.js';
22
22
  import { isScaleBand } from '../utils/scales.js';
23
23
  import { flattenPathData } from '../utils/path.js';
24
+ import { renderPathData } from '../utils/canvas.js';
25
+ import { getCanvasContext } from './layout/Canvas.svelte';
24
26
 
25
27
  const {
26
28
  data: contextData,
@@ -61,6 +63,11 @@
61
63
  export let curve: CurveFactory | CurveFactoryLineOnly | undefined = undefined;
62
64
  export let defined: Parameters<Line<any>['defined']>[0] | undefined = undefined;
63
65
 
66
+ export let fill: string | undefined = undefined;
67
+ export let stroke: string | undefined = undefined;
68
+ export let strokeWidth: number | undefined = undefined;
69
+ export let opacity: number | undefined = undefined;
70
+
64
71
  /** Marker to attach to start, mid, and end points of path */
65
72
  export let marker: ComponentProps<Marker>['type'] | ComponentProps<Marker> | undefined =
66
73
  undefined;
@@ -153,6 +160,31 @@
153
160
  key = Symbol();
154
161
  }
155
162
 
163
+ const canvasContext = getCanvasContext();
164
+ const renderContext = canvasContext ? 'canvas' : 'svg';
165
+
166
+ function render(ctx: CanvasRenderingContext2D) {
167
+ renderPathData(ctx, $tweened_d, {
168
+ styles: { stroke, fill, strokeWidth, opacity },
169
+ classes: $$props.class,
170
+ });
171
+ }
172
+
173
+ let canvasUnregister: ReturnType<typeof canvasContext.register>;
174
+ $: if (renderContext === 'canvas') {
175
+ canvasUnregister = canvasContext.register({ name: 'Spline', render });
176
+
177
+ tweened_d.subscribe(() => {
178
+ canvasContext.invalidate();
179
+ });
180
+ }
181
+
182
+ onDestroy(() => {
183
+ if (renderContext === 'canvas') {
184
+ canvasUnregister();
185
+ }
186
+ });
187
+
156
188
  let pathEl: SVGPathElement | undefined = undefined;
157
189
  const startPoint = writable<DOMPoint | undefined>(undefined);
158
190
  $: endPoint = motionStore<DOMPoint | undefined>(undefined, {
@@ -187,63 +219,69 @@
187
219
  }
188
220
  </script>
189
221
 
190
- {#key key}
191
- <!-- svelte-ignore a11y-no-static-element-interactions -->
192
- <path
193
- d={$tweened_d}
194
- {...$$restProps}
195
- class={cls(
196
- 'path-line',
197
- !$$props.fill && 'fill-none',
198
- !$$props.stroke && 'stroke-surface-content',
199
- $$props.class
200
- )}
201
- marker-start={markerStartId ? `url(#${markerStartId})` : undefined}
202
- marker-mid={markerMidId ? `url(#${markerMidId})` : undefined}
203
- marker-end={markerEndId ? `url(#${markerEndId})` : undefined}
204
- in:drawTransition|global={typeof draw === 'object' ? draw : undefined}
205
- on:click
206
- on:pointerenter
207
- on:pointermove
208
- on:pointerleave
209
- bind:this={pathEl}
210
- />
211
-
212
- <slot name="markerStart" id={markerStartId}>
213
- {#if markerStart}
222
+ {#if renderContext === 'svg'}
223
+ {#key key}
224
+ <!-- svelte-ignore a11y-no-static-element-interactions -->
225
+ <path
226
+ d={$tweened_d}
227
+ {...$$restProps}
228
+ class={cls(
229
+ 'path-line',
230
+ !$$props.fill && 'fill-none',
231
+ !$$props.stroke && 'stroke-surface-content',
232
+ $$props.class
233
+ )}
234
+ {fill}
235
+ {stroke}
236
+ stroke-width={strokeWidth}
237
+ {opacity}
238
+ marker-start={markerStartId ? `url(#${markerStartId})` : undefined}
239
+ marker-mid={markerMidId ? `url(#${markerMidId})` : undefined}
240
+ marker-end={markerEndId ? `url(#${markerEndId})` : undefined}
241
+ in:drawTransition|global={typeof draw === 'object' ? draw : undefined}
242
+ on:click
243
+ on:pointerenter
244
+ on:pointermove
245
+ on:pointerleave
246
+ bind:this={pathEl}
247
+ />
248
+
249
+ <slot name="markerStart" id={markerStartId}>
250
+ {#if markerStart}
251
+ <Marker
252
+ id={markerStartId}
253
+ type={typeof markerStart === 'string' ? markerStart : undefined}
254
+ {...typeof markerStart === 'object' ? markerStart : null}
255
+ />
256
+ {/if}
257
+ </slot>
258
+
259
+ <slot name="markerMid" id={markerMidId}>
214
260
  <Marker
215
- id={markerStartId}
216
- type={typeof markerStart === 'string' ? markerStart : undefined}
217
- {...typeof markerStart === 'object' ? markerStart : null}
261
+ id={markerMidId}
262
+ type={typeof markerMid === 'string' ? markerMid : undefined}
263
+ {...typeof markerMid === 'object' ? markerMid : null}
218
264
  />
219
- {/if}
220
- </slot>
265
+ </slot>
221
266
 
222
- <slot name="markerMid" id={markerMidId}>
223
- <Marker
224
- id={markerMidId}
225
- type={typeof markerMid === 'string' ? markerMid : undefined}
226
- {...typeof markerMid === 'object' ? markerMid : null}
227
- />
228
- </slot>
267
+ <slot name="markerEnd" id={markerEndId}>
268
+ <Marker
269
+ id={markerEndId}
270
+ type={typeof markerEnd === 'string' ? markerEnd : undefined}
271
+ {...typeof markerEnd === 'object' ? markerEnd : null}
272
+ />
273
+ </slot>
229
274
 
230
- <slot name="markerEnd" id={markerEndId}>
231
- <Marker
232
- id={markerEndId}
233
- type={typeof markerEnd === 'string' ? markerEnd : undefined}
234
- {...typeof markerEnd === 'object' ? markerEnd : null}
235
- />
236
- </slot>
237
-
238
- {#if $$slots.start && $startPoint}
239
- <Group x={$startPoint.x} y={$startPoint.y}>
240
- <slot name="start" point={$startPoint} />
241
- </Group>
242
- {/if}
243
-
244
- {#if $$slots.end && $endPoint}
245
- <Group x={$endPoint.x} y={$endPoint.y}>
246
- <slot name="end" point={$endPoint} />
247
- </Group>
248
- {/if}
249
- {/key}
275
+ {#if $$slots.start && $startPoint}
276
+ <Group x={$startPoint.x} y={$startPoint.y}>
277
+ <slot name="start" point={$startPoint} />
278
+ </Group>
279
+ {/if}
280
+
281
+ {#if $$slots.end && $endPoint}
282
+ <Group x={$endPoint.x} y={$endPoint.y}>
283
+ <slot name="end" point={$endPoint} />
284
+ </Group>
285
+ {/if}
286
+ {/key}
287
+ {/if}
@@ -1,10 +1,12 @@
1
1
  <script lang="ts">
2
- import { tick } from 'svelte';
2
+ import { onDestroy, tick } from 'svelte';
3
3
  import type { spring as springStore, tweened as tweenedStore } from 'svelte/motion';
4
4
  import { cls } from '@layerstack/tailwind';
5
5
 
6
6
  import { getStringWidth } from '../utils/string.js';
7
7
  import { motionStore } from '../stores/motionStore.js';
8
+ import { getCanvasContext } from './layout/Canvas.svelte';
9
+ import { renderText } from '../index.js/utils/canvas.js';
8
10
 
9
11
  /*
10
12
  TODO:
@@ -58,6 +60,11 @@
58
60
  /** Rotational angle of the text */
59
61
  export let rotate: number | undefined = undefined;
60
62
 
63
+ export let fill: string | undefined = undefined;
64
+ export let fillOpacity: number | undefined = undefined;
65
+ export let stroke: string | undefined = undefined;
66
+ export let strokeWidth: number | undefined = undefined;
67
+
61
68
  let wordsByLines: { words: string[]; width?: number }[] = [];
62
69
  let wordsWithWidth: { word: string; width: number }[] = [];
63
70
  let spaceWidth: number = 0;
@@ -97,8 +104,13 @@
97
104
  /**
98
105
  * Convert css value to pixel value (ex. 0.71em => 11.36)
99
106
  */
100
- function getPixelValue(cssValue: string) {
107
+ function getPixelValue(cssValue: number | string) {
101
108
  // TODO: Properly measure pixel values using DOM (handle inherited font size, zoom, etc)
109
+
110
+ if (typeof cssValue === 'number') {
111
+ return cssValue;
112
+ }
113
+
102
114
  // @ts-expect-error
103
115
  const [match, value, units] = cssValue.match(/([\d.]+)(\D+)/);
104
116
  const number = Number(value);
@@ -162,25 +174,71 @@
162
174
  tweened_x.set(x);
163
175
  tweened_y.set(y);
164
176
  });
177
+
178
+ const canvasContext = getCanvasContext();
179
+ const renderContext = canvasContext ? 'canvas' : 'svg';
180
+
181
+ function render(ctx: CanvasRenderingContext2D) {
182
+ wordsByLines.forEach((line, index) => {
183
+ renderText(
184
+ ctx,
185
+ line.words.join(' '),
186
+ {
187
+ x: getPixelValue($tweened_x) + getPixelValue(dx),
188
+ y:
189
+ getPixelValue($tweened_y) +
190
+ getPixelValue(dy) +
191
+ (index === 0 ? startDy : getPixelValue(lineHeight)),
192
+ },
193
+ {
194
+ styles: { fill, fillOpacity, stroke, strokeWidth, paintOrder: 'stroke', textAnchor },
195
+ classes: cls(fill === undefined && 'fill-surface-content', $$props.class),
196
+ }
197
+ );
198
+ });
199
+ }
200
+
201
+ let canvasUnregister: ReturnType<typeof canvasContext.register>;
202
+ $: if (renderContext === 'canvas') {
203
+ canvasUnregister = canvasContext.register({ name: 'Text', render });
204
+ }
205
+
206
+ $: if (renderContext === 'canvas') {
207
+ // Redraw when props changes (TODO: styles, class, etc)
208
+ value && $tweened_x && $tweened_y;
209
+ canvasContext.invalidate();
210
+ }
211
+
212
+ onDestroy(() => {
213
+ if (renderContext === 'canvas') {
214
+ canvasUnregister();
215
+ }
216
+ });
165
217
  </script>
166
218
 
167
- <!-- `overflow: visible` allow contents to be shown outside element -->
168
- <!-- `paint-order: stroke` supports stroke outlining text -->
169
- <svg x={dx} y={dy} class="overflow-visible [paint-order:stroke]">
170
- {#if isValidXOrY(x) && isValidXOrY(y)}
171
- <text
172
- x={$tweened_x}
173
- y={$tweened_y}
174
- {transform}
175
- text-anchor={textAnchor}
176
- {...$$restProps}
177
- class={cls($$props.fill === undefined && 'fill-surface-content', $$props.class)}
178
- >
179
- {#each wordsByLines as line, index}
180
- <tspan x={$tweened_x} dy={index === 0 ? startDy : lineHeight}>
181
- {line.words.join(' ')}
182
- </tspan>
183
- {/each}
184
- </text>
185
- {/if}
186
- </svg>
219
+ {#if renderContext === 'svg'}
220
+ <!-- `overflow: visible` allow contents to be shown outside element -->
221
+ <!-- `paint-order: stroke` supports stroke outlining text -->
222
+ <svg x={dx} y={dy} class="overflow-visible [paint-order:stroke]">
223
+ {#if isValidXOrY(x) && isValidXOrY(y)}
224
+ <text
225
+ x={$tweened_x}
226
+ y={$tweened_y}
227
+ {transform}
228
+ text-anchor={textAnchor}
229
+ {...$$restProps}
230
+ {fill}
231
+ fill-opacity={fillOpacity}
232
+ {stroke}
233
+ stroke-width={strokeWidth}
234
+ class={cls(fill === undefined && 'fill-surface-content', $$props.class)}
235
+ >
236
+ {#each wordsByLines as line, index}
237
+ <tspan x={$tweened_x} dy={index === 0 ? startDy : lineHeight}>
238
+ {line.words.join(' ')}
239
+ </tspan>
240
+ {/each}
241
+ </text>
242
+ {/if}
243
+ </svg>
244
+ {/if}
@@ -2,7 +2,7 @@ import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
- placement?: ("center" | "left" | "right" | "bottom" | "top" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
5
+ placement?: ("center" | "bottom" | "left" | "right" | "top" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
6
6
  orientation?: "horizontal" | "vertical" | undefined;
7
7
  size?: import("svelte-ux").ButtonSize | undefined;
8
8
  show?: ("reset" | "scrollMode" | "zoomIn" | "zoomOut" | "center")[] | undefined;
@@ -7,6 +7,7 @@
7
7
 
8
8
  import Area from '../Area.svelte';
9
9
  import Axis from '../Axis.svelte';
10
+ import Canvas from '../layout/Canvas.svelte';
10
11
  import Chart from '../Chart.svelte';
11
12
  import Grid from '../Grid.svelte';
12
13
  import Highlight from '../Highlight.svelte';
@@ -18,7 +19,12 @@
18
19
  import Svg from '../layout/Svg.svelte';
19
20
  import * as Tooltip from '../tooltip/index.js';
20
21
 
21
- import { accessor, chartDataArray, type Accessor } from '../../utils/common.js';
22
+ import {
23
+ accessor,
24
+ chartDataArray,
25
+ defaultChartPadding,
26
+ type Accessor,
27
+ } from '../../utils/common.js';
22
28
 
23
29
  interface $$Props extends ComponentProps<Chart<TData>> {
24
30
  axis?: typeof axis;
@@ -30,6 +36,7 @@
30
36
  rule?: typeof rule;
31
37
  series?: typeof series;
32
38
  seriesLayout?: typeof seriesLayout;
39
+ renderContext?: typeof renderContext;
33
40
  }
34
41
 
35
42
  export let data: $$Props['data'] = [];
@@ -74,6 +81,8 @@
74
81
  labels?: Partial<ComponentProps<Labels>>;
75
82
  } = {};
76
83
 
84
+ export let renderContext: 'svg' | 'canvas' = 'svg';
85
+
77
86
  $: allSeriesData = series
78
87
  .flatMap((s) => s.data?.map((d) => ({ seriesKey: s.key, ...d })))
79
88
  .filter((d) => d) as Array<TData & { stackData?: any }>;
@@ -126,7 +135,7 @@
126
135
  ? s.value[1]
127
136
  : (s.value ?? s.key),
128
137
  fill: s.color,
129
- 'fill-opacity': 0.3,
138
+ fillOpacity: 0.3,
130
139
  ...props.area,
131
140
  ...s.props,
132
141
  line: {
@@ -151,12 +160,7 @@
151
160
  yBaseline={0}
152
161
  yNice
153
162
  {radial}
154
- padding={radial || axis === false
155
- ? undefined
156
- : {
157
- left: axis === true || axis === 'y' ? 16 : 0,
158
- bottom: (axis === true || axis === 'x' ? 16 : 0) + (legend === true ? 32 : 0),
159
- }}
163
+ padding={radial ? undefined : defaultChartPadding(axis, legend)}
160
164
  tooltip={{ mode: 'bisect-x' }}
161
165
  {...$$restProps}
162
166
  let:x
@@ -186,7 +190,7 @@
186
190
  }}
187
191
 
188
192
  <slot {...slotProps}>
189
- <Svg center={radial}>
193
+ <svelte:component this={renderContext === 'canvas' ? Canvas : Svg} center={radial}>
190
194
  <slot name="grid" {...slotProps}>
191
195
  {#if grid}
192
196
  <Grid x={radial} y {...typeof grid === 'object' ? grid : null} {...props.grid} />
@@ -261,7 +265,7 @@
261
265
  {#if labels}
262
266
  <Labels {...props.labels} {...typeof labels === 'object' ? labels : null} />
263
267
  {/if}
264
- </Svg>
268
+ </svelte:component>
265
269
 
266
270
  <slot name="legend" {...slotProps}>
267
271
  {#if legend}