layerchart 2.0.0-next.1 → 2.0.0-next.3

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 (266) hide show
  1. package/dist/actions/movable.d.ts +28 -0
  2. package/dist/actions/movable.js +91 -0
  3. package/dist/components/AnnotationLine.svelte +143 -0
  4. package/dist/components/AnnotationLine.svelte.d.ts +30 -0
  5. package/dist/components/AnnotationPoint.svelte +119 -0
  6. package/dist/components/AnnotationPoint.svelte.d.ts +34 -0
  7. package/dist/components/AnnotationRange.svelte +147 -0
  8. package/dist/components/AnnotationRange.svelte.d.ts +40 -0
  9. package/dist/components/Arc.svelte +344 -151
  10. package/dist/components/Arc.svelte.d.ts +138 -0
  11. package/dist/components/Area.svelte +165 -149
  12. package/dist/components/Area.svelte.d.ts +45 -0
  13. package/dist/components/Axis.svelte +283 -180
  14. package/dist/components/Axis.svelte.d.ts +117 -0
  15. package/dist/components/Bar.svelte +166 -107
  16. package/dist/components/Bar.svelte.d.ts +51 -0
  17. package/dist/components/Bars.svelte +56 -67
  18. package/dist/components/Bars.svelte.d.ts +27 -0
  19. package/dist/components/Blur.svelte +42 -12
  20. package/dist/components/Blur.svelte.d.ts +23 -21
  21. package/dist/components/Bounds.svelte +49 -19
  22. package/dist/components/Bounds.svelte.d.ts +24 -50
  23. package/dist/components/BrushContext.svelte +296 -168
  24. package/dist/components/BrushContext.svelte.d.ts +97 -65
  25. package/dist/components/Calendar.svelte +116 -59
  26. package/dist/components/Calendar.svelte.d.ts +50 -31
  27. package/dist/components/Chart.svelte +1289 -398
  28. package/dist/components/Chart.svelte.d.ts +535 -410
  29. package/dist/components/ChartClipPath.svelte +37 -15
  30. package/dist/components/ChartClipPath.svelte.d.ts +21 -19
  31. package/dist/components/Circle.svelte +124 -85
  32. package/dist/components/Circle.svelte.d.ts +52 -0
  33. package/dist/components/CircleClipPath.svelte +76 -16
  34. package/dist/components/CircleClipPath.svelte.d.ts +46 -0
  35. package/dist/components/ClipPath.svelte +71 -21
  36. package/dist/components/ClipPath.svelte.d.ts +40 -27
  37. package/dist/components/ColorRamp.svelte +75 -9
  38. package/dist/components/ColorRamp.svelte.d.ts +37 -19
  39. package/dist/components/ComputedStyles.svelte +17 -5
  40. package/dist/components/ComputedStyles.svelte.d.ts +11 -19
  41. package/dist/components/Connector.svelte +149 -0
  42. package/dist/components/Connector.svelte.d.ts +51 -0
  43. package/dist/components/Dagre.svelte +211 -122
  44. package/dist/components/Dagre.svelte.d.ts +119 -56
  45. package/dist/components/ForceSimulation.svelte +215 -90
  46. package/dist/components/ForceSimulation.svelte.d.ts +82 -35
  47. package/dist/components/Frame.svelte +33 -13
  48. package/dist/components/Frame.svelte.d.ts +13 -17
  49. package/dist/components/GeoCircle.svelte +29 -16
  50. package/dist/components/GeoCircle.svelte.d.ts +22 -24
  51. package/dist/components/GeoContext.svelte +113 -72
  52. package/dist/components/GeoContext.svelte.d.ts +49 -41
  53. package/dist/components/GeoEdgeFade.svelte +49 -13
  54. package/dist/components/GeoEdgeFade.svelte.d.ts +17 -19
  55. package/dist/components/GeoPath.svelte +157 -127
  56. package/dist/components/GeoPath.svelte.d.ts +48 -36
  57. package/dist/components/GeoPoint.svelte +52 -20
  58. package/dist/components/GeoPoint.svelte.d.ts +25 -22
  59. package/dist/components/GeoSpline.svelte +75 -26
  60. package/dist/components/GeoSpline.svelte.d.ts +29 -20
  61. package/dist/components/GeoTile.svelte +100 -49
  62. package/dist/components/GeoTile.svelte.d.ts +38 -23
  63. package/dist/components/GeoVisible.svelte +17 -9
  64. package/dist/components/GeoVisible.svelte.d.ts +10 -18
  65. package/dist/components/Graticule.svelte +30 -14
  66. package/dist/components/Graticule.svelte.d.ts +11 -52
  67. package/dist/components/Grid.svelte +230 -117
  68. package/dist/components/Grid.svelte.d.ts +71 -0
  69. package/dist/components/Group.svelte +173 -106
  70. package/dist/components/Group.svelte.d.ts +81 -0
  71. package/dist/components/Highlight.svelte +410 -308
  72. package/dist/components/Highlight.svelte.d.ts +107 -0
  73. package/dist/components/Hull.svelte +97 -46
  74. package/dist/components/Hull.svelte.d.ts +40 -30
  75. package/dist/components/Labels.svelte +127 -47
  76. package/dist/components/Labels.svelte.d.ts +70 -27
  77. package/dist/components/Legend.svelte +374 -190
  78. package/dist/components/Legend.svelte.d.ts +95 -44
  79. package/dist/components/Line.svelte +163 -125
  80. package/dist/components/Line.svelte.d.ts +75 -0
  81. package/dist/components/LinearGradient.svelte +153 -78
  82. package/dist/components/LinearGradient.svelte.d.ts +66 -31
  83. package/dist/components/Link.svelte +160 -104
  84. package/dist/components/Link.svelte.d.ts +54 -0
  85. package/dist/components/Marker.svelte +100 -39
  86. package/dist/components/Marker.svelte.d.ts +59 -27
  87. package/dist/components/MarkerWrapper.svelte +35 -0
  88. package/dist/components/MarkerWrapper.svelte.d.ts +18 -0
  89. package/dist/components/MonthPath.svelte +65 -20
  90. package/dist/components/MonthPath.svelte.d.ts +23 -17
  91. package/dist/components/MotionPath.svelte +80 -24
  92. package/dist/components/MotionPath.svelte.d.ts +46 -27
  93. package/dist/components/Pack.svelte +53 -17
  94. package/dist/components/Pack.svelte.d.ts +42 -21
  95. package/dist/components/Partition.svelte +64 -22
  96. package/dist/components/Partition.svelte.d.ts +49 -26
  97. package/dist/components/Pattern.svelte +297 -11
  98. package/dist/components/Pattern.svelte.d.ts +103 -19
  99. package/dist/components/Pie.svelte +122 -76
  100. package/dist/components/Pie.svelte.d.ts +65 -51
  101. package/dist/components/Point.svelte +20 -9
  102. package/dist/components/Point.svelte.d.ts +16 -20
  103. package/dist/components/Points.svelte +148 -137
  104. package/dist/components/Points.svelte.d.ts +45 -34
  105. package/dist/components/RadialGradient.svelte +143 -70
  106. package/dist/components/RadialGradient.svelte.d.ts +69 -31
  107. package/dist/components/Rect.svelte +121 -102
  108. package/dist/components/Rect.svelte.d.ts +36 -0
  109. package/dist/components/RectClipPath.svelte +82 -18
  110. package/dist/components/RectClipPath.svelte.d.ts +55 -0
  111. package/dist/components/Rule.svelte +107 -63
  112. package/dist/components/Rule.svelte.d.ts +40 -19
  113. package/dist/components/Sankey.svelte +132 -55
  114. package/dist/components/Sankey.svelte.d.ts +61 -31
  115. package/dist/components/Spline.svelte +281 -218
  116. package/dist/components/Spline.svelte.d.ts +95 -0
  117. package/dist/components/Text.svelte +437 -176
  118. package/dist/components/Text.svelte.d.ts +130 -0
  119. package/dist/components/Threshold.svelte +48 -16
  120. package/dist/components/Threshold.svelte.d.ts +29 -31
  121. package/dist/components/TileImage.svelte +103 -30
  122. package/dist/components/TileImage.svelte.d.ts +48 -23
  123. package/dist/components/TransformContext.svelte +365 -171
  124. package/dist/components/TransformControls.svelte +50 -26
  125. package/dist/components/TransformControls.svelte.d.ts +27 -19
  126. package/dist/components/Tree.svelte +74 -33
  127. package/dist/components/Tree.svelte.d.ts +42 -30
  128. package/dist/components/Treemap.svelte +119 -42
  129. package/dist/components/Treemap.svelte.d.ts +75 -27
  130. package/dist/components/Voronoi.svelte +108 -76
  131. package/dist/components/Voronoi.svelte.d.ts +40 -41
  132. package/dist/components/charts/ArcChart.svelte +464 -0
  133. package/dist/components/charts/ArcChart.svelte.d.ts +90 -0
  134. package/dist/components/charts/AreaChart.svelte +450 -393
  135. package/dist/components/charts/AreaChart.svelte.d.ts +61 -0
  136. package/dist/components/charts/BarChart.svelte +454 -389
  137. package/dist/components/charts/BarChart.svelte.d.ts +76 -0
  138. package/dist/components/charts/ChartAnnotations.svelte +37 -0
  139. package/dist/components/charts/ChartAnnotations.svelte.d.ts +10 -0
  140. package/dist/components/charts/DefaultTooltip.svelte +60 -0
  141. package/dist/components/charts/DefaultTooltip.svelte.d.ts +10 -0
  142. package/dist/components/charts/LineChart.svelte +369 -314
  143. package/dist/components/charts/LineChart.svelte.d.ts +53 -0
  144. package/dist/components/charts/PieChart.svelte +458 -316
  145. package/dist/components/charts/PieChart.svelte.d.ts +137 -353
  146. package/dist/components/charts/ScatterChart.svelte +334 -296
  147. package/dist/components/charts/ScatterChart.svelte.d.ts +39 -0
  148. package/dist/components/charts/index.d.ts +8 -0
  149. package/dist/components/charts/index.js +7 -0
  150. package/dist/components/charts/types.d.ts +253 -0
  151. package/dist/components/charts/utils.svelte.d.ts +30 -0
  152. package/dist/components/charts/utils.svelte.js +55 -0
  153. package/dist/components/index.d.ts +76 -4
  154. package/dist/components/index.js +76 -5
  155. package/dist/components/layout/Canvas.svelte +321 -155
  156. package/dist/components/layout/Canvas.svelte.d.ts +104 -55
  157. package/dist/components/layout/Html.svelte +82 -42
  158. package/dist/components/layout/Html.svelte.d.ts +39 -28
  159. package/dist/components/layout/Layer.svelte +39 -0
  160. package/dist/components/layout/Layer.svelte.d.ts +17 -0
  161. package/dist/components/layout/Svg.svelte +122 -70
  162. package/dist/components/layout/Svg.svelte.d.ts +53 -34
  163. package/dist/components/layout/WebGL.svelte +135 -0
  164. package/dist/components/layout/WebGL.svelte.d.ts +50 -0
  165. package/dist/components/tooltip/Tooltip.svelte +246 -78
  166. package/dist/components/tooltip/Tooltip.svelte.d.ts +149 -31
  167. package/dist/components/tooltip/TooltipContext.svelte +409 -271
  168. package/dist/components/tooltip/TooltipContext.svelte.d.ts +86 -55
  169. package/dist/components/tooltip/TooltipHeader.svelte +100 -11
  170. package/dist/components/tooltip/TooltipHeader.svelte.d.ts +43 -23
  171. package/dist/components/tooltip/TooltipItem.svelte +167 -27
  172. package/dist/components/tooltip/TooltipItem.svelte.d.ts +63 -31
  173. package/dist/components/tooltip/TooltipList.svelte +22 -3
  174. package/dist/components/tooltip/TooltipList.svelte.d.ts +6 -17
  175. package/dist/components/tooltip/TooltipSeparator.svelte +27 -1
  176. package/dist/components/tooltip/TooltipSeparator.svelte.d.ts +6 -15
  177. package/dist/components/tooltip/index.d.ts +6 -0
  178. package/dist/components/tooltip/index.js +6 -0
  179. package/dist/components/tooltip/tooltipMetaContext.d.ts +79 -0
  180. package/dist/components/tooltip/tooltipMetaContext.js +139 -0
  181. package/dist/components/types.d.ts +1 -0
  182. package/dist/components/types.js +1 -0
  183. package/dist/docs/Blockquote.svelte.d.ts +18 -14
  184. package/dist/docs/Code.svelte.d.ts +26 -22
  185. package/dist/docs/ConnectorSweepMenuField.svelte +17 -0
  186. package/dist/docs/ConnectorSweepMenuField.svelte.d.ts +7 -0
  187. package/dist/docs/ConnectorTypeMenuField.svelte +17 -0
  188. package/dist/docs/ConnectorTypeMenuField.svelte.d.ts +7 -0
  189. package/dist/docs/CurveMenuField.svelte +14 -3
  190. package/dist/docs/CurveMenuField.svelte.d.ts +9 -18
  191. package/dist/docs/GeoDebug.svelte +47 -42
  192. package/dist/docs/GeoDebug.svelte.d.ts +4 -16
  193. package/dist/docs/Header1.svelte.d.ts +27 -16
  194. package/dist/docs/Json.svelte.d.ts +20 -16
  195. package/dist/docs/Layout.svelte.d.ts +18 -13
  196. package/dist/docs/Link.svelte.d.ts +33 -21
  197. package/dist/docs/PathDataMenuField.svelte +14 -10
  198. package/dist/docs/PathDataMenuField.svelte.d.ts +8 -18
  199. package/dist/docs/Preview.svelte +20 -7
  200. package/dist/docs/Preview.svelte.d.ts +12 -22
  201. package/dist/docs/TilesetField.svelte.d.ts +21 -17
  202. package/dist/docs/TransformDebug.svelte +5 -6
  203. package/dist/docs/TransformDebug.svelte.d.ts +18 -14
  204. package/dist/docs/ViewSourceButton.svelte.d.ts +21 -17
  205. package/dist/types/d3-shape-extentions.d.ts +7 -0
  206. package/dist/utils/afterTick.d.ts +5 -0
  207. package/dist/utils/afterTick.js +8 -0
  208. package/dist/utils/arcText.svelte.d.ts +57 -0
  209. package/dist/utils/arcText.svelte.js +262 -0
  210. package/dist/utils/array.d.ts +9 -1
  211. package/dist/utils/array.js +13 -0
  212. package/dist/utils/attributes.d.ts +29 -0
  213. package/dist/utils/attributes.js +40 -0
  214. package/dist/utils/canvas.js +47 -10
  215. package/dist/utils/chart.d.ts +78 -0
  216. package/dist/utils/chart.js +512 -0
  217. package/dist/utils/color.d.ts +1 -0
  218. package/dist/utils/color.js +8 -0
  219. package/dist/utils/common.d.ts +3 -5
  220. package/dist/utils/common.js +3 -2
  221. package/dist/utils/connectorUtils.d.ts +21 -0
  222. package/dist/utils/connectorUtils.js +111 -0
  223. package/dist/utils/createId.d.ts +7 -0
  224. package/dist/utils/createId.js +9 -0
  225. package/dist/utils/debug.d.ts +1 -0
  226. package/dist/utils/debug.js +84 -0
  227. package/dist/utils/filterObject.d.ts +9 -0
  228. package/dist/utils/filterObject.js +12 -0
  229. package/dist/utils/graph/dagre.d.ts +34 -0
  230. package/dist/utils/graph/dagre.js +78 -0
  231. package/dist/utils/graph/dagre.test.d.ts +1 -0
  232. package/dist/utils/{graph.test.js → graph/dagre.test.js} +19 -33
  233. package/dist/utils/graph/sankey.d.ts +28 -0
  234. package/dist/utils/{graph.js → graph/sankey.js} +13 -41
  235. package/dist/utils/index.d.ts +3 -1
  236. package/dist/utils/index.js +3 -1
  237. package/dist/utils/key.svelte.d.ts +3 -0
  238. package/dist/utils/key.svelte.js +11 -0
  239. package/dist/utils/legendPayload.d.ts +7 -0
  240. package/dist/utils/legendPayload.js +8 -0
  241. package/dist/utils/motion.svelte.d.ts +140 -0
  242. package/dist/utils/motion.svelte.js +180 -0
  243. package/dist/utils/motion.test.d.ts +1 -0
  244. package/dist/utils/motion.test.js +213 -0
  245. package/dist/utils/{rect.d.ts → rect.svelte.d.ts} +7 -4
  246. package/dist/utils/rect.svelte.js +105 -0
  247. package/dist/utils/scales.svelte.d.ts +90 -0
  248. package/dist/utils/{scales.js → scales.svelte.js} +100 -39
  249. package/dist/utils/stack.d.ts +2 -3
  250. package/dist/utils/stack.js +1 -1
  251. package/dist/utils/string.js +87 -0
  252. package/dist/utils/ticks.d.ts +8 -2
  253. package/dist/utils/ticks.js +28 -0
  254. package/dist/utils/ticks.test.d.ts +1 -0
  255. package/dist/utils/ticks.test.js +67 -0
  256. package/dist/utils/types.d.ts +81 -0
  257. package/package.json +21 -19
  258. package/dist/components/ChartContext.svelte +0 -295
  259. package/dist/components/ChartContext.svelte.d.ts +0 -139
  260. package/dist/components/TransformContext.svelte.d.ts +0 -158
  261. package/dist/stores/motionStore.d.ts +0 -30
  262. package/dist/stores/motionStore.js +0 -62
  263. package/dist/utils/graph.d.ts +0 -37
  264. package/dist/utils/rect.js +0 -107
  265. package/dist/utils/scales.d.ts +0 -66
  266. /package/dist/{utils/graph.test.d.ts → components/charts/types.js} +0 -0
