@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
@@ -1,16 +1,17 @@
1
- import type { AxisPlotState, AxisPlotCtx, AxisPlotKind, AxisPlotDefaults, DataRunState, HoverStageOptions, PhaseStage, PlotPhase } from '../types/phases';
1
+ import type { AxisPlotState, AxisPlotEnv, AxisPlotKind, AxisPlotDefaults, DataRunState, HoverStageOptions, PhaseStage, PlotPhase } from '../types/phases';
2
2
  import type { PlotStylesConfig } from '../types/configuration/styling';
3
3
  import type { FacetConfig } from '../types/layout/facet';
4
4
  import type { LegendState } from '../layout/legend/LegendState.svelte';
5
5
  import type { HoverStrategy } from '../types/layout/hover';
6
6
  import type { Accessor } from '../types/plots/data/common';
7
+ import type { GroupingAccessor } from '../types/layout/mapping';
7
8
  /** The core props an axis plot kind seeds its pipeline from. */
8
9
  export type AxisPipelineProps<TData extends Record<string, unknown>> = {
9
10
  series?: unknown[];
10
11
  data?: TData[];
11
12
  x?: Accessor<TData, unknown>;
12
13
  y?: Accessor<TData, unknown>;
13
- grouping?: Accessor<TData, unknown>;
14
+ grouping?: GroupingAccessor<TData>;
14
15
  color?: Accessor<TData, unknown>;
15
16
  opacity?: unknown;
16
17
  r?: unknown;
@@ -20,6 +21,7 @@ export type AxisPipelineProps<TData extends Record<string, unknown>> = {
20
21
  error?: Accessor<TData, unknown>;
21
22
  target?: unknown;
22
23
  ranges?: unknown[];
24
+ value?: Accessor<TData, unknown>;
23
25
  segments?: unknown;
24
26
  styles?: {
25
27
  gaps?: unknown;
@@ -53,7 +55,7 @@ export type PipelineOptions<TState> = {
53
55
  * Stages declared out of phase order still run in it - with a warning, once,
54
56
  * since the declared order would otherwise read as the one that runs.
55
57
  */
56
- export declare class Pipeline<TState, TCtx = unknown> {
58
+ export declare class Pipeline<TState, TEnv = unknown> {
57
59
  #private;
58
60
  /**
59
61
  * The phases that work on the plot's rows - everything before its scales,
@@ -63,25 +65,25 @@ export declare class Pipeline<TState, TCtx = unknown> {
63
65
  static readonly DATA_PHASES: readonly PlotPhase[];
64
66
  /** Every {@link PlotPhase}, in the order they run: the data phases, then each panel's own. */
65
67
  static readonly ORDER: readonly PlotPhase[];
66
- readonly stages: readonly PhaseStage<TState, TCtx>[];
67
- constructor(stages: PhaseStage<TState, TCtx>[], options?: PipelineOptions<TState>);
68
+ readonly stages: readonly PhaseStage<TState, TEnv>[];
69
+ constructor(stages: PhaseStage<TState, TEnv>[], options?: PipelineOptions<TState>);
68
70
  /**
69
71
  * An axis-based plot kind's pipeline: the shared stages, each set up with
70
72
  * the kind's own options - its marks and value labels among them - started
71
73
  * from a core's props. Built once per kind object.
72
74
  */
73
- static ofAxisKind<TState extends AxisPlotState<any, any, any, any>, TCtx extends AxisPlotCtx>(kind: AxisPlotKind<TState, TCtx> & Pick<AxisPlotDefaults<any, any>, 'timeline'>): Pipeline<TState, TCtx>;
75
+ static ofAxisKind<TState extends AxisPlotState<any, any, any, any>, TEnv extends AxisPlotEnv>(kind: AxisPlotKind<TState, TEnv> & Pick<AxisPlotDefaults<any, any>, 'timeline'>): Pipeline<TState, TEnv>;
74
76
  /** A plot's pipeline from what its kind gives: its axis-kind defaults, or a pipeline of its own. */
75
77
  static of(defaults: AxisPlotDefaults<any, any> | Pipeline<any, any>): Pipeline<any, any>;
76
78
  /** The stage of `phase`, if the pipeline has one. */
77
- stage(phase: PlotPhase): PhaseStage<TState, TCtx> | undefined;
79
+ stage(phase: PlotPhase): PhaseStage<TState, TEnv> | undefined;
78
80
  /**
79
81
  * A core's run: every stage over the state its `input` (an axis core's
80
82
  * props) seeds - or, given `panelState` (one facet panel's part of
81
83
  * {@link runData}), only the stages after the data phases, over that state
82
84
  * with the input's own props (its box, margins and scales) on top.
83
85
  */
84
- run: (input: unknown, ctx: TCtx, panelState?: object) => TState;
86
+ run: (input: unknown, env: TEnv, panelState?: object) => TState;
85
87
  /** Whether the pipeline has data phases to run once over every facet panel ({@link runData}). */
86
88
  get facets(): boolean;
87
89
  /**
@@ -2,6 +2,7 @@ import { FacetPhase } from './facet/FacetPhase';
2
2
  import { DataPhase } from './data/DataPhase';
3
3
  import { MappingPhase } from './mapping/MappingPhase';
4
4
  import { TransformsPhase } from './transforms/TransformsPhase';
5
+ import { ContextPhase } from './context/ContextPhase';
5
6
  import { StatisticsPhase } from './statistics/StatisticsPhase';
6
7
  import { ScalesPhase } from './scales/ScalesPhase';
7
8
  import { SharedScalesPhase } from './sharedScales/SharedScalesPhase';
@@ -33,6 +34,7 @@ export class Pipeline {
33
34
  'data',
34
35
  'mapping',
35
36
  'transforms',
37
+ 'context',
36
38
  'statistics',
37
39
  'sharedScales'
38
40
  ];
@@ -79,6 +81,7 @@ export class Pipeline {
79
81
  new DataPhase(kind.data),
80
82
  new MappingPhase(kind.mapping),
81
83
  new TransformsPhase(kind.transforms, kind.data?.segments?.connect),
84
+ new ContextPhase(kind.context),
82
85
  new StatisticsPhase(kind.statistics),
83
86
  new SharedScalesPhase(kind.sharedScales, scales),
84
87
  scales,
@@ -112,12 +115,12 @@ export class Pipeline {
112
115
  * {@link runData}), only the stages after the data phases, over that state
113
116
  * with the input's own props (its box, margins and scales) on top.
114
117
  */
115
- run = (input, ctx, panelState) => {
118
+ run = (input, env, panelState) => {
116
119
  const seed = this.#seed(input);
117
120
  if (!panelState)
118
- return Pipeline.#through(this.stages, seed, ctx);
121
+ return Pipeline.#through(this.stages, seed, env);
119
122
  this.#panel ??= this.stages.filter((stage) => !Pipeline.DATA_PHASES.includes(stage.phase));
120
- return Pipeline.#through(this.#panel, { ...panelState, ...seed }, ctx);
123
+ return Pipeline.#through(this.#panel, { ...panelState, ...seed }, env);
121
124
  };
122
125
  /** Whether the pipeline has data phases to run once over every facet panel ({@link runData}). */
123
126
  get facets() {
@@ -131,7 +134,7 @@ export class Pipeline {
131
134
  runData(props, rows, facet, legendInteraction, cfg) {
132
135
  this.#data ??= this.stages.filter((stage) => Pipeline.DATA_PHASES.includes(stage.phase));
133
136
  const seed = { ...this.#seed(props, rows), facet };
134
- return Pipeline.#through(this.#data, seed, Pipeline.#ctxFor(cfg, legendInteraction));
137
+ return Pipeline.#through(this.#data, seed, Pipeline.#envFor(cfg, legendInteraction));
135
138
  }
136
139
  /**
137
140
  * The plot's hover strategy when neither its `tooltip` nor a hover marker
@@ -143,7 +146,7 @@ export class Pipeline {
143
146
  if (fixed !== undefined)
144
147
  return fixed;
145
148
  const upToData = this.stages.filter((s) => s.phase === 'data');
146
- const state = Pipeline.#through(upToData, this.#seed(props), Pipeline.#ctxFor(cfg, null));
149
+ const state = Pipeline.#through(upToData, this.#seed(props), Pipeline.#envFor(cfg, null));
147
150
  return HoverSettings.strategyOf(state.axes);
148
151
  }
149
152
  /** The plot's default `timeline.filterMode`. */
@@ -162,7 +165,7 @@ export class Pipeline {
162
165
  return undefined;
163
166
  const upToMapping = this.stages.filter((s) => s.phase === 'data' || s.phase === 'mapping');
164
167
  // Without a legend: the channels read the same whatever it turns off.
165
- const state = Pipeline.#through(upToMapping, this.#seed(props), Pipeline.#ctxFor(cfg, null));
168
+ const state = Pipeline.#through(upToMapping, this.#seed(props), Pipeline.#envFor(cfg, null));
166
169
  const channel = (ref) => {
167
170
  const name = ref === 'value' || ref === 'category' ? state.axes?.[ref] : ref;
168
171
  if (name === undefined)
@@ -186,11 +189,11 @@ export class Pipeline {
186
189
  return this.#options.seed ? this.#options.seed(input, rows) : input;
187
190
  }
188
191
  /** `stages` over `state`, in order. */
189
- static #through(stages, state, ctx) {
190
- return stages.reduce((acc, stage) => stage.run(acc, ctx), state);
192
+ static #through(stages, state, env) {
193
+ return stages.reduce((acc, stage) => stage.run(acc, env), state);
191
194
  }
192
195
  /** The context a plot-level run reads, outside any core: the configuration and the legend. */
193
- static #ctxFor(cfg, legendInteraction) {
196
+ static #envFor(cfg, legendInteraction) {
194
197
  const interaction = new PlotInteraction(() => cfg, { legend: legendInteraction });
195
198
  return { cfg, interaction };
196
199
  }
@@ -215,6 +218,7 @@ export class Pipeline {
215
218
  error: props.error,
216
219
  target: props.target,
217
220
  ranges: props.ranges,
221
+ value: props.value,
218
222
  segments: props.segments ?? {},
219
223
  styles: props.styles,
220
224
  gaps: props.styles?.gaps,
@@ -0,0 +1,22 @@
1
+ import type { ContextStageOptions } from '../../types/phases/context/phase';
2
+ import type { PhaseStage, ProcessedData } from '../../types/phases';
3
+ import type { PlotAxes } from '../data/PlotAxes';
4
+ import type { Series } from '../../types/plots/data/common';
5
+ /** What the "context" phase reads. */
6
+ type ContextStageState = {
7
+ processedData?: ProcessedData;
8
+ resolvedSeries?: Series<any>[];
9
+ axes?: PlotAxes;
10
+ };
11
+ /**
12
+ * The "context" phase every axis-based plot shares: right after the transforms, it works out once what the plot
13
+ * knows of each processed row - the shared {@link RowContext}, with what the kind adds - and keeps it on the row,
14
+ * for the tooltip, the hover, the value labels and the author's own markers to read.
15
+ */
16
+ export declare class ContextPhase<TState extends ContextStageState, TEnv = unknown> implements PhaseStage<TState, TEnv> {
17
+ #private;
18
+ readonly phase: "context";
19
+ constructor(kind?: ContextStageOptions<TState, TEnv>);
20
+ run: (state: TState, env: TEnv) => TState;
21
+ }
22
+ export {};
@@ -0,0 +1,23 @@
1
+ import { RowContext } from './RowContext';
2
+ /**
3
+ * The "context" phase every axis-based plot shares: right after the transforms, it works out once what the plot
4
+ * knows of each processed row - the shared {@link RowContext}, with what the kind adds - and keeps it on the row,
5
+ * for the tooltip, the hover, the value labels and the author's own markers to read.
6
+ */
7
+ export class ContextPhase {
8
+ phase = 'context';
9
+ #kind;
10
+ constructor(kind) {
11
+ this.#kind = kind;
12
+ }
13
+ run = (state, env) => {
14
+ const rows = state.processedData?.data;
15
+ if (!rows?.length)
16
+ return state;
17
+ const shared = RowContext.shared(state);
18
+ const own = this.#kind?.(state, env);
19
+ for (const row of rows)
20
+ RowContext.tag(row, { ...shared(row), ...own?.(row) });
21
+ return state;
22
+ };
23
+ }
@@ -0,0 +1,35 @@
1
+ import { PlotAxes } from '../data/PlotAxes';
2
+ import type { PlotRowContext } from '../../types/layout/context';
3
+ import type { Series } from '../../types/plots/data/common';
4
+ import type { ProcessedData, ProcessedRow } from '../../types/phases';
5
+ /** What the shared context is worked out from. */
6
+ type ContextSource = {
7
+ processedData?: ProcessedData;
8
+ resolvedSeries?: Series<any>[];
9
+ axes?: PlotAxes;
10
+ };
11
+ /**
12
+ * The context of the rows a plot draws ({@link PlotRowContext}): worked out once per row by the "context" phase,
13
+ * kept on the row itself, and read back from it - or from any copy of it - with {@link of}.
14
+ */
15
+ export declare class RowContext {
16
+ #private;
17
+ /**
18
+ * What the plot knows of `row`: its series, where it sits, the value it shows and whatever its kind works out
19
+ * for it, with the row itself. A row no plot drew reads as its series alone.
20
+ */
21
+ static of<TContext extends PlotRowContext = PlotRowContext>(row: unknown): TContext;
22
+ /** Keeps `context` on `row`, for {@link of} to read back. */
23
+ static tag(row: ProcessedRow, context: PlotRowContext): void;
24
+ /** Whether `row` carries a context already. */
25
+ static has(row: unknown): boolean;
26
+ /** A reader of the rows of `state`: the context each carries, else the shared one, for a row no phase tagged. */
27
+ static reader(state: ContextSource): (row: ProcessedRow) => PlotRowContext;
28
+ /**
29
+ * The context every plot gives a processed row: its series; its `x` and `y` - each its series' own value
30
+ * (a stacked row's own, not the running total), else where the transforms put it (a density's estimate, a
31
+ * bin's centre); and its value on the plot's value axis, when that is a number.
32
+ */
33
+ static shared(state: ContextSource): (row: ProcessedRow) => PlotRowContext;
34
+ }
35
+ export {};
@@ -0,0 +1,95 @@
1
+ import { SERIES_ID_KEY, SERIES_KEY } from '../transforms/TransformsPhase';
2
+ import { ProcessedPositions } from '../transforms/ProcessedPositions';
3
+ import { PlotAxes } from '../data/PlotAxes';
4
+ import { resolveAccessor } from '../../utils/accessors';
5
+ import { seriesIdOf } from '../../utils/grouping';
6
+ /** Where a row's context is kept on it: under a symbol, which survives the copies svelteplot makes of a row. */
7
+ const KEY = Symbol('dct-row-context');
8
+ /**
9
+ * The context of the rows a plot draws ({@link PlotRowContext}): worked out once per row by the "context" phase,
10
+ * kept on the row itself, and read back from it - or from any copy of it - with {@link of}.
11
+ */
12
+ export class RowContext {
13
+ /**
14
+ * What the plot knows of `row`: its series, where it sits, the value it shows and whatever its kind works out
15
+ * for it, with the row itself. A row no plot drew reads as its series alone.
16
+ */
17
+ static of(row) {
18
+ if (row == null || typeof row !== 'object')
19
+ return {};
20
+ const record = row;
21
+ const own = record[KEY];
22
+ if (own)
23
+ return { ...own, row };
24
+ const series = record[SERIES_KEY];
25
+ return { ...(typeof series === 'string' ? { series } : {}), row };
26
+ }
27
+ /** Keeps `context` on `row`, for {@link of} to read back. */
28
+ static tag(row, context) {
29
+ row[KEY] = context;
30
+ }
31
+ /** Whether `row` carries a context already. */
32
+ static has(row) {
33
+ return row != null && typeof row === 'object' && KEY in row;
34
+ }
35
+ /** A reader of the rows of `state`: the context each carries, else the shared one, for a row no phase tagged. */
36
+ static reader(state) {
37
+ let shared;
38
+ return (row) => {
39
+ if (RowContext.has(row))
40
+ return RowContext.of(row);
41
+ shared ??= RowContext.shared(state);
42
+ return { ...shared(row), row };
43
+ };
44
+ }
45
+ /**
46
+ * The context every plot gives a processed row: its series; its `x` and `y` - each its series' own value
47
+ * (a stacked row's own, not the running total), else where the transforms put it (a density's estimate, a
48
+ * bin's centre); and its value on the plot's value axis, when that is a number.
49
+ */
50
+ static shared(state) {
51
+ const processed = state.processedData;
52
+ if (!processed)
53
+ return () => ({});
54
+ const valueAxis = PlotAxes.valueOf(state);
55
+ const placed = ProcessedPositions.of(processed, valueAxis);
56
+ const x = RowContext.#along(state, 'x', RowContext.#stacked(processed, 'x') ?? placed.x);
57
+ const y = RowContext.#along(state, 'y', RowContext.#stacked(processed, 'y') ?? placed.y);
58
+ return (row) => {
59
+ const series = row[SERIES_KEY];
60
+ const at = { x: x(row), y: y(row) };
61
+ const raw = at[valueAxis];
62
+ const value = raw instanceof Date || raw === null || raw === '' ? NaN : Number(raw);
63
+ return {
64
+ ...(typeof series === 'string' ? { series } : {}),
65
+ ...at,
66
+ ...(Number.isFinite(value) ? { value } : {})
67
+ };
68
+ };
69
+ }
70
+ /** A stacked row's own value along `axis` - its span, not the running total - or `undefined` with no stack there. */
71
+ static #stacked(processed, axis) {
72
+ const from = processed.channels[`${axis}1`];
73
+ const to = processed.channels[`${axis}2`];
74
+ const stack = axis === 'x' ? 'stackX' : 'stackY';
75
+ if (from === undefined || to === undefined)
76
+ return undefined;
77
+ if (!processed.transforms.some((t) => t.type === stack))
78
+ return undefined;
79
+ const low = resolveAccessor(from);
80
+ const high = resolveAccessor(to);
81
+ return (row) => Number(high(row)) - Number(low(row));
82
+ }
83
+ /** A row's value along `axis`: its series' own channel, else `placed`. */
84
+ static #along(state, axis, placed) {
85
+ const bySeries = new Map((state.resolvedSeries ?? []).flatMap((s) => {
86
+ const accessor = s[axis];
87
+ return accessor === undefined ? [] : [[seriesIdOf(s), resolveAccessor(accessor)]];
88
+ }));
89
+ return (row) => {
90
+ const own = bySeries.get(String(row[SERIES_ID_KEY]));
91
+ const value = own?.(row);
92
+ return value === undefined ? placed(row) : value;
93
+ };
94
+ }
95
+ }
@@ -1,4 +1,4 @@
1
- import type { AxisPlotState, AxisPlotCtx, DataStageOptions, PhaseStage } from '../../types/phases';
1
+ import type { AxisPlotState, AxisPlotEnv, DataStageOptions, PhaseStage } from '../../types/phases';
2
2
  type AnyAxisState = AxisPlotState<any, any, any, any>;
3
3
  /**
4
4
  * The "data" phase every axis-based plot shares: its series (from `series`,
@@ -10,10 +10,10 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
10
10
  * Colors and axes come from every series, before any is omitted or split by
11
11
  * facet panel, so they stay put and every panel agrees.
12
12
  */
13
- export declare class DataPhase<TState extends AnyAxisState, TCtx extends AxisPlotCtx> implements PhaseStage<TState, TCtx> {
13
+ export declare class DataPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
14
14
  #private;
15
15
  readonly phase: "data";
16
- constructor(options?: DataStageOptions<TState, TCtx>);
17
- run: (state: TState, ctx: TCtx) => TState;
16
+ constructor(options?: DataStageOptions<TState, TEnv>);
17
+ run: (state: TState, env: TEnv) => TState;
18
18
  }
19
19
  export {};
@@ -1,5 +1,5 @@
1
- import { buildSeries } from '../../utils/grouping';
2
- import { ColorRamp } from '../../utils/color';
1
+ import { buildSeries, Grouping } from '../../utils/grouping';
2
+ import { ColorRamp, ColorTones } from '../../utils/color';
3
3
  import { resolveAccessor } from '../../utils/accessors';
4
4
  import { buildGroupedSeries, buildScopedMarkerGroups } from '../../plots/utils/segments';
5
5
  import { buildGapFillMaps, isGapValue } from '../../plots/utils/gaps';
@@ -22,11 +22,11 @@ export class DataPhase {
22
22
  constructor(options = {}) {
23
23
  this.#options = options;
24
24
  }
25
- run = (state, ctx) => {
25
+ run = (state, env) => {
26
26
  const options = this.#options;
27
27
  const { series, data, segments, scales } = state;
28
28
  const { connect = true, color: segmentColor } = options.segments ?? {};
29
- const seriesGrouping = DataPhase.#buildGrouping(state);
29
+ const seriesGrouping = DataPhase.#buildGrouping(state, options.nested);
30
30
  const built = series ?? buildSeries(data ?? [], state.x, state.y, seriesGrouping);
31
31
  const fullSeries = options.orderSeries ? options.orderSeries(built, state) : built;
32
32
  const axes = PlotAxes.build({
@@ -35,11 +35,18 @@ export class DataPhase {
35
35
  given: { x: state.x !== undefined, y: state.y !== undefined },
36
36
  discrete: options.discreteAxes
37
37
  });
38
- const colorForSeries = ColorRamp.resolve(scales.color, (options.colorOrder ? options.colorOrder(fullSeries) : fullSeries).map((s) => s.name), ctx.cfg.palette);
38
+ const seriesColors = ColorRamp.resolve(scales.color, (options.colorOrder ? options.colorOrder(fullSeries) : fullSeries).map((s) => s.name), env.cfg.palette);
39
+ const colorForPath = series ? undefined : DataPhase.#buildPathColors(state, env);
40
+ // A plot that splits its series by every level colors each one by its path; a nested one by its outermost.
41
+ const colorForSeries = colorForPath && !options.nested
42
+ ? DataPhase.#byPath(state, colorForPath, seriesColors)
43
+ : seriesColors;
39
44
  const panelSeries = state.panels && state.panelOf && !series
40
45
  ? FacetPanels.splitSeries(fullSeries, state.panels, state.panelOf)
41
46
  : fullSeries;
42
- const resolvedSeries = ctx.interaction?.legend?.withoutOmitted(panelSeries) ?? panelSeries;
47
+ const legend = env.interaction?.legend;
48
+ const resolvedSeries = legend?.withoutOmitted(panelSeries) ?? panelSeries;
49
+ const removedSeries = legend?.removed(panelSeries);
43
50
  const baseFor = BasicStyles.of(state.styles, options.segments?.base);
44
51
  const groupedSeries = buildGroupedSeries(resolvedSeries, segments, connect, baseFor);
45
52
  const scopedGroups = buildScopedMarkerGroups({
@@ -57,6 +64,7 @@ export class DataPhase {
57
64
  ...state,
58
65
  axes,
59
66
  resolvedSeries,
67
+ ...(removedSeries ? { removedSeries } : {}),
60
68
  seriesGrouping,
61
69
  allSeriesNames: fullSeries.map((s) => s.name),
62
70
  groupedSeries,
@@ -64,20 +72,53 @@ export class DataPhase {
64
72
  flat: resolvedSeries.flatMap((s) => s.data),
65
73
  scopedGroups,
66
74
  colorForSeries,
75
+ ...(colorForPath ? { colorForPath } : {}),
67
76
  ...(gapFillMaps ? { gapFillMaps } : {})
68
77
  };
69
- return options.extend ? options.extend(next, ctx) : next;
78
+ return options.extend ? options.extend(next, env) : next;
70
79
  };
71
80
  /**
72
- * The key a plot's rows split into series by: its `grouping`, or its `color`
73
- * when that names categories. A numeric `color` is a continuous value (a
74
- * heatmap's cells), so it colors rows without grouping them.
81
+ * The color of a path of the plot's `grouping` levels, when `scales.color.depth` reaches past the outermost
82
+ * one: each outermost value its categorical color, and every path down to `depth` a tone of it (see
83
+ * {@link ColorTones.hierarchy}). `undefined` for a grouping of one level, or a depth of 1.
75
84
  */
76
- static #buildGrouping(state
85
+ static #buildPathColors(state, env) {
86
+ const depth = state.scales.color?.depth ?? 1;
87
+ const rows = state.data ?? [];
88
+ const levels = Grouping.levels(state.grouping, rows).map((level) => resolveAccessor(level));
89
+ if (depth <= 1 || levels.length <= 1)
90
+ return undefined;
91
+ const paths = rows.map((row) => levels.map((read) => String(read(row))));
92
+ const outermost = [...new Set(paths.map((path) => path[0]))];
93
+ const colorOf = ColorRamp.resolve(state.scales.color, outermost, env.cfg.palette);
94
+ return ColorTones.hierarchy(paths, depth, (value) => colorOf(value));
95
+ }
96
+ /** A series' color as the color of its path - its name is the key its levels make together. */
97
+ static #byPath(state, colorForPath, fallback) {
98
+ const rows = state.data ?? [];
99
+ const key = resolveAccessor(Grouping.key(state.grouping, rows));
100
+ const levels = Grouping.levels(state.grouping, rows).map((level) => resolveAccessor(level));
101
+ const pathOf = new Map();
102
+ for (const row of rows) {
103
+ const name = String(key(row));
104
+ if (!pathOf.has(name))
105
+ pathOf.set(name, levels.map((read) => String(read(row))));
106
+ }
107
+ return (name) => {
108
+ const path = pathOf.get(name);
109
+ return path ? colorForPath(path) : fallback(name);
110
+ };
111
+ }
112
+ /**
113
+ * The key a plot's rows split into series by: its `grouping` (its levels together, or the outermost
114
+ * one alone for a `nested` kind), or its `color` when that names categories. A numeric `color` is a
115
+ * continuous value (a heatmap's cells), so it colors rows without grouping them.
116
+ */
117
+ static #buildGrouping(state, nested = false
77
118
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
78
119
  ) {
79
120
  if (state.grouping !== undefined)
80
- return state.grouping;
121
+ return Grouping.key(state.grouping, state.data, nested);
81
122
  const color = state.color;
82
123
  if (color === undefined || !state.data)
83
124
  return color;
@@ -1,6 +1,6 @@
1
1
  import type { HoverDisplayPoint, HoverPoint } from '../../types/layout/hover';
2
2
  import { LegendState } from '../../layout/legend/LegendState.svelte';
3
- import type { AxisPlotCtx, AxisPlotState, HoverPosition, HoverStageOptions, PhaseStage, ProcessedData } from '../../types/phases';
3
+ import type { AxisPlotEnv, AxisPlotState, HoverPosition, HoverStageOptions, PhaseStage, ProcessedData } from '../../types/phases';
4
4
  type AnyAxisState = AxisPlotState<any, any, any, any>;
5
5
  /**
6
6
  * The "hover" phase every axis-based plot shares: what the pointer can match
@@ -9,15 +9,16 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
9
9
  * hover `rows`) of the series the legend shows, except gap rows and rows
10
10
  * outside the legend's narrowed range.
11
11
  */
12
- export declare class HoverPhase<TState extends AnyAxisState, TCtx extends AxisPlotCtx> implements PhaseStage<TState, TCtx> {
12
+ export declare class HoverPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
13
13
  #private;
14
14
  readonly phase: "hover";
15
- constructor(options?: HoverStageOptions<TState, TCtx>);
16
- run: (state: TState, ctx: TCtx) => TState;
15
+ constructor(options?: HoverStageOptions<TState, TEnv>);
16
+ run: (state: TState, env: TEnv) => TState;
17
17
  /**
18
18
  * Hover candidates for a plot's own processed rows: each visible row at its
19
19
  * position (a stacked row's top, a bin's centre), in its series' color. A
20
- * series the legend turned off is left out, as is any row `include` rejects.
20
+ * series the legend hides, omits or rescales away is left out (a dimmed one
21
+ * stays), as is any row `include` rejects.
21
22
  */
22
23
  static buildProcessedHoverPoints<TRow extends Record<string, unknown>>(args: {
23
24
  processed: ProcessedData;
@@ -25,8 +26,6 @@ export declare class HoverPhase<TState extends AnyAxisState, TCtx extends AxisPl
25
26
  legendInteraction?: LegendState | null;
26
27
  label: (row: TRow) => string;
27
28
  include?: (row: TRow) => boolean;
28
- /** The row a hovered point reads as, e.g. with derived fields added. Defaults to the processed row. */
29
- row?: (row: TRow) => TRow;
30
29
  /** Fields to add to (or replace on) each point. */
31
30
  decorate?: (row: TRow) => Partial<HoverDisplayPoint>;
32
31
  /** Where a row sits, as is. Defaults to its processed position, with `y` as a number. */
@@ -1,10 +1,12 @@
1
1
  import { ProcessedPositions } from '../transforms/ProcessedPositions';
2
2
  import { GAP_VALUE, SERIES_KEY } from '../transforms/TransformsPhase';
3
3
  import { HoverSettings } from '../../layout/hover/HoverSettings';
4
+ import { RowContext } from '../context/RowContext';
4
5
  import { PlotAxes } from '../data/PlotAxes';
5
6
  import { NumberFormat } from '../../utils/NumberFormat';
6
7
  import { isGapValue } from '../../plots/utils/gaps';
7
8
  import { LegendState } from '../../layout/legend/LegendState.svelte';
9
+ import { HoverDefaults } from '../../layout/hover/HoverDefaults';
8
10
  /**
9
11
  * The "hover" phase every axis-based plot shares: what the pointer can match
10
12
  * (`hover`), the rows it hovers over (`hoverRows`) and where each sits
@@ -18,7 +20,7 @@ export class HoverPhase {
18
20
  constructor(options = {}) {
19
21
  this.#options = options;
20
22
  }
21
- run = (state, ctx) => {
23
+ run = (state, env) => {
22
24
  const options = this.#options;
23
25
  const valueAxis = PlotAxes.valueOf(state);
24
26
  const raw = options.position?.(state) ??
@@ -28,20 +30,23 @@ export class HoverPhase {
28
30
  const position = options.position || state.axes?.isDiscrete(valueAxis)
29
31
  ? raw
30
32
  : { ...raw, [valueAxis]: (row) => Number(raw[valueAxis](row)) };
33
+ // A row's label is the value its context gives it, else its value channel's.
31
34
  const label = options.label?.(state) ??
32
- ((row) => String(state.channels[valueAxis].accessor(row)));
35
+ ((row) => {
36
+ const { value } = RowContext.of(row);
37
+ return String(value ?? state.channels[valueAxis].accessor(row));
38
+ });
33
39
  const processed = options.rows
34
40
  ? { ...state.processedData, data: options.rows(state) }
35
41
  : state.processedData;
36
42
  const points = HoverPhase.buildProcessedHoverPoints({
37
43
  processed,
38
44
  colorFor: state.colorForSeries,
39
- legendInteraction: ctx.interaction?.legend,
45
+ legendInteraction: env.interaction?.legend,
40
46
  label: label,
41
47
  position,
42
- include: HoverPhase.#hoverable(state, ctx, raw, valueAxis),
43
- row: options.row?.(state),
44
- decorate: options.decorate?.(state, ctx)
48
+ include: HoverPhase.#hoverable(state, env, raw, valueAxis),
49
+ decorate: options.decorate?.(state, env)
45
50
  });
46
51
  const hover = HoverSettings.buildConfig({
47
52
  tooltip: state.tooltip,
@@ -52,12 +57,18 @@ export class HoverPhase {
52
57
  label: label,
53
58
  defaultStrategy: options.strategy ?? HoverSettings.strategyOf(state.axes),
54
59
  pointMatching: options.pointMatching,
55
- number: NumberFormat.of(NumberFormat.displayOf(state.tooltip), ctx.cfg)
60
+ number: NumberFormat.of(NumberFormat.displayOf(state.tooltip), env.cfg)
56
61
  });
57
- const hitAreas = options.hitAreas?.(state, hover, ctx) ?? [];
62
+ const hitAreas = options.hitAreas?.(state, hover, env) ?? [];
63
+ const own = options.marker?.(state, env);
64
+ const look = typeof own === 'function'
65
+ ? own
66
+ : own
67
+ ? () => own
68
+ : (strategy) => HoverDefaults.of(strategy, hover.crosshair);
58
69
  return {
59
70
  ...state,
60
- hover,
71
+ hover: { ...hover, look },
61
72
  hoverPosition: position,
62
73
  hoverRows: processed.data,
63
74
  ...(hitAreas.length > 0 ? { markers: [...(state.markers ?? []), ...hitAreas] } : {})
@@ -66,10 +77,11 @@ export class HoverPhase {
66
77
  /**
67
78
  * Hover candidates for a plot's own processed rows: each visible row at its
68
79
  * position (a stacked row's top, a bin's centre), in its series' color. A
69
- * series the legend turned off is left out, as is any row `include` rejects.
80
+ * series the legend hides, omits or rescales away is left out (a dimmed one
81
+ * stays), as is any row `include` rejects.
70
82
  */
71
83
  static buildProcessedHoverPoints(args) {
72
- const { processed, colorFor, legendInteraction, label, include, row: rowOf, decorate } = args;
84
+ const { processed, colorFor, legendInteraction, label, include, decorate } = args;
73
85
  const processedPosition = ProcessedPositions.of(processed);
74
86
  const position = args.position ?? {
75
87
  x: processedPosition.x,
@@ -78,7 +90,7 @@ export class HoverPhase {
78
90
  const x = position.x;
79
91
  const y = position.y;
80
92
  return processed.data
81
- .filter((d) => !legendInteraction?.isOff(d[SERIES_KEY]))
93
+ .filter((d) => !legendInteraction?.isUnhoverable(d[SERIES_KEY]))
82
94
  .filter((d) => !include || include(d))
83
95
  .map((d) => {
84
96
  const row = d;
@@ -86,7 +98,8 @@ export class HoverPhase {
86
98
  return {
87
99
  x: x(d),
88
100
  y: y(d),
89
- row: rowOf ? rowOf(row) : row,
101
+ row,
102
+ context: RowContext.of(row),
90
103
  label: label(row),
91
104
  series: seriesName,
92
105
  color: colorFor(seriesName),
@@ -99,8 +112,8 @@ export class HoverPhase {
99
112
  * filled in by `styles.gaps`), and, while the legend narrows a continuous
100
113
  * color to a range, not outside it. A dimmed row stays drawn, never matched.
101
114
  */
102
- static #hoverable(state, ctx, position, valueAxis) {
103
- const range = ctx.interaction?.legend?.range;
115
+ static #hoverable(state, env, position, valueAxis) {
116
+ const range = env.interaction?.legend?.range;
104
117
  const color = state.channels?.color?.accessor;
105
118
  return (row) => {
106
119
  if (isGapValue(position[valueAxis](row)) || row[GAP_VALUE] !== undefined)
@@ -1,4 +1,4 @@
1
- import type { AxisPlotState, AxisPlotCtx, MappingStageOptions, PhaseStage } from '../../types/phases';
1
+ import type { AxisPlotState, AxisPlotEnv, MappingStageOptions, PhaseStage } from '../../types/phases';
2
2
  type AnyAxisState = AxisPlotState<any, any, any, any>;
3
3
  /**
4
4
  * The "mapping" phase every axis-based plot shares: every channel resolved to
@@ -8,10 +8,10 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
8
8
  * its prop is set, and a size channel given a number stays that literal size.
9
9
  * An unset `x`/`y` reads each row itself, with no `source`.
10
10
  */
11
- export declare class MappingPhase<TState extends AnyAxisState, TCtx extends AxisPlotCtx> implements PhaseStage<TState, TCtx> {
11
+ export declare class MappingPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
12
12
  #private;
13
13
  readonly phase: "mapping";
14
- constructor(options?: MappingStageOptions<TState, TCtx>);
15
- run: (state: TState, ctx: TCtx) => TState;
14
+ constructor(options?: MappingStageOptions<TState, TEnv>);
15
+ run: (state: TState, env: TEnv) => TState;
16
16
  }
17
17
  export {};