@fundar/data-chart-telling 1.16.0 → 1.18.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 (330) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/configuration/ConfigVars.svelte +14 -0
  3. package/dist/configuration/ConfigVars.svelte.d.ts +3 -0
  4. package/dist/configuration/config.svelte.d.ts +5 -0
  5. package/dist/configuration/config.svelte.js +20 -6
  6. package/dist/configuration/themes/dark.js +1 -1
  7. package/dist/configuration/themes/editorial.js +1 -1
  8. package/dist/index.d.ts +12 -4
  9. package/dist/index.js +4 -1
  10. package/dist/layout/base/BasePlotLayout.svelte +1 -1
  11. package/dist/layout/figure/Figure.svelte +5 -12
  12. package/dist/layout/figure/FigureChrome.svelte +2 -10
  13. package/dist/layout/geometry/GeometryLayout.svelte +219 -44
  14. package/dist/layout/hover/HoverDefaults.d.ts +52 -0
  15. package/dist/layout/hover/HoverDefaults.js +96 -0
  16. package/dist/layout/hover/HoverLayers.d.ts +35 -0
  17. package/dist/layout/hover/HoverLayers.js +122 -0
  18. package/dist/layout/hover/HoverSettings.js +4 -1
  19. package/dist/layout/hover/HoverShapes.d.ts +44 -0
  20. package/dist/layout/hover/HoverShapes.js +103 -0
  21. package/dist/layout/hover/PlotHover.svelte.d.ts +18 -0
  22. package/dist/layout/hover/PlotHover.svelte.js +54 -1
  23. package/dist/layout/legend/DisabledStyle.d.ts +1 -1
  24. package/dist/layout/legend/DisabledStyle.js +1 -1
  25. package/dist/layout/legend/DiscreteBadgeItem.svelte +1 -1
  26. package/dist/layout/legend/DiscreteSection.svelte +1 -1
  27. package/dist/layout/legend/LegendState.svelte.d.ts +14 -2
  28. package/dist/layout/legend/LegendState.svelte.js +23 -4
  29. package/dist/layout/legend/LegendText.d.ts +4 -1
  30. package/dist/layout/legend/LegendText.js +7 -1
  31. package/dist/layout/margins/PlotMargins.svelte.d.ts +2 -2
  32. package/dist/layout/margins/PlotMargins.svelte.js +2 -2
  33. package/dist/layout/plot/Core.svelte +2 -2
  34. package/dist/layout/plot/Plot.svelte +4 -2
  35. package/dist/layout/plot/Plot.svelte.d.ts +2 -1
  36. package/dist/layout/plot/PublicPlotContext.d.ts +6 -0
  37. package/dist/layout/plot/PublicPlotContext.js +8 -0
  38. package/dist/layout/scales/ScalesLayout.svelte +1 -1
  39. package/dist/layout/styles/ValueLabels.d.ts +43 -4
  40. package/dist/layout/styles/ValueLabels.js +87 -19
  41. package/dist/layout/timeline/Timeline.svelte +5 -1
  42. package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -9
  43. package/dist/layout/tooltip/TooltipState.svelte.js +28 -29
  44. package/dist/markers/MarkerKinds.d.ts +5 -0
  45. package/dist/markers/MarkerKinds.js +1 -0
  46. package/dist/markers/area/AreaMarker.svelte +3 -0
  47. package/dist/markers/arrow/ArrowMarker.svelte +9 -5
  48. package/dist/markers/band/BandMarker.svelte +74 -0
  49. package/dist/markers/band/BandMarker.svelte.d.ts +7 -0
  50. package/dist/markers/band/Bands.d.ts +16 -0
  51. package/dist/markers/band/Bands.js +48 -0
  52. package/dist/markers/bar/BarMarker.svelte +50 -96
  53. package/dist/markers/bollinger/BollingerMarker.svelte +3 -0
  54. package/dist/markers/box/BoxMarker.svelte +3 -1
  55. package/dist/markers/cell/CellMarker.svelte +11 -7
  56. package/dist/markers/contour/ContourMarker.svelte +3 -0
  57. package/dist/markers/delaunay/DelaunayLinkMarker.svelte +9 -5
  58. package/dist/markers/delaunay/DelaunayMeshMarker.svelte +3 -0
  59. package/dist/markers/density/DensityMarker.svelte +3 -0
  60. package/dist/markers/difference/DifferenceMarker.svelte +3 -0
  61. package/dist/markers/dot/DotMarker.svelte +11 -6
  62. package/dist/markers/geo/GraticuleMarker.svelte +3 -0
  63. package/dist/markers/geo/SphereMarker.svelte +3 -0
  64. package/dist/markers/hover/HoverMarker.svelte +7 -249
  65. package/dist/markers/hover/HoverMarker.svelte.d.ts +4 -27
  66. package/dist/markers/hull/HullMarker.svelte +3 -0
  67. package/dist/markers/image/ImageMarker.svelte +3 -0
  68. package/dist/markers/line/LineMarker.svelte +3 -0
  69. package/dist/markers/link/LinkMarker.svelte +3 -0
  70. package/dist/markers/raster/RasterMarker.svelte +3 -0
  71. package/dist/markers/rect/RectMarker.svelte +25 -17
  72. package/dist/markers/regression/RegressionMarker.svelte +3 -0
  73. package/dist/markers/rule/RuleMarker.svelte +15 -5
  74. package/dist/markers/text/TextFit.d.ts +44 -0
  75. package/dist/markers/text/TextFit.js +86 -0
  76. package/dist/markers/text/TextMarker.svelte +186 -90
  77. package/dist/markers/text/TextMarker.svelte.d.ts +2 -0
  78. package/dist/markers/tick/TickMarker.svelte +9 -3
  79. package/dist/markers/trail/TrailMarker.svelte +3 -0
  80. package/dist/markers/utils/BoxLabel.d.ts +58 -0
  81. package/dist/markers/utils/BoxLabel.js +175 -0
  82. package/dist/markers/utils/MarkerEvents.d.ts +23 -0
  83. package/dist/markers/utils/MarkerEvents.js +44 -0
  84. package/dist/markers/utils/MarkerLabel.svelte +33 -0
  85. package/dist/markers/utils/MarkerLabel.svelte.d.ts +10 -0
  86. package/dist/markers/utils/PointPixel.d.ts +37 -0
  87. package/dist/markers/utils/PointPixel.js +44 -0
  88. package/dist/markers/utils/RowStroke.d.ts +9 -21
  89. package/dist/markers/utils/RowStroke.js +10 -21
  90. package/dist/markers/utils/RowStyle.d.ts +26 -0
  91. package/dist/markers/utils/RowStyle.js +55 -0
  92. package/dist/markers/vector/VectorMarker.svelte +3 -0
  93. package/dist/markers/voronoi/VoronoiMarker.svelte +9 -5
  94. package/dist/markers/voronoi/VoronoiMeshMarker.svelte +3 -0
  95. package/dist/markers/waffle/WaffleMarker.svelte +9 -5
  96. package/dist/phases/Pipeline.d.ts +10 -8
  97. package/dist/phases/Pipeline.js +13 -9
  98. package/dist/phases/context/ContextPhase.d.ts +22 -0
  99. package/dist/phases/context/ContextPhase.js +23 -0
  100. package/dist/phases/context/RowContext.d.ts +35 -0
  101. package/dist/phases/context/RowContext.js +95 -0
  102. package/dist/phases/data/DataPhase.d.ts +4 -4
  103. package/dist/phases/data/DataPhase.js +53 -12
  104. package/dist/phases/hover/HoverPhase.d.ts +6 -7
  105. package/dist/phases/hover/HoverPhase.js +28 -15
  106. package/dist/phases/mapping/MappingPhase.d.ts +4 -4
  107. package/dist/phases/mapping/MappingPhase.js +4 -3
  108. package/dist/phases/markers/MarkerStyles.d.ts +26 -0
  109. package/dist/phases/markers/MarkerStyles.js +126 -0
  110. package/dist/phases/markers/MarkersPhase.d.ts +5 -5
  111. package/dist/phases/markers/MarkersPhase.js +8 -6
  112. package/dist/phases/scales/ScalesPhase.d.ts +4 -4
  113. package/dist/phases/scales/ScalesPhase.js +4 -4
  114. package/dist/phases/sharedScales/SharedScalesPhase.d.ts +2 -2
  115. package/dist/phases/sharedScales/SharedScalesPhase.js +2 -2
  116. package/dist/phases/statistics/MarkerGrouping.d.ts +0 -9
  117. package/dist/phases/statistics/MarkerGrouping.js +0 -16
  118. package/dist/phases/statistics/StatisticsPhase.js +1 -1
  119. package/dist/phases/styles/StylesPhase.d.ts +3 -3
  120. package/dist/phases/styles/StylesPhase.js +2 -2
  121. package/dist/phases/tooltip/TooltipPhase.d.ts +4 -4
  122. package/dist/phases/tooltip/TooltipPhase.js +10 -7
  123. package/dist/phases/transforms/Transforms.js +3 -1
  124. package/dist/phases/transforms/TransformsPhase.d.ts +3 -3
  125. package/dist/phases/transforms/TransformsPhase.js +60 -6
  126. package/dist/phases/transforms/methods/TreemapTransform.d.ts +28 -0
  127. package/dist/phases/transforms/methods/TreemapTransform.js +119 -0
  128. package/dist/plots/correlation/heatmap/defaults.d.ts +2 -2
  129. package/dist/plots/correlation/heatmap/defaults.js +23 -8
  130. package/dist/plots/correlation/heatmap/markers.d.ts +2 -10
  131. package/dist/plots/correlation/heatmap/markers.js +11 -37
  132. package/dist/plots/correlation/scatter/defaults.d.ts +2 -2
  133. package/dist/plots/correlation/scatter/defaults.js +9 -3
  134. package/dist/plots/correlation/scatter/markers.d.ts +3 -3
  135. package/dist/plots/correlation/scatter/markers.js +6 -5
  136. package/dist/plots/distribution/box/BoxSummaries.d.ts +17 -8
  137. package/dist/plots/distribution/box/BoxSummaries.js +90 -40
  138. package/dist/plots/distribution/box/defaults.d.ts +2 -2
  139. package/dist/plots/distribution/box/defaults.js +9 -6
  140. package/dist/plots/distribution/box/markers.d.ts +2 -2
  141. package/dist/plots/distribution/box/markers.js +3 -3
  142. package/dist/plots/distribution/density/defaults.d.ts +2 -2
  143. package/dist/plots/distribution/density/defaults.js +17 -1
  144. package/dist/plots/distribution/density/markers.d.ts +2 -2
  145. package/dist/plots/distribution/density/markers.js +4 -4
  146. package/dist/plots/distribution/histogram/defaults.d.ts +2 -2
  147. package/dist/plots/distribution/histogram/defaults.js +22 -27
  148. package/dist/plots/distribution/histogram/markers.d.ts +3 -12
  149. package/dist/plots/distribution/histogram/markers.js +21 -62
  150. package/dist/plots/distribution/pyramid/defaults.d.ts +2 -2
  151. package/dist/plots/distribution/pyramid/defaults.js +7 -4
  152. package/dist/plots/distribution/pyramid/markers.d.ts +2 -12
  153. package/dist/plots/distribution/pyramid/markers.js +16 -66
  154. package/dist/plots/distribution/violin/defaults.d.ts +2 -2
  155. package/dist/plots/distribution/violin/defaults.js +9 -7
  156. package/dist/plots/distribution/violin/markers.d.ts +2 -2
  157. package/dist/plots/distribution/violin/markers.js +4 -4
  158. package/dist/plots/evolution/area/defaults.d.ts +2 -2
  159. package/dist/plots/evolution/area/defaults.js +1 -1
  160. package/dist/plots/evolution/area/markers.d.ts +2 -2
  161. package/dist/plots/evolution/area/markers.js +4 -4
  162. package/dist/plots/evolution/line/defaults.d.ts +2 -2
  163. package/dist/plots/evolution/line/defaults.js +1 -1
  164. package/dist/plots/evolution/line/markers.d.ts +2 -2
  165. package/dist/plots/evolution/line/markers.js +3 -3
  166. package/dist/plots/evolution/slope/defaults.d.ts +2 -2
  167. package/dist/plots/evolution/slope/defaults.js +8 -4
  168. package/dist/plots/evolution/slope/markers.d.ts +2 -2
  169. package/dist/plots/evolution/slope/markers.js +3 -3
  170. package/dist/plots/evolution/sparkline/defaults.d.ts +2 -2
  171. package/dist/plots/evolution/sparkline/defaults.js +5 -2
  172. package/dist/plots/evolution/sparkline/markers.d.ts +2 -2
  173. package/dist/plots/evolution/sparkline/markers.js +3 -3
  174. package/dist/plots/map/geo/Core.svelte +3 -3
  175. package/dist/plots/map/geo/defaults.d.ts +2 -2
  176. package/dist/plots/map/geo/phases/data.d.ts +1 -1
  177. package/dist/plots/map/geo/phases/data.js +1 -1
  178. package/dist/plots/map/geo/phases/hover.d.ts +2 -2
  179. package/dist/plots/map/geo/phases/hover.js +3 -3
  180. package/dist/plots/map/geo/phases/markers.d.ts +2 -2
  181. package/dist/plots/map/geo/phases/markers.js +5 -4
  182. package/dist/plots/map/geo/phases/scales.d.ts +2 -2
  183. package/dist/plots/map/geo/phases/scales.js +2 -2
  184. package/dist/plots/part-of-a-whole/treemap/Plot.svelte +47 -0
  185. package/dist/plots/part-of-a-whole/treemap/Plot.svelte.d.ts +26 -0
  186. package/dist/plots/part-of-a-whole/treemap/defaults.d.ts +10 -0
  187. package/dist/plots/part-of-a-whole/treemap/defaults.js +183 -0
  188. package/dist/plots/ranking/bar/defaults.d.ts +2 -2
  189. package/dist/plots/ranking/bar/defaults.js +15 -9
  190. package/dist/plots/ranking/bar/markers.d.ts +4 -14
  191. package/dist/plots/ranking/bar/markers.js +45 -86
  192. package/dist/plots/ranking/bullet/defaults.d.ts +2 -2
  193. package/dist/plots/ranking/bullet/defaults.js +4 -4
  194. package/dist/plots/ranking/bullet/markers.d.ts +3 -3
  195. package/dist/plots/ranking/bullet/markers.js +11 -12
  196. package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +3 -3
  197. package/dist/plots/ranking/cleveland/ClevelandMarkers.js +28 -23
  198. package/dist/plots/ranking/cleveland/defaults.d.ts +2 -2
  199. package/dist/plots/ranking/cleveland/defaults.js +7 -4
  200. package/dist/plots/ranking/dumbbell/defaults.d.ts +2 -2
  201. package/dist/plots/ranking/forest/defaults.d.ts +2 -2
  202. package/dist/plots/ranking/lollipop/defaults.d.ts +2 -2
  203. package/dist/types/configuration/styling.d.ts +31 -2
  204. package/dist/types/layout/context.d.ts +21 -0
  205. package/dist/types/layout/context.js +1 -0
  206. package/dist/types/layout/hover.d.ts +3 -0
  207. package/dist/types/layout/legend.d.ts +8 -1
  208. package/dist/types/layout/mapping.d.ts +12 -3
  209. package/dist/types/layout/scales.d.ts +6 -0
  210. package/dist/types/layout/styles/values.d.ts +8 -2
  211. package/dist/types/layout/tooltip.d.ts +11 -4
  212. package/dist/types/markers/axis/arrow.d.ts +2 -8
  213. package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
  214. package/dist/types/markers/axis/band.d.ts +24 -0
  215. package/dist/types/markers/axis/band.js +1 -0
  216. package/dist/types/markers/axis/bar.d.ts +6 -10
  217. package/dist/types/markers/axis/cell.d.ts +5 -5
  218. package/dist/types/markers/axis/delaunayLink.d.ts +2 -2
  219. package/dist/types/markers/axis/hover.d.ts +60 -15
  220. package/dist/types/markers/axis/rect.d.ts +4 -8
  221. package/dist/types/markers/axis/rule.d.ts +2 -16
  222. package/dist/types/markers/axis/tick.d.ts +2 -2
  223. package/dist/types/markers/axis/voronoi.d.ts +2 -2
  224. package/dist/types/markers/axis/waffle.d.ts +4 -3
  225. package/dist/types/markers/basic/dot.d.ts +2 -2
  226. package/dist/types/markers/basic/text.d.ts +56 -14
  227. package/dist/types/markers/channels/commonMarkerConfig.d.ts +8 -1
  228. package/dist/types/markers/channels/commonMarkerConfigWithArea.d.ts +1 -2
  229. package/dist/types/markers/channels/commonMarkerConfigWithLabel.d.ts +10 -0
  230. package/dist/types/markers/channels/commonMarkerConfigWithLabel.js +1 -0
  231. package/dist/types/markers/channels/commonMarkerEvents.d.ts +17 -0
  232. package/dist/types/markers/channels/commonMarkerEvents.js +13 -0
  233. package/dist/types/markers/common.d.ts +1 -0
  234. package/dist/types/markers/common.js +1 -0
  235. package/dist/types/markers/geo/contour.d.ts +2 -1
  236. package/dist/types/markers/geo/graticule.d.ts +2 -1
  237. package/dist/types/markers/geo/link.d.ts +2 -1
  238. package/dist/types/markers/geo/sphere.d.ts +2 -1
  239. package/dist/types/markers/geo/vector.d.ts +2 -1
  240. package/dist/types/phases/context/phase.d.ts +7 -0
  241. package/dist/types/phases/context/phase.js +1 -0
  242. package/dist/types/phases/data/phase.d.ts +7 -2
  243. package/dist/types/phases/hover/phase.d.ts +10 -5
  244. package/dist/types/phases/index.d.ts +2 -1
  245. package/dist/types/phases/kind.d.ts +11 -8
  246. package/dist/types/phases/mapping/phase.d.ts +2 -2
  247. package/dist/types/phases/markers/phase.d.ts +3 -3
  248. package/dist/types/phases/scales/phase.d.ts +4 -4
  249. package/dist/types/phases/stage.d.ts +3 -3
  250. package/dist/types/phases/state.d.ts +8 -1
  251. package/dist/types/phases/statistics/phase.d.ts +2 -1
  252. package/dist/types/phases/styles/phase.d.ts +3 -2
  253. package/dist/types/phases/transforms/phase.d.ts +13 -2
  254. package/dist/types/plots/constants.d.ts +17 -19
  255. package/dist/types/plots/correlation/heatmap/props.d.ts +3 -3
  256. package/dist/types/plots/correlation/heatmap/state.d.ts +2 -2
  257. package/dist/types/plots/correlation/scatter/props.d.ts +3 -3
  258. package/dist/types/plots/correlation/scatter/state.d.ts +2 -2
  259. package/dist/types/plots/data/common.d.ts +19 -6
  260. package/dist/types/plots/data/geo.d.ts +1 -1
  261. package/dist/types/plots/distribution/box/props.d.ts +25 -3
  262. package/dist/types/plots/distribution/box/state.d.ts +6 -17
  263. package/dist/types/plots/distribution/density/props.d.ts +3 -11
  264. package/dist/types/plots/distribution/density/state.d.ts +2 -2
  265. package/dist/types/plots/distribution/histogram/props.d.ts +16 -11
  266. package/dist/types/plots/distribution/histogram/state.d.ts +2 -2
  267. package/dist/types/plots/distribution/pyramid/props.d.ts +3 -3
  268. package/dist/types/plots/distribution/pyramid/state.d.ts +2 -2
  269. package/dist/types/plots/distribution/violin/props.d.ts +4 -3
  270. package/dist/types/plots/distribution/violin/state.d.ts +2 -2
  271. package/dist/types/plots/evolution/area/props.d.ts +3 -3
  272. package/dist/types/plots/evolution/area/state.d.ts +2 -2
  273. package/dist/types/plots/evolution/line/props.d.ts +3 -3
  274. package/dist/types/plots/evolution/line/state.d.ts +2 -2
  275. package/dist/types/plots/evolution/slope/state.d.ts +2 -2
  276. package/dist/types/plots/evolution/sparkline/state.d.ts +2 -2
  277. package/dist/types/plots/map/geo/state.d.ts +1 -1
  278. package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +29 -0
  279. package/dist/types/plots/part-of-a-whole/treemap/props.js +1 -0
  280. package/dist/types/plots/part-of-a-whole/treemap/state.d.ts +6 -0
  281. package/dist/types/plots/part-of-a-whole/treemap/state.js +1 -0
  282. package/dist/types/plots/props.d.ts +10 -4
  283. package/dist/types/plots/ranking/bar/props.d.ts +3 -3
  284. package/dist/types/plots/ranking/bar/state.d.ts +2 -2
  285. package/dist/types/plots/ranking/bullet/state.d.ts +2 -2
  286. package/dist/types/plots/ranking/cleveland/props.d.ts +3 -3
  287. package/dist/types/plots/ranking/cleveland/state.d.ts +2 -2
  288. package/dist/types/plots/ranking/dumbbell/props.d.ts +3 -3
  289. package/dist/types/plots/ranking/dumbbell/state.d.ts +2 -2
  290. package/dist/types/plots/ranking/forest/props.d.ts +3 -3
  291. package/dist/types/plots/ranking/forest/state.d.ts +2 -2
  292. package/dist/types/plots/ranking/lollipop/props.d.ts +3 -3
  293. package/dist/types/plots/ranking/lollipop/state.d.ts +2 -2
  294. package/dist/types/plots/styling.d.ts +24 -0
  295. package/dist/types/transforms/index.d.ts +3 -1
  296. package/dist/types/transforms/treemap.d.ts +32 -0
  297. package/dist/types/transforms/treemap.js +5 -0
  298. package/dist/utils/color/ColorTones.d.ts +19 -0
  299. package/dist/utils/color/ColorTones.js +64 -0
  300. package/dist/utils/color/CssColor.d.ts +14 -5
  301. package/dist/utils/color/CssColor.js +69 -27
  302. package/dist/utils/color/index.d.ts +4 -0
  303. package/dist/utils/color/index.js +4 -0
  304. package/dist/utils/grouping.d.ts +18 -1
  305. package/dist/utils/grouping.js +31 -0
  306. package/docs/concepts.md +3 -2
  307. package/docs/legend.md +8 -5
  308. package/docs/markers.md +110 -28
  309. package/docs/plots/evolution/line.md +1 -1
  310. package/docs/plots/evolution/slope.md +1 -1
  311. package/docs/plots/part-of-a-whole/treemap.md +103 -0
  312. package/docs/plots/ranking/bar.md +2 -1
  313. package/docs/plots/ranking/cleveland.md +1 -1
  314. package/docs/plots.md +21 -20
  315. package/docs/scales.md +3 -0
  316. package/docs/state.md +34 -1
  317. package/docs/styles-and-segments.md +20 -19
  318. package/docs/theming.md +6 -12
  319. package/docs/tooltip-and-hover.md +81 -3
  320. package/docs/transforms-and-statistics.md +17 -16
  321. package/examples/LineDates.svelte +1 -1
  322. package/examples/ResponsiveLine.svelte +3 -1
  323. package/examples/Treemap.svelte +13 -0
  324. package/examples/TreemapHover.svelte +25 -0
  325. package/examples/ValueLabels.svelte +1 -1
  326. package/examples/datasets/economic-activity.ts +40 -0
  327. package/examples/datasets/index.ts +1 -0
  328. package/llms-full.txt +11 -9
  329. package/llms.txt +4 -1
  330. package/package.json +3 -1