@@ -1,8 +1,9 @@
1
- <script lang="ts" context="module">
2
- import { getContext, setContext } from 'svelte';
3
- import type { Readable } from 'svelte/store';
1
+ <script lang="ts" module>
2
+ import { Context } from 'runed';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { Without } from '../../utils/types.js';
4
5
 
5
- export const tooltipContextKey = Symbol();
6
+ const _TooltipContext = new Context<TooltipContextValue>('TooltipContext');
6
7
 
7
8
  type TooltipMode =
8
9
  | 'bisect-x'
@@ -14,124 +15,214 @@
14
15
  | 'quadtree'
15
16
  | 'manual';
16
17
 
17
- export type TooltipContextValue = {
18
+ export type TooltipContextValue<T = any> = {
18
19
  x: number;
19
20
  y: number;
20
- data: any;
21
- show(e: PointerEvent, tooltipData?: any): void;
21
+ data: T | null;
22
+ payload: TooltipPayload[];
23
+ show(e: PointerEvent, tooltipData?: any, payload?: TooltipPayload): void;
22
24
  hide(e?: PointerEvent): void;
23
25
  mode: TooltipMode;
26
+ isHoveringTooltipArea: boolean;
27
+ isHoveringTooltipContent: boolean;
24
28
  };
25
29
 
26
- export type TooltipContext = Readable<TooltipContextValue>;
27
-
28
- const defaultContext: TooltipContext = writable({
29
- x: 0,
30
- y: 0,
31
- data: null as any,
32
- show: () => {},
33
- hide: () => {},
34
- mode: 'manual',
35
- });
36
- export function tooltipContext() {
37
- return getContext<TooltipContext>(tooltipContextKey) ?? defaultContext;
30
+ // const defaultContext = {
31
+ // x: 0,
32
+ // y: 0,
33
+ // data: null as any,
34
+ // payload: [],
35
+ // show: () => {},
36
+ // hide: () => {},
37
+ // mode: 'manual',
38
+ // } as TooltipContextValue;
39
+
40
+ export function getTooltipContext<T = any>() {
41
+ return _TooltipContext.get() as TooltipContextValue<T>;
38
42
  }
39
43
 
40
- function setTooltipContext(tooltip: TooltipContext) {
41
- setContext(tooltipContextKey, tooltip);
44
+ function setTooltipContext<T = any>(tooltip: TooltipContextValue<T>) {
45
+ return _TooltipContext.set(tooltip) as TooltipContextValue<T>;
42
46
  }
47
+
48
+ type TooltipContextPropsWithoutHTML<T = any> = {
49
+ /**
50
+ * The tooltip interaction mode
51
+ * @default 'manual'
52
+ */
53
+ mode?: TooltipMode;
54
+
55
+ /**
56
+ * Method to find tooltip data
57
+ * @default 'closest'
58
+ */
59
+ findTooltipData?: 'closest' | 'left' | 'right';
60
+
61
+ /**
62
+ * Similar to d3-selection's raise, re-insert the e.target as the last child of its parent, so
63
+ * to be the top-most element
64
+ * @default false
65
+ */
66
+ raiseTarget?: boolean;
67
+
68
+ /**
69
+ * Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip
70
+ * @default false
71
+ */
72
+ locked?: boolean;
73
+
74
+ /**
75
+ * quadtree search radius
76
+ * @default Infinity
77
+ */
78
+ radius?: number;
79
+
80
+ /**
81
+ * Enable debug view (show hit targets, etc)
82
+ * @default false
83
+ */
84
+ debug?: boolean;
85
+
86
+ /**
87
+ * Click handler for the tooltip
88
+ * @default () => {}
89
+ */
90
+ onclick?: (e: MouseEvent, { data }: { data: any }) => any;
91
+
92
+ /**
93
+ * Exposed to allow binding in Chart
94
+ * @default { x: 0, y: 0, data: null, show: showTooltip, hide: hideTooltip, mode }
95
+ */
96
+ tooltipContext?: TooltipContextValue<T>;
97
+
98
+ /**
99
+ * Delay in ms before hiding tooltip
100
+ * @default 0
101
+ */
102
+ hideDelay?: number;
103
+
104
+ /**
105
+ * A reference to the tooltip container element.
106
+ *
107
+ * @bindable
108
+ */
109
+ ref?: HTMLElement;
110
+
111
+ children?: Snippet<[{ tooltipContext: TooltipContextValue<T> }]>;
112
+ };
113
+
114
+ export type TooltipContextProps<T = any> = TooltipContextPropsWithoutHTML<T> &
115
+ Without<HTMLAttributes<HTMLElement>, TooltipContextPropsWithoutHTML<T>>;
43
116
  </script>
44
117
 
45
- <script lang="ts">
46
- import { raise } from 'layercake';
47
- import { writable } from 'svelte/store';
118
+ <script lang="ts" generics="TData = any">
48
119
  import { bisector, max, min } from 'd3-array';
49
120
  import { quadtree as d3Quadtree, type Quadtree } from 'd3-quadtree';
50
121
  import { sortFunc, localPoint } from '@layerstack/utils';
51
122
  import { cls } from '@layerstack/tailwind';
52
123
 
53
124
  import Svg from './../layout/Svg.svelte';
54
- import { chartContext } from './../ChartContext.svelte';
125
+ import Arc from '../Arc.svelte';
55
126
  import ChartClipPath from './../ChartClipPath.svelte';
56
127
  import Voronoi from './../Voronoi.svelte';
57
128
 
58
- import { isScaleBand, scaleInvert } from '../../utils/scales.js';
129
+ import { isScaleBand, scaleInvert } from '../../utils/scales.svelte.js';
59
130
  import { cartesianToPolar } from '../../utils/math.js';
60
131
  import { quadtreeRects } from '../../utils/quadtree.js';
132
+ import { raise } from '../../utils/chart.js';
133
+ import { getChartContext } from '../Chart.svelte';
134
+ import type { Snippet } from 'svelte';
135
+ import {
136
+ getTooltipMetaContext,
137
+ getTooltipPayload,
138
+ type TooltipPayload,
139
+ } from './tooltipMetaContext.js';
140
+ import { layerClass } from '../../utils/attributes.js';
141
+
142
+ const ctx = getChartContext<any>();
143
+
144
+ let {
145
+ ref: refProp = $bindable(),
146
+ debug = false,
147
+ findTooltipData = 'closest',
148
+ hideDelay = 0,
149
+ locked = false,
150
+ mode = 'manual',
151
+ onclick = () => {},
152
+ radius = Infinity,
153
+ raiseTarget = false,
154
+ tooltipContext: tooltipContextProp = $bindable() as TooltipContextValue<TData>,
155
+ children,
156
+ }: TooltipContextProps<TData> = $props();
157
+
158
+ let ref = $state<HTMLElement>();
159
+ $effect.pre(() => {
160
+ refProp = ref;
161
+ });
162
+
163
+ let x = $state(0);
164
+ let y = $state(0);
165
+ let data = $state(null);
166
+ let payload = $state<TooltipPayload[]>([]);
61
167
 
62
- const {
63
- flatData,
64
- x,
65
- xScale,
66
- xGet,
67
- xRange,
68
- y,
69
- yScale,
70
- yGet,
71
- yRange,
72
- width,
73
- height,
74
- containerWidth,
75
- containerHeight,
76
- padding,
77
- radial,
78
- } = chartContext<any>();
168
+ /**
169
+ * If we're hovering the tooltip area on the chart
170
+ */
171
+ let isHoveringTooltipArea = $state(false);
172
+
173
+ /**
174
+ * If we're hovering the tooltip content container
175
+ */
176
+ let isHoveringTooltipContent = $state(false);
177
+
178
+ const metaCtx = getTooltipMetaContext();
179
+
180
+ const tooltipContext: TooltipContextValue = {
181
+ get x() {
182
+ return x;
183
+ },
184
+ get y() {
185
+ return y;
186
+ },
187
+ get data() {
188
+ return data;
189
+ },
190
+ get payload() {
191
+ return payload;
192
+ },
193
+ show: showTooltip,
194
+ hide: hideTooltip,
195
+ get mode() {
196
+ return mode;
197
+ },
198
+ get isHoveringTooltipArea() {
199
+ return isHoveringTooltipArea;
200
+ },
201
+ get isHoveringTooltipContent() {
202
+ return isHoveringTooltipContent;
203
+ },
204
+ set isHoveringTooltipContent(value) {
205
+ isHoveringTooltipContent = value;
206
+ },
207
+ };
208
+ tooltipContextProp = tooltipContext;
79
209
 
80
210
  /*
81
211
  TODO: Defaults to consider (if possible to detect scale type, which might not be possible)
82
212
  - scaleTime / scaleLinear: bisect
83
- - scaleTime / scaleLinear (multi/stack): bisect
213
+ - scaleTime / scaleLinear (multi/stack): bisect
84
214
  - scaleTime / scaleBand: bisect (or band)
85
215
  - scaleTime (multi) / scaleBand: bounds (or possible band if not overlapping)
86
216
  - scaleBand, scaleLinear: band (or bounds)
87
217
  - scaleBand, scaleLinear: band (or bounds) - multiple (overlapping) bars
88
218
  - scaleLinear, scaleLinear: voronoi (or quadtree)
89
219
  */
220
+ setTooltipContext(tooltipContext);
90
221
 
91
- /**
92
- * @type {'bisect-x' | 'bisect-y' | 'band' | 'bisect-band' | 'bounds' | 'voronoi' | 'quadtree' | 'manual'}
93
- */
94
- export let mode: TooltipMode = 'manual';
95
- /**
96
- * @type {'closest' | 'left' | 'right'}
97
- */
98
- export let findTooltipData: 'closest' | 'left' | 'right' = 'closest';
99
-
100
- /** 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 */
101
- export let raiseTarget = false;
102
-
103
- /** Lock tooltip (keep open, do not update on mouse movement). Allows for clicking on tooltip */
104
- export let locked = false;
105
-
106
- /** quadtree search radius
107
- * @type {number}
108
- */
109
- export let radius: number = Infinity;
110
- /** Enable debug view (show hit targets, etc) */
111
- export let debug = false;
112
-
113
- export let onclick: (e: MouseEvent, { data }: { data: any }) => any = () => {};
114
-
115
- /** Exposed to allow binding in Chart */
116
- export let tooltip = writable({
117
- x: 0,
118
- y: 0,
119
- data: null as any,
120
- show: showTooltip,
121
- hide: hideTooltip,
122
- mode,
123
- });
124
- setTooltipContext(tooltip);
125
-
126
- /** Delay in ms before hiding tooltip */
127
- export let hideDelay = 0;
222
+ let hideTimeoutId: ReturnType<typeof setTimeout>;
128
223
 
129
- let isHoveringTooltip = false;
130
- let hideTimeoutId: NodeJS.Timeout;
131
- let tooltipContextNode: HTMLDivElement;
132
-
133
- $: bisectX = bisector((d: any) => {
134
- const value = $x(d);
224
+ const bisectX = bisector((d: any) => {
225
+ const value = ctx.x(d);
135
226
  if (Array.isArray(value)) {
136
227
  // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
137
228
  // Using first value. Consider using average, max, etc
@@ -143,8 +234,8 @@
143
234
  }
144
235
  }).left;
145
236
 
146
- $: bisectY = bisector((d: any) => {
147
- const value = $y(d);
237
+ const bisectY = bisector((d: any) => {
238
+ const value = ctx.y(d);
148
239
  if (Array.isArray(value)) {
149
240
  // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
150
241
  // Using first value. Consider using average, max, etc
@@ -188,15 +279,16 @@
188
279
  return;
189
280
  }
190
281
 
191
- const containerNode = (e.target as Element).closest('.layercake-container')!;
282
+ const containerNode = (e.target as Element).closest('.lc-root-container')!;
192
283
  const point = localPoint(e, containerNode);
193
284
 
194
285
  if (
286
+ ref !== undefined &&
195
287
  tooltipData == null && // mode !== 'manual' but support annotations
196
- (point.x < tooltipContextNode.offsetLeft ||
197
- point.x > tooltipContextNode.offsetLeft + tooltipContextNode.offsetWidth ||
198
- point.y < tooltipContextNode.offsetTop ||
199
- point.y > tooltipContextNode.offsetTop + tooltipContextNode.offsetHeight)
288
+ (point.x < ref.offsetLeft ||
289
+ point.x > ref.offsetLeft + ref.offsetWidth ||
290
+ point.y < ref.offsetTop ||
291
+ point.y > ref.offsetTop + ref.offsetHeight)
200
292
  ) {
201
293
  // Ignore if within padding of chart
202
294
  hideTooltip();
@@ -209,55 +301,55 @@
209
301
  switch (mode) {
210
302
  case 'bisect-x': {
211
303
  let xValueAtPoint: any;
212
- if ($radial) {
304
+ if (ctx.radial) {
213
305
  // Assume radial is always centered
214
- const { radians } = cartesianToPolar(point.x - $width / 2, point.y - $height / 2);
215
- xValueAtPoint = scaleInvert($xScale, radians);
306
+ const { radians } = cartesianToPolar(point.x - ctx.width / 2, point.y - ctx.height / 2);
307
+ xValueAtPoint = scaleInvert(ctx.xScale, radians);
216
308
  } else {
217
- xValueAtPoint = scaleInvert($xScale, point.x - $padding.left);
309
+ xValueAtPoint = scaleInvert(ctx.xScale, point.x - ctx.padding.left);
218
310
  }
219
311
 
220
- const index = bisectX($flatData, xValueAtPoint, 1);
221
- const previousValue = $flatData[index - 1];
222
- const currentValue = $flatData[index];
223
- tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
312
+ const index = bisectX(ctx.flatData, xValueAtPoint, 1);
313
+ const previousValue = ctx.flatData[index - 1];
314
+ const currentValue = ctx.flatData[index];
315
+ tooltipData = findData(previousValue, currentValue, xValueAtPoint, ctx.x);
224
316
  break;
225
317
  }
226
318
 
227
319
  case 'bisect-y': {
228
320
  // `y` value at pointer coordinate
229
- const yValueAtPoint = scaleInvert($yScale, point.y - $padding.top);
321
+ const yValueAtPoint = scaleInvert(ctx.yScale, point.y - ctx.padding.top);
230
322
 
231
- const index = bisectY($flatData, yValueAtPoint, 1);
232
- const previousValue = $flatData[index - 1];
233
- const currentValue = $flatData[index];
234
- tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
323
+ const index = bisectY(ctx.flatData, yValueAtPoint, 1);
324
+ const previousValue = ctx.flatData[index - 1];
325
+ const currentValue = ctx.flatData[index];
326
+ tooltipData = findData(previousValue, currentValue, yValueAtPoint, ctx.y);
235
327
  break;
236
328
  }
237
329
 
238
330
  case 'bisect-band': {
239
331
  // `x` and `y` values at pointer coordinate
240
- const xValueAtPoint = scaleInvert($xScale, point.x);
241
- const yValueAtPoint = scaleInvert($yScale, point.y);
332
+ const xValueAtPoint = scaleInvert(ctx.xScale, point.x);
333
+ const yValueAtPoint = scaleInvert(ctx.yScale, point.y);
242
334
 
243
- if (isScaleBand($xScale)) {
335
+ if (isScaleBand(ctx.xScale)) {
244
336
  // Find point closest to pointer within the x band
245
- const bandData = $flatData
246
- .filter((d) => $x(d) === xValueAtPoint)
247
- .sort(sortFunc($y as () => any)); // sort for bisect
337
+ const bandData = ctx.flatData
338
+ .filter((d) => ctx.x(d) === xValueAtPoint)
339
+ .sort(sortFunc(ctx.y as () => any)); // sort for bisect
248
340
  const index = bisectY(bandData, yValueAtPoint, 1);
249
341
  const previousValue = bandData[index - 1];
250
342
  const currentValue = bandData[index];
251
- tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
252
- } else if (isScaleBand($yScale)) {
343
+ tooltipData = findData(previousValue, currentValue, yValueAtPoint, ctx.y);
344
+ } else if (isScaleBand(ctx.yScale)) {
253
345
  // Find point closest to pointer within the y band
254
- const bandData = $flatData
255
- .filter((d) => $y(d) === yValueAtPoint)
256
- .sort(sortFunc($x as () => any)); // sort for bisect
346
+ const bandData = ctx.flatData
347
+ .filter((d) => ctx.y(d) === yValueAtPoint)
348
+ .sort(sortFunc(ctx.x as () => any)); // sort for bisect
257
349
  const index = bisectX(bandData, xValueAtPoint, 1);
258
350
  const previousValue = bandData[index - 1];
259
351
  const currentValue = bandData[index];
260
- tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
352
+ tooltipData = findData(previousValue, currentValue, xValueAtPoint, ctx.x);
261
353
  } else {
262
354
  // TODO: Support `bisect-band` without band? Fallback to bisect?
263
355
  }
@@ -265,7 +357,7 @@
265
357
  }
266
358
 
267
359
  case 'quadtree': {
268
- tooltipData = quadtree.find(point.x, point.y, radius);
360
+ tooltipData = quadtree?.find(point.x, point.y, radius);
269
361
  break;
270
362
  }
271
363
  }
@@ -276,12 +368,12 @@
276
368
  raise(e.target as Element);
277
369
  }
278
370
 
279
- $tooltip = {
280
- ...$tooltip,
281
- x: point.x,
282
- y: point.y,
283
- data: tooltipData,
284
- };
371
+ const payloadData = getTooltipPayload({ ctx, tooltipData, metaCtx });
372
+
373
+ x = point.x;
374
+ y = point.y;
375
+ data = tooltipData;
376
+ payload = payloadData;
285
377
  } else {
286
378
  // Hide tooltip if unable to locate
287
379
  hideTooltip();
@@ -294,149 +386,162 @@
294
386
  return;
295
387
  }
296
388
 
297
- // Wait an event loop tick in case `showTooltip` is called immediately on another element, to allow tweeneing (ex. moving between bands/bars)
389
+ isHoveringTooltipArea = false;
390
+
391
+ // Wait an event loop tick in case `showTooltip` is called immediately on another element,
392
+ // to allow tweening (ex. moving between bands/bars)
298
393
  // Additional hideDelay can be configured to extend this delay further
299
394
  hideTimeoutId = setTimeout(() => {
300
- if (!isHoveringTooltip) {
301
- $tooltip = { ...$tooltip, data: null };
395
+ if (!isHoveringTooltipArea && !isHoveringTooltipContent) {
396
+ data = null;
397
+ payload = [];
302
398
  }
303
399
  }, hideDelay);
304
400
  }
305
401
 
306
- let quadtree: Quadtree<[number, number]>;
307
- $: if (mode === 'quadtree') {
308
- quadtree = d3Quadtree()
309
- .extent([
310
- [0, 0],
311
- [$width, $height],
312
- ])
313
- .x((d) => {
314
- const value = $xGet(d);
315
-
316
- if (Array.isArray(value)) {
317
- // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
318
- // Using first value. Consider using average, max, etc
319
- // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
320
- // return midpoint;
321
- return min(value);
322
- } else {
323
- return value;
324
- }
325
- })
326
- .y((d) => {
327
- const value = $yGet(d);
328
-
329
- if (Array.isArray(value)) {
330
- // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
331
- // Using first value. Consider using average, max, etc
332
- // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
333
- // return midpoint;
334
- return min(value);
335
- } else {
336
- return value;
337
- }
338
- })
339
- .addAll($flatData as [number, number][]);
340
- }
402
+ const quadtree: Quadtree<[number, number]> | undefined = $derived.by(() => {
403
+ if (mode === 'quadtree') {
404
+ return d3Quadtree()
405
+ .extent([
406
+ [0, 0],
407
+ [ctx.width, ctx.height],
408
+ ])
409
+ .x((d) => {
410
+ const value = ctx.xGet(d);
411
+
412
+ if (Array.isArray(value)) {
413
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
414
+ // Using first value. Consider using average, max, etc
415
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
416
+ // return midpoint;
417
+ return min(value);
418
+ } else {
419
+ return value;
420
+ }
421
+ })
422
+ .y((d) => {
423
+ const value = ctx.yGet(d);
424
+
425
+ if (Array.isArray(value)) {
426
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
427
+ // Using first value. Consider using average, max, etc
428
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
429
+ // return midpoint;
430
+ return min(value);
431
+ } else {
432
+ return value;
433
+ }
434
+ })
435
+ .addAll(ctx.flatData as [number, number][]);
436
+ }
437
+ });
341
438
 
342
- let rects: Array<{ x: number; y: number; width: number; height: number; data: any }> = [];
343
- $: if (mode === 'bounds' || mode === 'band') {
344
- // @ts-expect-error
345
- rects = $flatData
346
- .map((d) => {
347
- const xValue = $xGet(d);
348
- const yValue = $yGet(d);
349
-
350
- const x = Array.isArray(xValue) ? xValue[0] : xValue;
351
- const y = Array.isArray(yValue) ? yValue[0] : yValue;
352
-
353
- const xOffset = isScaleBand($xScale) ? ($xScale.padding() * $xScale.step()) / 2 : 0;
354
- const yOffset = isScaleBand($yScale) ? ($yScale.padding() * $yScale.step()) / 2 : 0;
355
-
356
- // @ts-expect-error
357
- const fullWidth = max($xRange) - min($xRange);
358
- // @ts-expect-error
359
- const fullHeight = max($yRange) - min($yRange);
360
-
361
- if (mode === 'band') {
362
- // full band width/height regardless of value
363
- return {
364
- x: isScaleBand($xScale) ? x - xOffset : min($xRange),
365
- y: isScaleBand($yScale) ? y - yOffset : min($yRange),
366
- width: isScaleBand($xScale) ? $xScale.step() : fullWidth,
367
- height: isScaleBand($yScale) ? $yScale.step() : fullHeight,
368
- data: d,
369
- };
370
- } else if (mode === 'bounds') {
371
- return {
372
- x: isScaleBand($xScale) || Array.isArray(xValue) ? x - xOffset : min($xRange),
373
- // y: isScaleBand($yScale) || Array.isArray(yValue) ? y - yOffset : min($yRange),
374
- y: y - yOffset,
375
-
376
- width: Array.isArray(xValue)
377
- ? xValue[1] - xValue[0]
378
- : isScaleBand($xScale)
379
- ? $xScale.step()
380
- : min($xRange) + x,
381
- height: Array.isArray(yValue)
382
- ? yValue[1] - yValue[0]
383
- : isScaleBand($yScale)
384
- ? $yScale.step()
385
- : // @ts-expect-error
386
- max($yRange) - y,
387
- data: d,
388
- };
389
- }
390
- })
391
- .sort(sortFunc('x'));
392
- }
439
+ const rects: Array<{ x: number; y: number; width: number; height: number; data: any }> =
440
+ $derived.by(() => {
441
+ if (mode === 'bounds' || mode === 'band') {
442
+ return ctx.flatData
443
+ .map((d) => {
444
+ const xValue = ctx.xGet(d);
445
+ const yValue = ctx.yGet(d);
446
+
447
+ const x = Array.isArray(xValue) ? xValue[0] : xValue;
448
+ const y = Array.isArray(yValue) ? yValue[0] : yValue;
449
+
450
+ const xOffset = isScaleBand(ctx.xScale)
451
+ ? (ctx.xScale.padding() * ctx.xScale.step()) / 2
452
+ : 0;
453
+ const yOffset = isScaleBand(ctx.yScale)
454
+ ? (ctx.yScale.padding() * ctx.yScale.step()) / 2
455
+ : 0;
456
+
457
+ const fullWidth = max(ctx.xRange) - min(ctx.xRange);
458
+ const fullHeight = max(ctx.yRange) - min(ctx.yRange);
459
+
460
+ if (mode === 'band') {
461
+ // full band width/height regardless of value
462
+ return {
463
+ x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange),
464
+ y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange),
465
+ width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth,
466
+ height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight,
467
+ data: d,
468
+ };
469
+ } else if (mode === 'bounds') {
470
+ return {
471
+ x: isScaleBand(ctx.xScale) || Array.isArray(xValue) ? x - xOffset : min(ctx.xRange),
472
+ // y: isScaleBand($yScale) || Array.isArray(yValue) ? y - yOffset : min($yRange),
473
+ y: y - yOffset,
474
+
475
+ width: Array.isArray(xValue)
476
+ ? xValue[1] - xValue[0]
477
+ : isScaleBand(ctx.xScale)
478
+ ? ctx.xScale.step()
479
+ : min(ctx.xRange) + x,
480
+ height: Array.isArray(yValue)
481
+ ? yValue[1] - yValue[0]
482
+ : isScaleBand(ctx.yScale)
483
+ ? ctx.yScale.step()
484
+ : max(ctx.yRange) - y,
485
+ data: d,
486
+ };
487
+ }
488
+ })
489
+ .filter((x) => x !== undefined) // make typescript happy
490
+ .sort(sortFunc('x'));
491
+ }
492
+ return [];
493
+ });
393
494
 
394
- $: triggerPointerEvents = ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode);
495
+ const triggerPointerEvents = $derived(
496
+ ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode)
497
+ );
395
498
  </script>
396
499
 
397
- <!-- svelte-ignore a11y-click-events-have-key-events -->
398
- <!-- svelte-ignore a11y-no-static-element-interactions -->
500
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
399
501
  <div
400
- style:top="{$padding.top}px"
401
- style:left="{$padding.left}px"
402
- style:width="{$width}px"
403
- style:height="{$height}px"
502
+ style:top="{ctx.padding.top}px"
503
+ style:left="{ctx.padding.left}px"
504
+ style:width="{ctx.width}px"
505
+ style:height="{ctx.height}px"
404
506
  class={cls(
405
- 'TooltipContext absolute touch-none',
507
+ layerClass('tooltip-context'),
508
+ 'absolute touch-none',
406
509
  debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
407
510
  )}
408
- on:pointerenter={(e) => {
409
- isHoveringTooltip = true;
511
+ onpointerenter={(e) => {
512
+ isHoveringTooltipArea = true;
410
513
  if (triggerPointerEvents) {
411
514
  showTooltip(e);
412
515
  }
413
516
  }}
414
- on:pointermove={(e) => {
517
+ onpointermove={(e) => {
415
518
  if (triggerPointerEvents) {
416
519
  showTooltip(e);
417
520
  }
418
521
  }}
419
- on:pointerleave={(e) => {
420
- isHoveringTooltip = false;
522
+ onpointerleave={(e) => {
523
+ isHoveringTooltipArea = false;
524
+
421
525
  hideTooltip();
422
526
  }}
423
- on:click={(e) => {
527
+ onclick={(e) => {
424
528
  // Ignore clicks without data (triggered from Legend clicks, for example)
425
- if (triggerPointerEvents && $tooltip?.data != null) {
426
- onclick(e, { data: $tooltip?.data });
529
+ if (triggerPointerEvents && tooltipContext.data != null) {
530
+ onclick(e, { data: tooltipContext.data });
427
531
  }
428
532
  }}
429
- bind:this={tooltipContextNode}
533
+ onkeydown={() => {}}
534
+ bind:this={ref}
430
535
  >
431
536
  <!-- Rendering slot within TooltipContext to allow pointer events to bubble up (ex. Brush) -->
432
537
  <div
433
- class="absolute"
434
- style:top="-{$padding.top ?? 0}px"
435
- style:left="-{$padding.left ?? 0}px"
436
- style:width="{$containerWidth}px"
437
- style:height="{$containerHeight}px"
538
+ class={cls(layerClass('tooltip-context-container'), 'absolute')}
539
+ style:top="-{ctx.padding.top ?? 0}px"
540
+ style:left="-{ctx.padding.left ?? 0}px"
541
+ style:width="{ctx.containerWidth}px"
542
+ style:height="{ctx.containerHeight}px"
438
543
  >
439
- <slot tooltip={$tooltip} />
544
+ {@render children?.({ tooltipContext: tooltipContext })}
440
545
 
441
546
  {#if mode === 'voronoi'}
442
547
  <Svg>
@@ -447,7 +552,7 @@
447
552
  onpointermove={(e, { data }) => {
448
553
  showTooltip(e, data);
449
554
  }}
450
- onpointerleave={hideTooltip}
555
+ onpointerleave={() => hideTooltip()}
451
556
  onpointerdown={(e) => {
452
557
  // @ts-expect-error
453
558
  if (e.target?.hasPointerCapture(e.pointerId)) {
@@ -462,45 +567,78 @@
462
567
  />
463
568
  </Svg>
464
569
  {:else if mode === 'bounds' || mode === 'band'}
465
- <Svg>
466
- <g class="tooltip-rects">
570
+ <Svg center={ctx.radial}>
571
+ <g class={layerClass('tooltip-rects-g')}>
467
572
  {#each rects as rect}
468
- <rect
469
- x={rect.x}
470
- y={rect.y}
471
- width={rect.width}
472
- height={rect.height}
473
- class={cls(debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent')}
474
- on:pointerenter={(e) => showTooltip(e, rect.data)}
475
- on:pointermove={(e) => showTooltip(e, rect.data)}
476
- on:pointerleave={hideTooltip}
477
- on:pointerdown={(e) => {
478
- // @ts-expect-error
479
- if (e.target?.hasPointerCapture(e.pointerId)) {
480
- // @ts-expect-error
481
- e.target.releasePointerCapture(e.pointerId);
482
- }
483
- }}
484
- on:click={(e) => {
485
- onclick(e, { data: rect.data });
486
- }}
487
- />
573
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
574
+ {#if ctx.radial}
575
+ <Arc
576
+ innerRadius={rect.y}
577
+ outerRadius={rect.y + rect.height}
578
+ startAngle={rect.x}
579
+ endAngle={rect.x + rect.width}
580
+ class={cls(
581
+ layerClass('tooltip-rect'),
582
+ debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
583
+ )}
584
+ onpointerenter={(e) => showTooltip(e, rect?.data)}
585
+ onpointermove={(e) => showTooltip(e, rect?.data)}
586
+ onpointerleave={() => hideTooltip()}
587
+ onpointerdown={(e) => {
588
+ const target = e.target as Element;
589
+ if (target?.hasPointerCapture(e.pointerId)) {
590
+ target.releasePointerCapture(e.pointerId);
591
+ }
592
+ }}
593
+ onclick={(e) => {
594
+ onclick(e, { data: rect?.data });
595
+ }}
596
+ />
597
+ {:else}
598
+ <rect
599
+ x={rect?.x}
600
+ y={rect?.y}
601
+ width={rect?.width}
602
+ height={rect?.height}
603
+ class={cls(
604
+ layerClass('tooltip-rect'),
605
+ debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
606
+ )}
607
+ onpointerenter={(e) => showTooltip(e, rect?.data)}
608
+ onpointermove={(e) => showTooltip(e, rect?.data)}
609
+ onpointerleave={() => hideTooltip()}
610
+ onpointerdown={(e) => {
611
+ const target = e.target as Element;
612
+ if (target?.hasPointerCapture(e.pointerId)) {
613
+ target.releasePointerCapture(e.pointerId);
614
+ }
615
+ }}
616
+ onclick={(e) => {
617
+ onclick(e, { data: rect?.data });
618
+ }}
619
+ />
620
+ {/if}
488
621
  {/each}
489
622
  </g>
490
623
  </Svg>
491
624
  {:else if mode === 'quadtree' && debug}
492
625
  <Svg pointerEvents={false}>
493
626
  <ChartClipPath>
494
- <g class="tooltip-quadtree">
495
- {#each quadtreeRects(quadtree, false) as rect}
496
- <rect
497
- x={rect.x}
498
- y={rect.y}
499
- width={rect.width}
500
- height={rect.height}
501
- class={cls(debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent')}
502
- />
503
- {/each}
627
+ <g class={layerClass('tooltip-quadtree-g')}>
628
+ {#if quadtree}
629
+ {#each quadtreeRects(quadtree, false) as rect}
630
+ <rect
631
+ x={rect.x}
632
+ y={rect.y}
633
+ width={rect.width}
634
+ height={rect.height}
635
+ class={cls(
636
+ layerClass('tooltip-quadtree-rect'),
637
+ debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
638
+ )}
639
+ />
640
+ {/each}
641
+ {/if}
504
642
  </g>
505
643
  </ChartClipPath>
506
644
  </Svg>