layerchart 2.0.0-next.50 → 2.0.0-next.51

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 (49) hide show
  1. package/dist/components/Axis.svelte +25 -0
  2. package/dist/components/Axis.svelte.d.ts +10 -0
  3. package/dist/components/Circle.svelte +82 -59
  4. package/dist/components/Ellipse.svelte +83 -64
  5. package/dist/components/GeoRaster.svelte +311 -0
  6. package/dist/components/GeoRaster.svelte.d.ts +61 -0
  7. package/dist/components/Grid.svelte +15 -0
  8. package/dist/components/Grid.svelte.d.ts +5 -0
  9. package/dist/components/Image.svelte +2 -2
  10. package/dist/components/Line.svelte +82 -62
  11. package/dist/components/Points.svelte +2 -2
  12. package/dist/components/Polygon.svelte +92 -56
  13. package/dist/components/Rect.svelte +113 -64
  14. package/dist/components/Rule.svelte +2 -0
  15. package/dist/components/Sankey.svelte +0 -2
  16. package/dist/components/Text.svelte +83 -52
  17. package/dist/components/charts/PieChart.svelte +2 -2
  18. package/dist/components/index.d.ts +2 -0
  19. package/dist/components/index.js +2 -0
  20. package/dist/components/layers/Canvas.svelte +65 -48
  21. package/dist/components/layers/Canvas.svelte.d.ts +10 -0
  22. package/dist/contexts/canvas.d.ts +3 -0
  23. package/dist/server/ContextCapture.svelte +30 -0
  24. package/dist/server/ContextCapture.svelte.d.ts +8 -0
  25. package/dist/server/ServerChart.svelte +26 -0
  26. package/dist/server/ServerChart.svelte.d.ts +11 -0
  27. package/dist/server/TestBarChart.svelte +35 -0
  28. package/dist/server/TestBarChart.svelte.d.ts +14 -0
  29. package/dist/server/TestLineChart.svelte +35 -0
  30. package/dist/server/TestLineChart.svelte.d.ts +14 -0
  31. package/dist/server/captureStore.d.ts +8 -0
  32. package/dist/server/captureStore.js +18 -0
  33. package/dist/server/index.d.ts +137 -0
  34. package/dist/server/index.js +141 -0
  35. package/dist/server/renderChart.ssr.test.d.ts +1 -0
  36. package/dist/server/renderChart.ssr.test.js +205 -0
  37. package/dist/server/renderTree.d.ts +8 -0
  38. package/dist/server/renderTree.js +29 -0
  39. 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
  40. 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
  41. package/dist/states/chart.svelte.d.ts +5 -1
  42. package/dist/states/chart.svelte.js +18 -3
  43. package/dist/states/chart.svelte.test.js +110 -0
  44. package/dist/states/geo.svelte.d.ts +5 -1
  45. package/dist/states/geo.svelte.js +80 -68
  46. package/dist/utils/canvas.js +29 -10
  47. package/dist/utils/canvas.svelte.test.js +2 -2
  48. package/dist/utils/motion.svelte.js +14 -0
  49. package/package.json +7 -1
@@ -137,8 +137,8 @@
137
137
  const scaledX: number = ctx.xScale(xVal);
138
138
  const scaledY: number = ctx.yScale(yVal);
139
139
 
140
- const x = scaledX + getOffset(scaledX, offsetX, ctx.xScale, ctx.x1Scale);
141
- const y = scaledY + getOffset(scaledY, offsetY, ctx.yScale, ctx.y1Scale);
140
+ const x = scaledX + getOffset(scaledX, offsetX, ctx.xScale, ctx.x1Scale ?? undefined);
141
+ const y = scaledY + getOffset(scaledY, offsetY, ctx.yScale, ctx.y1Scale ?? undefined);
142
142
 
143
143
  const radialPoint = pointRadial(x, y);
144
144
 
@@ -168,7 +168,13 @@
168
168
  type ResolvedMotion,
169
169
  } from '../utils/motion.svelte.js';
