layerchart 2.0.0-next.1 → 2.0.0-next.11

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 (275) 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 +320 -179
  14. package/dist/components/Axis.svelte.d.ts +127 -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 +148 -77
  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 +463 -197
  118. package/dist/components/Text.svelte.d.ts +136 -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 +153 -103
  131. package/dist/components/Voronoi.svelte.d.ts +42 -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 +444 -393
  135. package/dist/components/charts/AreaChart.svelte.d.ts +61 -0
  136. package/dist/components/charts/BarChart.svelte +463 -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 +366 -315
  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 +332 -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 +59 -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 +347 -171
  156. package/dist/components/layout/Canvas.svelte.d.ts +110 -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 +253 -78
  166. package/dist/components/tooltip/Tooltip.svelte.d.ts +149 -31
  167. package/dist/components/tooltip/TooltipContext.svelte +426 -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 +3 -1
  184. package/dist/docs/Blockquote.svelte.d.ts +5 -16
  185. package/dist/docs/Code.svelte +20 -12
  186. package/dist/docs/Code.svelte.d.ts +12 -22
  187. package/dist/docs/ConnectorSweepMenuField.svelte +17 -0
  188. package/dist/docs/ConnectorSweepMenuField.svelte.d.ts +7 -0
  189. package/dist/docs/ConnectorTypeMenuField.svelte +17 -0
  190. package/dist/docs/ConnectorTypeMenuField.svelte.d.ts +7 -0
  191. package/dist/docs/CurveMenuField.svelte +14 -3
  192. package/dist/docs/CurveMenuField.svelte.d.ts +9 -18
  193. package/dist/docs/GeoDebug.svelte +47 -42
  194. package/dist/docs/GeoDebug.svelte.d.ts +4 -16
  195. package/dist/docs/Header1.svelte +4 -2
  196. package/dist/docs/Header1.svelte.d.ts +5 -18
  197. package/dist/docs/Json.svelte +11 -3
  198. package/dist/docs/Json.svelte.d.ts +9 -17
  199. package/dist/docs/Layout.svelte +10 -7
  200. package/dist/docs/Layout.svelte.d.ts +5 -15
  201. package/dist/docs/Link.svelte +7 -3
  202. package/dist/docs/Link.svelte.d.ts +5 -27
  203. package/dist/docs/PathDataMenuField.svelte +14 -10
  204. package/dist/docs/PathDataMenuField.svelte.d.ts +8 -18
  205. package/dist/docs/Preview.svelte +20 -7
  206. package/dist/docs/Preview.svelte.d.ts +12 -22
  207. package/dist/docs/TilesetField.svelte +20 -19
  208. package/dist/docs/TilesetField.svelte.d.ts +6 -19
  209. package/dist/docs/TransformDebug.svelte +5 -6
  210. package/dist/docs/TransformDebug.svelte.d.ts +18 -14
  211. package/dist/docs/ViewSourceButton.svelte +7 -4
  212. package/dist/docs/ViewSourceButton.svelte.d.ts +8 -18
  213. package/dist/types/d3-shape-extentions.d.ts +7 -0
  214. package/dist/utils/afterTick.d.ts +5 -0
  215. package/dist/utils/afterTick.js +8 -0
  216. package/dist/utils/arcText.svelte.d.ts +57 -0
  217. package/dist/utils/arcText.svelte.js +262 -0
  218. package/dist/utils/array.d.ts +9 -1
  219. package/dist/utils/array.js +13 -0
  220. package/dist/utils/attributes.d.ts +29 -0
  221. package/dist/utils/attributes.js +40 -0
  222. package/dist/utils/canvas.js +47 -10
  223. package/dist/utils/chart.d.ts +78 -0
  224. package/dist/utils/chart.js +512 -0
  225. package/dist/utils/color.d.ts +1 -0
  226. package/dist/utils/color.js +8 -0
  227. package/dist/utils/common.d.ts +3 -5
  228. package/dist/utils/common.js +3 -2
  229. package/dist/utils/connectorUtils.d.ts +21 -0
  230. package/dist/utils/connectorUtils.js +111 -0
  231. package/dist/utils/createId.d.ts +7 -0
  232. package/dist/utils/createId.js +9 -0
  233. package/dist/utils/debug.d.ts +1 -0
  234. package/dist/utils/debug.js +84 -0
  235. package/dist/utils/filterObject.d.ts +9 -0
  236. package/dist/utils/filterObject.js +12 -0
  237. package/dist/utils/graph/dagre.d.ts +34 -0
  238. package/dist/utils/graph/dagre.js +78 -0
  239. package/dist/utils/graph/dagre.test.d.ts +1 -0
  240. package/dist/utils/{graph.test.js → graph/dagre.test.js} +19 -33
  241. package/dist/utils/graph/sankey.d.ts +28 -0
  242. package/dist/utils/{graph.js → graph/sankey.js} +13 -41
  243. package/dist/utils/index.d.ts +3 -1
  244. package/dist/utils/index.js +3 -1
  245. package/dist/utils/key.svelte.d.ts +3 -0
  246. package/dist/utils/key.svelte.js +11 -0
  247. package/dist/utils/legendPayload.d.ts +7 -0
  248. package/dist/utils/legendPayload.js +8 -0
  249. package/dist/utils/motion.svelte.d.ts +140 -0
  250. package/dist/utils/motion.svelte.js +180 -0
  251. package/dist/utils/motion.test.d.ts +1 -0
  252. package/dist/utils/motion.test.js +213 -0
  253. package/dist/utils/{rect.d.ts → rect.svelte.d.ts} +7 -4
  254. package/dist/utils/rect.svelte.js +105 -0
  255. package/dist/utils/scales.svelte.d.ts +91 -0
  256. package/dist/utils/scales.svelte.js +201 -0
  257. package/dist/utils/stack.d.ts +2 -3
  258. package/dist/utils/stack.js +1 -1
  259. package/dist/utils/string.js +87 -0
  260. package/dist/utils/ticks.d.ts +9 -3
  261. package/dist/utils/ticks.js +122 -147
  262. package/dist/utils/ticks.test.d.ts +1 -0
  263. package/dist/utils/ticks.test.js +57 -0
  264. package/dist/utils/types.d.ts +81 -0
  265. package/package.json +28 -24
  266. package/dist/components/ChartContext.svelte +0 -295
  267. package/dist/components/ChartContext.svelte.d.ts +0 -139
  268. package/dist/components/TransformContext.svelte.d.ts +0 -158
  269. package/dist/stores/motionStore.d.ts +0 -30
  270. package/dist/stores/motionStore.js +0 -62
  271. package/dist/utils/graph.d.ts +0 -37
  272. package/dist/utils/rect.js +0 -107
  273. package/dist/utils/scales.d.ts +0 -66
  274. package/dist/utils/scales.js +0 -136
  275. /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,216 @@
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 or voronoi clip 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">
119
+ import type { Snippet } from 'svelte';
48
120
  import { bisector, max, min } from 'd3-array';