@@ -28,6 +28,7 @@
28
28
  import DotMarker from '../../markers/dot/DotMarker.svelte';
29
29
  import TextMarker from '../../markers/text/TextMarker.svelte';
30
30
  import RuleMarker from '../../markers/rule/RuleMarker.svelte';
31
+ import BandMarker from '../../markers/band/BandMarker.svelte';
31
32
  import HoverMarker from '../../markers/hover/HoverMarker.svelte';
32
33
  import GeoHoverMarker from '../../markers/geo/GeoHoverMarker.svelte';
33
34
  import DeltaMarker from '../../markers/delta/DeltaMarker.svelte';
@@ -39,6 +40,7 @@
39
40
  import ContourMarker from '../../markers/contour/ContourMarker.svelte';
40
41
  import ContourClipMarker from '../../markers/contour/ContourClipMarker.svelte';
41
42
  import InsetMarker from '../../markers/inset/InsetMarker.svelte';
43
+ import MarkerLabel from '../../markers/utils/MarkerLabel.svelte';
42
44
  import FrameClip from './FrameClip.svelte';
43
45
  import MarkerOffset from './MarkerOffset.svelte';
44
46
  import { getConfiguration } from '../../configuration/config.svelte';
@@ -46,12 +48,21 @@
46
48
  import { PlotMargins } from '../margins/PlotMargins.svelte';