170
170
  import { renderPathData, type ComputedStylesOptions } from '../utils/canvas.js';
171
- import { hasAnyDataProp, resolveDataProp, resolveColorProp, resolveGeoDataPair, resolveStyleProp } from '../utils/dataProp.js';
171
+ import {
172
+ hasAnyDataProp,
173
+ resolveDataProp,
174
+ resolveColorProp,
175
+ resolveGeoDataPair,
176
+ resolveStyleProp,
177
+ } from '../utils/dataProp.js';
172
178
  import { getGeoContext } from '../contexts/geo.js';
173
179
  import { chartDataArray } from '../utils/common.js';
174
180
  import { createKey } from '../utils/key.svelte.js';
@@ -219,9 +225,7 @@
219
225
  const dataMode = $derived(hasAnyDataProp(cx, cy, r));
220
226
 
221
227
  // Data to iterate over in data mode
222
- const resolvedData: any[] = $derived(
223
- dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []
224
- );
228
+ const resolvedData: any[] = $derived(dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []);
225
229
 
226
230
  // Resolve a single data item to a polygon path string
227
231
  function resolvePolygon(d: any) {
@@ -234,22 +238,23 @@
234
238
  }
235
239
  const resolvedR = resolveDataProp(r, d, chartCtx.rScale, typeof r === 'number' ? r : 1);
236
240
 
237
- const pts = typeof points === 'number'
238
- ? polygon({
239
- cx: resolvedCx,
240
- cy: resolvedCy,
241
- count: points,
242
- radius: resolvedR,
243
- rotate,
244
- inset,
245
- scaleX,
246
- scaleY,
247
- skewX,
248
- skewY,
249
- tiltX,
250
- tiltY,
251
- })
252
- : points;
241
+ const pts =
242
+ typeof points === 'number'
243
+ ? polygon({
244
+ cx: resolvedCx,
245
+ cy: resolvedCy,
246
+ count: points,
247
+ radius: resolvedR,
248
+ rotate,
249
+ inset,
250
+ scaleX,
251
+ scaleY,
252
+ skewX,
253
+ skewY,
254
+ tiltX,
255
+ tiltY,
256
+ })
257
+ : points;
253
258
 
254
259
  return roundedPolygonPath(pts, cornerRadius);
255
260
  }
@@ -350,6 +355,13 @@
350
355
 
351
356
  const layerCtx = getLayerContext();
352
357
 
358
+ const staticFill = $derived(typeof fill === 'string' ? fill : undefined);
359
+ const staticFillOpacity = $derived(typeof fillOpacity === 'number' ? fillOpacity : undefined);
360
+ const staticStroke = $derived(typeof stroke === 'string' ? stroke : undefined);
361
+ const staticStrokeWidth = $derived(typeof strokeWidth === 'number' ? strokeWidth : undefined);
362
+ const staticOpacity = $derived(typeof opacity === 'number' ? opacity : undefined);
363
+ const staticClassName = $derived(typeof className === 'string' ? className : undefined);
364
+
353
365
  function getStyleOptions(
354
366
  styleOverrides: ComputedStylesOptions | undefined,
355
367
  itemFill?: string | undefined,
@@ -360,16 +372,29 @@
360
372
  itemClass?: string | undefined
361
373
  ) {
362
374
  return styleOverrides
363
- ? merge({ styles: { strokeWidth: itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined) } }, styleOverrides)
375
+ ? merge(
376
+ {
377
+ styles: {
378
+ strokeWidth:
379
+ itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined),
380
+ },
381
+ },
382
+ styleOverrides
383
+ )
364
384
  : {
365
385
  styles: {
366
386
  fill: itemFill ?? fill,
367
- fillOpacity: itemFillOpacity ?? (typeof fillOpacity === 'number' ? fillOpacity : undefined),
387
+ fillOpacity:
388
+ itemFillOpacity ?? (typeof fillOpacity === 'number' ? fillOpacity : undefined),
368
389
  stroke: itemStroke ?? stroke,
369
- strokeWidth: itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined),
390
+ strokeWidth:
391
+ itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined),
370
392
  opacity: itemOpacity ?? (typeof opacity === 'number' ? opacity : undefined),