49
121
  import { quadtree as d3Quadtree, type Quadtree } from 'd3-quadtree';
50
122
  import { sortFunc, localPoint } from '@layerstack/utils';
51
123
  import { cls } from '@layerstack/tailwind';
52
124
 
125
+ import { getChartContext } from '../Chart.svelte';
126
+ import { getGeoContext } from '../GeoContext.svelte';
53
127
  import Svg from './../layout/Svg.svelte';
54
- import { chartContext } from './../ChartContext.svelte';
128
+ import Arc from '../Arc.svelte';
55
129
  import ChartClipPath from './../ChartClipPath.svelte';
56
130
  import Voronoi from './../Voronoi.svelte';
57
131
 
58
- import { isScaleBand, scaleInvert } from '../../utils/scales.js';
132
+ import { isScaleBand, scaleInvert } from '../../utils/scales.svelte.js';
59
133
  import { cartesianToPolar } from '../../utils/math.js';
60
134
  import { quadtreeRects } from '../../utils/quadtree.js';
135
+ import { raise } from '../../utils/chart.js';
136
+ import {
137
+ getTooltipMetaContext,
138
+ getTooltipPayload,
139
+ type TooltipPayload,
140
+ } from './tooltipMetaContext.js';
141
+ import { layerClass } from '../../utils/attributes.js';
142
+
143
+ const ctx = getChartContext<any>();
144
+ const geoCtx = getGeoContext();
145
+
146
+ let {
147
+ ref: refProp = $bindable(),
148
+ debug = false,
149
+ findTooltipData = 'closest',
150
+ hideDelay = 0,
151
+ locked = false,
152
+ mode = 'manual',
153
+ onclick = () => {},
154
+ radius = Infinity,
155
+ raiseTarget = false,
156
+ tooltipContext: tooltipContextProp = $bindable() as TooltipContextValue<TData>,
157
+ children,
158
+ }: TooltipContextProps<TData> = $props();
159
+
160
+ let ref = $state<HTMLElement>();
161
+ $effect.pre(() => {
162
+ refProp = ref;
163
+ });
61
164
 
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>();
165
+ let x = $state(0);
166
+ let y = $state(0);
167
+ let data = $state(null);
168
+ let payload = $state<TooltipPayload[]>([]);
169
+
170
+ /**
171
+ * If we're hovering the tooltip area on the chart
172
+ */
173
+ let isHoveringTooltipArea = $state(false);
174
+
175
+ /**
176
+ * If we're hovering the tooltip content container
177
+ */
178
+ let isHoveringTooltipContent = $state(false);
179
+
180
+ const metaCtx = getTooltipMetaContext();
181
+
182
+ const tooltipContext: TooltipContextValue = {
183
+ get x() {
184
+ return x;
185
+ },
186
+ get y() {
187
+ return y;
188
+ },
189
+ get data() {
190
+ return data;
191
+ },
192
+ get payload() {
193
+ return payload;
194
+ },
195
+ show: showTooltip,
196
+ hide: hideTooltip,
197
+ get mode() {
198
+ return mode;
199
+ },
200
+ get isHoveringTooltipArea() {
201
+ return isHoveringTooltipArea;
202
+ },
203
+ get isHoveringTooltipContent() {
204
+ return isHoveringTooltipContent;
205
+ },
206
+ set isHoveringTooltipContent(value) {
207
+ isHoveringTooltipContent = value;
208
+ },
209
+ };
210
+ tooltipContextProp = tooltipContext;
79
211
 
