layerchart 0.96.0 → 0.97.1

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 (32) hide show
  1. package/dist/components/Arc.svelte +2 -1
  2. package/dist/components/Area.svelte +2 -2
  3. package/dist/components/Bar.svelte +3 -2
  4. package/dist/components/BrushContext.svelte +4 -5
  5. package/dist/components/Chart.svelte +18 -0
  6. package/dist/components/Chart.svelte.d.ts +11 -3
  7. package/dist/components/Circle.svelte +2 -1
  8. package/dist/components/GeoPath.svelte +3 -2
  9. package/dist/components/GeoPoint.svelte +2 -1
  10. package/dist/components/GeoTile.svelte +3 -2
  11. package/dist/components/Group.svelte +26 -5
  12. package/dist/components/Legend.svelte.d.ts +1 -1
  13. package/dist/components/Line.svelte +2 -1
  14. package/dist/components/LinearGradient.svelte +2 -1
  15. package/dist/components/RadialGradient.svelte +2 -1
  16. package/dist/components/Rect.svelte +2 -1
  17. package/dist/components/Spline.svelte +2 -1
  18. package/dist/components/Text.svelte +3 -2
  19. package/dist/components/TransformContext.svelte +2 -9
  20. package/dist/components/TransformControls.svelte.d.ts +2 -2
  21. package/dist/components/charts/PieChart.svelte.d.ts +4 -4
  22. package/dist/components/index.d.ts +2 -1
  23. package/dist/components/index.js +2 -1
  24. package/dist/components/layout/Canvas.svelte +6 -8
  25. package/dist/components/layout/Html.svelte +26 -1
  26. package/dist/components/layout/Html.svelte.d.ts +1 -0
  27. package/dist/components/layout/Svg.svelte +3 -1
  28. package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -1
  29. package/dist/components/tooltip/TooltipContext.svelte +2 -3
  30. package/package.json +7 -7
  31. package/dist/utils/event.d.ts +0 -4
  32. package/dist/utils/event.js +0 -44
@@ -27,6 +27,7 @@
27
27
 
28
28
  import { objectId } from '@layerstack/utils/object';
29
29
 
30
+ import { getRenderContext } from './Chart.svelte';
30
31
  import { chartContext } from './ChartContext.svelte';
31
32
  import { motionStore } from '../stores/motionStore.js';
32
33
  import { degreesToRadians } from '../utils/math.js';
@@ -199,8 +200,8 @@
199
200
  */
200
201
  export let data: any = undefined;
201
202
 
203
+ const renderContext = getRenderContext();
202
204
  const canvasContext = getCanvasContext();
203
- const renderContext = canvasContext ? 'canvas' : 'svg';
204
205
 