371
393
  },
372
- classes: cls('lc-polygon', itemClass ?? (typeof className === 'string' ? className : undefined)),
394
+ classes: cls(
395
+ 'lc-polygon',
396
+ itemClass ?? (typeof className === 'string' ? className : undefined)
397
+ ),
373
398
  style: restProps.style as string | undefined,
374
399
  };
375
400
  }
@@ -387,7 +412,15 @@
387
412
  const resolvedStrokeWidth = resolveStyleProp(strokeWidth, d);
388
413
  const resolvedOpacity = resolveStyleProp(opacity, d);
389
414
  const resolvedClass = resolveStyleProp(className, d);
390
- const styleOpts = getStyleOptions(styleOverrides, resolvedFill, resolvedStroke, resolvedFillOpacity, resolvedStrokeWidth, resolvedOpacity, resolvedClass);
415
+ const styleOpts = getStyleOptions(
416
+ styleOverrides,
417
+ resolvedFill,
418
+ resolvedStroke,
419
+ resolvedFillOpacity,
420
+ resolvedStrokeWidth,
421
+ resolvedOpacity,
422
+ resolvedClass
423
+ );
391
424
  renderPathData(ctx, pathData, styleOpts);
392
425
  }
393
426
  } else {
@@ -412,31 +445,34 @@
412
445
  color: typeof fill === 'string' ? fill : typeof stroke === 'string' ? stroke : undefined,
413
446
  };
414
447
  },
415
- canvasRender: layerCtx === 'canvas' ? {
416
- render,
417
- events: {
418
- click: restProps.onclick,
419
- pointerenter: restProps.onpointerenter,
420
- pointermove: restProps.onpointermove,
421
- pointerleave: restProps.onpointerleave,
422
- pointerdown: restProps.onpointerdown,
423
- pointerover: restProps.onpointerover,
424
- pointerout: restProps.onpointerout,
425
- touchmove: restProps.ontouchmove,
426
- },
427
- deps: () => [
428
- dataMode,
429
- dataMode ? resolvedItems : null,
430
- fillKey!.current,
431
- fillOpacity,
432
- strokeKey!.current,
433
- strokeWidth,
434
- opacity,
435
- className,
436
- tweenedState.current,
437
- restProps.style,
438
- ],
439
- } : undefined,
448
+ canvasRender:
449
+ layerCtx === 'canvas'
450
+ ? {
451
+ render,
452
+ events: {
453
+ click: restProps.onclick,
454
+ pointerenter: restProps.onpointerenter,
455
+ pointermove: restProps.onpointermove,
456
+ pointerleave: restProps.onpointerleave,
457
+ pointerdown: restProps.onpointerdown,
458
+ pointerover: restProps.onpointerover,
459
+ pointerout: restProps.onpointerout,
460
+ touchmove: restProps.ontouchmove,
461
+ },
462
+ deps: () => [
463
+ dataMode,
464
+ dataMode ? resolvedItems : null,
465
+ fillKey!.current,
466
+ fillOpacity,
467
+ strokeKey!.current,
468
+ strokeWidth,
469
+ opacity,
470
+ className,
471
+ tweenedState.current,
472
+ restProps.style,
473
+ ],
474
+ }
475
+ : undefined,
440
476
  });
441
477
  </script>
442
478
 
@@ -464,12 +500,12 @@
464
500
  {:else}
465
501
  <path
466
502
  d={tweenedState.current}
467
- fill={fill as string}
468
- fill-opacity={fillOpacity as number}
469
- stroke={stroke as string}
470
- stroke-width={strokeWidth as number}
471
- opacity={opacity as number}
472
- class={cls('lc-polygon', className as string)}
503
+ fill={staticFill}
504
+ fill-opacity={staticFillOpacity}
505
+ stroke={staticStroke}
506
+ stroke-width={staticStrokeWidth}
507
+ opacity={staticOpacity}
508
+ class={cls('lc-polygon', staticClassName)}
473
509
  {...restProps}