80
212
  /*
81
213
  TODO: Defaults to consider (if possible to detect scale type, which might not be possible)
82
214
  - scaleTime / scaleLinear: bisect
83
- - scaleTime / scaleLinear (multi/stack): bisect
215
+ - scaleTime / scaleLinear (multi/stack): bisect
84
216
  - scaleTime / scaleBand: bisect (or band)
85
217
  - scaleTime (multi) / scaleBand: bounds (or possible band if not overlapping)
86
218
  - scaleBand, scaleLinear: band (or bounds)
87
219
  - scaleBand, scaleLinear: band (or bounds) - multiple (overlapping) bars
88
220
  - scaleLinear, scaleLinear: voronoi (or quadtree)
89
221
  */
222
+ setTooltipContext(tooltipContext);
90
223
 
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;
128
-
129
- let isHoveringTooltip = false;
130
- let hideTimeoutId: NodeJS.Timeout;
131
- let tooltipContextNode: HTMLDivElement;
224
+ let hideTimeoutId: ReturnType<typeof setTimeout>;
132
225
 
133
- $: bisectX = bisector((d: any) => {
134
- const value = $x(d);
226
+ const bisectX = bisector((d: any) => {
227
+ const value = ctx.x(d);
135
228
  if (Array.isArray(value)) {
136
229
  // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
137
230
  // Using first value. Consider using average, max, etc
@@ -143,8 +236,8 @@
143
236
  }
144
237
  }).left;
145
238
 
146
- $: bisectY = bisector((d: any) => {
147
- const value = $y(d);
239
+ const bisectY = bisector((d: any) => {
240
+ const value = ctx.y(d);
148
241
  if (Array.isArray(value)) {
149
242
  // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
150
243
  // Using first value. Consider using average, max, etc
@@ -188,15 +281,16 @@
188
281
  return;
189
282
  }
190
283
 
191
- const containerNode = (e.target as Element).closest('.layercake-container')!;
284
+ const containerNode = (e.target as Element).closest('.lc-root-container')!;
192
285
  const point = localPoint(e, containerNode);
193
286
 
194
287
  if (
288
+ ref !== undefined &&
195
289
  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)
290
+ (point.x < ref.offsetLeft ||
291
+ point.x > ref.offsetLeft + ref.offsetWidth ||
292
+ point.y < ref.offsetTop ||
293
+ point.y > ref.offsetTop + ref.offsetHeight)
200
294
  ) {
201
295
  // Ignore if within padding of chart
202
296
  hideTooltip();
@@ -209,55 +303,55 @@
209
303
  switch (mode) {
210
304
  case 'bisect-x': {
211
305
  let xValueAtPoint: any;
212
- if ($radial) {
306
+ if (ctx.radial) {
213
307
  // Assume radial is always centered
214
- const { radians } = cartesianToPolar(point.x - $width / 2, point.y - $height / 2);
215
- xValueAtPoint = scaleInvert($xScale, radians);
308
+ const { radians } = cartesianToPolar(point.x - ctx.width / 2, point.y - ctx.height / 2);
309
+ xValueAtPoint = scaleInvert(ctx.xScale, radians);
216
310
  } else {
217
- xValueAtPoint = scaleInvert($xScale, point.x - $padding.left);
311
+ xValueAtPoint = scaleInvert(ctx.xScale, point.x - ctx.padding.left);
218
312
  }
219
313
 
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);
314
+ const index = bisectX(ctx.flatData, xValueAtPoint, 1);
315
+ const previousValue = ctx.flatData[index - 1];
316
+ const currentValue = ctx.flatData[index];
317
+ tooltipData = findData(previousValue, currentValue, xValueAtPoint, ctx.x);
224
318
  break;
225
319
  }
226
320
 
227
321
  case 'bisect-y': {
228
322
  // `y` value at pointer coordinate
229
- const yValueAtPoint = scaleInvert($yScale, point.y - $padding.top);
323
+ const yValueAtPoint = scaleInvert(ctx.yScale, point.y - ctx.padding.top);
230
324
 
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);
325
+ const index = bisectY(ctx.flatData, yValueAtPoint, 1);
326
+ const previousValue = ctx.flatData[index - 1];
327
+ const currentValue = ctx.flatData[index];
328
+ tooltipData = findData(previousValue, currentValue, yValueAtPoint, ctx.y);
235
329
  break;
236
330
  }
237
331
 
238
332
  case 'bisect-band': {
239
333
  // `x` and `y` values at pointer coordinate
240
- const xValueAtPoint = scaleInvert($xScale, point.x);
241
- const yValueAtPoint = scaleInvert($yScale, point.y);
334
+ const xValueAtPoint = scaleInvert(ctx.xScale, point.x);
335
+ const yValueAtPoint = scaleInvert(ctx.yScale, point.y);
242
336
 
243
- if (isScaleBand($xScale)) {
337
+ if (isScaleBand(ctx.xScale)) {
244
338
  // 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
339
+ const bandData = ctx.flatData
340
+ .filter((d) => ctx.x(d) === xValueAtPoint)
341
+ .sort(sortFunc(ctx.y as () => any)); // sort for bisect
248
342
  const index = bisectY(bandData, yValueAtPoint, 1);
249
343
  const previousValue = bandData[index - 1];
250
344
  const currentValue = bandData[index];
251
- tooltipData = findData(previousValue, currentValue, yValueAtPoint, $y);
252
- } else if (isScaleBand($yScale)) {
345
+ tooltipData = findData(previousValue, currentValue, yValueAtPoint, ctx.y);
346
+ } else if (isScaleBand(ctx.yScale)) {
253
347
  // 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
348
+ const bandData = ctx.flatData
349
+ .filter((d) => ctx.y(d) === yValueAtPoint)
350
+ .sort(sortFunc(ctx.x as () => any)); // sort for bisect
257
351
  const index = bisectX(bandData, xValueAtPoint, 1);
258
352
  const previousValue = bandData[index - 1];
259
353
  const currentValue = bandData[index];
260
- tooltipData = findData(previousValue, currentValue, xValueAtPoint, $x);
354
+ tooltipData = findData(previousValue, currentValue, xValueAtPoint, ctx.x);
261
355
  } else {
262
356
  // TODO: Support `bisect-band` without band? Fallback to bisect?
263
357
  }
@@ -265,7 +359,11 @@
265
359
  }
266
360
 
267
361
  case 'quadtree': {
268
- tooltipData = quadtree.find(point.x, point.y, radius);
362
+ tooltipData = quadtree?.find(
363
+ point.x - ctx.padding.left,
364
+ point.y - ctx.padding.top,
365
+ radius
366
+ );
269
367
  break;
270
368
  }
271
369
  }
@@ -276,12 +374,12 @@
276
374
  raise(e.target as Element);
277
375
  }
278
376
 
279
- $tooltip = {
280
- ...$tooltip,
281
- x: point.x,
282
- y: point.y,
283
- data: tooltipData,
284
- };
377
+ const payloadData = getTooltipPayload({ ctx, tooltipData, metaCtx });
378
+
379
+ x = point.x;
380
+ y = point.y;
381
+ data = tooltipData;
382
+ payload = payloadData;
285
383
  } else {
286
384
  // Hide tooltip if unable to locate
287
385
  hideTooltip();
@@ -294,160 +392,184 @@
294
392
  return;
295
393
  }
296
394
 
297
- // Wait an event loop tick in case `showTooltip` is called immediately on another element, to allow tweeneing (ex. moving between bands/bars)
395
+ isHoveringTooltipArea = false;
396
+
397
+ // Wait an event loop tick in case `showTooltip` is called immediately on another element,
398
+ // to allow tweening (ex. moving between bands/bars)
298
399
  // Additional hideDelay can be configured to extend this delay further
299
400
  hideTimeoutId = setTimeout(() => {
300
- if (!isHoveringTooltip) {
301
- $tooltip = { ...$tooltip, data: null };
401
+ if (!isHoveringTooltipArea && !isHoveringTooltipContent) {
402
+ data = null;
403
+ payload = [];
302
404
  }
303
405
  }, hideDelay);
304
406
  }
305
407
 
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
- }
408
+ const quadtree: Quadtree<[number, number]> | undefined = $derived.by(() => {
409
+ if (mode === 'quadtree') {
410
+ return d3Quadtree()
411
+ .x((d) => {
412
+ if (geoCtx.projection) {
413
+ const lat = ctx.x(d);
414
+ const long = ctx.y(d);
415
+ const geoValue = geoCtx.projection([lat, long]) ?? [0, 0];
416
+ return geoValue[0];
417
+ }
341
418
 
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
- }
419
+ const value = ctx.xGet(d);
420
+
421
+ if (Array.isArray(value)) {
422
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
423
+ // Using first value. Consider using average, max, etc
424
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
425
+ // return midpoint;
426
+ return min(value);
427
+ } else {
428
+ return value;
429
+ }
430
+ })
431
+ .y((d) => {
432
+ if (geoCtx.projection) {
433
+ const lat = ctx.x(d);
434
+ const long = ctx.y(d);
435
+ const geoValue = geoCtx.projection([lat, long]) ?? [0, 0];
436
+ return geoValue[1];
437
+ }
438
+
439
+ const value = ctx.yGet(d);
393
440
 
394
- $: triggerPointerEvents = ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode);
441
+ if (Array.isArray(value)) {
442
+ // `x` accessor with multiple properties (ex. `x={['start', 'end']})`)
443
+ // Using first value. Consider using average, max, etc
444
+ // const midpoint = new Date((value[1].valueOf() + value[0].getTime()) / 2);
445
+ // return midpoint;
446
+ return min(value);
447
+ } else {
448
+ return value;
449
+ }
450
+ })
451
+ .addAll(ctx.flatData as [number, number][]);
452
+ }
453
+ });
454
+
455
+ const rects: Array<{ x: number; y: number; width: number; height: number; data: any }> =
456
+ $derived.by(() => {
457
+ if (mode === 'bounds' || mode === 'band') {
458
+ return ctx.flatData
459
+ .map((d) => {
460
+ const xValue = ctx.xGet(d);
461
+ const yValue = ctx.yGet(d);
462
+
463
+ const x = Array.isArray(xValue) ? xValue[0] : xValue;
464
+ const y = Array.isArray(yValue) ? yValue[0] : yValue;
465
+
466
+ const xOffset = isScaleBand(ctx.xScale)
467
+ ? (ctx.xScale.padding() * ctx.xScale.step()) / 2
468
+ : 0;
469
+ const yOffset = isScaleBand(ctx.yScale)
470
+ ? (ctx.yScale.padding() * ctx.yScale.step()) / 2
471
+ : 0;
472
+
473
+ const fullWidth = max(ctx.xRange) - min(ctx.xRange);
474
+ const fullHeight = max(ctx.yRange) - min(ctx.yRange);
475
+
476
+ if (mode === 'band') {
477
+ // full band width/height regardless of value
478
+ return {
479
+ x: isScaleBand(ctx.xScale) ? x - xOffset : min(ctx.xRange),
480
+ y: isScaleBand(ctx.yScale) ? y - yOffset : min(ctx.yRange),
481
+ width: isScaleBand(ctx.xScale) ? ctx.xScale.step() : fullWidth,
482
+ height: isScaleBand(ctx.yScale) ? ctx.yScale.step() : fullHeight,
483
+ data: d,
484
+ };
485
+ } else if (mode === 'bounds') {
486
+ return {
487
+ x: isScaleBand(ctx.xScale) || Array.isArray(xValue) ? x - xOffset : min(ctx.xRange),
488
+ // y: isScaleBand($yScale) || Array.isArray(yValue) ? y - yOffset : min($yRange),
489
+ y: y - yOffset,
490
+
491
+ width: Array.isArray(xValue)
492
+ ? xValue[1] - xValue[0]
493
+ : isScaleBand(ctx.xScale)
494
+ ? ctx.xScale.step()
495
+ : min(ctx.xRange) + x,
496
+ height: Array.isArray(yValue)
497
+ ? yValue[1] - yValue[0]
498
+ : isScaleBand(ctx.yScale)
499
+ ? ctx.yScale.step()
500
+ : max(ctx.yRange) - y,
501
+ data: d,
502
+ };
503
+ }
504
+ })
505
+ .filter((x) => x !== undefined) // make typescript happy
506
+ .sort(sortFunc('x'));
507
+ }
508
+ return [];
509
+ });
510
+
511
+ const triggerPointerEvents = $derived(
512
+ ['bisect-x', 'bisect-y', 'bisect-band', 'quadtree'].includes(mode)
513
+ );
395
514
  </script>
396
515
 
397
- <!-- svelte-ignore a11y-click-events-have-key-events -->
398
- <!-- svelte-ignore a11y-no-static-element-interactions -->
516
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
399
517
  <div
400
- style:top="{$padding.top}px"
401
- style:left="{$padding.left}px"
402
- style:width="{$width}px"
403
- style:height="{$height}px"
518
+ style:top="{ctx.padding.top}px"
519
+ style:left="{ctx.padding.left}px"
520
+ style:width="{ctx.width}px"
521
+ style:height="{ctx.height}px"
404
522
  class={cls(
405
- 'TooltipContext absolute touch-none',
523
+ layerClass('tooltip-context'),
524
+ 'absolute touch-none',
406
525
  debug && triggerPointerEvents && 'bg-danger/10 outline outline-danger'
407
526
  )}
408
- on:pointerenter={(e) => {
409
- isHoveringTooltip = true;
527
+ onpointerenter={(e) => {
528
+ isHoveringTooltipArea = true;
410
529
  if (triggerPointerEvents) {
411
530
  showTooltip(e);
412
531
  }
413
532
  }}
414
- on:pointermove={(e) => {
533
+ onpointermove={(e) => {
415
534
  if (triggerPointerEvents) {
416
535
  showTooltip(e);
417
536
  }
418
537
  }}
419
- on:pointerleave={(e) => {
420
- isHoveringTooltip = false;
538
+ onpointerleave={(e) => {
539
+ isHoveringTooltipArea = false;
540
+
421
541
  hideTooltip();
422
542
  }}
423
- on:click={(e) => {
543
+ onclick={(e) => {
424
544
  // Ignore clicks without data (triggered from Legend clicks, for example)
425
- if (triggerPointerEvents && $tooltip?.data != null) {
426
- onclick(e, { data: $tooltip?.data });
545
+ if (triggerPointerEvents && tooltipContext.data != null) {
546
+ onclick(e, { data: tooltipContext.data });
427
547
  }
428
548
  }}
429
- bind:this={tooltipContextNode}
549
+ onkeydown={() => {}}
550
+ bind:this={ref}
430
551
  >
431
552
  <!-- Rendering slot within TooltipContext to allow pointer events to bubble up (ex. Brush) -->
432
553
  <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"
554
+ class={cls(layerClass('tooltip-context-container'), 'absolute')}
555
+ style:top="-{ctx.padding.top ?? 0}px"
556
+ style:left="-{ctx.padding.left ?? 0}px"
557
+ style:width="{ctx.containerWidth}px"
558
+ style:height="{ctx.containerHeight}px"
438
559
  >
439
- <slot tooltip={$tooltip} />
560
+ {@render children?.({ tooltipContext: tooltipContext })}
440
561
 
441
562
  {#if mode === 'voronoi'}
442
563
  <Svg>
443
564
  <Voronoi
565
+ r={radius}
444
566
  onpointerenter={(e, { data }) => {
445
567
  showTooltip(e, data);
446
568
  }}
447
569
  onpointermove={(e, { data }) => {
448
570
  showTooltip(e, data);
449
571
  }}
450
- onpointerleave={hideTooltip}
572
+ onpointerleave={() => hideTooltip()}
451
573
  onpointerdown={(e) => {
452
574
  // @ts-expect-error
453
575
  if (e.target?.hasPointerCapture(e.pointerId)) {
@@ -462,45 +584,78 @@
462
584
  />
463
585
  </Svg>
464
586
  {:else if mode === 'bounds' || mode === 'band'}
465
- <Svg>
466
- <g class="tooltip-rects">
587
+ <Svg center={ctx.radial}>
588
+ <g class={layerClass('tooltip-rects-g')}>
467
589
  {#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
- />
590
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
591
+ {#if ctx.radial}
592
+ <Arc
593
+ innerRadius={rect.y}
594
+ outerRadius={rect.y + rect.height}
595
+ startAngle={rect.x}
596
+ endAngle={rect.x + rect.width}
597
+ class={cls(
598
+ layerClass('tooltip-rect'),
599
+ debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
600
+ )}
601
+ onpointerenter={(e) => showTooltip(e, rect?.data)}
602
+ onpointermove={(e) => showTooltip(e, rect?.data)}
603
+ onpointerleave={() => hideTooltip()}
604
+ onpointerdown={(e) => {
605
+ const target = e.target as Element;
606
+ if (target?.hasPointerCapture(e.pointerId)) {
607
+ target.releasePointerCapture(e.pointerId);
608
+ }
609
+ }}
610
+ onclick={(e) => {
611
+ onclick(e, { data: rect?.data });
612
+ }}
613
+ />
614
+ {:else}
615
+ <rect
616
+ x={rect?.x}
617
+ y={rect?.y}
618
+ width={rect?.width}
619
+ height={rect?.height}
620
+ class={cls(
621
+ layerClass('tooltip-rect'),
622
+ debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
623
+ )}
624
+ onpointerenter={(e) => showTooltip(e, rect?.data)}
625
+ onpointermove={(e) => showTooltip(e, rect?.data)}
626
+ onpointerleave={() => hideTooltip()}
627
+ onpointerdown={(e) => {
628
+ const target = e.target as Element;
629
+ if (target?.hasPointerCapture(e.pointerId)) {
630
+ target.releasePointerCapture(e.pointerId);
631
+ }
632
+ }}
633
+ onclick={(e) => {
634
+ onclick(e, { data: rect?.data });
635
+ }}
636
+ />
637
+ {/if}
488
638
  {/each}
489
639
  </g>
490
640
  </Svg>
491
641
  {:else if mode === 'quadtree' && debug}
492
642
  <Svg pointerEvents={false}>
493
643
  <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}
644
+ <g class={layerClass('tooltip-quadtree-g')}>
645
+ {#if quadtree}
646
+ {#each quadtreeRects(quadtree, false) as rect}
647
+ <rect
648
+ x={rect.x}
649
+ y={rect.y}
650
+ width={rect.width}
651
+ height={rect.height}
652
+ class={cls(
653
+ layerClass('tooltip-quadtree-rect'),
654
+ debug ? 'fill-danger/10 stroke-danger' : 'fill-transparent'
655
+ )}
656
+ />
657
+ {/each}
658
+ {/if}
504
659
  </g>
505
660
  </ChartClipPath>
506
661
  </Svg>