@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,6 +1,7 @@
1
1
  import { buildMarks } from './markers';
2
+ import { PlotAxes } from '../../../phases/data/PlotAxes';
3
+ import { HoverDefaults } from '../../../layout/hover/HoverDefaults';
2
4
  import { BoxSummaries } from './BoxSummaries';
3
- import { TooltipState } from '../../../layout/tooltip/TooltipState.svelte';
4
5
  /**
5
6
  * BoxPlot on the shared pipeline: one box per category of each series along
6
7
  * one category axis - `x`, or `y` for horizontal boxes, as the "data" phase
@@ -22,17 +23,19 @@ export function buildBoxDefaults() {
22
23
  },
23
24
  scales: {
24
25
  bandOrder: 'data',
25
- defaults: (_state, ctx) => ({
26
- category: { paddingInner: ctx.cfg.box.paddingInner, paddingOuter: ctx.cfg.box.paddingOuter }
26
+ defaults: (_state, env) => ({
27
+ category: { paddingInner: env.cfg.box.paddingInner, paddingOuter: env.cfg.box.paddingOuter }
27
28
  })
28
29
  },
30
+ // Each value's box: its quartiles and whiskers, worked out once for its tooltip and hover to read.
31
+ context: (state) => BoxSummaries.context(state),
29
32
  markers: { marks: buildMarks },
30
33
  hover: {
34
+ // The hovered category's band behind its shape.
35
+ marker: (state) => HoverDefaults.behindBand(PlotAxes.other(PlotAxes.valueOf(state))),
31
36
  rows: BoxSummaries.of,
32
37
  position: BoxSummaries.position,
33
- label: () => ((row) => String(row.median)),
34
- format: (state) => BoxSummaries.format(state),
35
- sort: () => TooltipState.descending((row) => row.median)
38
+ format: (state) => BoxSummaries.format(state)
36
39
  }
37
40
  };
38
41
  }
@@ -1,4 +1,4 @@
1
- import type { BoxPlotState, BoxPlotCtx } from '../../../types/plots/distribution/box/state';
1
+ import type { BoxPlotState, BoxPlotEnv } from '../../../types/plots/distribution/box/state';
2
2
  import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
3
3
  /**
4
4
  * BoxPlot's "markers" phase: one `box` per visual segment of each series,
@@ -9,4 +9,4 @@ import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
9
9
  * A series toggled off in the legend (style mode), or dimmed by hovering
10
10
  * another one, takes the legend's disabled fill.
11
11
  */
12
- export declare function buildMarks<TData extends Record<string, unknown>>(state: BoxPlotState<TData>, ctx: BoxPlotCtx): AxisBasedMarkersConfig[];
12
+ export declare function buildMarks<TData extends Record<string, unknown>>(state: BoxPlotState<TData>, env: BoxPlotEnv): AxisBasedMarkersConfig[];
@@ -7,12 +7,12 @@
7
7
  * A series toggled off in the legend (style mode), or dimmed by hovering
8
8
  * another one, takes the legend's disabled fill.
9
9
  */