47
49
  import type { Series } from '../../types/plots/data/common';
48
50
  import type { MarkerConfig } from '../../types/markers/all';
51
+ import type { CommonMarkerEvents } from '../../types/markers/channels/commonMarkerEvents';
49
52
  import type { TooltipAnchorX, TooltipAnchorY } from '../../types/layout/tooltip';
50
53
  import type { PlotHover } from '../hover/PlotHover.svelte';
51
54
  import type { ScopedMarkerGroup } from '../../types/layout/geometry';
52
55
  import type { GeoFeature } from '../../types/plots/data/geo';
53
56
  import { MarkerGrouping } from '../../phases/statistics/MarkerGrouping';
54
57
  import { FrameClipping } from './FrameClipping';
58
+ import { HoverShapes, type HoverShapesReach } from '../hover/HoverShapes';
59
+ import { PlotInteraction } from '../interaction/PlotInteraction.svelte';
60
+ import { SERIES_KEY } from '../../phases/transforms/TransformsPhase';
61
+ import { HoverLayers, type HoverPointGroup } from '../hover/HoverLayers';
62
+ import { BandNudge } from '../../markers/utils/BandNudge';
63
+ import { PointPixel } from '../../markers/utils/PointPixel';
64
+ import { HoverDefaults } from '../hover/HoverDefaults';
65
+ import type { HoverMarkerConfig } from '../../types/markers/common';
55
66
 