474
510
  bind:this={ref}
475
511
  />
@@ -131,13 +131,20 @@
131
131
  <script lang="ts">
132
132
  import { cls } from '@layerstack/tailwind';
133
133
  import { merge } from '@layerstack/utils';
134
+ import type { HTMLAttributes } from 'svelte/elements';
134
135
 
135
136
  import { untrack } from 'svelte';
136
137
  import { getLayerContext } from '../contexts/layer.js';
137
138
  import { getChartContext } from '../contexts/chart.js';
138
139
  import { createDataMotionMap, type MotionOptions } from '../utils/motion.svelte.js';
139
140
  import { createKey } from '../utils/key.svelte.js';
140
- import { hasAnyDataProp, resolveDataProp, resolveColorProp, resolveGeoDataPair, resolveStyleProp } from '../utils/dataProp.js';
141
+ import {
142
+ hasAnyDataProp,
143
+ resolveDataProp,
144
+ resolveColorProp,
145
+ resolveGeoDataPair,
146
+ resolveStyleProp,
147
+ } from '../utils/dataProp.js';
141
148
  import { getGeoContext } from '../contexts/geo.js';
142
149
  import { chartDataArray } from '../utils/common.js';
143
150
  import { resolveInsets } from '../utils/rect.svelte.js';
@@ -189,9 +196,7 @@
189
196
  const geo = getGeoContext();
190
197
 
191
198
  // Data to iterate over in data mode
192
- const resolvedData: any[] = $derived(
193
- dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []
194
- );
199
+ const resolvedData: any[] = $derived(dataMode ? (dataProp ?? chartDataArray(chartCtx.data)) : []);
195
200
 
196
201
  // Resolve a single data item to rect dimensions
197
202
  function resolveRect(d: any) {
@@ -288,8 +293,8 @@
288
293
 
289
294
  const _initialX = initialX ?? (typeof x === 'number' ? x : 0);
290
295
  const _initialY = initialY ?? (typeof y === 'number' ? y : 0);
291
- const _initialWidth = initialWidth ?? (width ?? 0);
292
- const _initialHeight = initialHeight ?? (height ?? 0);
296
+ const _initialWidth = initialWidth ?? width ?? 0;
297
+ const _initialHeight = initialHeight ?? height ?? 0;
293
298
 
294
299
  // Parse motion config once, then pass resolved config to each axis
295
300
  // (avoids 4 separate parseMotionProp calls that re-parse the same prop)
@@ -316,6 +321,20 @@
316
321
 
317
322
  const layerCtx = getLayerContext();
318
323
 
324
+ const staticFill = $derived(typeof fill === 'string' ? fill : undefined);
325
+ const staticFillOpacity = $derived(typeof fillOpacity === 'number' ? fillOpacity : undefined);
326
+ const staticStroke = $derived(typeof stroke === 'string' ? stroke : undefined);
327
+ const staticStrokeOpacity = $derived(
328
+ typeof strokeOpacity === 'number' ? strokeOpacity : undefined
329
+ );
330
+ const staticStrokeWidth = $derived(typeof strokeWidth === 'number' ? strokeWidth : undefined);
331
+ const staticOpacity = $derived(typeof opacity === 'number' ? opacity : undefined);
332
+ const staticClassName = $derived(typeof className === 'string' ? className : undefined);
333
+ const staticBorderWidth = $derived(
334
+ typeof strokeWidth === 'number' ? `${strokeWidth}px` : undefined
335
+ );
336
+ const htmlRestProps = $derived(restProps as unknown as HTMLAttributes<HTMLDivElement>);
337
+
319
338
  function getStyleOptions(
320
339
  styleOverrides: ComputedStylesOptions | undefined,
321
340
  itemFill?: string | undefined,
@@ -327,17 +346,31 @@
327
346
  itemClass?: string | undefined
328
347
  ) {
329
348
  return styleOverrides
330
- ? merge({ styles: { strokeWidth: itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined) } }, styleOverrides)
349
+ ? merge(
350
+ {
351
+ styles: {
352
+ strokeWidth:
353
+ itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined),
354
+ },
355
+ },
356
+ styleOverrides
357
+ )
331
358
  : {
332
359
  styles: {
333
360
  fill: itemFill ?? fill,
334
- fillOpacity: itemFillOpacity ?? (typeof fillOpacity === 'number' ? fillOpacity : undefined),
361
+ fillOpacity:
362
+ itemFillOpacity ?? (typeof fillOpacity === 'number' ? fillOpacity : undefined),
335
363
  stroke: itemStroke ?? stroke,
336
- strokeOpacity: itemStrokeOpacity ?? (typeof strokeOpacity === 'number' ? strokeOpacity : undefined),
337
- strokeWidth: itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined),
364
+ strokeOpacity:
365
+ itemStrokeOpacity ?? (typeof strokeOpacity === 'number' ? strokeOpacity : undefined),
366
+ strokeWidth:
367
+ itemStrokeWidth ?? (typeof strokeWidth === 'number' ? strokeWidth : undefined),
338
368
  opacity: itemOpacity ?? (typeof opacity === 'number' ? opacity : undefined),
339
369
  },
