layerchart 0.53.0 → 0.54.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 (107) hide show
  1. package/dist/components/Arc.svelte +170 -144
  2. package/dist/components/Area.svelte +96 -67
  3. package/dist/components/Area.svelte.d.ts +1 -0
  4. package/dist/components/Axis.svelte +241 -234
  5. package/dist/components/Axis.svelte.d.ts +2 -1
  6. package/dist/components/Bar.svelte +72 -45
  7. package/dist/components/Bars.svelte +46 -34
  8. package/dist/components/Bars.svelte.d.ts +1 -0
  9. package/dist/components/Blur.svelte +5 -3
  10. package/dist/components/Bounds.svelte +37 -21
  11. package/dist/components/Brush.svelte +181 -110
  12. package/dist/components/Calendar.svelte +51 -38
  13. package/dist/components/Chart.svelte +296 -73
  14. package/dist/components/Chart.svelte.d.ts +42 -25
  15. package/dist/components/ChartClipPath.svelte +8 -5
  16. package/dist/components/ChartContext.svelte +243 -93
  17. package/dist/components/ChartContext.svelte.d.ts +15 -23
  18. package/dist/components/Circle.svelte +25 -16
  19. package/dist/components/CircleClipPath.svelte +16 -10
  20. package/dist/components/ClipPath.svelte +11 -7
  21. package/dist/components/ColorRamp.svelte +12 -10
  22. package/dist/components/ForceSimulation.svelte +185 -116
  23. package/dist/components/Frame.svelte +10 -6
  24. package/dist/components/GeoCircle.svelte +15 -9
  25. package/dist/components/GeoContext.svelte +109 -62
  26. package/dist/components/GeoEdgeFade.svelte +20 -14
  27. package/dist/components/GeoPath.svelte +107 -69
  28. package/dist/components/GeoPoint.svelte +32 -18
  29. package/dist/components/GeoSpline.svelte +30 -22
  30. package/dist/components/GeoTile.svelte +40 -30
  31. package/dist/components/GeoVisible.svelte +10 -7
  32. package/dist/components/Graticule.svelte +14 -8
  33. package/dist/components/Grid.svelte +178 -0
  34. package/dist/components/Grid.svelte.d.ts +35 -0
  35. package/dist/components/Group.svelte +43 -31
  36. package/dist/components/Highlight.svelte +284 -243
  37. package/dist/components/HitCanvas.svelte +75 -42
  38. package/dist/components/Hull.svelte +40 -20
  39. package/dist/components/Labels.svelte +84 -63
  40. package/dist/components/Labels.svelte.d.ts +2 -0
  41. package/dist/components/Legend.svelte +106 -75
  42. package/dist/components/Legend.svelte.d.ts +1 -1
  43. package/dist/components/Line.svelte +29 -19
  44. package/dist/components/LinearGradient.svelte +21 -15
  45. package/dist/components/Link.svelte +44 -22
  46. package/dist/components/MonthPath.svelte +23 -16
  47. package/dist/components/MotionPath.svelte +34 -25
  48. package/dist/components/Pack.svelte +21 -14
  49. package/dist/components/Partition.svelte +35 -20
  50. package/dist/components/Pattern.svelte +8 -6
  51. package/dist/components/Pie.svelte +76 -57
  52. package/dist/components/Point.svelte +11 -7
  53. package/dist/components/Points.svelte +178 -143
  54. package/dist/components/RadialGradient.svelte +25 -18
  55. package/dist/components/Rect.svelte +33 -19
  56. package/dist/components/RectClipPath.svelte +16 -11
  57. package/dist/components/Rule.svelte +66 -42
  58. package/dist/components/Rule.svelte.d.ts +2 -0
  59. package/dist/components/Sankey.svelte +55 -30
  60. package/dist/components/Spline.svelte +118 -96
  61. package/dist/components/Text.svelte +137 -104
  62. package/dist/components/Threshold.svelte +18 -7
  63. package/dist/components/TileImage.svelte +56 -50
  64. package/dist/components/TransformContext.svelte +238 -136
  65. package/dist/components/TransformControls.svelte +57 -29
  66. package/dist/components/TransformControls.svelte.d.ts +1 -1
  67. package/dist/components/Tree.svelte +33 -23
  68. package/dist/components/Treemap.svelte +69 -41
  69. package/dist/components/Voronoi.svelte +55 -28
  70. package/dist/components/charts/AreaChart.svelte +162 -87
  71. package/dist/components/charts/AreaChart.svelte.d.ts +41 -3
  72. package/dist/components/charts/BarChart.svelte +207 -108
  73. package/dist/components/charts/BarChart.svelte.d.ts +41 -3
  74. package/dist/components/charts/LineChart.svelte +119 -47
  75. package/dist/components/charts/LineChart.svelte.d.ts +41 -3
  76. package/dist/components/charts/PieChart.svelte +117 -53
  77. package/dist/components/charts/PieChart.svelte.d.ts +17 -2
  78. package/dist/components/charts/ScatterChart.svelte +92 -42
  79. package/dist/components/charts/ScatterChart.svelte.d.ts +39 -3
  80. package/dist/components/index.d.ts +1 -0
  81. package/dist/components/index.js +1 -0
  82. package/dist/components/layout/Canvas.svelte +63 -43
  83. package/dist/components/layout/Html.svelte +28 -18
  84. package/dist/components/layout/Svg.svelte +47 -32
  85. package/dist/components/tooltip/Tooltip.svelte +143 -82
  86. package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -1
  87. package/dist/components/tooltip/TooltipContext.svelte +315 -248
  88. package/dist/components/tooltip/TooltipContext.svelte.d.ts +7 -0
  89. package/dist/components/tooltip/TooltipHeader.svelte +9 -3
  90. package/dist/components/tooltip/TooltipItem.svelte +17 -9
  91. package/dist/components/tooltip/TooltipList.svelte +2 -1
  92. package/dist/components/tooltip/TooltipSeparator.svelte +3 -2
  93. package/dist/docs/Blockquote.svelte +4 -3
  94. package/dist/docs/Code.svelte +15 -8
  95. package/dist/docs/CurveMenuField.svelte +17 -12
  96. package/dist/docs/GeoDebug.svelte +13 -9
  97. package/dist/docs/Header1.svelte +2 -1
  98. package/dist/docs/Json.svelte +6 -4
  99. package/dist/docs/Layout.svelte +6 -6
  100. package/dist/docs/PathDataMenuField.svelte +52 -44
  101. package/dist/docs/Preview.svelte +48 -29
  102. package/dist/docs/TilesetField.svelte +80 -62
  103. package/dist/docs/TransformDebug.svelte +8 -5
  104. package/dist/docs/ViewSourceButton.svelte +13 -9
  105. package/dist/stores/motionStore.d.ts +1 -1
  106. package/dist/utils/scales.d.ts +4 -4
  107. package/package.json +29 -30
