layerchart 0.54.0 → 0.55.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 (105) 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 +205 -155
  5. package/dist/components/Bar.svelte +72 -45
  6. package/dist/components/Bars.svelte +45 -34
  7. package/dist/components/Blur.svelte +5 -3
  8. package/dist/components/Bounds.svelte +37 -21
  9. package/dist/components/Brush.svelte +269 -112
  10. package/dist/components/Brush.svelte.d.ts +7 -0
  11. package/dist/components/Calendar.svelte +51 -38
  12. package/dist/components/Chart.svelte +295 -74
  13. package/dist/components/Chart.svelte.d.ts +17 -17
  14. package/dist/components/ChartClipPath.svelte +8 -5
  15. package/dist/components/ChartContext.svelte +243 -93
  16. package/dist/components/ChartContext.svelte.d.ts +15 -23
  17. package/dist/components/Circle.svelte +25 -16
  18. package/dist/components/CircleClipPath.svelte +16 -10
  19. package/dist/components/ClipPath.svelte +11 -7
  20. package/dist/components/ColorRamp.svelte +12 -10
  21. package/dist/components/ForceSimulation.svelte +185 -116
  22. package/dist/components/Frame.svelte +10 -6
  23. package/dist/components/GeoCircle.svelte +15 -9
  24. package/dist/components/GeoContext.svelte +109 -62
  25. package/dist/components/GeoEdgeFade.svelte +20 -14
  26. package/dist/components/GeoPath.svelte +107 -69
  27. package/dist/components/GeoPoint.svelte +32 -18
  28. package/dist/components/GeoSpline.svelte +30 -22
  29. package/dist/components/GeoTile.svelte +40 -30
  30. package/dist/components/GeoVisible.svelte +10 -7
  31. package/dist/components/Graticule.svelte +14 -8
  32. package/dist/components/Grid.svelte +75 -48
  33. package/dist/components/Group.svelte +43 -31
  34. package/dist/components/Highlight.svelte +284 -243
  35. package/dist/components/HitCanvas.svelte +75 -42
  36. package/dist/components/Hull.svelte +40 -20
  37. package/dist/components/Labels.svelte +81 -70
  38. package/dist/components/Legend.svelte +105 -74
  39. package/dist/components/Legend.svelte.d.ts +1 -1
  40. package/dist/components/Line.svelte +65 -19
  41. package/dist/components/Line.svelte.d.ts +13 -1
  42. package/dist/components/LinearGradient.svelte +21 -15
  43. package/dist/components/Link.svelte +94 -22
  44. package/dist/components/Link.svelte.d.ts +17 -1
  45. package/dist/components/Marker.svelte +81 -0
  46. package/dist/components/Marker.svelte.d.ts +28 -0
  47. package/dist/components/MonthPath.svelte +23 -16
  48. package/dist/components/MotionPath.svelte +34 -25
  49. package/dist/components/Pack.svelte +21 -14
  50. package/dist/components/Partition.svelte +35 -20
  51. package/dist/components/Pattern.svelte +8 -6
  52. package/dist/components/Pie.svelte +76 -57
  53. package/dist/components/Point.svelte +11 -7
  54. package/dist/components/Points.svelte +178 -143
  55. package/dist/components/RadialGradient.svelte +25 -18
  56. package/dist/components/Rect.svelte +33 -19
  57. package/dist/components/RectClipPath.svelte +16 -11
  58. package/dist/components/Rule.svelte +50 -42
  59. package/dist/components/Sankey.svelte +55 -30
  60. package/dist/components/Spline.svelte +167 -96
  61. package/dist/components/Spline.svelte.d.ts +15 -0
  62. package/dist/components/Text.svelte +137 -104
  63. package/dist/components/Threshold.svelte +18 -7
  64. package/dist/components/TileImage.svelte +56 -50
  65. package/dist/components/TransformContext.svelte +235 -135
  66. package/dist/components/TransformControls.svelte +57 -29
  67. package/dist/components/TransformControls.svelte.d.ts +1 -1
  68. package/dist/components/Tree.svelte +33 -23
  69. package/dist/components/Treemap.svelte +69 -41
  70. package/dist/components/Voronoi.svelte +55 -28
  71. package/dist/components/charts/AreaChart.svelte +138 -87
  72. package/dist/components/charts/AreaChart.svelte.d.ts +4 -4
  73. package/dist/components/charts/BarChart.svelte +179 -114
  74. package/dist/components/charts/BarChart.svelte.d.ts +4 -4
  75. package/dist/components/charts/LineChart.svelte +97 -53
  76. package/dist/components/charts/LineChart.svelte.d.ts +4 -4
  77. package/dist/components/charts/PieChart.svelte +104 -54
  78. package/dist/components/charts/PieChart.svelte.d.ts +3 -3
  79. package/dist/components/charts/ScatterChart.svelte +83 -48
  80. package/dist/components/charts/ScatterChart.svelte.d.ts +4 -4
  81. package/dist/components/layout/Canvas.svelte +63 -43
  82. package/dist/components/layout/Html.svelte +28 -18
  83. package/dist/components/layout/Svg.svelte +47 -32
  84. package/dist/components/tooltip/Tooltip.svelte +137 -91
  85. package/dist/components/tooltip/Tooltip.svelte.d.ts +1 -1
  86. package/dist/components/tooltip/TooltipContext.svelte +315 -249
  87. package/dist/components/tooltip/TooltipHeader.svelte +9 -3
  88. package/dist/components/tooltip/TooltipItem.svelte +17 -9
  89. package/dist/components/tooltip/TooltipList.svelte +2 -1
  90. package/dist/components/tooltip/TooltipSeparator.svelte +3 -2
  91. package/dist/docs/Blockquote.svelte +4 -3
  92. package/dist/docs/Code.svelte +15 -8
  93. package/dist/docs/CurveMenuField.svelte +17 -12
  94. package/dist/docs/GeoDebug.svelte +13 -9
  95. package/dist/docs/Header1.svelte +2 -1
  96. package/dist/docs/Json.svelte +6 -4
  97. package/dist/docs/Layout.svelte +6 -6
  98. package/dist/docs/PathDataMenuField.svelte +52 -44
  99. package/dist/docs/Preview.svelte +39 -33
  100. package/dist/docs/TilesetField.svelte +80 -62
  101. package/dist/docs/TransformDebug.svelte +8 -5
  102. package/dist/docs/ViewSourceButton.svelte +13 -9
  103. package/dist/stores/motionStore.d.ts +1 -1
  104. package/dist/utils/scales.d.ts +3 -3
  105. package/package.json +29 -30