56
67
  /**
57
68
  * Renders every marker in `markers`, in array order, each delegated to the
@@ -105,9 +116,137 @@
105
116
  } = $props();
106
117
 
107
118
  const cfg = $derived(getConfiguration());
119
+ const interaction = PlotInteraction.current(() => cfg);
120
+
121
+ /**
122
+ * The markers, each `hover` one laid over the plot kind's own hover under the strategy in force - read as they
123
+ * are drawn, so a strategy changed while the plot is shown changes what the hover draws.
124
+ */
125
+ const drawn = $derived.by(() => {
126
+ const look = ctrl.look;
127
+ return markers.map((marker) =>
128
+ marker.type === 'hover'
129
+ ? (HoverDefaults.merge(look, marker as HoverMarkerConfig) as MarkerConfig)
130
+ : marker
131
+ );
132
+ });
133
+
134
+ /** The look the hover markers give the shapes linked to the hover. */
135
+ const shapes = $derived(new HoverShapes(drawn));
136
+ const reach: HoverShapesReach = {
137
+ roleOf: (row, series) => ctrl.roleOf(row as TData, series),
138
+ dimmed: (row) => {
139
+ const series = row[SERIES_KEY];
140
+ return typeof series === 'string' && interaction.fillFor(series) !== undefined;
141
+ },
142
+ get cfg() {
143
+ return cfg;
144
+ }
145
+ };
108
146
 
109
147
  // Mounted inside svelteplot's `<Plot>`, the one place the margins it settles on can be read.
