layerchart 0.36.4 → 0.37.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 (57) hide show
  1. package/dist/components/Arc.svelte +4 -2
  2. package/dist/components/Arc.svelte.d.ts +4 -2
  3. package/dist/components/Area.svelte +2 -2
  4. package/dist/components/Area.svelte.d.ts +2 -2
  5. package/dist/components/Axis.svelte +59 -10
  6. package/dist/components/Axis.svelte.d.ts +6 -3
  7. package/dist/components/Calendar.svelte +2 -2
  8. package/dist/components/Chart.svelte +74 -31
  9. package/dist/components/Chart.svelte.d.ts +33 -6
  10. package/dist/components/Circle.svelte +2 -2
  11. package/dist/components/Circle.svelte.d.ts +2 -2
  12. package/dist/components/ClipPath.svelte +1 -1
  13. package/dist/components/ClipPath.svelte.d.ts +2 -2
  14. package/dist/components/GeoCircle.svelte +1 -1
  15. package/dist/components/GeoCircle.svelte.d.ts +2 -2
  16. package/dist/components/GeoContext.svelte +31 -7
  17. package/dist/components/GeoContext.svelte.d.ts +2 -0
  18. package/dist/components/GeoPath.svelte +12 -10
  19. package/dist/components/GeoPath.svelte.d.ts +6 -7
  20. package/dist/components/GeoPoint.svelte +1 -3
  21. package/dist/components/GeoTile.svelte +1 -3
  22. package/dist/components/Group.svelte +18 -1
  23. package/dist/components/Group.svelte.d.ts +4 -2
  24. package/dist/components/HitCanvas.svelte +86 -0
  25. package/dist/components/HitCanvas.svelte.d.ts +32 -0
  26. package/dist/components/Hull.svelte +4 -4
  27. package/dist/components/Hull.svelte.d.ts +3 -3
  28. package/dist/components/Line.svelte +2 -2
  29. package/dist/components/Line.svelte.d.ts +2 -2
  30. package/dist/components/Link.svelte +4 -4
  31. package/dist/components/Link.svelte.d.ts +4 -4
  32. package/dist/components/Pie.svelte +9 -2
  33. package/dist/components/Rect.svelte +4 -4
  34. package/dist/components/Rect.svelte.d.ts +10 -10
  35. package/dist/components/Sankey.svelte +1 -1
  36. package/dist/components/Spline.svelte +2 -2
  37. package/dist/components/Spline.svelte.d.ts +2 -2
  38. package/dist/components/TooltipContext.svelte +21 -18
  39. package/dist/components/TooltipContext.svelte.d.ts +4 -4
  40. package/dist/components/{Transform.svelte → TransformContext.svelte} +87 -76
  41. package/dist/components/TransformContext.svelte.d.ts +111 -0
  42. package/dist/components/Voronoi.svelte +13 -5
  43. package/dist/components/Voronoi.svelte.d.ts +3 -3
  44. package/dist/components/index.d.ts +1 -1
  45. package/dist/components/index.js +1 -1
  46. package/dist/components/layout/Canvas.svelte +78 -0
  47. package/dist/components/layout/Canvas.svelte.d.ts +37 -0
  48. package/dist/components/layout/Svg.svelte +68 -0
  49. package/dist/components/layout/Svg.svelte.d.ts +32 -0
  50. package/dist/docs/PathDataMenuField.svelte +10 -10
  51. package/dist/docs/TransformControls.svelte +4 -2
  52. package/dist/docs/TransformControls.svelte.d.ts +1 -2
  53. package/dist/docs/TransformDebug.svelte +21 -0
  54. package/dist/docs/TransformDebug.svelte.d.ts +16 -0
  55. package/dist/utils/event.d.ts +1 -1
  56. package/package.json +23 -24
  57. package/dist/components/Transform.svelte.d.ts +0 -76
@@ -159,8 +159,10 @@ $: yOffset = -Math.cos(angle) * offset;
159
159
  transform="translate({xOffset}, {yOffset})"
160
160
  {...$$restProps}
161
161
  on:click
162
- on:mousemove
163
- on:mouseleave
162
+ on:pointerenter
163
+ on:pointermove
164
+ on:pointerleave
165
+ on:touchmove
164
166
  />