@@ -1,309 +1,375 @@
1
- <script context="module">import { getContext, setContext } from 'svelte';
2
- export const tooltipContextKey = Symbol();
3
- const defaultContext = writable({
1
+ <script lang="ts" context="module">
2
+ import { getContext, setContext } from 'svelte';
3
+ import type { Readable } from 'svelte/store';
4
+
5
+ export const tooltipContextKey = Symbol();
6
+
7
+ export type TooltipContextValue = {
8
+ x: number;
9
+ y: number;
10
+ data: any;
11
+ show(e: PointerEvent, tooltipData?: any): void;
12
+ hide(e?: PointerEvent): void;
13
+ };
14
+
15
+ export type TooltipContext = Readable<TooltipContextValue>;
16
+
17
+ const defaultContext: TooltipContext = writable({
4
18
  x: 0,
5
19
  y: 0,
6
- data: null,
7
- show: () => { },
8
- hide: () => { },
9
- });
10
- export function tooltipContext() {
11
- return getContext(tooltipContextKey) ?? defaultContext;
12
- }
13
- function setTooltipContext(tooltip) {
20
+ data: null as any,
21
+ show: () => {},
22
+ hide: () => {},
23
+ });
24
+ export function tooltipContext() {
25
+ return getContext<TooltipContext>(tooltipContextKey) ?? defaultContext;
26
+ }
27
+
28
+ function setTooltipContext(tooltip: TooltipContext) {
14
29
  setContext(tooltipContextKey, tooltip);
15
- }
30
+ }
16
31
  </script>
17
32
 