340
- classes: cls('lc-rect', itemClass ?? (typeof className === 'string' ? className : undefined)),
370
+ classes: cls(
371
+ 'lc-rect',
372
+ itemClass ?? (typeof className === 'string' ? className : undefined)
373
+ ),
341
374
  style: restProps.style as string | undefined,
342
375
  };
343
376
  }
@@ -355,15 +388,28 @@
355
388
  const resolvedStrokeWidth = resolveStyleProp(strokeWidth, item.d);
356
389
  const resolvedOpacity = resolveStyleProp(opacity, item.d);
357
390
  const resolvedClass = resolveStyleProp(className, item.d);
358
- const styleOpts = getStyleOptions(styleOverrides, resolvedFill, resolvedStroke, resolvedFillOpacity, resolvedStrokeOpacity, resolvedStrokeWidth, resolvedOpacity, resolvedClass);
359
- renderRect(ctx, {
360
- x: item.x,
361
- y: item.y,
362
- width: item.width,
363
- height: item.height,
364
- rx,
365
- ry,
366
- }, styleOpts);
391
+ const styleOpts = getStyleOptions(
392
+ styleOverrides,
393
+ resolvedFill,
394
+ resolvedStroke,
395
+ resolvedFillOpacity,
396
+ resolvedStrokeOpacity,
397
+ resolvedStrokeWidth,
398
+ resolvedOpacity,
399
+ resolvedClass
400
+ );
401
+ renderRect(
402
+ ctx,
403
+ {
404
+ x: item.x,
405
+ y: item.y,
406
+ width: item.width,
407
+ height: item.height,
408
+ rx,
409
+ ry,
410
+ },
411
+ styleOpts
412
+ );
367
413
  }
368
414
  } else {
369
415
  const styleOpts = getStyleOptions(styleOverrides);
@@ -399,36 +445,39 @@
399
445
  color: typeof fill === 'string' ? fill : typeof stroke === 'string' ? stroke : undefined,
400
446
  };
401
447
  },