110
- PlotMargins.current()?.follow(usePlot().svelteplot);
148
+ const svelteplot = usePlot().svelteplot;
149
+ PlotMargins.current()?.follow(svelteplot);
150
+
151
+ /**
152
+ * The points a hover marker draws over: every matched one; with `series`, that series' only, in its color -
153
+ * or with `scope: 'segment'`, each segment's, in the segment's. The first is the active one of a series.
154
+ */
155
+ function hoverGroupsOf(marker: HoverMarkerConfig): HoverPointGroup[] {
156
+ const points = ctrl.points;
157
+ if (points.length === 0) return [];
158
+ const nearest = JSON.parse(nearestKey || '{}') as {
159
+ all?: number;
160
+ bySeries?: Record<string, number>;
161
+ };
162
+ const scope = marker.series;
163
+ if (!scope) {
164
+ const active = nearest.all !== undefined ? points[nearest.all] : undefined;
165
+ return [{ key: '', points, active: active ?? ctrl.activePoint }];
166
+ }
167
+ const under = nearest.bySeries?.[scope];
168
+ const activeOf = (list: typeof points) =>
169
+ (under !== undefined && list.find((p) => p.row === points[under].row)) || list[0] || null;
170
+ const group = groupByName.get(scope);
171
+ if (!group) return [];
172
+ const own = points.filter((p) => p.series === scope);
173
+ const colored = (list: typeof own, color: string | undefined) =>
174
+ color ? list.map((p) => ({ ...p, color })) : list;
175
+ if (marker.scope !== 'segment') {
176
+ const seriesPoints = colored(own, group.segments[0]?.color ?? group.color);
177
+ return [{ key: scope, points: seriesPoints, active: activeOf(seriesPoints) }];
178
+ }
179
+ return group.segments.map((seg, i) => {
180
+ // p.row (TData) is always a superset of TSeries in practice, not provable across two independent generics.
181
+ const segPoints = colored(
182
+ own.filter((p) => seg.match(p.row as unknown as TSeries)),
183
+ seg.color
184
+ );
185
+ return { key: `${scope}-${i}`, points: segPoints, active: activeOf(segPoints) };
186
+ });
187
+ }
188
+
189
+ /**
190
+ * The hovered point under the pointer: of all of them, and of each series - the nearest to the pointer, not the
191
+ * first the strategy matched, so a crosshair at it follows the pointer across the series of a category. Kept as
192
+ * text, so the hover's markers are built again only when it changes, not at every move of the pointer.
193
+ */
194
+ const nearestKey = $derived.by(() => {
195
+ const cursor = ctrl.cursor;
196
+ const points = ctrl.points;
197
+ if (!cursor || points.length === 0) return '';
198
+ const all = PointPixel.nearest(svelteplot.scales, points, cursor);
199
+ const bySeries: Record<string, number> = {};
200
+ for (const series of new Set(points.map((p) => p.series))) {
201
+ if (series == null) continue;
202
+ const indexes = points.flatMap((p, i) => (p.series === series ? [i] : []));
203
+ const nearest = PointPixel.nearest(
204
+ svelteplot.scales,
205
+ indexes.map((i) => points[i]),
206
+ cursor
207
+ );
208
+ if (nearest >= 0) bySeries[series] = indexes[nearest];
209
+ }
210
+ return JSON.stringify({ all: all >= 0 ? all : undefined, bySeries });
211
+ });
212
+
213
+ /** The markers `marker`'s `layer` draws, over each group of the points it draws over. */
214
+ function hoverPartsOf(marker: HoverMarkerConfig, layer: 'back' | 'front', index: number) {
215
+ return hoverGroupsOf(marker).flatMap((group) =>
216
+ HoverLayers.parts(
217
+ marker,
218
+ layer,
219
+ {
220
+ ...group,
221
+ points: HoverLayers.labelled(group.points, marker, cfg),
222
+ active: group.active && HoverLayers.labelled([group.active], marker, cfg)[0]
223
+ },
224
+ cfg
225
+ ).map((part) => ({ ...part, key: `${index}-${part.key}` }))
226
+ );
227
+ }
228
+
229
+ /**
230
+ * What each hover marker draws, behind and in front, built once per hover - not as it is drawn, where reading
231
+ * the scales would build its markers anew whenever svelteplot settles them, and settle them again.
232
+ */
233
+ const hoverLayers = $derived(
234
+ new Map(
235
+ drawn.flatMap((marker, index) =>
236
+ marker.type === 'hover'
237
+ ? [
238
+ [
239
+ index,
240
+ {
241
+ back: hoverPartsOf(marker as HoverMarkerConfig, 'back', index),
242
+ front: hoverPartsOf(marker as HoverMarkerConfig, 'front', index)
243
+ }
244
+ ] as const
245
+ ]
246
+ : []
247
+ )
248
+ )
249
+ );
111
250
 
112
251
  const scopedSeriesOf = (marker: MarkerConfig): string | undefined =>
113
252
  'series' in marker && typeof marker.series === 'string' && marker.series
@@ -127,6 +266,33 @@
127
266
  if (marker.type === 'bar') return `bar-${marker.role}-${i}`;
128
267
  return `${marker.type}-${i}`;
129
268
  }
269
+
270
+ /**
271
+ * A marker with `hover: true` or `'trigger'`, with the plot's hover added to its own pointer handlers: entering or
272
+ * moving over one of its shapes hovers that shape's row, and leaving it ends the hover.
273
+ */
274
+ function withHover(marker: MarkerConfig, rows: TData[] | TSeries[]): MarkerConfig {
275
+ if (!('hover' in marker) || (marker.hover !== true && marker.hover !== 'trigger'))
276
+ return marker;
277
+ const own = marker as CommonMarkerEvents & { data?: unknown[] };
278
+ // The row of the shape under the pointer - a copy svelteplot hands over, which the hover finds by its place.
279
+ const hovered = (row: unknown) => [(row ?? (own.data ?? rows)[0]) as TData];
280
+ return {
281
+ ...marker,
282
+ onpointerenter: (event: Event, row: unknown, index: number) => {
283
+ own.onpointerenter?.(event, row, index);
284
+ ctrl.onPointer(hovered(row));
285
+ },
286
+ onpointerleave: (event: Event, row: unknown, index: number) => {
287
+ own.onpointerleave?.(event, row, index);
288
+ ctrl.onLeave();
289
+ },
290
+ onpointermove: (event: Event, row: unknown, index: number) => {
291
+ own.onpointermove?.(event, row, index);
292
+ ctrl.onPointer(hovered(row));
293
+ }
294
+ } as MarkerConfig;
295
+ }
130
296
  </script>
131
297
 