18
- <script>import { raise } from 'layercake';
19
- import { writable } from 'svelte/store';
20
- import { bisector, max, min } from 'd3-array';
21
- import { quadtree as d3Quadtree } from 'd3-quadtree';
22
- import { sortFunc } from '@layerstack/utils';
23
- import { cls } from '@layerstack/tailwind';
24
- import Svg from './../layout/Svg.svelte';
25
- import { chartContext } from './../ChartContext.svelte';
26
- import ChartClipPath from './../ChartClipPath.svelte';
27
- import Voronoi from './../Voronoi.svelte';
28
- import { localPoint } from '../../utils/event.js';
29
- import { isScaleBand, scaleInvert } from '../../utils/scales.js';
30
- import { cartesianToPolar } from '../../utils/math.js';
31
- import { quadtreeRects } from '../../utils/quadtree.js';
32
- const { flatData, x, xScale, xGet, xRange, y, yScale, yGet, yRange, width, height, containerWidth, containerHeight, padding, radial, } = chartContext();
33
- /*
34
- TODO: Defaults to consider (if possible to detect scale type, which might not be possible)
35
- - scaleTime / scaleLinear: bisect
36
- - scaleTime / scaleLinear (multi/stack): bisect
37
- - scaleTime / scaleBand: bisect (or band)
38
- - scaleTime (multi) / scaleBand: bounds (or possible band if not overlapping)
39
- - scaleBand, scaleLinear: band (or bounds)
40
- - scaleBand, scaleLinear: band (or bounds) - multiple (overlapping) bars
41
- - scaleLinear, scaleLinear: voronoi (or quadtree)
42
- */
43
- /**
44
- * @type {'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual'}
45
- */
46
- export let mode = 'manual';
47
- /**
48
- * @type {'closest' | 'left' | 'right'}
49
- */
50
- export let findTooltipData = 'closest';
51
- /** Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so to be the top-most element */
52
- export let raiseTarget = false;
53
- /** quadtree search radius
54
- * @type {number}
55
- */
56
- export let radius = Infinity;
57
- /** Enable debug view (show hit targets, etc) */
58
- export let debug = false;
59
- export let onClick = () => { };
60
- /** Exposed to allow binding in Chart */
61
- export let tooltip = writable({
33
+ <script lang="ts">
34
+ import { raise } from 'layercake';
35
+ import { writable } from 'svelte/store';
36
+ import { bisector, max, min } from 'd3-array';
37
+ import { quadtree as d3Quadtree, type Quadtree } from 'd3-quadtree';
38
+ import { sortFunc } from '@layerstack/utils';
39
+ import { cls } from '@layerstack/tailwind';
40
+
41
+ import Svg from './../layout/Svg.svelte';
42
+ import { chartContext } from './../ChartContext.svelte';
43
+ import ChartClipPath from './../ChartClipPath.svelte';
44
+ import Voronoi from './../Voronoi.svelte';
45
+
46
+ import { localPoint } from '../../utils/event.js';
47
+ import { isScaleBand, scaleInvert } from '../../utils/scales.js';
48
+ import { cartesianToPolar } from '../../utils/math.js';
49
+ import { quadtreeRects } from '../../utils/quadtree.js';
50
+
51
+ const {
52
+ flatData,
53
+ x,
54
+ xScale,
55
+ xGet,
56
+ xRange,
57
+ y,
58
+ yScale,
59
+ yGet,
60
+ yRange,
61
+ width,
62
+ height,
63
+ containerWidth,
64
+ containerHeight,
65
+ padding,
66
+ radial,
67
+ } = chartContext<any>();
68
+
69
+ /*
70
+ TODO: Defaults to consider (if possible to detect scale type, which might not be possible)
71
+ - scaleTime / scaleLinear: bisect
72
+ - scaleTime / scaleLinear (multi/stack): bisect
73
+ - scaleTime / scaleBand: bisect (or band)
74
+ - scaleTime (multi) / scaleBand: bounds (or possible band if not overlapping)
75
+ - scaleBand, scaleLinear: band (or bounds)
76
+ - scaleBand, scaleLinear: band (or bounds) - multiple (overlapping) bars
77
+ - scaleLinear, scaleLinear: voronoi (or quadtree)
78
+ */
79
+
80
+ /**
81
+ * @type {'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual'}
82
+ */
83
+ export let mode:
84
+ | 'bisect-x'
85
+ | 'bisect-y'
86
+ | 'band'
87
+ | 'bisect-band'
88
+ | 'bounds'
89
+ | 'voronoi'
90
+ | 'quadtree'
91
+ | 'manual' = 'manual';
92
+ /**
93
+ * @type {'closest' | 'left' | 'right'}
94
+ */
95
+ export let findTooltipData: 'closest' | 'left' | 'right' = 'closest';
96
+
97
+ /** Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so to be the top-most element */
98
+ export let raiseTarget = false;
99
+
100
+ /** quadtree search radius
101
+ * @type {number}
102
+ */
103
+ export let radius: number = Infinity;
104
+ /** Enable debug view (show hit targets, etc) */
105
+ export let debug = false;
106
+
107
+ export let onClick: ({ data }: { data: any }) => any = () => {};
108
+
109
+ /** Exposed to allow binding in Chart */
110
+ export let tooltip = writable({
62
111
  y: 0,
63
112
  x: 0,
64
- data: null,
113
+ data: null as any,
65
114
  show: showTooltip,
66
115
  hide: hideTooltip,
67
- });
68
- setTooltipContext(tooltip);
69
- let hideTimeoutId;
70
- $: bisectX = bisector((d) => {
116
+ });
117
+ setTooltipContext(tooltip);
118
+
119
+ let hideTimeoutId: NodeJS.Timeout;
120
+
121
+ $: bisectX = bisector((d: any) => {
71
122
  const value = $x(d);
72
123
  if (Array.isArray(value)) {
73
- // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
74
- // Using first value. Consider using average, max, etc
75
- // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
76
- // return midpoint;
77
- return value[0];
78
- }
79
- else {
80
- return value;
124
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
125
+ // Using first value. Consider using average, max, etc
126
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
127
+ // return midpoint;
128
+ return value[0];
129
+ } else {
130
+ return value;
81
131
  }
82
- }).left;
83
- $: bisectY = bisector((d) => {
132
+ }).left;
133
+
134
+ $: bisectY = bisector((d: any) => {
84
135
  const value = $y(d);
85
136
  if (Array.isArray(value)) {
86
- // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
87
- // Using first value. Consider using average, max, etc
88
- // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
89
- // return midpoint;
90
- return value[0];
91
- }
92
- else {
93
- return value;
137
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
138
+ // Using first value. Consider using average, max, etc
139
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
140
+ // return midpoint;
141
+ return value[0];
142
+ } else {
143
+ return value;
94
144
  }
95
- }).left;
96
- function findData(previousValue, currentValue, valueAtPoint, accessor) {
145
+ }).left;
146
+
147
+ function findData(previousValue: any, currentValue: any, valueAtPoint: any, accessor: Function) {
97
148
  switch (findTooltipData) {
98
- case 'closest':
99
- if (currentValue === undefined) {
100
- return previousValue;
101
- }
102
- else if (previousValue === undefined) {
103
- return currentValue;
104
- }
105
- else {
106
- return Number(valueAtPoint) - Number(accessor(previousValue)) >
107
- Number(accessor(currentValue)) - Number(valueAtPoint)
108
- ? currentValue
109
- : previousValue;
110
- }
111
- case 'left':
112
- return previousValue;
113
- case 'right':
114
- default:
115
- return currentValue;
149
+ case 'closest':
150
+ if (currentValue === undefined) {
151
+ return previousValue;
152
+ } else if (previousValue === undefined) {
153
+ return currentValue;
154
+ } else {
155
+ return Number(valueAtPoint) - Number(accessor(previousValue)) >
156
+ Number(accessor(currentValue)) - Number(valueAtPoint)
157
+ ? currentValue
158
+ : previousValue;
159
+ }
160
+ case 'left':
161
+ return previousValue;
162
+ case 'right':
163
+ default:
164
+ return currentValue;
116
165
  }
117
- }
118
- function showTooltip(e, tooltipData) {
166
+ }
167
+
168
+ function showTooltip(e: PointerEvent, tooltipData?: any) {
119
169
  // Cancel hiding tooltip if from previous event loop
120
170
  clearTimeout(hideTimeoutId);
121
- const referenceNode = e.target.closest('.layercake-container');
171
+
172
+ const referenceNode = (e.target as Element).closest('.layercake-container')!;
122
173
  const point = localPoint(referenceNode, e);
123
174
  const localX = point?.x ?? 0;
124
175
  const localY = point?.y ?? 0;
176
+
125
177
  if (
126
- // @ts-expect-error
127
- e.offsetX < e.currentTarget?.offsetLeft ||
128
- // @ts-expect-error
129
- e.offsetX > e.currentTarget?.offsetLeft + e.currentTarget?.offsetWidth ||
130
- // @ts-expect-error
131
- e.offsetY < e.currentTarget?.offsetTop ||
132
- // @ts-expect-error
133
- e.offsetY > e.currentTarget?.offsetTop + e.currentTarget?.offsetHeight) {
134
- // Ignore if within padding of chart
135
- hideTooltip();
136
- return;
178
+ // @ts-expect-error
179
+ e.offsetX < e.currentTarget?.offsetLeft ||
180
+ // @ts-expect-error
181
+ e.offsetX > e.currentTarget?.offsetLeft + e.currentTarget?.offsetWidth ||
182
+ // @ts-expect-error
183
+ e.offsetY < e.currentTarget?.offsetTop ||
184
+ // @ts-expect-error
185
+ e.offsetY > e.currentTarget?.offsetTop + e.currentTarget?.offsetHeight
186
+ ) {
187
+ // Ignore if within padding of chart
188
+ hideTooltip();
189
+ return;
137
190
  }
191
+
138
192
  // If tooltipData not provided already (voronoi, etc), attempt to find it
139
193
  // TODO: When using bisect-x/y/band, values should be sorted. Typically they are for `x`, but not `y` (and band depends on if x or y scale)
140
194
  if (tooltipData == null) {
141
- switch (mode) {
142
- case 'bisect-x': {
143
- let xValueAtPoint;
144
- if ($radial) {
145
- // Assume radial is always centered
146
- const { radians } = cartesianToPolar(localX - $width / 2, localY - $height / 2);
147
- xValueAtPoint = scaleInvert($xScale, radians);
148
- }
149
- else {
150
- xValueAtPoint = scaleInvert($xScale, localX - $padding.left);
151
- }
152
- const index = bisectX($flatData, xValueAtPoint, 1);
153
- const previousValue = $flatData[index - 1];
154
- const currentValue = $flatData[index];
155
- tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
156
- break;
157
- }
158
- case 'bisect-y': {
159
- // `y` value at pointer coordinate
160
- const yValueAtPoint = scaleInvert($yScale, localY - $padding.top);
161
- const index = bisectY($flatData, yValueAtPoint, 1);
162
- const previousValue = $flatData[index - 1];
163
- const currentValue = $flatData[index];
164
- tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
165
- break;
166
- }
167
- case 'bisect-band': {
168
- // `x` and `y` values at pointer coordinate
169
- const xValueAtPoint = scaleInvert($xScale, localX);
170
- const yValueAtPoint = scaleInvert($yScale, localY);
171
- if (isScaleBand($xScale)) {
172
- // Find point closest to pointer within the x band
173
- const bandData = $flatData
174
- .filter((d) => $x(d) === xValueAtPoint)
175
- .sort(sortFunc($y)); // sort for bisect
176
- const index = bisectY(bandData, yValueAtPoint, 1);
177
- const previousValue = bandData[index - 1];
178
- const currentValue = bandData[index];
179
- tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
180
- }
181
- else if (isScaleBand($yScale)) {
182
- // Find point closest to pointer within the y band
183
- const bandData = $flatData
184
- .filter((d) => $y(d) === yValueAtPoint)
185
- .sort(sortFunc($x)); // sort for bisect
186
- const index = bisectX(bandData, xValueAtPoint, 1);
187
- const previousValue = bandData[index - 1];
188
- const currentValue = bandData[index];
189
- tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
190
- }
191
- else {
192
- // TODO: Support `bisect-band` without band? Fallback to bisect?
193
- }
194
- break;
195
- }
196
- case 'quadtree': {
197
- tooltipData = quadtree.find(localX, localY, radius);
198
- break;
199
- }
195
+ switch (mode) {
196
+ case 'bisect-x': {
197
+ let xValueAtPoint: any;
198
+ if ($radial) {
199
+ // Assume radial is always centered
200
+ const { radians } = cartesianToPolar(localX - $width / 2, localY - $height / 2);
201
+ xValueAtPoint = scaleInvert($xScale, radians);
202
+ } else {
203
+ xValueAtPoint = scaleInvert($xScale, localX - $padding.left);
204
+ }
205
+
206
+ const index = bisectX($flatData, xValueAtPoint, 1);
207
+ const previousValue = $flatData[index - 1];
208
+ const currentValue = $flatData[index];
209
+ tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
210
+ break;
200
211
  }
201
- }
202
- if (tooltipData) {
203
- if (raiseTarget) {
204
- raise(e.target);
212
+
213
+ case 'bisect-y': {
214
+ // `y` value at pointer coordinate
215
+ const yValueAtPoint = scaleInvert($yScale, localY - $padding.top);
216
+
217
+ const index = bisectY($flatData, yValueAtPoint, 1);
218
+ const previousValue = $flatData[index - 1];
219
+ const currentValue = $flatData[index];
220
+ tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
221
+ break;
222
+ }
223
+
224
+ case 'bisect-band': {
225
+ // `x` and `y` values at pointer coordinate
226
+ const xValueAtPoint = scaleInvert($xScale, localX);
227
+ const yValueAtPoint = scaleInvert($yScale, localY);
228
+
229
+ if (isScaleBand($xScale)) {
230
+ // Find point closest to pointer within the x band
231
+ const bandData = $flatData
232
+ .filter((d) => $x(d) === xValueAtPoint)
233
+ .sort(sortFunc($y as () => any)); // sort for bisect
234
+ const index = bisectY(bandData, yValueAtPoint, 1);
235
+ const previousValue = bandData[index - 1];
236
+ const currentValue = bandData[index];
237
+ tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
238
+ } else if (isScaleBand($yScale)) {
239
+ // Find point closest to pointer within the y band
240
+ const bandData = $flatData
241
+ .filter((d) => $y(d) === yValueAtPoint)
242
+ .sort(sortFunc($x as () => any)); // sort for bisect
243
+ const index = bisectX(bandData, xValueAtPoint, 1);
244
+ const previousValue = bandData[index - 1];
245
+ const currentValue = bandData[index];
246
+ tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
247
+ } else {
248
+ // TODO: Support `bisect-band` without band? Fallback to bisect?
249
+ }
250
+ break;
251
+ }
252
+
253
+ case 'quadtree': {
254
+ tooltipData = quadtree.find(localX, localY, radius);
255
+ break;
205
256
  }
206
- $tooltip = {
207
- ...$tooltip,
208
- x: localX,
209
- y: localY,
210
- data: tooltipData,
211
- };
257
+ }
212
258
  }
213
- else {
214
- // Hide tooltip if unable to locate
215
- hideTooltip();
259
+
260
+ if (tooltipData) {
261
+ if (raiseTarget) {
262
+ raise(e.target as Element);
263
+ }
264
+
265
+ $tooltip = {
266
+ ...$tooltip,
267
+ x: localX,
268
+ y: localY,
269
+ data: tooltipData,
270
+ };
271
+ } else {
272
+ // Hide tooltip if unable to locate
273
+ hideTooltip();
216
274
  }
217
- }
218
- function hideTooltip() {
275
+ }
276
+
277
+ function hideTooltip() {
219
278
  // Wait an event loop tick in case `showTooltip` is called immediately on another element, to allow tweeneing (ex. moving between bands/bars)
220
279
  hideTimeoutId = setTimeout(() => {
221
- $tooltip = { ...$tooltip, data: null };
280
+ $tooltip = { ...$tooltip, data: null };
222
281
  });
223
- }
224
- let quadtree;
225
- $: if (mode === 'quadtree') {
282
+ }
283
+
284
+ let quadtree: Quadtree<[number, number]>;
285
+ $: if (mode === 'quadtree') {
226
286
  quadtree = d3Quadtree()
227
- .extent([
287
+ .extent([
228
288
  [0, 0],
229
289
  [$width, $height],
230
- ])
231
- .x((d) => {
290
+ ])
291
+ .x((d) => {
232
292
  const value = $xGet(d);
293
+
233
294
  if (Array.isArray(value)) {
234
- // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
235
- // Using first value. Consider using average, max, etc
236
- // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
237
- // return midpoint;
238
- return min(value);
239
- }
240
- else {
241
- return value;
295
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
296
+ // Using first value. Consider using average, max, etc
297
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
298
+ // return midpoint;
299
+ return min(value);
300
+ } else {
301
+ return value;
242
302
  }
243
- })
244
- .y((d) => {
303
+ })
304
+ .y((d) => {
245
305
  const value = $yGet(d);
306
+
246
307
  if (Array.isArray(value)) {
247
- // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
248
- // Using first value. Consider using average, max, etc
249
- // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
250
- // return midpoint;
251
- return min(value);
252
- }
253
- else {
254
- return value;
308
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
309
+ // Using first value. Consider using average, max, etc
310
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
311
+ // return midpoint;
312
+ return min(value);
313
+ } else {
314
+ return value;
255
315
  }
256
- })
257
- .addAll($flatData);
258
- }
259
- let rects = [];
260
- $: if (mode === 'bounds' || mode === 'band') {
316
+ })
317
+ .addAll($flatData as [number, number][]);
318
+ }
319
+
320
+ let rects: Array<{ x: number; y: number; width: number; height: number; data: any }> = [];
321
+ $: if (mode === 'bounds' || mode === 'band') {
261
322
  // @ts-expect-error
262
323
  rects = $flatData
263
- .map((d) => {
324
+ .map((d) => {
264
325
  const xValue = $xGet(d);
265
326
  const yValue = $yGet(d);
327
+
266
328
  const x = Array.isArray(xValue) ? xValue[0] : xValue;
267
329
  const y = Array.isArray(yValue) ? yValue[0] : yValue;
330
+
268
331
  const xOffset = isScaleBand($xScale) ? ($xScale.padding() * $xScale.step()) / 2 : 0;
269
332
  const yOffset = isScaleBand($yScale) ? ($yScale.padding() * $yScale.step()) / 2 : 0;
333
+
270
334
  // @ts-expect-error
271
335
  const fullWidth = max($xRange) - min($xRange);
272
336
  // @ts-expect-error
273
337
  const fullHeight = max($yRange) - min($yRange);
338
+
274
339
  if (mode === 'band') {
275
- // full band width/height regardless of value
276
- return {
277
- x: isScaleBand($xScale) ? x - xOffset : min($xRange),
278
- y: isScaleBand($yScale) ? y - yOffset : min($yRange),
279
- width: isScaleBand($xScale) ? $xScale.step() : fullWidth,
280
- height: isScaleBand($yScale) ? $yScale.step() : fullHeight,
281
- data: d,
282
- };
283
- }
284
- else if (mode === 'bounds') {
285
- return {
286
- x: isScaleBand($xScale) || Array.isArray(xValue) ? x - xOffset : min($xRange),
287
- // y: isScaleBand($yScale) || Array.isArray(yValue) ? y - yOffset : min($yRange),
288
- y: y - yOffset,
289
- width: Array.isArray(xValue)
290
- ? xValue[1] - xValue[0]
291
- : isScaleBand($xScale)
292
- ? $xScale.step()
293
- : min($xRange) + x,
294
- height: Array.isArray(yValue)
295
- ? yValue[1] - yValue[0]
296
- : isScaleBand($yScale)
297
- ? $yScale.step()
298
- : // @ts-expect-error
299
- max($yRange) - y,
300
- data: d,
301
- };
340
+ // full band width/height regardless of value
341
+ return {
342
+ x: isScaleBand($xScale) ? x - xOffset : min($xRange),
343
+ y: isScaleBand($yScale) ? y - yOffset : min($yRange),
344
+ width: isScaleBand($xScale) ? $xScale.step() : fullWidth,
345
+ height: isScaleBand($yScale) ? $yScale.step() : fullHeight,
346
+ data: d,
347
+ };
348
+ } else if (mode === 'bounds') {
349
+ return {
350
+ x: isScaleBand($xScale) || Array.isArray(xValue) ? x - xOffset : min($xRange),
351
+ // y: isScaleBand($yScale) || Array.isArray(yValue) ? y - yOffset : min($yRange),
352
+ y: y - yOffset,
353
+
354
+ width: Array.isArray(xValue)
355
+ ? xValue[1] - xValue[0]
356
+ : isScaleBand($xScale)
357
+ ? $xScale.step()
358
+ : min($xRange) + x,
359
+ height: Array.isArray(yValue)
360
+ ? yValue[1] - yValue[0]
361
+ : isScaleBand($yScale)
362
+ ? $yScale.step()
363
+ : // @ts-expect-error
364
+ max($yRange) - y,
365
+ data: d,
366
+ };
302
367
  }
303
- })
304
- .sort(sortFunc('x'));
305
- }
306
- $: triggerPointEvents = ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode);
368
+ })
369
+ .sort(sortFunc('x'));
370
+ }
371
+
372
+ $: triggerPointEvents = ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode);
307
373
  </script>
308
374
 
309
375
  <!-- svelte-ignore a11y-click-events-have-key-events -->
@@ -1,6 +1,12 @@
1
- <script>import { cls } from '@layerstack/tailwind';
2
- export let color = undefined;
3
- export let classes = {};
1
+ <script lang="ts">
2
+ import { cls } from '@layerstack/tailwind';
3
+
4
+ export let color: string | undefined = undefined;
5
+
6
+ export let classes: {
7
+ root?: string;
8
+ color?: string;
9
+ } = {};
4
10
  </script>
5
11
 
6
12
  <div