402
- canvasRender: layerCtx === 'canvas' ? {
403
- render,
404
- events: {
405
- click: onclick,
406
- dblclick: ondblclick,
407
- pointerenter: onpointerenter,
408
- pointermove: onpointermove,
409
- pointerleave: onpointerleave,
410
- pointerover: onpointerover,
411
- pointerout: onpointerout,
412
- },
413
- deps: () => [
414
- dataMode,
415
- dataMode ? resolvedItems : null,
416
- motionX.current,
417
- motionY.current,
418
- motionWidth.current,
419
- motionHeight.current,
420
- fillKey!.current,
421
- strokeKey!.current,
422
- fillOpacity,
423
- strokeOpacity,
424
- strokeWidth,
425
- opacity,
426
- className,
427
- restProps.style,
428
- rx,
429
- ry,
430
- ],
431
- } : undefined,
448
+ canvasRender:
449
+ layerCtx === 'canvas'
450
+ ? {
451
+ render,
452
+ events: {
453
+ click: onclick,
454
+ dblclick: ondblclick,
455
+ pointerenter: onpointerenter,
456
+ pointermove: onpointermove,
457
+ pointerleave: onpointerleave,
458
+ pointerover: onpointerover,
459
+ pointerout: onpointerout,
460
+ },
461
+ deps: () => [
462
+ dataMode,
463
+ dataMode ? resolvedItems : null,
464
+ motionX.current,
465
+ motionY.current,
466
+ motionWidth.current,
467
+ motionHeight.current,
468
+ fillKey!.current,
469
+ strokeKey!.current,
470
+ fillOpacity,
471
+ strokeOpacity,
472
+ strokeWidth,
473
+ opacity,
474
+ className,
475
+ restProps.style,
476
+ rx,
477
+ ry,
478
+ ],
479
+ }
480
+ : undefined,
432
481
  });
433
482
  </script>
434
483
 
@@ -472,15 +521,15 @@
472
521
  y={motionY.current}
473
522
  width={motionWidth.current}
474
523
  height={motionHeight.current}
475
- fill={fill as string}
476
- fill-opacity={fillOpacity as number}
477
- stroke={stroke as string}
478
- stroke-opacity={strokeOpacity as number}
479
- stroke-width={strokeWidth as number}
480
- opacity={opacity as number}
524
+ fill={staticFill}
525
+ fill-opacity={staticFillOpacity}
526
+ stroke={staticStroke}
527
+ stroke-opacity={staticStrokeOpacity}
528
+ stroke-width={staticStrokeWidth}
529
+ opacity={staticOpacity}
481
530
  {rx}
482
531
  {ry}
483
- class={cls('lc-rect', className as string)}
532
+ class={cls('lc-rect', staticClassName)}
484
533
  {...restProps}
485
534
  {onclick}
486
535
  {ondblclick}
@@ -516,7 +565,7 @@
516
565
  style:border-color={resolvedStroke}
517
566
  style:border-radius="{rx}px"
518
567
  class={cls('lc-rect', resolvedClass)}
519
- {...restProps as any}
568
+ {...htmlRestProps}
520
569
  {onclick}
521
570
  {ondblclick}
522
571
  {onpointerenter}
@@ -535,14 +584,14 @@
535
584
  style:top="{motionY.current}px"
536
585
  style:width="{motionWidth.current}px"
537
586
  style:height="{motionHeight.current}px"
538
- style:background={fill as string}
539
- style:opacity={opacity as number}
540
- style:border-width="{strokeWidth as number}px"
587
+ style:background={staticFill}
588
+ style:opacity={staticOpacity}
589
+ style:border-width={staticBorderWidth}
541
590
  style:border-style="solid"
542
- style:border-color={stroke as string}
591
+ style:border-color={staticStroke}
543
592
  style:border-radius="{rx}px"
544
- class={cls('lc-rect', className as string)}
545
- {...restProps as any}
593
+ class={cls('lc-rect', staticClassName)}
594
+ {...htmlRestProps}
546
595
  {onclick}
547
596
  {ondblclick}
548
597
  {onpointerenter}
@@ -77,6 +77,8 @@
77
77
 
78
78
  const ctx = getChartContext();
79
79
 
80
+ ctx.registerComponent({ name: 'Rule', kind: 'composite-mark' });
81
+
80
82
  const data = $derived(chartDataArray(dataProp ?? ctx.data));
81
83
 
82
84
  const singleX = $derived(
@@ -107,8 +107,6 @@
107
107
  const ctx = getChartContext();
108
108
 
109
109
  const sankeyData = $derived.by(() => {
110
- if (typeof document === 'undefined') return { nodes: [], links: [] };
111
-
112
110
  return (
113
111
  d3Sankey()
114
112
  .size([ctx.width, ctx.height])