205
206
  function render(
206
207
  ctx: CanvasRenderingContext2D,
@@ -12,13 +12,13 @@
12
12
 
13
13
  import { motionStore } from '../stores/motionStore.js';
14
14
 
15
+ import { getRenderContext } from './Chart.svelte';
15
16
  import { chartContext } from './ChartContext.svelte';
16
17
  import Spline from './Spline.svelte';
17
18
  import { accessor, type Accessor } from '../utils/common.js';
18
19
  import { isScaleBand } from '../utils/scales.js';
19
20
  import { getCanvasContext } from './layout/Canvas.svelte';
20
21
  import { renderPathData, type ComputedStylesOptions } from '../utils/canvas.js';
21
-
22
22
  const {
23
23
  data: contextData,
24
24
  xScale,
@@ -143,8 +143,8 @@
143
143
  tweened_d.set(d ?? '');
144
144
  }
145
145
 
146
+ const renderContext = getRenderContext();
146
147
  const canvasContext = getCanvasContext();
147
- const renderContext = canvasContext ? 'canvas' : 'svg';
148
148
 
149
149
  function render(
150
150
  ctx: CanvasRenderingContext2D,
@@ -5,11 +5,12 @@
5
5
  import Rect from './Rect.svelte';
6
6
  import Spline from './Spline.svelte';
7
7
 
8
+ import { getRenderContext } from './Chart.svelte';
9
+ import { getCanvasContext } from './layout/Canvas.svelte';
8
10
  import { createDimensionGetter, type Insets } from '../utils/rect.js';
9
11
  import { isScaleBand } from '../utils/scales.js';
10
12
  import { accessor, type Accessor } from '../utils/common.js';
11
13
  import { greatestAbs } from '@layerstack/utils';
12
- import { getCanvasContext } from './layout/Canvas.svelte';
13
14
 
14
15
  const { x: xContext, y: yContext, xScale } = chartContext();
15
16
 
@@ -113,8 +114,8 @@
113
114
  .split('\n')
114
115
  .join('');
115
116
 
117
+ const renderContext = getRenderContext();
116
118
  const canvasContext = getCanvasContext();
117
- const renderContext = canvasContext ? 'canvas' : 'svg';
118
119
  </script>
119
120
 
120
121
  {#if _rounded === 'all' || _rounded === 'none' || radius === 0}
@@ -42,13 +42,12 @@
42
42
 
43
43
  <script lang="ts">
44
44
  import { extent, min, max } from 'd3-array';
45
- import { clamp } from '@layerstack/utils';
45
+ import { clamp, localPoint } from '@layerstack/utils';
46
46
  import { cls } from '@layerstack/tailwind';
47
47
  import { Logger } from '@layerstack/utils';
48
48
 
49
49
  import { chartContext } from './ChartContext.svelte';
50
50
 
51
- import { localPoint } from '../utils/event.js';
52
51
  import type { DomainType } from '../utils/scales.js';
53
52
  import { add } from '../utils/math.js';
54
53
  import type { HTMLAttributes } from 'svelte/elements';
@@ -143,7 +142,7 @@
143
142
  logger.debug('drag start');
144
143
  e.stopPropagation();
145
144
 
146
- const startPoint = localPoint(rootEl, e);
145
+ const startPoint = localPoint(e, rootEl);
147
146
 
148
147
  if (
149
148
  startPoint &&
@@ -165,7 +164,7 @@
165
164
  onbrushstart({ xDomain, yDomain });
166
165
 
167
166
  const onPointerMove = (e: PointerEvent) => {
168
- const currentPoint = localPoint(rootEl, e);
167
+ const currentPoint = localPoint(e, rootEl);
169
168
  fn(start, {
170
169
  x: $xScale.invert?.(currentPoint?.x ?? 0),
171
170
  y: $yScale.invert?.(currentPoint?.y ?? 0),
@@ -175,7 +174,7 @@
175
174
  };
176
175
 
177
176
  const onPointerUp = (e: PointerEvent) => {
178
- const currentPoint = localPoint(rootEl, e);
177
+ const currentPoint = localPoint(e, rootEl);
179
178
  const xPointDelta = Math.abs((startPoint?.x ?? 0) - (currentPoint?.x ?? 0));
180
179
  const yPointDelta = Math.abs((startPoint?.y ?? 0) - (currentPoint?.y ?? 0));
181
180
 
@@ -1,3 +1,21 @@
1
+ <script lang="ts" context="module">
2
+ import { getContext, setContext } from 'svelte';
3
+
4
+ export const renderContextKey = Symbol();
5
+
6
+ type RenderContext = 'canvas' | 'svg' | 'html';
7
+
8
+ /** Get render context. Useful to conditionally render components based on the render context. */
9
+ export function getRenderContext() {
10
+ return getContext<RenderContext>(renderContextKey);
11
+ }
12
+
13
+ /** Set by Canavs, Html, or Svg render/layout component */
14
+ export function setRenderContext(context: RenderContext) {
15
+ setContext(renderContextKey, context);
16
+ }
17
+ </script>
18
+
1
19
  <script lang="ts" generics="TData">
2
20
  import { onMount, type ComponentProps } from 'svelte';
3
21
  import { LayerCake } from 'layercake';
@@ -1,4 +1,10 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
+ export declare const renderContextKey: unique symbol;
3
+ type RenderContext = 'canvas' | 'svg' | 'html';
4
+ /** Get render context. Useful to conditionally render components based on the render context. */
5
+ export declare function getRenderContext(): RenderContext;
6
+ /** Set by Canavs, Html, or Svg render/layout component */
7
+ export declare function setRenderContext(context: RenderContext): void;
2
8
  import type { HierarchyNode } from 'd3-hierarchy';
3
9
  import type { SankeyGraph } from 'd3-sankey';
4
10
  import TransformContext from './TransformContext.svelte';
@@ -216,10 +222,10 @@ declare class __sveltets_Render<TData> {
216
222
  }> | undefined;
217
223
  /** Props passed to TransformContext */
218
224
  transform?: Partial<{
219
- mode?: "canvas" | "manual" | "none";
225
+ mode?: "none" | "canvas" | "manual";
220
226
  translateOnScale?: boolean;
221
227
  spring?: boolean | Parameters<typeof import("../stores/motionStore").motionStore>[1]["spring"];
222
- tweened?: boolean | Parameters<typeof import("../stores/motionStore").motionStore>[1]["tweened"];
228
+ tweened?: boolean | Parameters<typeof import("../stores/motionStore").motionStore>[1] /** Override the default r range of `[1, 25]` by setting an array or function with argument `({ width, height})` that returns an array. Setting this prop overrides `rReverse`. This can also be a list of numbers or strings for scales with discrete ranges like [scaleThreshold](https://github.com/d3/d3-scale#threshold-scales) or [scaleQuantize](https://github.com/d3/d3-scale#quantize-scales). */["tweened"];
223
229
  processTranslate?: (x: number, y: number, deltaX: number, deltaY: number, scale: number) => {
224
230
  x: number;
225
231
  y: number;
@@ -296,7 +302,9 @@ declare class __sveltets_Render<TData> {
296
302
  }) => void;
297
303
  onbrushstart?: (detail: {
298
304
  xDomain?: DomainType;
299
- yDomain?: DomainType;
305
+ yDomain
306
+ /** Exposed via bind: to support `bind:brushContext` for external access (ex. `brushContext.xDomain) */
307
+ ?: DomainType;
300
308
  }) => void;
301
309
  onbrushend?: (detail: {
302
310
  xDomain?: DomainType;
@@ -5,6 +5,7 @@
5
5
  import { objectId } from '@layerstack/utils/object';
6
6
  import { merge } from 'lodash-es';
7
7
 
8
+ import { getRenderContext } from './Chart.svelte';
8
9
  import { motionStore } from '../stores/motionStore.js';
9
10
  import { getCanvasContext } from './layout/Canvas.svelte';
10
11
  import { renderCircle, type ComputedStylesOptions } from '../utils/canvas.js';
@@ -45,8 +46,8 @@
45
46
  tweened_r.set(r);
46
47
  });
47
48
 
49
+ const renderContext = getRenderContext();
48
50
  const canvasContext = getCanvasContext();
49
- const renderContext = canvasContext ? 'canvas' : 'svg';
50
51
 
51
52
  function render(
52
53
  ctx: CanvasRenderingContext2D,
@@ -10,12 +10,13 @@
10
10
  import { cls } from '@layerstack/tailwind';
11
11
  import { merge } from 'lodash-es';
12
12
 
13
+ import { getRenderContext } from './Chart.svelte';
14
+ import { getCanvasContext } from './layout/Canvas.svelte';
13
15
  import { geoContext } from './GeoContext.svelte';
14
16
  import type { TooltipContextValue } from './tooltip/TooltipContext.svelte';
15
17
  import { curveLinearClosed, type CurveFactory, type CurveFactoryLineOnly } from 'd3-shape';
16
18
  import { geoCurvePath } from '../utils/geo.js';
17
19
  import { renderPathData, type ComputedStylesOptions } from '../utils/canvas.js';
18
- import { getCanvasContext } from './layout/Canvas.svelte';
19
20
  import { objectId } from '@layerstack/utils/object';
20
21
 
21
22
  export let geojson: GeoPermissibleObjects | null | undefined = undefined;
@@ -71,8 +72,8 @@
71
72
  geoPath = geoCurvePath(_projection, curve);
72
73
  }
73
74
 
75
+ const renderContext = getRenderContext();
74
76
  const canvasContext = getCanvasContext();
75
- const renderContext = canvasContext ? 'canvas' : 'svg';
76
77
 
77
78
  function render(
78
79
  ctx: CanvasRenderingContext2D,
@@ -5,6 +5,7 @@
5
5
  import Circle from './Circle.svelte';
6
6
  import Group from './Group.svelte';
7
7
  import { getCanvasContext } from './layout/Canvas.svelte';
8
+ import { getRenderContext } from './Chart.svelte';
8
9
 
9
10
  /** Latitude */
10
11
  export let lat: number;
@@ -15,8 +16,8 @@
15
16
 
16
17
  $: [x, y] = $geo([long, lat]) ?? [0, 0];
17
18
 
19
+ const renderContext = getRenderContext();
18
20
  const canvasContext = getCanvasContext();
19
- const renderContext = canvasContext ? 'canvas' : 'svg';
20
21
  </script>
21
22
 
22
23
  {#if renderContext === 'svg'}
@@ -3,11 +3,12 @@
3
3
  // @ts-expect-error
4
4
  import { tile as d3Tile } from 'd3-tile';
5
5
 
6
+ import { getRenderContext } from './Chart.svelte';
6
7
  import { chartContext } from './ChartContext.svelte';
8
+ import { getCanvasContext } from './layout/Canvas.svelte';
7
9
  import { geoContext } from './GeoContext.svelte';
8
10
  import Group from './Group.svelte';
9
11
  import TileImage from './TileImage.svelte';
10
- import { getCanvasContext } from './layout/Canvas.svelte';
11
12
 
12
13
  export let url: (x: number, y: number, z: number) => string;
13
14
  export let zoomDelta = 0;
@@ -33,8 +34,8 @@
33
34
  scale,
34
35
  } = tiles);
35
36
 
37
+ const renderContext = getRenderContext();
36
38
  const canvasContext = getCanvasContext();
37
- const renderContext = canvasContext ? 'canvas' : 'svg';
38
39
 
39
40
  function render(ctx: CanvasRenderingContext2D) {
40
41
  tiles.forEach(([x, y, z]: number[]) => {
@@ -1,11 +1,12 @@
1
1
  <script lang="ts">
2
2
  import { onDestroy, tick } from 'svelte';
3
3
  import type { spring as springStore, tweened as tweenedStore } from 'svelte/motion';
4
+ import { cls } from '@layerstack/tailwind';
4
5
 
6
+ import { getRenderContext } from './Chart.svelte';
5
7
  import { chartContext } from './ChartContext.svelte';
6
8
  import { motionStore } from '../stores/motionStore.js';
7
9
  import { getCanvasContext } from './layout/Canvas.svelte';
8
-
9
10
  const { width, height } = chartContext();
10
11
 
11
12
  /**
@@ -50,11 +51,11 @@
50
51
 
51
52
  let transform: string | undefined = undefined;
52
53
  $: if (center || x != null || y != null) {
53
- transform = `translate(${$tweened_x ?? 0}, ${$tweened_y ?? 0})`;
54
+ transform = `translate(${$tweened_x ?? 0}px, ${$tweened_y ?? 0}px)`;
54
55
  }
55
56
 
57
+ const renderContext = getRenderContext();
56
58
  const canvasContext = getCanvasContext();
57
- const renderContext = canvasContext ? 'canvas' : 'svg';
58
59
 
59
60
  function render(ctx: CanvasRenderingContext2D) {
60
61
  ctx.translate($tweened_x ?? 0, $tweened_y ?? 0);
@@ -92,9 +93,9 @@
92
93
  {#if renderContext === 'canvas'}
93
94
  <slot />
94
95
  {:else if renderContext === 'svg'}
95
- <!-- svelte-ignore a11y-no-static-element-interactions -->
96
+ <!-- TODO: Find out why `<svelte:element this={renderContext === 'html' ? 'div' : 'g'}>` doesn't work for the SVG use case -->
96
97
  <g
97
- {transform}
98
+ style:transform
98
99
  {...$$restProps}
99
100
  on:click={onclick}
100
101
  on:dblclick={ondblclick}
@@ -111,4 +112,24 @@
111
112
  >
112
113
  <slot />
113
114
  </g>
115
+ {:else}
116
+ <div
117
+ style:transform
118
+ {...$$restProps}
119
+ class={cls('absolute', $$restProps.class)}
120
+ on:click={onclick}
121
+ on:dblclick={ondblclick}
122
+ on:pointerenter={onpointerenter}
123
+ on:pointermove={onpointermove}
124
+ on:pointerleave={onpointerleave}
125
+ on:pointerdown={onpointerdown}
126
+ on:touchmove={(e) => {
127
+ if (preventTouchMove) {
128
+ // Prevent touch to not interfer with pointer
129
+ e.preventDefault();
130
+ }
131
+ }}
132
+ >
133
+ <slot />
134
+ </div>
114
135
  {/if}
@@ -12,7 +12,7 @@ declare const __propDef: {
12
12
  tickValues?: any[] | undefined | undefined;
13
13
  tickFontSize?: number | undefined;
14
14
  tickLength?: number | undefined;
15
- placement?: ("center" | "bottom" | "left" | "right" | "top" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
15
+ placement?: ("bottom" | "left" | "right" | "top" | "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
16
16
  orientation?: "horizontal" | "vertical" | undefined;
17
17
  onclick?: ((e: MouseEvent, detail: any) => any) | undefined | undefined;
18
18
  onpointerenter?: ((e: MouseEvent, detail: any) => any) | undefined | undefined;
@@ -11,6 +11,7 @@
11
11
  import Marker from './Marker.svelte';
12
12
  import { renderPathData, type ComputedStylesOptions } from '../utils/canvas.js';
13
13
  import { getCanvasContext } from './layout/Canvas.svelte';
14
+ import { getRenderContext } from './Chart.svelte';
14
15
 
15
16
  export let x1: number;
16
17
  export let initialX1 = x1;
@@ -64,8 +65,8 @@
64
65
  tweened_y2.set(y2);
65
66
  });
66
67
 
68
+ const renderContext = getRenderContext();
67
69
  const canvasContext = getCanvasContext();
68
- const renderContext = canvasContext ? 'canvas' : 'svg';
69
70
 
70
71
  function render(
71
72
  ctx: CanvasRenderingContext2D,
@@ -2,6 +2,7 @@
2
2
  import { onDestroy } from 'svelte';
3
3
  import { uniqueId } from '@layerstack/utils';
4
4
 
5
+ import { getRenderContext } from './Chart.svelte';
5
6
  import { chartContext } from './ChartContext.svelte';
6
7
  import { getCanvasContext } from './layout/Canvas.svelte';
7
8
  import { createLinearGradient, getComputedStyles } from '../utils/canvas.js';
@@ -30,8 +31,8 @@
30
31
 
31
32
  const { width, height, padding } = chartContext();
32
33
 
34
+ const renderContext = getRenderContext();
33
35
  const canvasContext = getCanvasContext();
34
- const renderContext = canvasContext ? 'canvas' : 'svg';
35
36
 
36
37
  let canvasGradient: CanvasGradient;
37
38
 
@@ -2,6 +2,7 @@
2
2
  import { onDestroy } from 'svelte';
3
3
  import { uniqueId } from '@layerstack/utils';
4
4
 
5
+ import { getRenderContext } from './Chart.svelte';
5
6
  import { chartContext } from './ChartContext.svelte';
6
7
  import { getCanvasContext } from './layout/Canvas.svelte';
7
8
  import { getComputedStyles } from '../utils/canvas.js';
@@ -34,8 +35,8 @@
34
35
 
35
36
  const { width, height, padding } = chartContext();
36
37
 
38
+ const renderContext = getRenderContext();
37
39
  const canvasContext = getCanvasContext();
38
- const renderContext = canvasContext ? 'canvas' : 'svg';
39
40
 
40
41
  let canvasGradient: CanvasGradient;
41
42
 
@@ -11,6 +11,7 @@
11
11
  type SpringOptions,
12
12
  type TweenedOptions,
13
13
  } from '../stores/motionStore.js';
14
+ import { getRenderContext } from './Chart.svelte';
14
15
  import { getCanvasContext } from './layout/Canvas.svelte';
15
16
  import { renderRect, type ComputedStylesOptions } from '../utils/canvas.js';
16
17
 
@@ -60,8 +61,8 @@
60
61
  tweened_height.set(height);
61
62
  });
62
63
 
64
+ const renderContext = getRenderContext();
63
65
  const canvasContext = getCanvasContext();
64
- const renderContext = canvasContext ? 'canvas' : 'svg';
65
66
 
66
67
  function render(
67
68
  ctx: CanvasRenderingContext2D,
@@ -25,6 +25,7 @@
25
25
  import { flattenPathData } from '../utils/path.js';
26
26
  import { getCanvasContext } from './layout/Canvas.svelte';
27
27
  import { renderPathData, type ComputedStylesOptions } from '../utils/canvas.js';
28
+ import { getRenderContext } from './Chart.svelte';
28
29
 
29
30
  const {
30
31
  data: contextData,
@@ -174,8 +175,8 @@
174
175
  key = Symbol();
175
176
  }
176
177
 
178
+ const renderContext = getRenderContext();
177
179
  const canvasContext = getCanvasContext();
178
- const renderContext = canvasContext ? 'canvas' : 'svg';
179
180
 
180
181
  function render(
181
182
  ctx: CanvasRenderingContext2D,
@@ -5,9 +5,10 @@
5
5
  import { objectId } from '@layerstack/utils/object';
6
6
  import { merge } from 'lodash-es';
7
7
 
8
+ import { getRenderContext } from './Chart.svelte';
9
+ import { getCanvasContext } from './layout/Canvas.svelte';
8
10
  import { getStringWidth } from '../utils/string.js';
9
11
  import { motionStore } from '../stores/motionStore.js';
10
- import { getCanvasContext } from './layout/Canvas.svelte';
11
12
  import { renderText, type ComputedStylesOptions } from '../utils/canvas.js';
12
13
 
13
14
  /*
@@ -180,8 +181,8 @@
180
181
  tweened_y.set(y);
181
182
  });
182
183
 
184
+ const renderContext = getRenderContext();
183
185
  const canvasContext = getCanvasContext();
184
- const renderContext = canvasContext ? 'canvas' : 'svg';
185
186
 
186
187
  function render(
187
188
  ctx: CanvasRenderingContext2D,
@@ -56,6 +56,7 @@
56
56
  <script lang="ts">
57
57
  import { chartContext } from './ChartContext.svelte';
58
58
  import { motionStore, type MotionOptions, motionFinishHandler } from '../stores/motionStore.js';
59
+ import { localPoint } from '@layerstack/utils';
59
60
 
60
61
  const { width, height } = chartContext();
61
62
 
@@ -162,7 +163,7 @@
162
163
  ondragstart?.();
163
164
  }
164
165
 
165
- function onPointerMove(e: PointerEvent) {
166
+ function onPointerMove(e: PointerEvent & { currentTarget: HTMLDivElement }) {
166
167
  if (!pointerDown) return;
167
168
 
168
169
  e.preventDefault(); // Stop text selection
@@ -178,7 +179,6 @@
178
179
 
179
180
  if ($dragging) {
180
181
  e.stopPropagation(); // Stop tooltip from trigging (along with `capture: true`)
181
- // @ts-expect-error
182
182
  e.currentTarget?.setPointerCapture(e.pointerId);
183
183
 
184
184
  setTranslate(
@@ -281,13 +281,6 @@
281
281
  scaling.handle(scale.set(value, options));
282
282
  }
283
283
 
284
- function localPoint(e: PointerEvent | MouseEvent | WheelEvent) {
285
- return {
286
- x: e.offsetX,
287
- y: e.offsetY,
288
- };
289
- }
290
-
291
284
  $: center = { x: $width / 2, y: $height / 2 };
292
285
 
293
286
  $: viewportCenter = {
@@ -2,10 +2,10 @@ import { SvelteComponentTyped } from "svelte";
2
2
  declare const __propDef: {
3
3
  props: {
4
4
  [x: string]: any;
5
- placement?: ("center" | "bottom" | "left" | "right" | "top" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
5
+ placement?: ("bottom" | "left" | "right" | "top" | "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
6
6
  orientation?: "horizontal" | "vertical" | undefined;
7
7
  size?: import("svelte-ux").ButtonSize | undefined;
8
- show?: ("reset" | "scrollMode" | "zoomIn" | "zoomOut" | "center")[] | undefined;
8
+ show?: ("center" | "reset" | "scrollMode" | "zoomIn" | "zoomOut")[] | undefined;
9
9
  };
10
10
  events: {
11
11
  [evt: string]: CustomEvent<any>;
@@ -150,7 +150,7 @@ declare class __sveltets_Render<TData> {
150
150
  mode: "manual" | "bisect-x" | "bisect-y" | "band" | "bisect-band" | "bounds" | "voronoi" | "quadtree";
151
151
  }> | undefined;
152
152
  transform?: Partial<{
153
- mode?: "canvas" | "manual" | "none";
153
+ mode?: "none" | "canvas" | "manual";
154
154
  translateOnScale?: boolean;
155
155
  spring?: boolean | Parameters<typeof import("../../stores/motionStore").motionStore>[1]["spring"];
156
156
  tweened?: boolean | Parameters<typeof import("../../stores/motionStore").motionStore>[1]["tweened"];
@@ -267,7 +267,7 @@ declare class __sveltets_Render<TData> {
267
267
  tickValues?: any[] | undefined | undefined;
268
268
  tickFontSize?: number | undefined;
269
269
  tickLength?: number | undefined;
270
- placement?: ("center" | "bottom" | "left" | "right" | "top" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
270
+ placement?: ("bottom" | "left" | "right" | "top" | "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
271
271
  orientation?: "horizontal" | "vertical" | undefined;
272
272
  onclick?: ((e: MouseEvent, detail: any) => any) | undefined | undefined;
273
273
  onpointerenter?: ((e: MouseEvent, detail: any) => any) | undefined | undefined;
@@ -287,7 +287,7 @@ declare class __sveltets_Render<TData> {
287
287
  outerRadius?: number | undefined;
288
288
  padAngle?: number;
289
289
  center?: boolean;
290
- placement?: "center" | "left" | "right";
290
+ placement?: "left" | "right" | "center";
291
291
  profile?: boolean;
292
292
  debug?: boolean;
293
293
  props?: {
@@ -317,7 +317,7 @@ declare class __sveltets_Render<TData> {
317
317
  props?: Partial<ComponentProps<Arc>>;
318
318
  }[] | undefined;
319
319
  value?: Accessor<TData>;
320
- renderContext?: "canvas" | "svg";
320
+ renderContext?: "svg" | "canvas";
321
321
  onarcclick?: ((e: MouseEvent, detail: {
322
322
  data: any;
323
323
  series: {
@@ -1,4 +1,4 @@
1
- export { Html, WebGL } from 'layercake';
1
+ export { WebGL } from 'layercake';
2
2
  export * from './charts/index.js';
3
3
  export { default as Arc } from './Arc.svelte';
4
4
  export { default as Area } from './Area.svelte';
@@ -31,6 +31,7 @@ export { default as Graticule } from './Graticule.svelte';
31
31
  export { default as Grid } from './Grid.svelte';
32
32
  export { default as Group } from './Group.svelte';
33
33
  export { default as Highlight } from './Highlight.svelte';
34
+ export { default as Html } from './layout/Html.svelte';
34
35
  export { default as Hull } from './Hull.svelte';
35
36
  export { default as Labels } from './Labels.svelte';
36
37
  export { default as Legend } from './Legend.svelte';
@@ -1,5 +1,5 @@
1
1
  // Re-export for easy access (Svg and Canvas are provided by LayerChart)
2
- export { Html, WebGL } from 'layercake';
2
+ export { WebGL } from 'layercake';
3
3
  export * from './charts/index.js';
4
4
  export { default as Arc } from './Arc.svelte';
5
5
  export { default as Area } from './Area.svelte';
@@ -32,6 +32,7 @@ export { default as Graticule } from './Graticule.svelte';
32
32
  export { default as Grid } from './Grid.svelte';
33
33
  export { default as Group } from './Group.svelte';
34
34
  export { default as Highlight } from './Highlight.svelte';
35
+ export { default as Html } from './layout/Html.svelte';
35
36
  export { default as Hull } from './Hull.svelte';
36
37
  export { default as Labels } from './Labels.svelte';
37
38
  export { default as Legend } from './Legend.svelte';
@@ -1,5 +1,5 @@
1
1
  <script lang="ts" context="module">
2
- import { getContext, onDestroy, setContext } from 'svelte';
2
+ import { getContext, setContext } from 'svelte';
3
3
 
4
4
  type ComponentRender = {
5
5
  name: string;
@@ -36,17 +36,15 @@
36
36
  </script>
37
37
 
38
38
  <script lang="ts">
39
- import { onMount } from 'svelte';
39
+ import { onMount, onDestroy } from 'svelte';
40
40
  import { cls } from '@layerstack/tailwind';
41
- import { Logger } from '@layerstack/utils';
41
+ import { Logger, localPoint } from '@layerstack/utils';
42
42
 
43
+ import { setRenderContext } from '../Chart.svelte';
43
44
  import { chartContext } from '../ChartContext.svelte';
44
45
  import { transformContext } from '../TransformContext.svelte';
45
46
  import { getPixelColor, scaleCanvas, type ComputedStylesOptions } from '../../utils/canvas.js';
46
47
  import { getColorStr, rgbColorGenerator } from '../../utils/color.js';
47
- import { localPoint } from '../../utils/event.js';
48
- import { tooltipContext } from '../tooltip/TooltipContext.svelte';
49
-
50
48
  const { width, height, containerWidth, containerHeight, padding } = chartContext();
51
49
 
52
50
  /** The `<canvas>` tag. Useful for bindings. */
@@ -93,7 +91,6 @@
93
91
  let frameId: number | undefined;
94
92
 
95
93
  const { mode, scale, translate, dragging, moving } = transformContext();
96
- const tooltip = tooltipContext();
97
94
 
98
95
  /**
99
96
  * HitCanvas
@@ -106,7 +103,7 @@
106
103
  const componentByColor = new Map<string, ComponentRender>();
107
104
 
108
105
  function getPointerComponent(e: PointerEvent | MouseEvent | TouchEvent) {
109
- const { x, y } = localPoint(e.target as HTMLCanvasElement, e) ?? { x: 0, y: 0 };
106
+ const { x, y } = localPoint(e);
110
107
  const color = getPixelColor(hitCanvasContext!, x, y);
111
108
  const colorKey = getColorStr(color);
112
109
  const component = componentByColor.get(colorKey);
@@ -260,6 +257,7 @@
260
257
  }
261
258
 
262
259
  setCanvasContext(canvasContext);
260
+ setRenderContext('canvas');
263
261
  </script>
264
262
 
265
263
  <canvas
@@ -1,6 +1,9 @@
1
1
  <script lang="ts">
2
2
  import { cls } from '@layerstack/tailwind';
3
+
4
+ import { setRenderContext } from '../Chart.svelte';
3
5
  import { chartContext } from '../ChartContext.svelte';
6
+ import { transformContext } from '../TransformContext.svelte';
4
7
 
5
8
  /** The layer's outermost `<div>` tag. Useful for bindings. */
6
9
  export let element: HTMLDivElement | undefined = undefined;
@@ -23,9 +26,29 @@
23
26
  /** A string passed to the `aria-describedby` property on the `<div>` tag. */
24
27
  export let describedBy: string | undefined = undefined;
25
28
 
26
- const { padding } = chartContext();
29
+ /**
30
+ * Translate children to center (useful for radial layouts)
31
+ */
32
+ export let center: boolean | 'x' | 'y' = false;
27
33
 
28
34
  $: roleVal = role || (label || labelledBy || describedBy ? 'figure' : undefined);
35
+
36
+ const { width, height, padding } = chartContext();
37
+ const { mode, scale, translate } = transformContext();
38
+
39
+ $: transform = center
40
+ ? `translate(${center === 'x' || center === true ? $width / 2 : 0}, ${center === 'y' || center === true ? $height / 2 : 0})`
41
+ : '';
42
+ $: if (mode === 'canvas') {
43
+ const center = { x: $width / 2, y: $height / 2 };
44
+ const newTranslate = {
45
+ x: $translate.x * $scale + center.x - center.x * $scale,
46
+ y: $translate.y * $scale + center.y - center.y * $scale,
47
+ };
48
+ transform = `translate(${newTranslate.x}px,${newTranslate.y}px) scale(${$scale})`;
49
+ }
50
+
51
+ setRenderContext('html');
29
52
  </script>
30
53
 
31
54
  <div
@@ -36,6 +59,8 @@
36
59
  pointerEvents === false && 'pointer-events-none',
37
60
  $$props.class
38
61
  )}
62
+ style:transform
63
+ style:transform-origin="top left"
39
64
  style:z-index={zIndex}
40
65
  style:pointer-events={pointerEvents === false ? 'none' : null}
41
66
  style:top="{$padding.top}px"
@@ -9,6 +9,7 @@ declare const __propDef: {
9
9
  label?: string | undefined | undefined;
10
10
  labelledBy?: string | undefined | undefined;
11
11
  describedBy?: string | undefined | undefined;
12
+ center?: boolean | "x" | "y" | undefined;
12
13
  };
13
14
  events: {
14
15
  [evt: string]: CustomEvent<any>;
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { cls } from '@layerstack/tailwind';
3
3
 
4
+ import { setRenderContext } from '../Chart.svelte';
4
5
  import { chartContext } from '../ChartContext.svelte';
5
6
  import { transformContext } from '../TransformContext.svelte';
6
7
 
@@ -37,7 +38,6 @@
37
38
  export let center: boolean | 'x' | 'y' = false;
38
39
 
39
40
  const { containerWidth, containerHeight, width, height, padding } = chartContext();
40
-
41
41
  const { mode, scale, translate } = transformContext();
42
42
 
43
43
  $: transform = center
@@ -51,6 +51,8 @@
51
51
  };
52
52
  transform = `translate(${newTranslate.x},${newTranslate.y}) scale(${$scale})`;
53
53
  }
54
+
55
+ setRenderContext('svg');
54
56
  </script>
55
57
 
56
58
  <!-- svelte-ignore a11y-click-events-have-key-events -->
@@ -6,7 +6,7 @@ declare const __propDef: {
6
6
  y?: "pointer" | "data" | number | undefined;
7
7
  xOffset?: number | undefined;
8
8
  yOffset?: number | undefined;
9
- anchor?: ("center" | "bottom" | "left" | "right" | "top" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
9
+ anchor?: ("bottom" | "left" | "right" | "top" | "center" | "top-left" | "top-right" | "bottom-left" | "bottom-right") | undefined;
10
10
  contained?: "container" | "window" | false | undefined;
11
11
  variant?: "default" | "invert" | "none" | undefined;
12
12
  motion?: boolean | undefined;
@@ -47,7 +47,7 @@
47
47
  import { writable } from 'svelte/store';
48
48
  import { bisector, max, min } from 'd3-array';
49
49
  import { quadtree as d3Quadtree, type Quadtree } from 'd3-quadtree';
50
- import { sortFunc } from '@layerstack/utils';
50
+ import { sortFunc, localPoint } from '@layerstack/utils';
51
51
  import { cls } from '@layerstack/tailwind';
52
52
 
53
53
  import Svg from './../layout/Svg.svelte';
@@ -55,7 +55,6 @@
55
55
  import ChartClipPath from './../ChartClipPath.svelte';
56
56
  import Voronoi from './../Voronoi.svelte';
57
57
 
58
- import { localPoint } from '../../utils/event.js';
59
58
  import { isScaleBand, scaleInvert } from '../../utils/scales.js';
60
59
  import { cartesianToPolar } from '../../utils/math.js';
61
60
  import { quadtreeRects } from '../../utils/quadtree.js';
@@ -189,7 +188,7 @@
189
188
  }
190
189
 
191
190
  const referenceNode = (e.target as Element).closest('.layercake-container')!;
192
- const point = localPoint(referenceNode, e);
191
+ const point = localPoint(e, referenceNode);
193
192
  const pointerX = point?.x ?? 0;
194
193
  const pointerY = point?.y ?? 0;
195
194
 
package/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "author": "Sean Lynch <techniq35@gmail.com>",
5
5
  "license": "MIT",
6
6
  "repository": "techniq/layerchart",
7
- "version": "0.96.0",
7
+ "version": "0.97.1",
8
8
  "devDependencies": {
9
9
  "@changesets/cli": "^2.27.12",
10
10
  "@mdi/js": "^7.4.47",
@@ -41,7 +41,7 @@
41
41
  "autoprefixer": "^10.4.20",
42
42
  "marked": "^15.0.7",
43
43
  "mdsvex": "^0.12.3",
44
- "posthog-js": "^1.217.0",
44
+ "posthog-js": "^1.217.2",
45
45
  "prettier": "^3.5.0",
46
46
  "prettier-plugin-svelte": "^3.3.3",
47
47
  "prism-svelte": "^0.5.0",
@@ -50,7 +50,7 @@
50
50
  "rehype-slug": "^6.0.0",
51
51
  "shapefile": "^0.6.6",
52
52
  "solar-calculator": "^0.3.0",
53
- "svelte": "5.19.10",
53
+ "svelte": "5.20.0",
54
54
  "svelte-check": "^4.1.4",
55
55
  "svelte-json-tree": "^2.2.0",
56
56
  "svelte-ux": "^0.90.1",
@@ -68,10 +68,10 @@
68
68
  "type": "module",
69
69
  "dependencies": {
70
70
  "@dagrejs/dagre": "^1.1.4",
71
- "@layerstack/svelte-actions": "^0.0.11",
72
- "@layerstack/svelte-stores": "^0.0.10",
73
- "@layerstack/tailwind": "^0.0.11",
74
- "@layerstack/utils": "^0.0.7",
71
+ "@layerstack/svelte-actions": "^0.0.12",
72
+ "@layerstack/svelte-stores": "^0.0.11",
73
+ "@layerstack/tailwind": "^0.0.12",
74
+ "@layerstack/utils": "^0.1.0",
75
75
  "d3-array": "^3.2.4",
76
76
  "d3-color": "^3.1.0",
77
77
  "d3-delaunay": "^6.0.4",
@@ -1,4 +0,0 @@
1
- export declare function localPoint(node: Element, event: MouseEvent | TouchEvent | PointerEvent): {
2
- x: number;
3
- y: number;
4
- } | null;
@@ -1,44 +0,0 @@
1
- import { isSVGElement, isSVGGraphicsElement, isSVGSVGElement, isTouchEvent, } from '@layerstack/utils';
2
- // See: https://github.com/airbnb/visx/blob/master/packages/visx-event/src/localPointGeneric.ts
3
- // TODO: Matches event.layerX/Y, but are deprecated (https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/layerX).
4
- // Similar and could be replaced by event.offsetX/Y (but not identical)
5
- export function localPoint(node, event) {
6
- if (!node || !event)
7
- return null;
8
- const coords = getPointFromEvent(event);
9
- // find top-most SVG
10
- const svg = isSVGElement(node) ? node.ownerSVGElement : node;
11
- const screenCTM = isSVGGraphicsElement(svg) ? svg.getScreenCTM() : null;
12
- if (isSVGSVGElement(svg) && screenCTM) {
13
- let point = svg.createSVGPoint();
14
- point.x = coords.x;
15
- point.y = coords.y;
16
- point = point.matrixTransform(screenCTM.inverse());
17
- return {
18
- x: point.x,
19
- y: point.y,
20
- };
21
- }
22
- // fall back to bounding box
23
- const rect = node.getBoundingClientRect();
24
- return {
25
- x: coords.x - rect.left - node.clientLeft,
26
- y: coords.y - rect.top - node.clientTop,
27
- };
28
- }
29
- function getPointFromEvent(event) {
30
- if (!event)
31
- return { x: 0, y: 0 };
32
- if (isTouchEvent(event)) {
33
- return event.changedTouches.length > 0
34
- ? {
35
- x: event.changedTouches[0].clientX,
36
- y: event.changedTouches[0].clientY,
37
- }
38
- : { x: 0, y: 0 };
39
- }
40
- return {
41
- x: event.clientX,
42
- y: event.clientY,
43
- };
44
- }