10
- export function buildMarks(state, ctx) {
10
+ export function buildMarks(state, env) {
11
11
  const { channels } = state.processedData;
12
- const { cfg } = ctx;
12
+ const { cfg } = env;
13
13
  return (state.processedGroups ?? []).flatMap((group) => {
14
14
  const name = group.series.name;
15
- const disabled = ctx.interaction?.fillFor(name);
15
+ const disabled = env.interaction?.fillFor(name);
16
16
  return group.visualSegments.map((seg) => {
17
17
  const { stroke, strokeWidth, strokeOpacity, borderRadius } = seg.styles;
18
18
  const fill = disabled?.fill ?? seg.styles.fill ?? state.colorForSeries(name);
@@ -1,9 +1,9 @@
1
1
  import type { AxisPlotDefaults } from '../../../types/phases';
2
- import type { DensityPlotState, DensityPlotCtx } from '../../../types/plots/distribution/density/state';
2
+ import type { DensityPlotState, DensityPlotEnv } from '../../../types/plots/distribution/density/state';
3
3
  /**
4
4
  * DensityPlot on the shared pipeline: series read one position channel - `x`,
5
5
  * or `y` for a horizontal curve - estimated by the plot's transforms merged
6
6
  * over the default density of that axis, drawn from a zero baseline as an area
7
7
  * or a line, and its own markers. Its plot defaults to: hover along the estimated axis.
8
8
  */
9
- export declare function buildDensityDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<DensityPlotState<TData>, DensityPlotCtx>;
9
+ export declare function buildDensityDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<DensityPlotState<TData>, DensityPlotEnv>;
@@ -1,4 +1,10 @@
1
1
  import { buildMarks } from './markers';
2
+ import { RowContext } from '../../../phases/context/RowContext';
3
+ import { TooltipState } from '../../../layout/tooltip/TooltipState.svelte';
4
+ import { NumberFormat } from '../../../utils/NumberFormat';
5
+ import { getConfiguration } from '../../../configuration/config.svelte';
6
+ /** A density is a small number: three decimals tell its points apart. */
7
+ const DENSITY_DECIMALS = 3;
2
8
  /**
3
9
  * The plot's own density along its axis merged over the default one, the
4
10
  * author's props winning, and every other transform kept after it in order. A
@@ -30,6 +36,16 @@ export function buildDensityDefaults() {
30
36
  transforms: (state) => mergeDensity(state.transforms ?? [], state.axes?.isHorizontal ?? false)
31
37
  },
32
38
  scales: { zero: ['value'] },
33
- markers: { marks: buildMarks }
39
+ markers: { marks: buildMarks },
40
+ hover: {
41
+ // A hovered point reads as its estimate, the value its context gives it - a small number, written with
42
+ // three decimals unless the author asks otherwise.
43
+ label: (state) => {
44
+ const number = NumberFormat.of(NumberFormat.displayOf(state.values), getConfiguration(), DENSITY_DECIMALS);
45
+ return ((row) => number(Number(RowContext.of(row).value)));
46
+ },
47
+ // Its tooltip writes the estimate the same way.
48
+ format: (state) => TooltipState.default(state, NumberFormat.of(NumberFormat.displayOf(state.tooltip), getConfiguration(), DENSITY_DECIMALS))
49
+ }
34
50
  };
35
51
  }
@@ -1,4 +1,4 @@
1
- import type { DensityPlotState, DensityPlotCtx } from '../../../types/plots/distribution/density/state';
1
+ import type { DensityPlotState, DensityPlotEnv } from '../../../types/plots/distribution/density/state';
2
2
  import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
3
3
  /**
4
4
  * DensityPlot's "markers" phase: one `area` - or `line`, by `styles.mark` - per
@@ -6,4 +6,4 @@ import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
6
6
  * its series. The markers the "statistics" phase already put in `state.markers`
7
7
  * come after.
8
8
  */
9
- export declare function buildMarks<TData extends Record<string, unknown>>(state: DensityPlotState<TData>, ctx: DensityPlotCtx): AxisBasedMarkersConfig[];
9
+ export declare function buildMarks<TData extends Record<string, unknown>>(state: DensityPlotState<TData>, env: DensityPlotEnv): AxisBasedMarkersConfig[];
@@ -5,15 +5,15 @@ import { Transforms } from '../../../phases/transforms/Transforms';
5
5
  * its series. The markers the "statistics" phase already put in `state.markers`
6
6
  * come after.
7
7
  */
8
- export function buildMarks(state, ctx) {
8
+ export function buildMarks(state, env) {
9
9
  const { channels, options, transforms } = state.processedData;
10
- const { cfg } = ctx;
10
+ const { cfg } = env;
11
11
  const styles = state.styles;
12
12
  const asLine = styles?.mark === 'line';
13
13
  return (state.processedGroups ?? []).flatMap((group) => {
14
14
  const name = group.series.name;
15
- const disabledFill = ctx.interaction?.fillFor(name);
16
- const disabledStroke = ctx.interaction?.strokeFor(name);
15
+ const disabledFill = env.interaction?.fillFor(name);
16
+ const disabledStroke = env.interaction?.strokeFor(name);
17
17
  return group.visualSegments.map((seg) => {
18
18
  const color = seg.styles.fill ?? state.colorForSeries(name);
19
19
  const style = asLine
@@ -1,9 +1,9 @@
1
1
  import type { AxisPlotDefaults } from '../../../types/phases';
2
- import type { HistogramPlotState, HistogramPlotCtx } from '../../../types/plots/distribution/histogram/state';
2
+ import type { HistogramPlotState, HistogramPlotEnv } from '../../../types/plots/distribution/histogram/state';
3
3
  /**
4
4
  * HistogramPlot on the shared pipeline: series read one position channel -
5
5
  * `x`, or `y` for a horizontal histogram - binned by the plot's transforms
6
6
  * merged over the default bin of that axis, bars from a zero baseline, and its
7
7
  * own markers. Its plot defaults to: hover along the binned axis.
8
8
  */
9
- export declare function buildHistogramDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<HistogramPlotState<TData>, HistogramPlotCtx>;
9
+ export declare function buildHistogramDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<HistogramPlotState<TData>, HistogramPlotEnv>;
@@ -1,5 +1,5 @@
1
- import { buildMarks, buildValueLabels } from './markers';
2
- import { SERIES_KEY } from '../../../phases/transforms/TransformsPhase';
1
+ import { buildMarks } from './markers';
2
+ import { HoverDefaults } from '../../../layout/hover/HoverDefaults';
3
3
  import { resolveAccessor } from '../../../utils/accessors';
4
4
  import { PlotAxes } from '../../../phases/data/PlotAxes';
5
5
  /** One processed channel's value on a row - `undefined` for a channel the transforms didn't set. */
@@ -40,7 +40,23 @@ export function buildHistogramDefaults() {
40
40
  }
41
41
  },
42
42
  transforms: {
43
- transforms: (state, ctx) => mergeBin(state.transforms ?? [], ctx.cfg, state.axes?.isHorizontal ?? false)
43
+ transforms: (state, env) => mergeBin(state.transforms ?? [], env.cfg, state.axes?.isHorizontal ?? false)
44
+ },
45
+ // A bin's count and the edges it spans, for its label, its tooltip and its hover.
46
+ context: (state) => {
47
+ const { channels } = state.processedData;
48
+ const value = PlotAxes.valueOf(state);
49
+ const binned = PlotAxes.other(value);
50
+ const [count, from, to] = [
51
+ channels[value],
52
+ channels[`${binned}1`],
53
+ channels[`${binned}2`]
54
+ ].map(readChannel);
55
+ return ((row) => ({
56
+ count: Number(count(row)),
57
+ from: Number(from(row)),
58
+ to: Number(to(row))
59
+ }));
44
60
  },
45
61
  scales: { zero: ['value'] },
46
62
  styles: {
@@ -63,31 +79,10 @@ export function buildHistogramDefaults() {
63
79
  }
64
80
  }
65
81
  },
66
- markers: { marks: buildMarks, valueLabels: buildValueLabels },
82
+ markers: { marks: buildMarks },
67
83
  hover: {
68
- // A hovered bin is labelled with its count, and reads as its row plus its count,
69
- // the edges it spans and its series.
70
- label: (state) => {
71
- const count = readChannel(state.processedData.channels[PlotAxes.valueOf(state)]);
72
- return ((row) => String(Number(count(row))));
73
- },
74
- row: (state) => {
75
- const { channels } = state.processedData;
76
- const value = PlotAxes.valueOf(state);
77
- const binned = PlotAxes.other(value);
78
- const [count, from, to] = [
79
- channels[value],
80
- channels[`${binned}1`],
81
- channels[`${binned}2`]
82
- ].map(readChannel);
83
- return ((row) => ({
84
- ...row,
85
- count: Number(count(row)),
86
- from: Number(from(row)),
87
- to: Number(to(row)),
88
- group: row[SERIES_KEY]
89
- }));
90
- }
84
+ // The hovered bin's span behind its bar, the whole height of the plot: a bin is no band of a category.
85
+ marker: (state) => HoverDefaults.behindSpan(PlotAxes.other(PlotAxes.valueOf(state)), 'from', 'to')
91
86
  }
92
87
  };
93
88
  }
@@ -1,18 +1,9 @@
1
- import type { HistogramPlotState, HistogramPlotCtx } from '../../../types/plots/distribution/histogram/state';
2
- import type { AxisBasedMarkersConfig, TextMarkerConfig } from '../../../types/markers/common';
3
- import type { ValueLabels } from '../../../layout/styles/ValueLabels';
4
- /**
5
- * HistogramPlot's `styles.values` as one `'text'` marker over its non-empty
6
- * bins (a `filter` on the count), each labelled with its count by `format`.
7
- * `anchor` places each label along its bar: past its top (`'outside'`), just
8
- * inside it (`'start'`), at its base (`'end'`), or centred (`'middle'`) -
9
- * upward, or rightward on a horizontal histogram.
10
- */
11
- export declare function buildValueLabels<TData extends Record<string, unknown>>(labels: ValueLabels, state: HistogramPlotState<TData>, ctx: HistogramPlotCtx): TextMarkerConfig[];
1
+ import type { HistogramPlotState, HistogramPlotEnv } from '../../../types/plots/distribution/histogram/state';
2
+ import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
12
3
  /**
13
4
  * HistogramPlot's "markers" phase: one `rect` per visual segment of each
14
5
  * series, drawing that segment's bins, dimmed with its series. The markers
15
6
  * the "statistics" phase already put in `state.markers` come after, and its
16
7
  * value labels last.
17
8
  */
18
- export declare function buildMarks<TData extends Record<string, unknown>>(state: HistogramPlotState<TData>, ctx: HistogramPlotCtx): AxisBasedMarkersConfig[];
9
+ export declare function buildMarks<TData extends Record<string, unknown>>(state: HistogramPlotState<TData>, env: HistogramPlotEnv): AxisBasedMarkersConfig[];
@@ -1,83 +1,42 @@
1
1
  import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
2
- import { SERIES_KEY } from '../../../phases/transforms/TransformsPhase';
2
+ import { ValueLabels } from '../../../layout/styles/ValueLabels';
3
3
  import { Transforms } from '../../../phases/transforms/Transforms';
4
4
  import { resolveAccessor } from '../../../utils/accessors';
5
5
  import { PlotAxes } from '../../../phases/data/PlotAxes';
6
- /**
7
- * HistogramPlot's `styles.values` as one `'text'` marker over its non-empty
8
- * bins (a `filter` on the count), each labelled with its count by `format`.
9
- * `anchor` places each label along its bar: past its top (`'outside'`), just
10
- * inside it (`'start'`), at its base (`'end'`), or centred (`'middle'`) -
11
- * upward, or rightward on a horizontal histogram.
12
- */
13
- export function buildValueLabels(labels, state, ctx) {
14
- const { processedData: processed } = state;
15
- if (!processed?.data.length)
16
- return [];
17
- const { font, anchor, format } = labels;
18
- const nameOf = (d) => String(d[SERIES_KEY]);
19
- const value = PlotAxes.valueOf(state);
20
- const binned = PlotAxes.other(value);
21
- const horizontal = value === 'x';
22
- const position = ProcessedPositions.of(processed, value);
23
- const read = (channel) => channel === undefined
24
- ? undefined
25
- : resolveAccessor(channel);
26
- const topOf = (d) => Number(position[value](d));
27
- const bottomOf = read(processed.channels[`${value}1`]) ?? (() => 0);
28
- const countRead = read(processed.channels[value]);
29
- const countOf = (d) => countRead ? Number(countRead(d)) : topOf(d) - Number(bottomOf(d));
30
- const along = anchor === 'end'
31
- ? bottomOf
32
- : anchor === 'middle'
33
- ? (d) => (topOf(d) + Number(bottomOf(d))) / 2
34
- : topOf;
35
- // Outward from the bar's top: past it, just inside it, or out from its base.
36
- const outward = anchor === 'outside' ? 6 : anchor === 'start' ? -4 : anchor === 'end' ? 4 : 0;
37
- const outwardAnchor = anchor === 'start' ? 'end' : anchor === 'middle' ? 'middle' : 'start';
38
- const marker = Transforms.resolve({
39
- type: 'text',
40
- data: processed.data,
41
- [binned]: position[binned],
42
- [value]: along,
43
- transforms: [{ type: 'filter', filter: (d) => countOf(d) > 0 }],
44
- text: (d) => format(countOf(d), nameOf(d), d),
45
- styles: {
46
- ...font,
47
- fill: font?.fill ?? ctx.cfg.axis.color,
48
- fontSize: font?.fontSize ?? 12,
49
- dx: font?.dx ?? (horizontal ? outward : 0),
50
- dy: font?.dy ?? (horizontal ? 0 : -outward),
51
- textAnchor: labels.textAnchor ?? (horizontal ? outwardAnchor : 'middle'),
52
- lineAnchor: font?.lineAnchor ??
53
- (horizontal
54
- ? 'middle'
55
- : anchor === 'start'
56
- ? 'top'
57
- : anchor === 'middle'
58
- ? 'middle'
59
- : 'bottom')
60
- }
61
- }, processed.data);
62
- return marker.data?.length ? [marker] : [];
63
- }
64
6
  /**
65
7
  * HistogramPlot's "markers" phase: one `rect` per visual segment of each
66
8
  * series, drawing that segment's bins, dimmed with its series. The markers
67
9
  * the "statistics" phase already put in `state.markers` come after, and its
68
10
  * value labels last.
69
11
  */
70
- export function buildMarks(state, ctx) {
12
+ export function buildMarks(state, env) {
71
13
  const { channels, options, transforms } = state.processedData;
72
- const fillOpacity = ctx.cfg.histogram.fillOpacity;
14
+ const fillOpacity = env.cfg.histogram.fillOpacity;
15
+ // Each bin writes its own count, along its bar: past its top (`'outside'`), against an edge, at its tip or its
16
+ // base - upward, or rightward on a horizontal histogram. A bin with nothing in it writes nothing.
17
+ const labels = state.valueLabels?.show ? state.valueLabels : undefined;
18
+ const value = PlotAxes.valueOf(state);
19
+ const position = ProcessedPositions.of(state.processedData, value);
20
+ const read = (channel) => channel === undefined
21
+ ? undefined
22
+ : resolveAccessor(channel);
23
+ const bottomOf = read(channels[`${value}1`]) ?? (() => 0);
24
+ const countRead = read(channels[value]);
25
+ const countOf = (d) => countRead ? Number(countRead(d)) : Number(position[value](d)) - Number(bottomOf(d));
26
+ const labelFor = (name) => labels?.shapeLabel(env, (d) => (countOf(d) > 0 ? labels.format(countOf(d), d, name) : ''), {
27
+ fill: 'currentColor',
28
+ ...ValueLabels.boxAnchor(labels.anchor, { isHorizontal: value === 'x' })
29
+ });
73
30
  const rects = (state.processedGroups ?? []).flatMap((group) => {
74
- const disabled = ctx.interaction?.fillFor(group.series.name);
31
+ const disabled = env.interaction?.fillFor(group.series.name);
75
32
  // A stroke the segment sets is not a reason to lose the series' fill, as the marker would take it for the color.
76
33
  const color = state.colorForSeries(group.series.name);
77
34
  return group.visualSegments.map((seg) => Transforms.finish({
78
35
  type: 'rect',
79
36
  series: group.series.name,
80
37
  data: seg.data,
38
+ hover: 'style',
39
+ ...(labels ? { label: labelFor(group.series.name) } : {}),
81
40
  ...channels,
82
41
  ...options,
83
42
  styles: {
@@ -1,5 +1,5 @@
1
1
  import type { AxisPlotDefaults } from '../../../types/phases';
2
- import type { PyramidPlotState, PyramidPlotCtx } from '../../../types/plots/distribution/pyramid/state';
2
+ import type { PyramidPlotState, PyramidPlotEnv } from '../../../types/plots/distribution/pyramid/state';
3
3
  /**
4
4
  * PyramidPlot on the shared pipeline. Its `x`/`y` are the visual axes: the one
5
5
  * holding categories (read off the values by the "data" phase) runs the bars,
@@ -10,4 +10,4 @@ import type { PyramidPlotState, PyramidPlotCtx } from '../../../types/plots/dist
10
10
  * category and magnitude.
11
11
  * Its plot defaults to: hover along the category axis; the tween is of the magnitude, keyed by category and side.
12
12
  */
13
- export declare function buildPyramidDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<PyramidPlotState<TData>, PyramidPlotCtx>;
13
+ export declare function buildPyramidDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<PyramidPlotState<TData>, PyramidPlotEnv>;
@@ -1,6 +1,7 @@
1
1
  import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
2
+ import { HoverDefaults } from '../../../layout/hover/HoverDefaults';
2
3
  import { PlotAxes } from '../../../phases/data/PlotAxes';
3
- import { buildMarks, buildValueLabels } from './markers';
4
+ import { buildMarks } from './markers';
4
5
  import { ValueLabels } from '../../../layout/styles/ValueLabels';
5
6
  import { seriesIdOf } from '../../../utils/grouping';
6
7
  import { isGapValue } from '../../utils/gaps';
@@ -48,14 +49,14 @@ export function buildPyramidDefaults() {
48
49
  values: {
49
50
  // A label past its bar's end reaches out on its own side, the longest bar's to the edge.
50
51
  reach: (labels, state) => {
51
- if (labels.anchor === 'middle' || labels.anchor === 'end')
52
+ if (labels.anchor !== 'outside')
52
53
  return [];
53
54
  const axis = PlotAxes.valueOf(state);
54
55
  const isHorizontal = state.axes?.isHorizontal ?? true;
55
56
  const offset = labels.offset(axis);
56
57
  return labels.extremes(state.resolvedSeries ?? [], axis).map(({ series, value }) => {
57
58
  const left = series.side === 'left';
58
- const text = labels.format(Math.abs(value), series.name);
59
+ const text = labels.format(Math.abs(value), undefined, series.name);
59
60
  return isHorizontal
60
61
  ? labels.edgeBox(text, { x: left ? 'before' : 'after', y: 'middle' }, { x: left ? -offset : offset }, [left ? 'left' : 'right'])
61
62
  : labels.edgeBox(text, { x: 'middle', y: left ? 'after' : 'before' }, { y: left ? offset : -offset }, [left ? 'bottom' : 'top']);
@@ -63,8 +64,10 @@ export function buildPyramidDefaults() {
63
64
  }
64
65
  }
65
66
  },
66
- markers: { marks: buildMarks, valueLabels: buildValueLabels },
67
+ markers: { marks: buildMarks },
67
68
  hover: {
69
+ // The hovered age group's band behind its bars, across both sides.
70
+ marker: (state) => HoverDefaults.behindBand(PlotAxes.other(PlotAxes.valueOf(state))),
68
71
  // A bar sits at its signed magnitude - below or left of the baseline on the first
69
72
  // side - and its category, and reads as its magnitude.
70
73
  position: (state) => {
@@ -1,15 +1,5 @@
1
- import type { TextMarkerConfig } from '../../../types/markers/common';
2
- import type { PyramidPlotState, PyramidPlotCtx } from '../../../types/plots/distribution/pyramid/state';
3
- import type { ValueLabels } from '../../../layout/styles/ValueLabels';
1
+ import type { PyramidPlotState, PyramidPlotEnv } from '../../../types/plots/distribution/pyramid/state';
4
2
  import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
5
- /**
6
- * PyramidPlot's `styles.values` as one `'text'` marker per series, over the
7
- * same processed rows its bars draw (gap rows never get a label), mirrored to
8
- * its own side of the shared zero baseline. `anchor` places each label along
9
- * its bar: past its end (`'outside'`/`'start'`), at the baseline (`'end'`),
10
- * or centred (`'middle'`). On a vertical pyramid the sides run down and up.
11
- */
12
- export declare function buildValueLabels<TData extends Record<string, unknown>>(labels: ValueLabels, state: PyramidPlotState<TData>, ctx: PyramidPlotCtx): TextMarkerConfig[];
13
3
  /**
14
4
  * PyramidPlot's "markers" phase: one `role: 'segment'` bar per visual
15
5
  * segment, along the category axis the "data" phase read (horizontal bars for
@@ -18,4 +8,4 @@ export declare function buildValueLabels<TData extends Record<string, unknown>>(
18
8
  * `state.markers`. Emits no `role: 'hitArea'` markers - PyramidPlot's hover
19
9
  * matches nearest points rather than hit-testing category bands.
20
10
  */
21
- export declare function buildMarks<TData extends Record<string, unknown>>(state: PyramidPlotState<TData>, ctx: PyramidPlotCtx): AxisBasedMarkersConfig[];
11
+ export declare function buildMarks<TData extends Record<string, unknown>>(state: PyramidPlotState<TData>, env: PyramidPlotEnv): AxisBasedMarkersConfig[];
@@ -1,5 +1,5 @@
1
+ import { ValueLabels } from '../../../layout/styles/ValueLabels';
1
2
  import { resolveAccessor } from '../../../utils/accessors';
2
- import { SERIES_ID_KEY } from '../../../phases/transforms/TransformsPhase';
3
3
  import { seriesIdOf } from '../../../utils/grouping';
4
4
  import { PlotAxes } from '../../../phases/data/PlotAxes';
5
5
  import { getConfiguration } from '../../../configuration/config.svelte';
@@ -8,69 +8,6 @@ const GAP_KINDS = ['start', 'middle', 'end'];
8
8
  function signFor(s, magnitude) {
9
9
  return s.side === 'left' ? -magnitude : magnitude;
10
10
  }
11
- /**
12
- * PyramidPlot's `styles.values` as one `'text'` marker per series, over the
13
- * same processed rows its bars draw (gap rows never get a label), mirrored to
14
- * its own side of the shared zero baseline. `anchor` places each label along
15
- * its bar: past its end (`'outside'`/`'start'`), at the baseline (`'end'`),
16
- * or centred (`'middle'`). On a vertical pyramid the sides run down and up.
17
- */
18
- export function buildValueLabels(labels, state, ctx) {
19
- const { processedData } = state;
20
- if (!processedData)
21
- return [];
22
- const { font, anchor, format } = labels;
23
- const categoryAxis = PlotAxes.categoryOf(state);
24
- const valueAxis = PlotAxes.valueOf(state);
25
- const isHorizontal = state.axes?.isHorizontal ?? true;
26
- return (state.processedGroups ?? []).flatMap(({ series }) => {
27
- const id = seriesIdOf(series);
28
- const side = state.resolvedSeries.find((s) => seriesIdOf(s) === id).side;
29
- const isLeft = side === 'left';
30
- const getMagnitude = resolveAccessor(series[valueAxis]);
31
- const magnitude = (d) => Math.abs(Number(getMagnitude(d)));
32
- const signed = (d) => (isLeft ? -magnitude(d) : magnitude(d));
33
- const data = processedData.data.filter((d) => d[SERIES_ID_KEY] === id && !isGapValue(getMagnitude(d)));
34
- if (data.length === 0)
35
- return [];
36
- const outward = isLeft ? -1 : 1;
37
- const at = anchor === 'middle' ? (d) => signed(d) / 2 : anchor === 'end' ? 0 : signed;
38
- const shift = anchor === 'middle' ? 0 : outward * (anchor === 'end' ? 4 : 6);
39
- // Away from the baseline: left/right on a horizontal pyramid, down/up on a vertical one.
40
- const awayAnchor = isHorizontal
41
- ? anchor === 'middle'
42
- ? 'middle'
43
- : isLeft
44
- ? 'end'
45
- : 'start'
46
- : 'middle';
47
- const awayLine = isHorizontal
48
- ? 'middle'
49
- : anchor === 'middle'
50
- ? 'middle'
51
- : isLeft
52
- ? 'top'
53
- : 'bottom';
54
- return [
55
- {
56
- type: 'text',
57
- data,
58
- [valueAxis]: at,
59
- [categoryAxis]: series[categoryAxis],
60
- text: (d) => format(magnitude(d), series.name, d),
61
- styles: {
62
- ...font,
63
- fill: font?.fill ?? ctx.cfg.axis.color,
64
- fontSize: font?.fontSize ?? 12,
65
- dx: font?.dx ?? (isHorizontal ? shift : 0),
66
- dy: font?.dy ?? (isHorizontal ? 0 : -shift),
67
- textAnchor: labels.textAnchor ?? awayAnchor,
68
- lineAnchor: font?.lineAnchor ?? awayLine
69
- }
70
- }
71
- ];
72
- });
73
- }
74
11
  /**
75
12
  * PyramidPlot's "markers" phase: one `role: 'segment'` bar per visual
76
13
  * segment, along the category axis the "data" phase read (horizontal bars for
@@ -79,12 +16,18 @@ export function buildValueLabels(labels, state, ctx) {
79
16
  * `state.markers`. Emits no `role: 'hitArea'` markers - PyramidPlot's hover
80
17
  * matches nearest points rather than hit-testing category bands.
81
18
  */
82
- export function buildMarks(state, ctx) {
19
+ export function buildMarks(state, env) {
83
20
  const { groupedSeries, gapFillMaps } = state;
84
21
  const gapDefaults = getConfiguration().pyramid.gap;
85
22
  const categoryAxis = PlotAxes.categoryOf(state);
86
23
  const valueAxis = PlotAxes.valueOf(state);
87
24
  const isHorizontal = state.axes?.isHorizontal ?? true;
25
+ const labels = state.valueLabels?.show ? state.valueLabels : undefined;
26
+ /**
27
+ * Where a series' labels sit on its bars, which run out from the shared baseline to its own side: left and right
28
+ * of it on a horizontal pyramid, down and up on a vertical one.
29
+ */
30
+ const anchorOf = (side) => ValueLabels.boxAnchor(labels?.anchor ?? 'outside', { isHorizontal, negative: side === 'left' });
88
31
  /** One bar's own channels: its category, and its span from the baseline to its signed value. */
89
32
  const span = (category, to) => ({
90
33
  isHorizontal,
@@ -104,7 +47,7 @@ export function buildMarks(state, ctx) {
104
47
  // practice, just not provably so to TypeScript here.
105
48
  const category = group.series[categoryAxis];
106
49
  const defaultColor = state.colorForSeries(group.series.name);
107
- const disabledFill = ctx.interaction?.fillFor(group.series.name);
50
+ const disabledFill = env.interaction?.fillFor(group.series.name);
108
51
  const processed = processedGroups.get(seriesIdOf(group.series));
109
52
  const processedCategory = processed?.series[categoryAxis];
110
53
  const getMagnitude = resolveAccessor((processed?.series[valueAxis] ?? group.series[valueAxis]));
@@ -117,7 +60,14 @@ export function buildMarks(state, ctx) {
117
60
  type: 'bar',
118
61
  role: 'segment',
119
62
  data: realData,
63
+ hover: 'style',
120
64
  ...span(processedCategory, signed),
65
+ // Each bar writes its own magnitude, on its side of the baseline.
66
+ ...(labels
67
+ ? {
68
+ label: labels.shapeLabel(env, (d) => labels.format(Math.abs(Number(getMagnitude(d))), d, group.series.name), { fill: 'currentColor', ...anchorOf(group.series.side) })
69
+ }
70
+ : {}),
121
71
  styles: {
122
72
  // An outline asked for without a color is the fill's.
123
73
  ...(seg.styles.strokeWidth !== undefined
@@ -1,5 +1,5 @@
1
1
  import type { AxisPlotDefaults } from '../../../types/phases';
2
- import type { ViolinPlotState, ViolinPlotCtx } from '../../../types/plots/distribution/violin/state';
2
+ import type { ViolinPlotState, ViolinPlotEnv } from '../../../types/plots/distribution/violin/state';
3
3
  /**
4
4
  * ViolinPlot on the shared pipeline: one violin per category of each series
5
5
  * along one category axis - `x`, or `y` for horizontal violins - in the order
@@ -7,4 +7,4 @@ import type { ViolinPlotState, ViolinPlotCtx } from '../../../types/plots/distri
7
7
  * fits the values, without reaching for zero. Its plot defaults to: hover
8
8
  * along the category axis, over one summary per violin, read as a box plot's.
9
9
  */
10
- export declare function buildViolinDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<ViolinPlotState<TData>, ViolinPlotCtx>;
10
+ export declare function buildViolinDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<ViolinPlotState<TData>, ViolinPlotEnv>;
@@ -1,9 +1,9 @@
1
1
  import { buildMarks } from './markers';
2
+ import { HoverDefaults } from '../../../layout/hover/HoverDefaults';
2
3
  import { BoxSummaries } from '../box/BoxSummaries';
3
4
  import { PlotAxes } from '../../../phases/data/PlotAxes';
4
5
  import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
5
6
  import { NiceTicks } from '../../../layout/scales/NiceTicks';
6
- import { TooltipState } from '../../../layout/tooltip/TooltipState.svelte';
7
7
  /**
8
8
  * The value axis fit to the values the violins are drawn from, when the author leaves it unpinned: no svelteplot mark reads them, so nothing else sets its domain.
9
9
  */
@@ -43,20 +43,22 @@ export function buildViolinDefaults() {
43
43
  scales: {
44
44
  bandOrder: 'data',
45
45
  fit: (state) => fitValueDomain(state),
46
- defaults: (_state, ctx) => ({
46
+ defaults: (_state, env) => ({
47
47
  category: {
48
- paddingInner: ctx.cfg.violin.paddingInner,
49
- paddingOuter: ctx.cfg.violin.paddingOuter
48
+ paddingInner: env.cfg.violin.paddingInner,
49
+ paddingOuter: env.cfg.violin.paddingOuter
50
50
  }
51
51
  })
52
52
  },
53
+ // Each value's box: its quartiles and whiskers, worked out once for its tooltip and hover to read.
54
+ context: (state) => BoxSummaries.context(state),
53
55
  markers: { marks: buildMarks },
54
56
  hover: {
57
+ // The hovered category's band behind its shape.
58
+ marker: (state) => HoverDefaults.behindBand(PlotAxes.other(PlotAxes.valueOf(state))),
55
59
  rows: BoxSummaries.of,
56
60
  position: BoxSummaries.position,
57
- label: () => ((row) => String(row.median)),
58
- format: (state) => BoxSummaries.format(state),
59
- sort: () => TooltipState.descending((row) => row.median)
61
+ format: (state) => BoxSummaries.format(state)
60
62
  }
61
63
  };
62
64
  }
@@ -1,4 +1,4 @@
1
- import type { ViolinPlotState, ViolinPlotCtx } from '../../../types/plots/distribution/violin/state';
1
+ import type { ViolinPlotState, ViolinPlotEnv } from '../../../types/plots/distribution/violin/state';
2
2
  import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
3
3
  /**
4
4
  * ViolinPlot's "markers" phase: one `violin` - and a narrow `box` over it - per visual
@@ -7,4 +7,4 @@ import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
7
7
  * by side. The markers the "statistics" phase already put in `state.markers`
8
8
  * come after, so they render on top.
9
9
  */
10
- export declare function buildMarks<TData extends Record<string, unknown>>(state: ViolinPlotState<TData>, ctx: ViolinPlotCtx): AxisBasedMarkersConfig[];
10
+ export declare function buildMarks<TData extends Record<string, unknown>>(state: ViolinPlotState<TData>, env: ViolinPlotEnv): AxisBasedMarkersConfig[];