165
167
 
166
168
  <slot value={$tweened_value} centroid={trackArcCentroid} {boundingBox} />
@@ -21,8 +21,10 @@ declare const __propDef: {
21
21
  };
22
22
  events: {
23
23
  click: MouseEvent;
24
- mousemove: MouseEvent;
25
- mouseleave: MouseEvent;
24
+ pointerenter: PointerEvent;
25
+ pointermove: PointerEvent;
26
+ pointerleave: PointerEvent;
27
+ touchmove: TouchEvent;
26
28
  } & {
27
29
  [evt: string]: CustomEvent<any>;
28
30
  };
@@ -56,6 +56,6 @@ $: {
56
56
  {...$$restProps}
57
57
  class={cls('path-area', $$props.class)}
58
58
  on:click
59
- on:mousemove
60
- on:mouseleave
59
+ on:pointermove
60
+ on:pointerleave
61
61
  />
@@ -30,8 +30,8 @@ declare const __propDef: {
30
30
  };
31
31
  events: {
32
32
  click: MouseEvent;
33
- mousemove: MouseEvent;
34
- mouseleave: MouseEvent;
33
+ pointermove: PointerEvent;
34
+ pointerleave: PointerEvent;
35
35
  } & {
36
36
  [evt: string]: CustomEvent<any>;
37
37
  };
@@ -8,9 +8,15 @@ import Circle from './Circle.svelte';
8
8
  import Line from './Line.svelte';
9
9
  import Text from './Text.svelte';
10
10
  import { isScaleBand } from '../utils/scales.js';
11
- const { xScale, yScale, xRange, yRange, width } = getContext('LayerCake');
11
+ const { xScale, yScale, xRange, yRange, width, height, padding } = getContext('LayerCake');
12
12
  /** Location of axis */
13
13
  export let placement;
14
+ /** Axis label */
15
+ export let label = '';
16
+ /** Location of axis label */
17
+ export let labelPlacement = 'middle';
18
+ /** Props applied label Text */
19
+ export let labelProps = undefined;
14
20
  /** Draw a rule line. Use Rule component for greater rendering order control */
15
21
  export let rule = false;
16
22
  /** Draw a grid lines */
@@ -19,8 +25,10 @@ export let grid = false;
19
25
  export let ticks = placement === 'left' || placement === 'right' ? 4 : undefined;
20
26
  /** Length of the tick line */
21
27
  export let tickLength = 4;
28
+ /** Format tick labels */
22
29
  export let format = undefined;
23
- export let labelProps = undefined;
30
+ /** Props to apply to each tick label */
31
+ export let tickLabelProps = undefined;
24
32
  export let spring = undefined;
25
33
  export let tweened = undefined;
26
34
  export let transitionIn = tweened ? fade : () => { };
@@ -77,7 +85,7 @@ function getCoords(tick) {
77
85
  };
78
86
  }
79
87
  }