@@ -1,53 +1,80 @@
1
- <script>import {} from 'svelte';
2
- import { chartContext } from './ChartContext.svelte';
3
- import Rect from './Rect.svelte';
4
- import Spline from './Spline.svelte';
5
- import { createDimensionGetter } from '../utils/rect.js';
6
- const { x: xContext, y: yContext } = chartContext();
7
- export let bar;
8
- /**
9
- * Override `x` from context. Useful for multiple Bar instances
10
- */
11
- export let x = $xContext;
12
- /**
13
- * Override `y` from context. Useful for multiple Bar instances
14
- */
15
- export let y = $yContext;
16
- /**
17
- * Override `x1` from context. Useful for multiple Bar instances
18
- */
19
- export let x1 = undefined;
20
- /**
21
- * Override `y1` from context. Useful for multiple Bar instances
22
- */
23
- export let y1 = undefined;
24
- export let fill = undefined;
25
- export let stroke = 'black';
26
- export let strokeWidth = 0;
27
- export let radius = 0;
28
- /** Control which corners are rounded with radius. Uses <path> instead of <rect> when not set to `all` */
29
- export let rounded = 'all';
30
- export let inset = 0;
31
- export let spring = undefined;
32
- export let tweened = undefined;
33
- $: if (stroke === null || stroke === undefined)
34
- stroke = 'black';
35
- $: getDimensions = createDimensionGetter(chartContext(), {
1
+ <script lang="ts">
2
+ import { type ComponentProps } from 'svelte';
3
+
4
+ import { chartContext } from './ChartContext.svelte';
5
+ import Rect from './Rect.svelte';
6
+ import Spline from './Spline.svelte';
7
+
8
+ import { createDimensionGetter } from '../utils/rect.js';
9
+ import type { Accessor } from '../utils/common.js';
10
+
11
+ const { x: xContext, y: yContext } = chartContext();
12
+
13
+ export let bar: Object;
14
+
15
+ /**
16
+ * Override `x` from context. Useful for multiple Bar instances
17
+ */
18
+ export let x: Accessor = $xContext;
19
+
20
+ /**
21
+ * Override `y` from context. Useful for multiple Bar instances
22
+ */
23
+ export let y: Accessor = $yContext;
24
+
25
+ /**
26
+ * Override `x1` from context. Useful for multiple Bar instances
27
+ */
28
+ export let x1: Accessor = undefined;
29
+
30
+ /**
31
+ * Override `y1` from context. Useful for multiple Bar instances
32
+ */
33
+ export let y1: Accessor = undefined;
34
+
35
+ export let fill: string | undefined = undefined;
36
+ export let stroke = 'black';
37
+ export let strokeWidth = 0;
38
+ export let radius = 0;
39
+
40
+ /** Control which corners are rounded with radius. Uses <path> instead of <rect> when not set to `all` */
41
+ export let rounded:
42
+ | 'all'
43
+ | 'top'
44
+ | 'bottom'
45
+ | 'left'
46
+ | 'right'
47
+ | 'top-left'
48
+ | 'top-right'
49
+ | 'bottom-left'
50
+ | 'bottom-right' = 'all';
51
+
52
+ export let inset = 0;
53
+
54
+ export let spring: ComponentProps<Rect>['spring'] = undefined;
55
+ export let tweened: ComponentProps<Rect>['tweened'] = undefined;
56
+
57
+ $: if (stroke === null || stroke === undefined) stroke = 'black';
58
+
59
+ $: getDimensions = createDimensionGetter(chartContext(), {
36
60
  x,
37
61
  y,
38
62
  x1,
39
63
  y1,
40
64
  inset,
41
- });
42
- $: dimensions = $getDimensions(bar) ?? { x: 0, y: 0, width: 0, height: 0 };
43
- $: topLeft = ['all', 'top', 'left', 'top-left'].includes(rounded);
44
- $: topRight = ['all', 'top', 'right', 'top-right'].includes(rounded);
45
- $: bottomLeft = ['all', 'bottom', 'left', 'bottom-left'].includes(rounded);
46
- $: bottomRight = ['all', 'bottom', 'right', 'bottom-right'].includes(rounded);
47
- $: width = dimensions.width;
48
- $: height = dimensions.height;
49
- $: diameter = 2 * radius;
50
- $: pathData = `M${dimensions.x + radius},${dimensions.y} h${width - diameter}
65
+ });
66
+ $: dimensions = $getDimensions(bar) ?? { x: 0, y: 0, width: 0, height: 0 };
67
+
68
+ $: topLeft = ['all', 'top', 'left', 'top-left'].includes(rounded);
69
+ $: topRight = ['all', 'top', 'right', 'top-right'].includes(rounded);
70
+ $: bottomLeft = ['all', 'bottom', 'left', 'bottom-left'].includes(rounded);
71
+ $: bottomRight = ['all', 'bottom', 'right', 'bottom-right'].includes(rounded);
72
+
73
+ $: width = dimensions.width;
74
+ $: height = dimensions.height;
75
+ $: diameter = 2 * radius;
76
+
77
+ $: pathData = `M${dimensions.x + radius},${dimensions.y} h${width - diameter}
51
78
  ${topRight ? `a${radius},${radius} 0 0 1 ${radius},${radius}` : `h${radius}v${radius}`}
52
79
  v${height - diameter}
53
80
  ${bottomRight ? `a${radius},${radius} 0 0 1 ${-radius},${radius}` : `v${radius}h${-radius}`}
@@ -1,36 +1,48 @@
1
- <script>import {} from 'svelte';
2
- import { chartContext } from './ChartContext.svelte';
3
- import Bar from './Bar.svelte';
4
- import Rect from './Rect.svelte';
5
- import { chartDataArray } from '../utils/common.js';
6
- const { data: contextData, cGet, config } = chartContext();
7
- /**
8
- * Override `data` from context. Useful for multiple Bar instances
9
- */
10
- export let data = undefined;
11
- /**
12
- * Override `x` from context. Useful for multiple Bar instances
13
- */
14
- export let x = undefined;
15
- /**
16
- * Override `y` from context. Useful for multiple Bar instances
17
- */
18
- export let y = undefined;
19
- /**
20
- * Override `x1` from context. Useful for multiple Bar instances
21
- */
22
- export let x1 = undefined;
23
- /**
24
- * Override `y1` from context. Useful for multiple Bar instances
25
- */
26
- export let y1 = undefined;
27
- export let stroke = 'black';
28
- export let strokeWidth = 0;
29
- export let radius = 0;
30
- /** Inset the rect for amount of padding. Useful with multiple bars (bullet, overlap, etc) */
31
- export let inset = 0;
32
- export let spring = undefined;
33
- export let tweened = undefined;
1
+ <script lang="ts">
2
+ import { type ComponentProps } from 'svelte';
3
+
4
+ import { chartContext } from './ChartContext.svelte';
5
+ import Bar from './Bar.svelte';
6
+ import Rect from './Rect.svelte';
7
+ import { chartDataArray, type Accessor } from '../utils/common.js';
8
+
9
+ const { data: contextData, cGet, config } = chartContext();
10
+
11
+ /**
12
+ * Override `data` from context. Useful for multiple Bar instances
13
+ */
14
+ export let data: any = undefined;
15
+
16
+ /**
17
+ * Override `x` from context. Useful for multiple Bar instances
18
+ */
19
+ export let x: Accessor = undefined;
20
+
21
+ /**
22
+ * Override `y` from context. Useful for multiple Bar instances
23
+ */
24
+ export let y: Accessor = undefined;
25
+
26
+ /**
27
+ * Override `x1` from context. Useful for multiple Bar instances
28
+ */
29
+ export let x1: Accessor = undefined;
30
+
31
+ /**
32
+ * Override `y1` from context. Useful for multiple Bar instances
33
+ */
34
+ export let y1: Accessor = undefined;
35
+
36
+ export let stroke = 'black';
37
+ export let strokeWidth = 0;
38
+ export let radius = 0;
39
+ export let fill: string | undefined = undefined;
40
+
41
+ /** Inset the rect for amount of padding. Useful with multiple bars (bullet, overlap, etc) */
42
+ export let inset = 0;
43
+
44
+ export let spring: ComponentProps<Rect>['spring'] = undefined;
45
+ export let tweened: ComponentProps<Rect>['tweened'] = undefined;
34
46
  </script>
35
47
 
36
48
  <g class="Bars">
@@ -42,7 +54,7 @@ export let tweened = undefined;
42
54
  {y}
43
55
  {x1}
44
56
  {y1}
45
- fill={$config.c ? $cGet(item) : null}
57
+ fill={fill ?? ($config.c ? $cGet(item) : null)}
46
58
  {stroke}
47
59
  {strokeWidth}
48
60
  {radius}
@@ -13,6 +13,7 @@ declare const __propDef: {
13
13
  stroke?: string | undefined;
14
14
  strokeWidth?: number | undefined;
15
15
  radius?: number | undefined;
16
+ fill?: string | undefined;
16
17
  inset?: number | undefined;
17
18
  spring?: ComponentProps<Rect>["spring"];
18
19
  tweened?: ComponentProps<Rect>["tweened"];
@@ -1,6 +1,8 @@
1
- <script>import { uniqueId } from '@layerstack/utils';
2
- export let id = uniqueId('blur-');
3
- export let stdDeviation = 5;
1
+ <script lang="ts">
2
+ import { uniqueId } from '@layerstack/utils';
3
+
4
+ export let id: string = uniqueId('blur-');
5
+ export let stdDeviation = 5;
4
6
  </script>
5
7
 
6
8
  <defs>
@@ -1,26 +1,42 @@
1
- <script>import { scaleLinear } from 'd3-scale';
2
- import { chartContext } from './ChartContext.svelte';
3
- import { motionScale } from '../utils/scales.js';
4
- const { width, height } = chartContext();
5
- export let domain = undefined;
6
- export let range = undefined;
7
- export let spring = undefined;
8
- export let tweened = undefined;
9
- function getExtents(extents, axis, fallback) {
10
- const resolvedExtents = typeof extents === 'function' ? extents({ width: $width, height: $height }) : extents;
1
+ <script lang="ts">
2
+ import { scaleLinear } from 'd3-scale';
3
+
4
+ import { chartContext } from './ChartContext.svelte';
5
+ import { motionScale } from '../utils/scales.js';
6
+
7
+ const { width, height } = chartContext();
8
+
9
+ type Extents = Partial<{ x0: number; y0: number; x1: number; y1: number }>;
10
+ type ExtentsAcccessor = (dimensions: { width: number; height: number }) => Extents;
11
+
12
+ export let domain: Extents | ExtentsAcccessor | null | undefined = undefined;
13
+ export let range: Extents | ExtentsAcccessor | null | undefined = undefined;
14
+ export let spring: boolean | Parameters<typeof motionScale>[1]['spring'] = undefined;
15
+ export let tweened: boolean | Parameters<typeof motionScale>[1]['tweened'] = undefined;
16
+
17
+ function getExtents(
18
+ extents: Extents | ExtentsAcccessor | null | undefined,
19
+ axis: 'x' | 'y',
20
+ fallback: number
21
+ ) {
22
+ const resolvedExtents =
23
+ typeof extents === 'function' ? extents({ width: $width, height: $height }) : extents;
24
+
11
25
  return [
12
- // @ts-expect-error
13
- resolvedExtents?.[axis + '0'] ?? 0, // x0 or y0
14
- // @ts-expect-error
15
- resolvedExtents?.[axis + '1'] ?? fallback, // x1 or y1, fallback as $width or $height
26
+ // @ts-expect-error
27
+ resolvedExtents?.[axis + '0'] ?? 0, // x0 or y0
28
+ // @ts-expect-error
29
+ resolvedExtents?.[axis + '1'] ?? fallback, // x1 or y1, fallback as $width or $height
16
30
  ];
17
- }
18
- const xScale = motionScale(scaleLinear, { spring, tweened });
19
- $: xScale.domain(getExtents(domain, 'x', $width));
20
- $: xScale.range(getExtents(range, 'x', $width));
21
- const yScale = motionScale(scaleLinear, { spring, tweened });
22
- $: yScale.domain(getExtents(domain, 'y', $height));
23
- $: yScale.range(getExtents(range, 'y', $height));
31
+ }
32
+
33
+ const xScale = motionScale(scaleLinear as any, { spring, tweened });
34
+ $: xScale.domain(getExtents(domain, 'x', $width));
35
+ $: xScale.range(getExtents(range, 'x', $width));
36
+
37
+ const yScale = motionScale(scaleLinear as any, { spring, tweened });
38
+ $: yScale.domain(getExtents(domain, 'y', $height));
39
+ $: yScale.range(getExtents(range, 'y', $height));
24
40
  </script>
25
41
 
26
42
  <slot xScale={$xScale} yScale={$yScale} />
@@ -1,135 +1,206 @@
1
- <script>import { createEventDispatcher } from 'svelte';
2
- import { extent } from 'd3-array';
3
- import { clamp } from '@layerstack/utils';
4
- import { cls } from '@layerstack/tailwind';
5
- import { chartContext } from './ChartContext.svelte';
6
- import Frame from './Frame.svelte';
7
- import { localPoint } from '../utils/event.js';
8
- import Group from './Group.svelte';
9
- const { xScale, yScale, width, height, padding } = chartContext();
10
- const dispatch = createEventDispatcher();
11
- /** Axis to apply brushing */
12
- export let axis = 'x';
13
- /** Size of draggable handles (width/height) */
14
- export let handleSize = 5;
15
- /** Only show range while actively brushing. Useful with `brushEnd` event */
16
- export let resetOnEnd = false;
17
- export let xDomain = $xScale.domain();
18
- export let yDomain = $yScale.domain();
19
- // Capture original domains for reset()
20
- const originalXDomain = $xScale.domain();
21
- const originalYDomain = $yScale.domain();
22
- $: [xDomainMin, xDomainMax] = extent($xScale.domain());
23
- $: [yDomainMin, yDomainMax] = extent($yScale.domain());
24
- /** Attributes passed to range <rect> element */
25
- export let range = undefined;
26
- /** Attributes passed to handle <rect> elements */
27
- export let handle = undefined;
28
- export let classes = {};
29
- let frameEl;
30
- function handler(fn) {
31
- return (e) => {
32
- const start = {
33
- xDomain: [xDomain[0] ?? xDomainMin, xDomain[1] ?? xDomainMax],
34
- yDomain: [yDomain[0] ?? yDomainMin, yDomain[1] ?? yDomainMax],
35
- value: {
36
- x: $xScale.invert?.((localPoint(frameEl, e)?.x ?? 0) - $padding.left),
37
- y: $yScale.invert?.((localPoint(frameEl, e)?.y ?? 0) - $padding.top),
38
- },
39
- };
40
- dispatch('brushStart', { xDomain, yDomain });
41
- const onPointerMove = (e) => {
42
- fn(start, {
43
- x: $xScale.invert?.((localPoint(frameEl, e)?.x ?? 0) - $padding.left),
44
- y: $yScale.invert?.((localPoint(frameEl, e)?.y ?? 0) - $padding.top),
45
- });
46
- // if (xDomain[0] === xDomain[1] || yDomain[0] === yDomain[1]) {
47
- // // Ignore?
48
- // // TODO: What about when using `x` or `y` axis?
49
- // } else {
50
- dispatch('change', { xDomain, yDomain });
51
- // }
52
- };
53
- const onPointerUp = (e) => {
54
- if (e.target === frameEl) {
55
- reset();
56
- dispatch('change', { xDomain, yDomain });
57
- }
58
- dispatch('brushEnd', { xDomain, yDomain });
59
- if (resetOnEnd) {
60
- reset();
61
- }
62
- window.removeEventListener('pointermove', onPointerMove);
63
- window.removeEventListener('pointerup', onPointerUp);
64
- };
65
- window.addEventListener('pointermove', onPointerMove);
66
- window.addEventListener('pointerup', onPointerUp);
1
+ <script lang="ts">
2
+ import { createEventDispatcher } from 'svelte';
3
+ import type { SVGAttributes } from 'svelte/elements';
4
+ import { extent } from 'd3-array';
5
+ import { clamp } from '@layerstack/utils';
6
+ import { cls } from '@layerstack/tailwind';
7
+
8
+ import { chartContext } from './ChartContext.svelte';
9
+ import Frame from './Frame.svelte';
10
+ import { localPoint } from '../utils/event.js';
11
+ import Group from './Group.svelte';
12
+
13
+ const { xScale, yScale, width, height, padding } = chartContext();
14
+
15
+ const dispatch = createEventDispatcher<{
16
+ change: { xDomain?: [any, any]; yDomain?: [any, any] };
17
+ brushStart: { xDomain?: [any, any]; yDomain?: [any, any] };
18
+ brushEnd: { xDomain?: [any, any]; yDomain?: [any, any] };
19
+ }>();
20
+
21
+ /** Axis to apply brushing */
22
+ export let axis: 'x' | 'y' | 'both' = 'x';
23
+
24
+ /** Size of draggable handles (width/height) */
25
+ export let handleSize = 5;
26
+
27
+ /** Only show range while actively brushing. Useful with `brushEnd` event */
28
+ export let resetOnEnd = false;
29
+
30
+ export let xDomain: [number | Date | null, number | Date | null] = $xScale.domain() as [
31
+ number,
32
+ number,
33
+ ];
34
+ export let yDomain: [number | Date | null, number | Date | null] = $yScale.domain() as [
35
+ number,
36
+ number,
37
+ ];
38
+
39
+ // Capture original domains for reset()
40
+ const originalXDomain = $xScale.domain() as [number, number];
41
+ const originalYDomain = $yScale.domain() as [number, number];
42
+
43
+ $: [xDomainMin, xDomainMax] = extent<number>($xScale.domain()) as [number, number];
44
+ $: [yDomainMin, yDomainMax] = extent<number>($yScale.domain()) as [number, number];
45
+
46
+ /** Attributes passed to range <rect> element */
47
+ export let range: SVGAttributes<SVGRectElement> | undefined = undefined;
48
+
49
+ /** Attributes passed to handle <rect> elements */
50
+ export let handle: SVGAttributes<SVGRectElement> | undefined = undefined;
51
+
52
+ export let classes: {
53
+ root?: string;
54
+ frame?: string;
55
+ range?: string;
56
+ handle?: string;
57
+ } = {};
58
+
59
+ let frameEl: SVGRectElement;
60
+
61
+ function handler(
62
+ fn: (
63
+ start: {
64
+ xDomain: [number, number];
65
+ yDomain: [number, number];
66
+ value: { x: number; y: number };
67
+ },
68
+ value: { x: number; y: number }
69
+ ) => void
70
+ ) {
71
+ return (e: PointerEvent) => {
72
+ const start = {
73
+ xDomain: [xDomain[0] ?? xDomainMin, xDomain[1] ?? xDomainMax] as [number, number],
74
+ yDomain: [yDomain[0] ?? yDomainMin, yDomain[1] ?? yDomainMax] as [number, number],
75
+ value: {
76
+ x: $xScale.invert?.((localPoint(frameEl, e)?.x ?? 0) - $padding.left),
77
+ y: $yScale.invert?.((localPoint(frameEl, e)?.y ?? 0) - $padding.top),
78
+ },
79
+ };
80
+
81
+ dispatch('brushStart', { xDomain, yDomain });
82
+
83
+ const onPointerMove = (e: PointerEvent) => {
84
+ fn(start, {
85
+ x: $xScale.invert?.((localPoint(frameEl, e)?.x ?? 0) - $padding.left),
86
+ y: $yScale.invert?.((localPoint(frameEl, e)?.y ?? 0) - $padding.top),
87
+ });
88
+
89
+ // if (xDomain[0] === xDomain[1] || yDomain[0] === yDomain[1]) {
90
+ // // Ignore?
91
+ // // TODO: What about when using `x` or `y` axis?
92
+ // } else {
93
+ dispatch('change', { xDomain, yDomain });
94
+ // }
95
+ };
96
+
97
+ const onPointerUp = (e: PointerEvent) => {
98
+ if (e.target === frameEl) {
99
+ reset();
100
+ dispatch('change', { xDomain, yDomain });
101
+ }
102
+
103
+ dispatch('brushEnd', { xDomain, yDomain });
104
+
105
+ if (resetOnEnd) {
106
+ reset();
107
+ }
108
+
109
+ window.removeEventListener('pointermove', onPointerMove);
110
+ window.removeEventListener('pointerup', onPointerUp);
111
+ };
112
+
113
+ window.addEventListener('pointermove', onPointerMove);
114
+ window.addEventListener('pointerup', onPointerUp);
67
115
  };
68
- }
69
- const createRange = handler((start, value) => {
116
+ }
117
+
118
+ const createRange = handler((start, value) => {
70
119
  isActive = true;
120
+
71
121
  xDomain = [
72
- clamp(Math.min(start.value.x, value.x), xDomainMin, xDomainMax),
73
- clamp(Math.max(start.value.x, value.x), xDomainMin, xDomainMax),
122
+ clamp(Math.min(start.value.x, value.x), xDomainMin, xDomainMax),
123
+ clamp(Math.max(start.value.x, value.x), xDomainMin, xDomainMax),
74
124
  ];
125
+
75
126
  yDomain = [
76
- clamp(Math.min(start.value.y, value.y), yDomainMin, yDomainMax),
77
- clamp(Math.max(start.value.y, value.y), yDomainMin, yDomainMax),
127
+ clamp(Math.min(start.value.y, value.y), yDomainMin, yDomainMax),
128
+ clamp(Math.max(start.value.y, value.y), yDomainMin, yDomainMax),
78
129
  ];
79
- });
80
- const adjustRange = handler((start, value) => {
81
- const dx = clamp(value.x - start.value.x, xDomainMin - start.xDomain[0], xDomainMax - start.xDomain[1]);
130
+ });
131
+
132
+ const adjustRange = handler((start, value) => {
133
+ const dx = clamp(
134
+ value.x - start.value.x,
135
+ xDomainMin - start.xDomain[0],
136
+ xDomainMax - start.xDomain[1]
137
+ );
82
138
  xDomain = [Number(start.xDomain[0]) + dx, Number(start.xDomain[1]) + dx];
83
- const dy = clamp(value.y - start.value.y, yDomainMin - start.yDomain[0], yDomainMax - start.yDomain[1]);
139
+
140
+ const dy = clamp(
141
+ value.y - start.value.y,
142
+ yDomainMin - start.yDomain[0],
143
+ yDomainMax - start.yDomain[1]
144
+ );
84
145
  yDomain = [Number(start.yDomain[0]) + dy, Number(start.yDomain[1]) + dy];
85
- });
86
- const adjustBottom = handler((start, value) => {
146
+ });
147
+
148
+ const adjustBottom = handler((start, value) => {
87
149
  yDomain = [
88
- clamp(value.y > start.yDomain[1] ? start.yDomain[1] : value.y, yDomainMin, yDomainMax),
89
- clamp(value.y > start.yDomain[1] ? value.y : start.yDomain[1], yDomainMin, yDomainMax),
150
+ clamp(value.y > start.yDomain[1] ? start.yDomain[1] : value.y, yDomainMin, yDomainMax),
151
+ clamp(value.y > start.yDomain[1] ? value.y : start.yDomain[1], yDomainMin, yDomainMax),
90
152
  ];
91
- });
92
- const adjustTop = handler((start, value) => {
153
+ });
154
+
155
+ const adjustTop = handler((start, value) => {
93
156
  yDomain = [
94
- clamp(value.y < start.yDomain[1] ? value.y : start.yDomain[0], yDomainMin, yDomainMax),
95
- clamp(value.y < start.yDomain[1] ? start.yDomain[0] : value.y, yDomainMin, yDomainMax),
157
+ clamp(value.y < start.yDomain[1] ? value.y : start.yDomain[0], yDomainMin, yDomainMax),
158
+ clamp(value.y < start.yDomain[1] ? start.yDomain[0] : value.y, yDomainMin, yDomainMax),
96
159
  ];
97
- });
98
- const adjustLeft = handler((start, value) => {
160
+ });
161
+
162
+ const adjustLeft = handler((start, value) => {
99
163
  xDomain = [
100
- clamp(value.x > start.xDomain[1] ? start.xDomain[1] : value.x, xDomainMin, xDomainMax),
101
- clamp(value.x > start.xDomain[1] ? value.x : start.xDomain[1], xDomainMin, xDomainMax),
164
+ clamp(value.x > start.xDomain[1] ? start.xDomain[1] : value.x, xDomainMin, xDomainMax),
165
+ clamp(value.x > start.xDomain[1] ? value.x : start.xDomain[1], xDomainMin, xDomainMax),
102
166
  ];
103
- });
104
- const adjustRight = handler((start, value) => {
167
+ });
168
+
169
+ const adjustRight = handler((start, value) => {
105
170
  xDomain = [
106
- clamp(value.x < start.xDomain[0] ? value.x : start.xDomain[0], xDomainMin, xDomainMax),
107
- clamp(value.x < start.xDomain[0] ? start.xDomain[0] : value.x, xDomainMin, xDomainMax),
171
+ clamp(value.x < start.xDomain[0] ? value.x : start.xDomain[0], xDomainMin, xDomainMax),
172
+ clamp(value.x < start.xDomain[0] ? start.xDomain[0] : value.x, xDomainMin, xDomainMax),
108
173
  ];
109
- });
110
- function reset() {
174
+ });
175
+
176
+ function reset() {
111
177
  isActive = false;
178
+
112
179
  xDomain = originalXDomain;
113
180
  yDomain = originalYDomain;
114
- }
115
- function selectAll() {
181
+ }
182
+
183
+ function selectAll() {
116
184
  xDomain = [xDomainMin, xDomainMax];
117
185
  yDomain = [yDomainMin, yDomainMax];
118
- }
119
- $: top = $yScale(yDomain[1]);
120
- $: bottom = $yScale(yDomain[0]);
121
- $: left = $xScale(xDomain[0]);
122
- $: right = $xScale(xDomain[1]);
123
- $: rangeTop = axis === 'both' || axis === 'y' ? top : 0;
124
- $: rangeLeft = axis === 'both' || axis === 'x' ? left : 0;
125
- $: rangeWidth = axis === 'both' || axis === 'x' ? right - left : $width;
126
- $: rangeHeight = axis === 'both' || axis === 'y' ? bottom - top : $height;
127
- // Set reactively to handle cases where xDomain/yDomain are set externally (ex. `bind:xDomain`)
128
- $: isActive =
186
+ }
187
+
188
+ $: top = $yScale(yDomain[1]);
189
+ $: bottom = $yScale(yDomain[0]);
190
+ $: left = $xScale(xDomain[0]);
191
+ $: right = $xScale(xDomain[1]);
192
+
193
+ $: rangeTop = axis === 'both' || axis === 'y' ? top : 0;
194
+ $: rangeLeft = axis === 'both' || axis === 'x' ? left : 0;
195
+ $: rangeWidth = axis === 'both' || axis === 'x' ? right - left : $width;
196
+ $: rangeHeight = axis === 'both' || axis === 'y' ? bottom - top : $height;
197
+
198
+ // Set reactively to handle cases where xDomain/yDomain are set externally (ex. `bind:xDomain`)
199
+ $: isActive =
129
200
  xDomain[0]?.valueOf() !== originalXDomain[0]?.valueOf() ||
130
- xDomain[1]?.valueOf() !== originalXDomain[1]?.valueOf() ||
131
- yDomain[0]?.valueOf() !== originalYDomain[0]?.valueOf() ||
132
- yDomain[1]?.valueOf() !== originalYDomain[1]?.valueOf();
201
+ xDomain[1]?.valueOf() !== originalXDomain[1]?.valueOf() ||
202
+ yDomain[0]?.valueOf() !== originalYDomain[0]?.valueOf() ||
203
+ yDomain[1]?.valueOf() !== originalYDomain[1]?.valueOf();
133
204
  </script>
134
205
 
135
206
  <g class={cls('Brush select-none', classes.root, $$props.class)}>