132
298
  {#snippet drawMarker(marker: MarkerConfig, rows: TData[] | TSeries[])}
@@ -182,6 +348,8 @@
182
348
  <TextMarker marker={{ ...marker, data: marker.data ?? rows }} />
183
349
  {:else if marker.type === 'rule'}
184
350
  <RuleMarker {marker} />
351
+ {:else if marker.type === 'band'}
352
+ <BandMarker {marker} />
185
353
  {:else if marker.type === 'geo'}
186
354
  <GeoFeaturesMarker {marker} />
187
355
  {:else if marker.type === 'graticule'}
@@ -219,15 +387,6 @@
219
387
  <marker.component {...marker.props} data={marker.data ?? seriesData} />
220
388
  {:else if marker.type === 'geo-component'}
221
389
  <marker.component {...marker.props} data={marker.data ?? rows} />
222
- {:else if marker.type === 'hover'}
223
- <HoverMarker
224
- {marker}
225
- data={ctrl.points}
226
- activePoint={ctrl.activePoint}
227
- impliesCrosshairX={ctrl.impliesCrosshairX}
228
- impliesCrosshairY={ctrl.impliesCrosshairY}
229
- onActivePointPixel={ctrl.reportActivePointPixel}
230
- />
231
390
  {:else if marker.type === 'geo-hover'}
232
391
  <GeoHoverMarker {marker} data={ctrl.points} />
233
392
  {:else if marker.type === 'delta'}
@@ -236,41 +395,16 @@
236
395
  {/snippet}
237
396
 
238
397
  {#snippet renderMarker(marker: MarkerConfig, rows: TData[] | TSeries[])}
239
- <MarkerOffset {marker}>
240
- {@render drawMarker(marker, rows)}
241
- </MarkerOffset>
398
+ <!-- In parts the hover styles alike, while it restyles the marker's shapes. -->
399
+ {#each shapes.split(withHover(marker, rows), rows, reach) as part (part.key)}
400
+ <MarkerOffset marker={part.marker}>
401
+ {@render drawMarker(part.marker, rows)}
402
+ </MarkerOffset>
403
+ {/each}
242
404
  {/snippet}
243
405
 
244
406
  {#snippet renderScoped(marker: MarkerConfig, group: ScopedMarkerGroup<TSeries>)}
245
- {#if marker.type === 'hover'}
246
- {@const seriesPoints = ctrl.points.filter((p) => p.series === group.name)}
247
- {#if marker.scope === 'segment'}
248
- {#each group.segments as seg, segIdx (`${group.name}-hover-segment-${segIdx}`)}
249
- <!-- p.row (TData) is always a superset of TSeries in practice, not provable across two independent generics. -->
250
- {@const segPoints = seriesPoints.filter((p) => seg.match(p.row as unknown as TSeries))}
251
- {#if segPoints.length > 0}
252
- <HoverMarker
253
- marker={MarkerGrouping.withHoverSeriesColor(marker, seg.color)}
254
- data={segPoints}
255
- activePoint={segPoints[0] ?? null}
256
- impliesCrosshairX={ctrl.impliesCrosshairX}
257
- impliesCrosshairY={ctrl.impliesCrosshairY}
258
- />
259
- {/if}
260
- {/each}
261
- {:else}
262
- <HoverMarker
263
- marker={MarkerGrouping.withHoverSeriesColor(
264
- marker,
265
- group.segments[0]?.color ?? group.color
266
- )}
267
- data={seriesPoints}
268
- activePoint={seriesPoints[0] ?? null}
269
- impliesCrosshairX={ctrl.impliesCrosshairX}
270
- impliesCrosshairY={ctrl.impliesCrosshairY}
271
- />
272
- {/if}
273
- {:else if marker.type === 'component'}
407
+ {#if marker.type === 'component'}
274
408
  {#if marker.scope === 'segment'}
275
409
  {#each group.segments as seg, segIdx (`${group.name}-component-segment-${segIdx}`)}
276
410
  {@const segmentData = group.data.filter((row) => seg.match(row))}
@@ -288,10 +422,35 @@
288
422
  {/if}
289
423
  {/snippet}
290
424
 
291
- <!-- Every marker in array order, so a later one always draws on top. -->
425
+ {#snippet renderHoverLayer(index: number, layer: 'back' | 'front')}
426
+ {#each hoverLayers.get(index)?.[layer] ?? [] as part (part.key)}
427
+ <!-- A point in a slice of its band (a grouped bar's series) is drawn in the middle of it. -->
428
+ {@const nudge = BandNudge.of(svelteplot.scales, part.slice)}
429
+ <g transform="translate({nudge.dx}, {nudge.dy})">
430
+ <FrameClip clip={FrameClipping.isClipped(part.marker)}>
431
+ {@render renderMarker(part.marker as MarkerConfig, data)}
432
+ </FrameClip>
433
+ </g>
434
+ {/each}
435
+ {/snippet}
436
+
437
+ <!-- What the hover draws behind the plot's shapes, before any of them. -->
438
+ {#each [...hoverLayers.keys()] as index (index)}
439
+ {@render renderHoverLayer(index, 'back')}
440
+ {/each}
441
+
442
+ <!-- Every marker in array order, so a later one always draws on top; a hover marker draws its front markers. -->
292
443
  {#each markers as marker, i (markerKey(marker, i))}
293
444
  {@const scope = scopedSeriesOf(marker)}
294
- {#if scope === undefined}
445
+ {#if marker.type === 'hover'}
446
+ {#if scope === undefined}
447
+ <HoverMarker
448
+ activePoint={ctrl.activePoint}
449
+ onActivePointPixel={ctrl.reportActivePointPixel}
450
+ />
451
+ {/if}
452
+ {@render renderHoverLayer(i, 'front')}
453
+ {:else if scope === undefined}
295
454
  <FrameClip clip={FrameClipping.isClipped(marker)}>
296
455
  {@render renderMarker(marker, data)}
297
456
  </FrameClip>
@@ -299,3 +458,19 @@
299
458
  {@render renderScoped(marker, groupByName.get(scope)!)}
300
459
  {/if}
301
460
  {/each}
461
+
462
+ <!--
463
+ The labels the shapes write in themselves, after every marker - the hover's hit areas too, which are the last of them -
464
+ so a label that listens for the pointer is not covered, and one outside its shape is not clipped with it.
465
+ -->
466
+ {#each markers as marker, i (markerKey(marker, i))}
467
+ {@const scope = scopedSeriesOf(marker)}
468
+ {#if 'label' in marker && marker.label && (scope === undefined || groupByName.has(scope))}
469
+ <!-- Split as the shapes are, so a label reads on its shape's color under the hover. -->
470
+ {#each shapes.split(marker, data, reach) as part (part.key)}
471
+ <MarkerOffset marker={part.marker}>
472
+ <MarkerLabel marker={{ ...part.marker, data: part.marker.data ?? data }} />
473
+ </MarkerOffset>
474
+ {/each}
475
+ {/if}
476
+ {/each}
@@ -0,0 +1,52 @@
1
+ import type { HoverDisplayPoint, HoverStrategy } from '../../types/layout/hover';
2
+ import type { HoverLayerMarker, HoverLook, HoverMarkerConfig } from '../../types/markers/common';
3
+ import type { PlotStylesConfig } from '../../types/configuration/styling';
4
+ /** An end of a span: a field of the hovered point's context (else of its row), or a function of the point. */
5
+ type SpanEnd = string | ((point: HoverDisplayPoint) => unknown);
6
+ /**
7
+ * The hover a plot kind draws, and how an author's `hover` marker is laid over it. Its parts - a crosshair rule, a
8
+ * band, a dot, a label - are the markers a kind composes its own hover from; each takes the configuration's
9
+ * `hover` look as it is drawn (see `HoverLayers`).
10
+ */
11
+ export declare class HoverDefaults {
12
+ /** A crosshair along `axis`, at the point under the pointer. */
13
+ static rule(axis: 'x' | 'y'): HoverLayerMarker;
14
+ /** The band of each hovered category along `axis`, or its series' slice of it when it alone is hovered there. */
15
+ static band(axis: 'x' | 'y'): HoverLayerMarker;
16
+ /**
17
+ * The span of the point under the pointer along `axis`, from `from` to `to`, across the whole of the other axis -
18
+ * where a band is no category's: a histogram's bin, an interval on a continuous axis. Each end is a field of the
19
+ * point's context (a bin's `from` and `to`) - else of its row - or a function of the point.
20
+ */
21
+ static span(axis: 'x' | 'y', from: SpanEnd, to: SpanEnd): HoverLayerMarker;
22
+ /** A dot on each hovered point, in its series' color. */
23
+ static dot(): HoverLayerMarker;
24
+ /** Each hovered point's label, in its series' color. */
25
+ static text(): HoverLayerMarker;
26
+ /**
27
+ * A hover that only restyles the shapes, with `active` and `others`: a treemap's tiles, a heatmap's cells. The
28
+ * hovered one is outlined, in the configuration's `hover.active`.
29
+ */
30
+ static shapes(cfg: PlotStylesConfig): HoverLook;
31
+ /** The hovered category's band along `axis`, behind the plot's shapes: a bar's, a box's, a violin's. */
32
+ static behindBand(axis: 'x' | 'y'): HoverLook;
33
+ /** The span of the point under the pointer along `axis`, behind the plot's shapes: a histogram's bin. */
34
+ static behindSpan(axis: 'x' | 'y', from: SpanEnd, to: SpanEnd): HoverLook;
35
+ /**
36
+ * A rule along the value axis at the point under the pointer, and a dot and a label on each point - for a plot
37
+ * whose other axis holds a few positions or categories, where a crosshair along it says little (a slope's, a
38
+ * Cleveland plot's).
39
+ */
40
+ static valueRule(valueAxis: 'x' | 'y'): HoverLook;
41
+ /**
42
+ * The hover every plot kind starts from: a crosshair along each axis its `strategy` matches along (unless
43
+ * `crosshair` is off), and a dot and a label on each hovered point.
44
+ */
45
+ static of(strategy: HoverStrategy, crosshair?: boolean | undefined): HoverLook;
46
+ /**
47
+ * An author's `hover` marker over its kind's `look`: `active` and `others` field by field, `back` and `front`
48
+ * the author's when set (an empty list draws nothing), the kind's otherwise.
49
+ */
50
+ static merge(look: HoverLook, marker: HoverMarkerConfig): HoverMarkerConfig;
51
+ }
52
+ export {};
@@ -0,0 +1,96 @@
1
+ /**
2
+ * The hover a plot kind draws, and how an author's `hover` marker is laid over it. Its parts - a crosshair rule, a
3
+ * band, a dot, a label - are the markers a kind composes its own hover from; each takes the configuration's
4
+ * `hover` look as it is drawn (see `HoverLayers`).
5
+ */
6
+ export class HoverDefaults {
7
+ /** A crosshair along `axis`, at the point under the pointer. */
8
+ static rule(axis) {
9
+ return { type: 'rule', axis, points: 'active' };
10
+ }
11
+ /** The band of each hovered category along `axis`, or its series' slice of it when it alone is hovered there. */
12
+ static band(axis) {
13
+ return { type: 'band', axis };
14
+ }
15
+ /**
16
+ * The span of the point under the pointer along `axis`, from `from` to `to`, across the whole of the other axis -
17
+ * where a band is no category's: a histogram's bin, an interval on a continuous axis. Each end is a field of the
18
+ * point's context (a bin's `from` and `to`) - else of its row - or a function of the point.
19
+ */
20
+ static span(axis, from, to) {
21
+ const end = (side) => typeof side === 'function'
22
+ ? side
23
+ : (point) => point.context?.[side] ?? point.row?.[side];
24
+ return {
25
+ type: 'rect',
26
+ [`${axis}1`]: end(from),
27
+ [`${axis}2`]: end(to),
28
+ points: 'active'
29
+ };
30
+ }
31
+ /** A dot on each hovered point, in its series' color. */
32
+ static dot() {
33
+ return { type: 'dot' };
34
+ }
35
+ /** Each hovered point's label, in its series' color. */
36
+ static text() {
37
+ return { type: 'text' };
38
+ }
39
+ /**
40
+ * A hover that only restyles the shapes, with `active` and `others`: a treemap's tiles, a heatmap's cells. The
41
+ * hovered one is outlined, in the configuration's `hover.active`.
42
+ */
43
+ static shapes(cfg) {
44
+ return { back: [], front: [], active: { ...cfg.hover.active } };
45
+ }
46
+ /** The hovered category's band along `axis`, behind the plot's shapes: a bar's, a box's, a violin's. */
47
+ static behindBand(axis) {
48
+ return { back: [HoverDefaults.band(axis)], front: [] };
49
+ }
50
+ /** The span of the point under the pointer along `axis`, behind the plot's shapes: a histogram's bin. */
51
+ static behindSpan(axis, from, to) {
52
+ return { back: [HoverDefaults.span(axis, from, to)], front: [] };
53
+ }
54
+ /**
55
+ * A rule along the value axis at the point under the pointer, and a dot and a label on each point - for a plot
56
+ * whose other axis holds a few positions or categories, where a crosshair along it says little (a slope's, a
57
+ * Cleveland plot's).
58
+ */
59
+ static valueRule(valueAxis) {
60
+ return {
61
+ back: [HoverDefaults.rule(valueAxis)],
62
+ front: [HoverDefaults.dot(), HoverDefaults.text()]
63
+ };
64
+ }
65
+ /**
66
+ * The hover every plot kind starts from: a crosshair along each axis its `strategy` matches along (unless
67
+ * `crosshair` is off), and a dot and a label on each hovered point.
68
+ */
69
+ static of(strategy, crosshair = true) {
70
+ const axes = strategy === 'x'
71
+ ? ['x']
72
+ : strategy === 'y'
73
+ ? ['y']
74
+ : strategy === 'punctual'
75
+ ? ['x', 'y']
76
+ : [];
77
+ return {
78
+ back: crosshair === false ? [] : axes.map((axis) => HoverDefaults.rule(axis)),
79
+ front: [HoverDefaults.dot(), HoverDefaults.text()]
80
+ };
81
+ }
82
+ /**
83
+ * An author's `hover` marker over its kind's `look`: `active` and `others` field by field, `back` and `front`
84
+ * the author's when set (an empty list draws nothing), the kind's otherwise.
85
+ */
86
+ static merge(look, marker) {
87
+ const styles = (own, base) => own || base ? { ...base, ...own } : undefined;
88
+ return {
89
+ ...marker,
90
+ active: styles(marker.active, look.active),
91
+ others: styles(marker.others, look.others),
92
+ back: marker.back ?? look.back ?? [],
93
+ front: marker.front ?? look.front ?? []
94
+ };
95
+ }
96
+ }
@@ -0,0 +1,35 @@
1
+ import type { BandSlice, HoverDisplayPoint } from '../../types/layout/hover';
2
+ import type { HoverLayerMarker, HoverMarkerConfig } from '../../types/markers/common';
3
+ import type { PlotStylesConfig } from '../../types/configuration/styling';
4
+ type Point = HoverDisplayPoint & {
5
+ row?: unknown;
6
+ };
7
+ /** One marker a hover layer draws, keyed so it keeps its place while the hover moves, and the slice it is moved into. */
8
+ export type HoverLayerPart = {
9
+ key: string;
10
+ marker: HoverLayerMarker;
11
+ slice?: BandSlice;
12
+ };
13
+ /** Some hovered points: of the whole plot, of one series, or of one segment of it, with the one under the pointer. */
14
+ export type HoverPointGroup = {
15
+ key: string;
16
+ points: Point[];
17
+ active: Point | null;
18
+ };
19
+ /**
20
+ * The markers a `hover` marker draws in its `back` and `front` layers, over the hovered points: each with the
21
+ * points as its rows, unless it has `data` of its own, placed at them, and split by the slice of the band a point
22
+ * sits in (a grouped bar's series), to be moved into it - all but a `band`, which takes the slice itself.
23
+ */
24
+ export declare class HoverLayers {
25
+ #private;
26
+ /** `points` with their label written as `marker`'s number fields, or its `format`, ask. */
27
+ static labelled<T extends Point>(points: readonly T[], marker: HoverMarkerConfig, cfg: PlotStylesConfig): T[];
28
+ /**
29
+ * The markers of `marker`'s `layer` over a group of points. A marker over points that sit in a slice of their
30
+ * band is one part per slice, which `slice` names, to be moved into it as it is drawn - the move is in pixels,
31
+ * so it is left to the drawing, which knows the band's width.
32
+ */
33
+ static parts(marker: HoverMarkerConfig, layer: 'back' | 'front', group: HoverPointGroup, cfg: PlotStylesConfig): HoverLayerPart[];
34
+ }
35
+ export {};
@@ -0,0 +1,122 @@
1
+ import { NumberFormat } from '../../utils/NumberFormat';
2
+ /**
3
+ * The markers a `hover` marker draws in its `back` and `front` layers, over the hovered points: each with the
4
+ * points as its rows, unless it has `data` of its own, placed at them, and split by the slice of the band a point
5
+ * sits in (a grouped bar's series), to be moved into it - all but a `band`, which takes the slice itself.
6
+ */
7
+ export class HoverLayers {
8
+ /** The kinds placed by `x` and `y`, which default to the point's. */
9
+ static #PLACED = new Set(['dot', 'text', 'tick', 'image', 'line', 'trail']);
10
+ /** `points` with their label written as `marker`'s number fields, or its `format`, ask. */
11
+ static labelled(points, marker, cfg) {
12
+ const numberOf = NumberFormat.maybe(NumberFormat.displayOf(marker), cfg);
13
+ const number = numberOf ?? NumberFormat.of(undefined, cfg);
14
+ const { format } = marker;
15
+ if (!format && !numberOf)
16
+ return [...points];
17
+ return points.map((point) => {
18
+ if (format)
19
+ return { ...point, label: format(point, number) };
20
+ const value = Number(point.label);
21
+ const written = point.label !== undefined && point.label !== '' && Number.isFinite(value)
22
+ ? numberOf(value)
23
+ : point.label;
24
+ return { ...point, label: written ?? '' };
25
+ });
26
+ }
27
+ /**
28
+ * The markers of `marker`'s `layer` over a group of points. A marker over points that sit in a slice of their
29
+ * band is one part per slice, which `slice` names, to be moved into it as it is drawn - the move is in pixels,
30
+ * so it is left to the drawing, which knows the band's width.
31
+ */
32
+ static parts(marker, layer, group, cfg) {
33
+ if (group.points.length === 0)
34
+ return [];
35
+ return (marker[layer] ?? []).flatMap((nested, i) => {
36
+ const key = `${layer}-${group.key}-${i}`;
37
+ const { points: which, ...own } = nested;
38
+ if (own.data)
39
+ return [{ key, marker: own }];
40
+ const rows = HoverLayers.#pointsOf(which, group);
41
+ if (rows.length === 0)
42
+ return [];
43
+ const placed = HoverLayers.#placed(HoverLayers.#inHover(own, cfg));
44
+ if (own.type === 'band')
45
+ return [{ key, marker: { ...placed, data: rows } }];
46
+ return HoverLayers.#bySlice(rows).map(({ slice, points }) => ({
47
+ key: `${key}-${slice ? `${slice.start},${slice.end}` : ''}`,
48
+ marker: { ...placed, data: points },
49
+ slice
50
+ }));
51
+ });
52
+ }
53
+ /** The points a nested marker draws: all of them, the one under the pointer, or those a function keeps. */
54
+ static #pointsOf(which, group) {
55
+ if (which === 'active')
56
+ return group.active ? [group.active] : [];
57
+ if (typeof which === 'function')
58
+ return group.points.filter(which);
59
+ return group.points;
60
+ }
61
+ /**
62
+ * `marker` with what it leaves unset taken from the hover: a `rule` at each point along its axis and a `band`
63
+ * around it, in its slice; a `text` writes the point's label; each in the configuration's `hover` look (a `rect`
64
+ * too, in its `area` one), and a `dot` and a `text` in the point's series color.
65
+ */
66
+ static #inHover(marker, cfg) {
67
+ const own = marker;
68
+ const color = (point) => point.color ?? 'currentColor';
69
+ switch (marker.type) {
70
+ case 'rule':
71
+ return {
72
+ ...marker,
73
+ value: own.value ?? ((point) => point[marker.axis]),
74
+ styles: { ...cfg.hover.rule, ...own.styles }
75
+ };
76
+ case 'band':
77
+ return {
78
+ ...marker,
79
+ value: own.value ?? ((point) => point[marker.axis]),
80
+ slice: own.slice ?? ((point) => point.areaInset),
81
+ styles: { ...cfg.hover.area, ...own.styles }
82
+ };
83
+ case 'rect':
84
+ return { ...marker, styles: { ...cfg.hover.area, ...own.styles } };
85
+ case 'dot':
86
+ return {
87
+ ...marker,
88
+ styles: { ...cfg.hover.dot, dotFill: color, dotStroke: color, ...own.styles }
89
+ };
90
+ case 'text':
91
+ return {
92
+ ...marker,
93
+ text: own.text ?? ((point) => point.label),
94
+ styles: { ...cfg.hover.font, fill: color, ...own.styles }
95
+ };
96
+ default:
97
+ return marker;
98
+ }
99
+ }
100
+ /** `marker` placed at the points: its own `x` and `y`, else the point's. */
101
+ static #placed(marker) {
102
+ if (!HoverLayers.#PLACED.has(marker.type))
103
+ return marker;
104
+ const own = marker;
105
+ return {
106
+ ...marker,
107
+ x: own.x ?? ((point) => point.x),
108
+ y: own.y ?? ((point) => point.y)
109
+ };
110
+ }
111
+ /** `points` split by the slice of the band each one sits in, in the order they come. */
112
+ static #bySlice(points) {
113
+ const groups = new Map();
114
+ for (const point of points) {
115
+ const slice = point.areaInset;
116
+ const id = slice ? `${slice.start},${slice.end}` : '';
117
+ const group = groups.get(id) ?? groups.set(id, { slice, points: [] }).get(id);
118
+ group.points.push(point);
119
+ }
120
+ return [...groups.values()];
121
+ }
122
+ }
@@ -1,3 +1,4 @@
1
+ import { RowContext } from '../../phases/context/RowContext';
1
2
  import { PlotAxes } from '../../phases/data/PlotAxes';
2
3
  /**
3
4
  * A plot's hover as its `tooltip` and hover marker set it up: whether it is on,
@@ -44,7 +45,9 @@ export class HoverSettings {
44
45
  sync: settings.sync,
45
46
  tooltip: tooltip && {
46
47
  ...tooltip,
47
- format: tooltip.format ? (row) => tooltip.format(row, number) : format,
48
+ format: tooltip.format
49
+ ? (row) => tooltip.format(row, number, RowContext.of(row))
50
+ : format,
48
51
  ...(sort ? { sort } : {})
49
52
  },
50
53
  ...(pointMatching ? { pointMatching } : {})