80
- function getDefaultLabelProps(tick) {
88
+ function getDefaultTickLabelProps(tick) {
81
89
  switch (placement) {
82
90
  case 'top':
83
91
  return {
@@ -166,20 +174,61 @@ function getDefaultLabelProps(tick) {
166
174
  {/if}
167
175
  {/if}
168
176
 
177
+ {#if label}
178
+ {@const resolvedLabelProps = {
179
+ value: label,
180
+ x:
181
+ placement === 'left' || (orientation === 'horizontal' && labelPlacement === 'start')
182
+ ? -$padding.left
183
+ : placement === 'right' || (orientation === 'horizontal' && labelPlacement === 'end')
184
+ ? $width + $padding.right
185
+ : $width / 2,
186
+ y:
187
+ placement === 'top' || (orientation === 'vertical' && labelPlacement === 'start')
188
+ ? -$padding.top
189
+ : orientation === 'vertical' && labelPlacement === 'middle'
190
+ ? $height / 2
191
+ : placement === 'bottom' || labelPlacement === 'end'
192
+ ? $height + $padding.bottom
193
+ : 0,
194
+ textAnchor:
195
+ labelPlacement === 'middle'
196
+ ? 'middle'
197
+ : placement === 'right' || (orientation === 'horizontal' && labelPlacement === 'end')
198
+ ? 'end'
199
+ : 'start',
200
+ verticalAnchor:
201
+ placement === 'top' ||
202
+ (orientation === 'vertical' && labelPlacement === 'start') ||
203
+ (placement === 'left' && labelPlacement === 'middle')
204
+ ? 'start'
205
+ : 'end',
206
+ rotate: orientation === 'vertical' && labelPlacement === 'middle' ? -90 : 0,
207
+ capHeight: '.5rem', // text-[10px]
208
+ ...labelProps,
209
+ class: cls(
210
+ 'label text-[10px] stroke-surface-100 [stroke-width:2px] font-light',
211
+ labelProps?.class
212
+ ),
213
+ }}
214
+
215
+ <Text value={label} {...resolvedLabelProps} />
216
+ {/if}
217
+
169
218
  {#each tickVals as tick, index (tick)}
170
219
  {@const tickCoords = getCoords(tick)}
171
220
  {@const radialTickCoords = pointRadial(tickCoords.x, tickCoords.y)}
172
- {@const textLabelProps = {
221
+ {@const resolvedTickLabelProps = {
173
222
  x: orientation === 'angle' ? radialTickCoords[0] : tickCoords.x,
174
223
  y: orientation === 'angle' ? radialTickCoords[1] : tickCoords.y,
175
224
  value: formatValue(tick, format ?? scale.tickFormat?.() ?? ((v) => v)),
176
- ...getDefaultLabelProps(tick),
225
+ ...getDefaultTickLabelProps(tick),
177
226
  tweened,
178
227
  spring,
179
- ...labelProps,
228
+ ...tickLabelProps,
180
229
  class: cls(
181
- 'label text-[10px] stroke-surface-100 [stroke-width:2px] font-light',
182
- labelProps?.class
230
+ 'tickLabel text-[10px] stroke-surface-100 [stroke-width:2px] font-light',
231
+ tickLabelProps?.class
183
232
  ),
184
233
  }}
185
234
 
@@ -254,8 +303,8 @@ function getDefaultLabelProps(tick) {
254
303
  />
255
304
  {/if}
256
305
 
257
- <slot name="label" labelProps={textLabelProps} {index}>
258
- <Text {...textLabelProps} />
306
+ <slot name="tickLabel" labelProps={resolvedTickLabelProps} {index}>
307
+ <Text {...resolvedTickLabelProps} />
259
308
  </slot>
260
309
  </g>
261
310
  {/each}
@@ -8,12 +8,15 @@ import Text from './Text.svelte';
8
8
  declare const __propDef: {
9
9
  props: {
10
10
  /** Location of axis */ placement: 'top' | 'bottom' | 'left' | 'right' | 'angle' | 'radius';
11
+ /** Axis label */ label?: string | undefined;
12
+ /** Location of axis label */ labelPlacement?: "start" | "end" | "middle" | undefined;
13
+ /** Props applied label Text */ labelProps?: Partial<ComponentProps<Text>> | undefined;
11
14
  /** Draw a rule line. Use Rule component for greater rendering order control */ rule?: boolean | SVGAttributes<SVGLineElement> | undefined;
12
15
  /** Draw a grid lines */ grid?: boolean | SVGAttributes<SVGLineElement> | undefined;
13
16
  /** Control the number of ticks*/ ticks?: number | any[] | Function | undefined;
14
17
  /** Length of the tick line */ tickLength?: number | undefined;
15
- format?: FormatType | undefined;
16
- labelProps?: Partial<ComponentProps<Text>> | undefined;
18
+ /** Format tick labels */ format?: FormatType | undefined;
19
+ /** Props to apply to each tick label */ tickLabelProps?: Partial<ComponentProps<Text>> | undefined;
17
20
  spring?: boolean | Parameters<typeof springStore>[1];
18
21
  tweened?: boolean | Parameters<typeof tweenedStore>[1];
19
22
  transitionIn?: typeof fade | (() => void) | undefined;
@@ -23,7 +26,7 @@ declare const __propDef: {
23
26
  [evt: string]: CustomEvent<any>;
24
27
  };
25
28
  slots: {
26
- label: {
29
+ tickLabel: {
27
30
  labelProps: any;
28
31
  index: any;
29
32
  };
@@ -49,8 +49,8 @@ $: cells = yearDays.map((date) => {
49
49
  width={cellWidth}
50
50
  height={cellHeight}
51
51
  fill={cell.color}
52
- on:mousemove={(e) => tooltip?.show(e, cell.data)}
53
- on:mouseleave={(e) => tooltip?.hide()}
52
+ on:pointermove={(e) => tooltip?.show(e, cell.data)}
53
+ on:pointerleave={(e) => tooltip?.hide()}
54
54
  class="stroke-surface-content/5"
55
55
  {...$$restProps}
56
56
  />
@@ -2,18 +2,25 @@
2
2
  // export { Svg, Html };
3
3
  // TODO: Workaround for sveld error: `Cannot read properties of null (reading 'type')` in `ComponentParser`
4
4
  // See: https://github.com/carbon-design-system/sveld/issues/104
5
- import { LayerCake, Svg as _Svg, Html as _Html, Canvas as _Canvas, WebGL as _WebGL, } from 'layercake';
6
- export const Svg = _Svg;
7
- export const Html = _Html;
5
+ import { LayerCake,
6
+ // Canvas as _Canvas,
7
+ Html as _Html,
8
+ // Svg as _Svg,
9
+ WebGL as _WebGL, } from 'layercake';
10
+ import _Canvas from './layout/Canvas.svelte';
11
+ import _Svg from './layout/Svg.svelte';
8
12
  export const Canvas = _Canvas;
13
+ export const Html = _Html;
14
+ export const Svg = _Svg;
9
15
  export const WebGL = _WebGL;
10
16
  </script>
11
17
 
12
18
  <script>import { max, min } from 'd3-array';
13
19
  import { get } from 'lodash-es';
14
20
  import { isScaleBand } from '../utils/scales.js';
15
- import TooltipContext from './TooltipContext.svelte';
16
21
  import GeoContext from './GeoContext.svelte';
22
+ import TooltipContext from './TooltipContext.svelte';
23
+ import TransformContext from './TransformContext.svelte';
17
24
  /**
18
25
  * Resolve a value from data based on the accessor type
19
26
  */
@@ -59,8 +66,14 @@ $: if (yBaseline != null) {
59
66
  * see: https://github.com/mhkeller/layercake/issues/83
60
67
  */
61
68
  $: yReverse = yScale ? !isScaleBand(yScale) : true;
62
- export let tooltip = undefined;
69
+ /** Props passed to GeoContext */
63
70
  export let geo = undefined;
71
+ /** Props passed to TooltipContext */
72
+ export let tooltip = undefined;
73
+ /** Props passed to TransformContext */
74
+ export let transform = undefined;
75
+ export let transformContext = undefined;
76
+ let geoProjection = undefined;
64
77
  </script>
65
78
 
66
79
  <LayerCake
@@ -90,30 +103,60 @@ export let geo = undefined;
90
103
  let:data
91
104
  let:flatData
92
105
  >
93
- <GeoContext {...geo} let:projection>
94
- {@const tooltipProps = typeof tooltip === 'object' ? tooltip : {}}
95
- <TooltipContext {...tooltipProps} let:tooltip>
96
- <slot
97
- {aspectRatio}
98
- {containerHeight}
99
- {containerWidth}
100
- {height}
101
- {width}
102
- {element}
103
- {projection}
104
- {tooltip}
105
- {xScale}
106
- {xGet}
107
- {yScale}
108
- {yGet}
109
- {zScale}
110
- {zGet}
111
- {rScale}
112
- {rGet}
113
- {padding}
114
- {data}
115
- {flatData}
116
- />
117
- </TooltipContext>
118
- </GeoContext>
106
+ <TransformContext
107
+ bind:this={transformContext}
108
+ processTranslate={geo
109
+ ? (x, y, deltaX, deltaY, scale) => {
110
+ if (geo.applyTransform?.includes('rotate')) {
111
+ // When applying transform to rotate, invert `y` values and reduce sensitivity based on projection scale
112
+ // see: https://observablehq.com/@benoldenburg/simple-globe and https://observablehq.com/@michael-keith/draggable-globe-in-d3
113
+ const projectionScale = $geoProjection.scale();
114
+ const sensitivity = 75;
115
+ return {
116
+ x: x + deltaX * (sensitivity / projectionScale),
117
+ y: y + deltaY * (sensitivity / projectionScale) * -1,
118
+ };
119
+ } else if (geo.applyTransform?.includes('translate')) {
120
+ // When applying to `translate`, use pointer values as is (with no `scale` adjustment)
121
+ return { x: x + deltaX, y: y + deltaY };
122
+ } else {
123
+ // Apply default TransformContext.processTransform (passing `undefined` below appears to not work when checking for `geo?.applyTransform` exists)
124
+ return { x: x + deltaX / scale, y: y + deltaY / scale };
125
+ }
126
+ }
127
+ : undefined}
128
+ {...transform}
129
+ let:transform={_transform}
130
+ on:transform
131
+ on:dragstart
132
+ on:dragend
133
+ >
134
+ <GeoContext {...geo} bind:geo={geoProjection} let:projection>
135
+ {@const tooltipProps = typeof tooltip === 'object' ? tooltip : {}}
136
+ <TooltipContext {...tooltipProps} let:tooltip>
137
+ <slot
138
+ {aspectRatio}
139
+ {containerHeight}
140
+ {containerWidth}
141
+ {height}
142
+ {width}
143
+ {element}
144
+ {projection}
145
+ transform={_transform}
146
+ {tooltip}
147
+ {xScale}
148
+ {xGet}
149
+ {yScale}
150
+ {yGet}
151
+ {zScale}
152
+ {zGet}
153
+ {rScale}
154
+ {rGet}
155
+ {padding}
156
+ {data}
157
+ {flatData}
158
+ />
159
+ </TooltipContext>
160
+ </GeoContext>
161
+ </TransformContext>
119
162
  </LayerCake>
@@ -1,12 +1,15 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import { Svg as _Svg, Html as _Html, Canvas as _Canvas, WebGL as _WebGL } from 'layercake';
3
- export declare const Svg: typeof _Svg;
4
- export declare const Html: typeof _Html;
2
+ import { Html as _Html, WebGL as _WebGL } from 'layercake';
3
+ import _Canvas from './layout/Canvas.svelte';
4
+ import _Svg from './layout/Svg.svelte';
5
5
  export declare const Canvas: typeof _Canvas;
6
+ export declare const Html: typeof _Html;
7
+ export declare const Svg: typeof _Svg;
6
8
  export declare const WebGL: typeof _WebGL;
7
9
  import type { ComponentProps } from 'svelte';
8
- import TooltipContext from './TooltipContext.svelte';
9
10
  import GeoContext from './GeoContext.svelte';
11
+ import TooltipContext from './TooltipContext.svelte';
12
+ import TransformContext from './TransformContext.svelte';
10
13
  declare const __propDef: {
11
14
  props: {
12
15
  [x: string]: any;
@@ -16,10 +19,22 @@ declare const __propDef: {
16
19
  yScale?: Function | undefined;
17
20
  xBaseline?: number | null | undefined;
18
21
  yBaseline?: number | null | undefined;
19
- tooltip?: Partial<ComponentProps<TooltipContext>> | boolean | undefined;
20
22
  geo?: Partial<ComponentProps<GeoContext>> | undefined;
23
+ tooltip?: Partial<ComponentProps<TooltipContext>> | boolean | undefined;
24
+ transform?: Partial<ComponentProps<TransformContext>> | undefined;
25
+ transformContext?: TransformContext | undefined;
21
26
  };
22
27
  events: {
28
+ transform: CustomEvent<{
29
+ scale: number;
30
+ translate: {
31
+ x: number;
32
+ y: number;
33
+ };
34
+ }>;
35
+ dragstart: CustomEvent<null>;
36
+ dragend: CustomEvent<null>;
37
+ } & {
23
38
  [evt: string]: CustomEvent<any>;
24
39
  };
25
40
  slots: {
@@ -31,11 +46,23 @@ declare const __propDef: {
31
46
  width: number;
32
47
  element: Element;
33
48
  projection: import("d3-geo").GeoProjection | import("d3-geo").GeoIdentityTransform;
49
+ transform: {
50
+ scale: any;
51
+ translate: any;
52
+ zoomTo: (center: {
53
+ x: number;
54
+ y: number;
55
+ }, rect?: {
56
+ width: number;
57
+ height: number;
58
+ } | undefined) => void;
59
+ reset: () => void;
60
+ };
34
61
  tooltip: {
35
62
  y: number;
36
63
  x: number;
37
64
  data: null;
38
- show: (event: MouseEvent | TouchEvent, tooltipData?: any) => void;
65
+ show: (e: PointerEvent, tooltipData?: any) => void;
39
66
  hide: () => void;
40
67
  };
41
68
  xScale: any;
@@ -26,6 +26,6 @@ $: tick().then(() => {
26
26
  class={cls($$props.fill == null && 'fill-surface-content')}
27
27
  {...$$restProps}
28
28
  on:click
29
- on:mousemove
30
- on:mouseleave
29
+ on:pointermove
30
+ on:pointerleave
31
31
  />
@@ -14,8 +14,8 @@ declare const __propDef: {
14
14
  };
15
15
  events: {
16
16
  click: MouseEvent;
17
- mousemove: MouseEvent;
18
- mouseleave: MouseEvent;
17
+ pointermove: PointerEvent;
18
+ pointerleave: PointerEvent;
19
19
  } & {
20
20
  [evt: string]: CustomEvent<any>;
21
21
  };
@@ -21,7 +21,7 @@ export let disabled = false;
21
21
  {#if disabled}
22
22
  <slot />
23
23
  {:else}
24
- <g style:clip-path="url(#{id})" on:click on:mousemove on:mouseleave on:keydown>
24
+ <g style:clip-path="url(#{id})" on:click on:pointermove on:pointerleave on:keydown>
25
25
  <slot {id} url="url(#{id})" {useId} />
26
26
  </g>
27
27
  {/if}
@@ -8,8 +8,8 @@ declare const __propDef: {
8
8
  };
9
9
  events: {
10
10
  click: MouseEvent;
11
- mousemove: MouseEvent;
12
- mouseleave: MouseEvent;
11
+ pointermove: PointerEvent;
12
+ pointerleave: PointerEvent;
13
13
  keydown: KeyboardEvent;
14
14
  } & {
15
15
  [evt: string]: CustomEvent<any>;
@@ -9,4 +9,4 @@ export let precision = 6;
9
9
  $: geojson = geoCircle().radius(radius).center(center).precision(precision)();
10
10
  </script>
11
11
 
12
- <GeoPath {geojson} {...$$restProps} on:mousemove on:mouseleave on:click />
12
+ <GeoPath {geojson} {...$$restProps} on:pointermove on:pointerleave on:click />
@@ -7,8 +7,8 @@ declare const __propDef: {
7
7
  precision?: number | undefined;
8
8
  };
9
9
  events: {
10
- mousemove: MouseEvent;
11
- mouseleave: MouseEvent;
10
+ pointermove: PointerEvent;
11
+ pointerleave: PointerEvent;
12
12
  click: CustomEvent<any>;
13
13
  } & {
14
14
  [evt: string]: CustomEvent<any>;
@@ -1,6 +1,7 @@
1
1
  <script context="module">import { getContext, setContext } from 'svelte';
2
2
  import { writable } from 'svelte/store';
3
3
  import {} from 'd3-geo';
4
+ import { transformContext } from './TransformContext.svelte';
4
5
  export const geoContextKey = Symbol();
5
6
  export function geoContext() {
6
7
  return getContext(geoContextKey);
@@ -22,24 +23,47 @@ export let rotate = undefined;
22
23
  export let scale = undefined;
23
24
  export let translate = undefined;
24
25
  export let center = undefined;
26
+ /** Apply TransformContext to the selected properties. Typically `translate` or `rotate` are mutually selected */
27
+ export let applyTransform = [];
25
28
  export let reflectX = undefined;
26
29
  export let reflectY = undefined;
27
- const geo = writable(projection?.());
30
+ /** Exposed to allow binding in Chart */
31
+ export let geo = writable(projection?.());
28
32
  setGeoContext(geo);
33
+ const { scale: transformScale, translate: transformTranslate } = transformContext();
29
34
  $: fitSizeRange = (fixedAspectRatio ? [100, 100 / fixedAspectRatio] : [$width, $height]);
30
35
  $: if (projection) {
31
36
  const _projection = projection();
32
37
  if (fitGeojson && 'fitSize' in _projection) {
33
38
  _projection.fitSize(fitSizeRange, fitGeojson);
34
39
  }
35
- if (scale && 'scale' in _projection) {
36
- _projection.scale(scale);
40
+ if ('scale' in _projection) {
41
+ if (scale) {
42
+ _projection.scale(scale);
43
+ }
44
+ if (applyTransform.includes('scale')) {
45
+ _projection.scale($transformScale);
46
+ }
37
47
  }
38
- if (rotate && 'rotate' in _projection) {
39
- _projection.rotate([rotate.yaw, rotate.pitch, rotate.roll]);
48
+ if ('rotate' in _projection) {
49
+ if (rotate) {
50
+ _projection.rotate([rotate.yaw, rotate.pitch, rotate.roll]);
51
+ }
52
+ if (applyTransform.includes('rotate')) {
53
+ _projection.rotate([
54
+ $transformTranslate.x, // yaw
55
+ $transformTranslate.y, // pitch
56
+ // TODO: `roll` from `transformContext`?
57
+ ]);
58
+ }
40
59
  }
41
- if (translate && 'translate' in _projection) {
42
- _projection.translate(translate);
60
+ if ('translate' in _projection) {
61
+ if (translate) {
62
+ _projection.translate(translate);
63
+ }
64
+ if (applyTransform.includes('translate')) {
65
+ _projection.translate([$transformTranslate.x, $transformTranslate.y]);
66
+ }
43
67
  }
44
68
  if (center && 'center' in _projection) {
45
69
  _projection.center(center);
@@ -22,8 +22,10 @@ declare const __propDef: {
22
22
  scale?: number | undefined;
23
23
  translate?: [number, number] | undefined;
24
24
  center?: [number, number] | undefined;
25
+ /** Apply TransformContext to the selected properties. Typically `translate` or `rotate` are mutually selected */ applyTransform?: ("rotate" | "scale" | "translate")[] | undefined;
25
26
  reflectX?: boolean | undefined;
26
27
  reflectY?: boolean | undefined;
28
+ /** Exposed to allow binding in Chart */ geo?: Writable<GeoProjection | GeoIdentityTransform> | undefined;
27
29
  };
28
30
  events: {
29
31
  [evt: string]: CustomEvent<any>;
@@ -1,16 +1,15 @@
1
1
  <script>import { createEventDispatcher, getContext } from 'svelte';
2
2
  import {} from 'd3-geo';
3
- import { scaleCanvas } from 'layercake';
4
3
  import { cls } from 'svelte-ux';
5
4
  import { geoContext } from './GeoContext.svelte';
6
5
  import { curveLinearClosed } from 'd3-shape';
7
6
  import { geoCurvePath } from '../utils/geo.js';
8
- export let geojson;
7
+ export let geojson = undefined;
8
+ /** Render to canvas */
9
+ export let render = undefined;
9
10
  export let fill = undefined;
10
11
  export let stroke = undefined;
11
12
  export let strokeWidth = undefined;
12
- /** Render to canvas */
13
- export let render = undefined;
14
13
  /**
15
14
  * Tooltip context to setup mouse events to show tooltip for related data
16
15
  */
@@ -41,7 +40,6 @@ $: if (renderContext === 'canvas' && $ctx) {
41
40
  computedStyles = window.getComputedStyle($ctx.canvas);
42
41
  }
43
42
  // console.count('render');
44
- scaleCanvas($ctx, $width, $height);
45
43
  $ctx.clearRect(0, 0, $width, $height);
46
44
  if (render) {
47
45
  geoPath = geoCurvePath($geo, curve, $ctx);
@@ -58,7 +56,8 @@ $: if (renderContext === 'canvas' && $ctx) {
58
56
  'transparent';
59
57
  $ctx.fill();
60
58
  $ctx.lineWidth = strokeWidth;
61
- $ctx.strokeStyle = stroke ?? computedStyles.stroke;
59
+ $ctx.strokeStyle =
60
+ stroke ?? computedStyles.stroke === 'none' ? 'transparent' : computedStyles.stroke;
62
61
  $ctx.stroke();
63
62
  }
64
63
  }
@@ -71,10 +70,13 @@ $: if (renderContext === 'canvas' && $ctx) {
71
70
  d={geoPath(geojson)}
72
71
  {fill}
73
72
  {stroke}
74
- on:mousemove={(e) => tooltip?.show(e, geojson)}
75
- on:mousemove
76
- on:mouseleave={(e) => tooltip?.hide()}
77
- on:mouseleave
73
+ stroke-width={strokeWidth}
74
+ on:pointerenter={(e) => tooltip?.show(e, geojson)}
75
+ on:pointerenter
76
+ on:pointermove={(e) => tooltip?.show(e, geojson)}
77
+ on:pointermove
78
+ on:pointerleave={(e) => tooltip?.hide()}
79
+ on:pointerleave
78
80
  on:click={(event) => dispatch('click', { geoPath, event })}
79
81
  on:click
80
82
  class={cls($$props.fill == null && 'fill-transparent', $$props.class)}
@@ -1,23 +1,22 @@
1
1
  import { SvelteComponentTyped } from "svelte";
2
- import { type GeoPermissibleObjects } from 'd3-geo';
2
+ import { type GeoPath, type GeoPermissibleObjects } from 'd3-geo';
3
3
  import type { TooltipContextValue } from './TooltipContext.svelte';
4
4
  import { type CurveFactory, type CurveFactoryLineOnly } from 'd3-shape';
5
5
  declare const __propDef: {
6
6
  props: {
7
7
  [x: string]: any;
8
- geojson: GeoPermissibleObjects;
8
+ geojson?: GeoPermissibleObjects | undefined;
9
+ render?: ((ctx: CanvasRenderingContext2D, { geoPath: GeoPath }) => any) | undefined;
9
10
  fill?: string | undefined;
10
11
  stroke?: string | undefined;
11
12
  strokeWidth?: number | string | undefined;
12
- render?: ((ctx: CanvasRenderingContext2D, { geoPath: GeoPath }: {
13
- geoPath: any;
14
- }) => any) | undefined;
15
13
  tooltip?: TooltipContextValue | undefined;
16
14
  curve?: CurveFactory | CurveFactoryLineOnly | undefined;
17
15
  };
18
16
  events: {
19
- mousemove: MouseEvent;
20
- mouseleave: MouseEvent;
17
+ pointerenter: PointerEvent;
18
+ pointermove: PointerEvent;
19
+ pointerleave: PointerEvent;
21
20
  click: CustomEvent<any>;
22
21
  } & {
23
22
  [evt: string]: CustomEvent<any>;
@@ -1,5 +1,4 @@
1
1
  <script>import { getContext } from 'svelte';
2
- import { scaleCanvas } from 'layercake';
3
2
  import { geoContext } from './GeoContext.svelte';
4
3
  import Circle from './Circle.svelte';
5
4
  import Group from './Group.svelte';
@@ -16,8 +15,7 @@ $: [x, y] = $geo([long, lat]) ?? [0, 0];
16
15
  $: renderContext = canvas ? 'canvas' : 'svg';
17
16
  $: ctx = canvas?.ctx;
18
17
  $: if (renderContext === 'canvas' && $ctx) {
19
- scaleCanvas($ctx, $width, $height);
20
- $ctx.clearRect(0, 0, $width, $height);
18
+ // $ctx.clearRect(0, 0, $width, $height);
21
19
  // Transfer classes defined on <GeoPoint> to <canvas> to enable window.getComputedStyle() retrieval (Tailwind classes, etc)
22
20
  if ($$props.class) {
23
21
  $ctx.canvas.classList.add(...$$props.class.split(' '));