@fundar/data-chart-telling 1.17.0 → 1.19.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 (353) hide show
  1. package/CHANGELOG.md +59 -0
  2. package/README.md +2 -1
  3. package/dist/configuration/config.svelte.js +4 -3
  4. package/dist/index.d.ts +10 -3
  5. package/dist/index.js +4 -1
  6. package/dist/layout/coordinates/CoordinatesLayout.svelte +3 -1
  7. package/dist/layout/geometry/GeometryLayout.svelte +222 -53
  8. package/dist/layout/geometry/ScaleFreeContext.d.ts +31 -0
  9. package/dist/layout/geometry/ScaleFreeContext.js +65 -0
  10. package/dist/layout/geometry/ScaleFreeMarks.svelte +14 -0
  11. package/dist/layout/geometry/ScaleFreeMarks.svelte.d.ts +7 -0
  12. package/dist/layout/geometry/ScaleGate.svelte.d.ts +8 -0
  13. package/dist/layout/geometry/ScaleGate.svelte.js +95 -0
  14. package/dist/layout/geometry/ScaleGateMarks.svelte +15 -0
  15. package/dist/layout/geometry/ScaleGateMarks.svelte.d.ts +7 -0
  16. package/dist/layout/hover/HoverDefaults.d.ts +52 -0
  17. package/dist/layout/hover/HoverDefaults.js +96 -0
  18. package/dist/layout/hover/HoverLayers.d.ts +35 -0
  19. package/dist/layout/hover/HoverLayers.js +122 -0
  20. package/dist/layout/hover/HoverSettings.d.ts +1 -3
  21. package/dist/layout/hover/HoverSettings.js +3 -2
  22. package/dist/layout/hover/HoverShapes.d.ts +56 -0
  23. package/dist/layout/hover/HoverShapes.js +163 -0
  24. package/dist/layout/hover/PlotHover.svelte.d.ts +18 -0
  25. package/dist/layout/hover/PlotHover.svelte.js +54 -1
  26. package/dist/layout/legend/LegendState.svelte.d.ts +2 -0
  27. package/dist/layout/legend/LegendState.svelte.js +5 -0
  28. package/dist/layout/margins/Box.d.ts +4 -0
  29. package/dist/layout/margins/Box.js +14 -0
  30. package/dist/layout/margins/PlotMargins.svelte.js +26 -1
  31. package/dist/layout/plot/{Plot.svelte.d.ts → AbstractPlot.svelte.d.ts} +3 -3
  32. package/dist/layout/plot/Core.svelte +2 -2
  33. package/dist/layout/plot/PublicPlotContext.d.ts +6 -0
  34. package/dist/layout/plot/PublicPlotContext.js +8 -0
  35. package/dist/layout/styles/ValueLabels.d.ts +118 -59
  36. package/dist/layout/styles/ValueLabels.js +313 -146
  37. package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -9
  38. package/dist/layout/tooltip/TooltipState.svelte.js +28 -29
  39. package/dist/markers/MarkerKinds.d.ts +84 -1
  40. package/dist/markers/MarkerKinds.js +150 -23
  41. package/dist/markers/area/AreaMarker.svelte +1 -1
  42. package/dist/markers/band/BandMarker.svelte +74 -0
  43. package/dist/markers/band/BandMarker.svelte.d.ts +7 -0
  44. package/dist/markers/band/Bands.d.ts +16 -0
  45. package/dist/markers/band/Bands.js +48 -0
  46. package/dist/markers/bar/BarMarker.svelte +29 -70
  47. package/dist/markers/bollinger/BollingerMarker.svelte +1 -1
  48. package/dist/markers/box/BoxMarker.svelte +1 -1
  49. package/dist/markers/dot/DotRadius.d.ts +11 -0
  50. package/dist/markers/dot/DotRadius.js +21 -0
  51. package/dist/markers/hover/HoverMarker.svelte +7 -265
  52. package/dist/markers/hover/HoverMarker.svelte.d.ts +4 -27
  53. package/dist/markers/labels/CurveLabel.svelte +56 -0
  54. package/dist/markers/labels/CurveLabel.svelte.d.ts +9 -0
  55. package/dist/markers/labels/LabelMerge.d.ts +11 -0
  56. package/dist/markers/labels/LabelMerge.js +87 -0
  57. package/dist/markers/labels/MarkerLabel.svelte +36 -0
  58. package/dist/markers/labels/MarkerLabel.svelte.d.ts +10 -0
  59. package/dist/markers/labels/MarkerLabels.d.ts +52 -0
  60. package/dist/markers/labels/MarkerLabels.js +97 -0
  61. package/dist/markers/labels/geometry/BoxGeometry.d.ts +8 -0
  62. package/dist/markers/labels/geometry/BoxGeometry.js +101 -0
  63. package/dist/markers/labels/geometry/CurveGeometry.d.ts +34 -0
  64. package/dist/markers/labels/geometry/CurveGeometry.js +193 -0
  65. package/dist/markers/labels/geometry/PointGeometry.d.ts +9 -0
  66. package/dist/markers/labels/geometry/PointGeometry.js +22 -0
  67. package/dist/markers/labels/layouts/BoxLayout.d.ts +10 -0
  68. package/dist/markers/labels/layouts/BoxLayout.js +49 -0
  69. package/dist/markers/labels/layouts/PathLayout.d.ts +11 -0
  70. package/dist/markers/labels/layouts/PathLayout.js +91 -0
  71. package/dist/markers/labels/layouts/PointLayout.d.ts +19 -0
  72. package/dist/markers/labels/layouts/PointLayout.js +94 -0
  73. package/dist/markers/regression/RegressionMarker.svelte +1 -1
  74. package/dist/markers/text/Covering.d.ts +13 -0
  75. package/dist/markers/text/Covering.js +29 -0
  76. package/dist/markers/text/Declutter.d.ts +24 -3
  77. package/dist/markers/text/Declutter.js +46 -3
  78. package/dist/markers/text/TextMarker.svelte +90 -17
  79. package/dist/markers/text/TextMarker.svelte.d.ts +1 -1
  80. package/dist/markers/tick/TickMarker.svelte +1 -1
  81. package/dist/markers/utils/MarkerChannels.d.ts +1 -1
  82. package/dist/markers/utils/MarkerChannels.js +3 -2
  83. package/dist/markers/utils/PointPixel.d.ts +37 -0
  84. package/dist/markers/utils/PointPixel.js +44 -0
  85. package/dist/markers/violin/ViolinMarker.svelte +1 -1
  86. package/dist/markers/waffle/WaffleMarker.svelte +1 -1
  87. package/dist/phases/Pipeline.d.ts +7 -7
  88. package/dist/phases/Pipeline.js +12 -9
  89. package/dist/phases/context/ContextPhase.d.ts +22 -0
  90. package/dist/phases/context/ContextPhase.js +23 -0
  91. package/dist/phases/context/RowContext.d.ts +37 -0
  92. package/dist/phases/context/RowContext.js +97 -0
  93. package/dist/phases/data/DataPhase.d.ts +4 -4
  94. package/dist/phases/data/DataPhase.js +7 -7
  95. package/dist/phases/hover/HoverPhase.d.ts +6 -7
  96. package/dist/phases/hover/HoverPhase.js +28 -23
  97. package/dist/phases/mapping/MappingPhase.d.ts +4 -4
  98. package/dist/phases/mapping/MappingPhase.js +2 -2
  99. package/dist/phases/markers/MarkerStyles.d.ts +8 -0
  100. package/dist/phases/markers/MarkerStyles.js +24 -6
  101. package/dist/phases/markers/MarkersPhase.d.ts +6 -7
  102. package/dist/phases/markers/MarkersPhase.js +18 -12
  103. package/dist/phases/scales/ScalesPhase.d.ts +4 -4
  104. package/dist/phases/scales/ScalesPhase.js +4 -4
  105. package/dist/phases/sharedScales/SharedScalesPhase.d.ts +2 -2
  106. package/dist/phases/sharedScales/SharedScalesPhase.js +2 -2
  107. package/dist/phases/statistics/MarkerGrouping.d.ts +0 -9
  108. package/dist/phases/statistics/MarkerGrouping.js +5 -48
  109. package/dist/phases/statistics/MarkerInheritance.d.ts +11 -0
  110. package/dist/phases/statistics/MarkerInheritance.js +25 -0
  111. package/dist/phases/statistics/MarkerOrientation.d.ts +26 -0
  112. package/dist/phases/statistics/MarkerOrientation.js +29 -0
  113. package/dist/phases/statistics/StatisticsPhase.js +15 -15
  114. package/dist/phases/styles/StylesPhase.d.ts +3 -3
  115. package/dist/phases/styles/StylesPhase.js +2 -2
  116. package/dist/phases/tooltip/TooltipPhase.d.ts +4 -4
  117. package/dist/phases/tooltip/TooltipPhase.js +10 -7
  118. package/dist/phases/transforms/TransformsPhase.d.ts +3 -3
  119. package/dist/phases/transforms/TransformsPhase.js +7 -5
  120. package/dist/plots/correlation/heatmap/Plot.svelte +2 -2
  121. package/dist/plots/correlation/heatmap/Plot.svelte.d.ts +0 -1
  122. package/dist/plots/correlation/heatmap/defaults.d.ts +2 -2
  123. package/dist/plots/correlation/heatmap/defaults.js +35 -7
  124. package/dist/plots/correlation/heatmap/markers.d.ts +2 -8
  125. package/dist/plots/correlation/heatmap/markers.js +8 -11
  126. package/dist/plots/correlation/scatter/Plot.svelte +2 -2
  127. package/dist/plots/correlation/scatter/Plot.svelte.d.ts +0 -1
  128. package/dist/plots/correlation/scatter/defaults.d.ts +2 -2
  129. package/dist/plots/correlation/scatter/defaults.js +18 -6
  130. package/dist/plots/correlation/scatter/markers.d.ts +2 -11
  131. package/dist/plots/correlation/scatter/markers.js +24 -30
  132. package/dist/plots/distribution/box/BoxSummaries.d.ts +22 -8
  133. package/dist/plots/distribution/box/BoxSummaries.js +99 -40
  134. package/dist/plots/distribution/box/Plot.svelte +2 -2
  135. package/dist/plots/distribution/box/Plot.svelte.d.ts +0 -1
  136. package/dist/plots/distribution/box/defaults.d.ts +2 -2
  137. package/dist/plots/distribution/box/defaults.js +20 -6
  138. package/dist/plots/distribution/box/markers.d.ts +2 -2
  139. package/dist/plots/distribution/box/markers.js +13 -4
  140. package/dist/plots/distribution/density/Plot.svelte +2 -2
  141. package/dist/plots/distribution/density/Plot.svelte.d.ts +0 -1
  142. package/dist/plots/distribution/density/defaults.d.ts +2 -2
  143. package/dist/plots/distribution/density/defaults.js +33 -1
  144. package/dist/plots/distribution/density/markers.d.ts +2 -2
  145. package/dist/plots/distribution/density/markers.js +9 -5
  146. package/dist/plots/distribution/histogram/Plot.svelte +2 -2
  147. package/dist/plots/distribution/histogram/Plot.svelte.d.ts +0 -1
  148. package/dist/plots/distribution/histogram/defaults.d.ts +2 -2
  149. package/dist/plots/distribution/histogram/defaults.js +36 -36
  150. package/dist/plots/distribution/histogram/markers.d.ts +2 -2
  151. package/dist/plots/distribution/histogram/markers.js +7 -6
  152. package/dist/plots/distribution/pyramid/Plot.svelte +2 -2
  153. package/dist/plots/distribution/pyramid/Plot.svelte.d.ts +0 -1
  154. package/dist/plots/distribution/pyramid/defaults.d.ts +2 -2
  155. package/dist/plots/distribution/pyramid/defaults.js +13 -3
  156. package/dist/plots/distribution/pyramid/markers.d.ts +2 -10
  157. package/dist/plots/distribution/pyramid/markers.js +9 -18
  158. package/dist/plots/distribution/violin/Plot.svelte +2 -2
  159. package/dist/plots/distribution/violin/Plot.svelte.d.ts +0 -1
  160. package/dist/plots/distribution/violin/defaults.d.ts +2 -2
  161. package/dist/plots/distribution/violin/defaults.js +20 -7
  162. package/dist/plots/distribution/violin/markers.d.ts +2 -2
  163. package/dist/plots/distribution/violin/markers.js +30 -6
  164. package/dist/plots/evolution/area/Plot.svelte +2 -2
  165. package/dist/plots/evolution/area/Plot.svelte.d.ts +0 -1
  166. package/dist/plots/evolution/area/defaults.d.ts +2 -2
  167. package/dist/plots/evolution/area/defaults.js +5 -8
  168. package/dist/plots/evolution/area/markers.d.ts +2 -2
  169. package/dist/plots/evolution/area/markers.js +7 -5
  170. package/dist/plots/evolution/line/Plot.svelte +2 -2
  171. package/dist/plots/evolution/line/Plot.svelte.d.ts +0 -1
  172. package/dist/plots/evolution/line/defaults.d.ts +2 -2
  173. package/dist/plots/evolution/line/defaults.js +5 -7
  174. package/dist/plots/evolution/line/markers.d.ts +2 -2
  175. package/dist/plots/evolution/line/markers.js +6 -4
  176. package/dist/plots/evolution/slope/Plot.svelte +2 -2
  177. package/dist/plots/evolution/slope/Plot.svelte.d.ts +0 -1
  178. package/dist/plots/evolution/slope/defaults.d.ts +2 -2
  179. package/dist/plots/evolution/slope/defaults.js +11 -6
  180. package/dist/plots/evolution/slope/markers.d.ts +6 -5
  181. package/dist/plots/evolution/slope/markers.js +19 -12
  182. package/dist/plots/evolution/sparkline/Plot.svelte +2 -2
  183. package/dist/plots/evolution/sparkline/Plot.svelte.d.ts +0 -1
  184. package/dist/plots/evolution/sparkline/defaults.d.ts +2 -2
  185. package/dist/plots/evolution/sparkline/defaults.js +5 -2
  186. package/dist/plots/evolution/sparkline/markers.d.ts +2 -2
  187. package/dist/plots/evolution/sparkline/markers.js +6 -4
  188. package/dist/plots/generic/Plot.svelte +42 -0
  189. package/dist/plots/generic/Plot.svelte.d.ts +25 -0
  190. package/dist/plots/generic/defaults.d.ts +4 -0
  191. package/dist/plots/generic/defaults.js +7 -0
  192. package/dist/plots/map/geo/Core.svelte +3 -3
  193. package/dist/plots/map/geo/Plot.svelte +2 -2
  194. package/dist/plots/map/geo/Plot.svelte.d.ts +0 -1
  195. package/dist/plots/map/geo/defaults.d.ts +2 -2
  196. package/dist/plots/map/geo/phases/data.d.ts +1 -1
  197. package/dist/plots/map/geo/phases/data.js +1 -1
  198. package/dist/plots/map/geo/phases/hover.d.ts +2 -2
  199. package/dist/plots/map/geo/phases/hover.js +3 -3
  200. package/dist/plots/map/geo/phases/markers.d.ts +2 -2
  201. package/dist/plots/map/geo/phases/markers.js +3 -3
  202. package/dist/plots/map/geo/phases/scales.d.ts +2 -2
  203. package/dist/plots/map/geo/phases/scales.js +2 -2
  204. package/dist/plots/part-of-a-whole/treemap/Plot.svelte +2 -2
  205. package/dist/plots/part-of-a-whole/treemap/Plot.svelte.d.ts +0 -1
  206. package/dist/plots/part-of-a-whole/treemap/defaults.d.ts +2 -2
  207. package/dist/plots/part-of-a-whole/treemap/defaults.js +38 -22
  208. package/dist/plots/ranking/bar/Plot.svelte +2 -2
  209. package/dist/plots/ranking/bar/Plot.svelte.d.ts +0 -1
  210. package/dist/plots/ranking/bar/defaults.d.ts +2 -2
  211. package/dist/plots/ranking/bar/defaults.js +26 -10
  212. package/dist/plots/ranking/bar/markers.d.ts +3 -3
  213. package/dist/plots/ranking/bar/markers.js +17 -33
  214. package/dist/plots/ranking/bullet/Plot.svelte +2 -2
  215. package/dist/plots/ranking/bullet/Plot.svelte.d.ts +0 -1
  216. package/dist/plots/ranking/bullet/defaults.d.ts +2 -2
  217. package/dist/plots/ranking/bullet/defaults.js +24 -4
  218. package/dist/plots/ranking/bullet/markers.d.ts +3 -3
  219. package/dist/plots/ranking/bullet/markers.js +16 -10
  220. package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +4 -11
  221. package/dist/plots/ranking/cleveland/ClevelandMarkers.js +73 -54
  222. package/dist/plots/ranking/cleveland/Plot.svelte +2 -2
  223. package/dist/plots/ranking/cleveland/Plot.svelte.d.ts +0 -1
  224. package/dist/plots/ranking/cleveland/defaults.d.ts +2 -2
  225. package/dist/plots/ranking/cleveland/defaults.js +39 -5
  226. package/dist/plots/ranking/dumbbell/Plot.svelte +2 -2
  227. package/dist/plots/ranking/dumbbell/Plot.svelte.d.ts +0 -1
  228. package/dist/plots/ranking/dumbbell/defaults.d.ts +2 -2
  229. package/dist/plots/ranking/forest/Plot.svelte +2 -2
  230. package/dist/plots/ranking/forest/Plot.svelte.d.ts +0 -1
  231. package/dist/plots/ranking/forest/defaults.d.ts +2 -2
  232. package/dist/plots/ranking/lollipop/Plot.svelte +2 -2
  233. package/dist/plots/ranking/lollipop/Plot.svelte.d.ts +0 -1
  234. package/dist/plots/ranking/lollipop/defaults.d.ts +2 -2
  235. package/dist/types/configuration/styling.d.ts +4 -0
  236. package/dist/types/layout/context.d.ts +23 -0
  237. package/dist/types/layout/context.js +1 -0
  238. package/dist/types/layout/hover.d.ts +3 -0
  239. package/dist/types/layout/styles/bullet.d.ts +4 -1
  240. package/dist/types/layout/styles/values.d.ts +59 -13
  241. package/dist/types/layout/tooltip.d.ts +5 -10
  242. package/dist/types/markers/axis/area.d.ts +5 -1
  243. package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
  244. package/dist/types/markers/axis/band.d.ts +24 -0
  245. package/dist/types/markers/axis/band.js +1 -0
  246. package/dist/types/markers/axis/bar.d.ts +7 -4
  247. package/dist/types/markers/axis/bollinger.d.ts +2 -1
  248. package/dist/types/markers/axis/box.d.ts +2 -1
  249. package/dist/types/markers/axis/cell.d.ts +4 -1
  250. package/dist/types/markers/axis/hover.d.ts +60 -15
  251. package/dist/types/markers/axis/line.d.ts +4 -1
  252. package/dist/types/markers/axis/rect.d.ts +4 -1
  253. package/dist/types/markers/axis/regression.d.ts +2 -1
  254. package/dist/types/markers/axis/tick.d.ts +2 -1
  255. package/dist/types/markers/axis/trail.d.ts +4 -1
  256. package/dist/types/markers/axis/violin.d.ts +2 -1
  257. package/dist/types/markers/axis/waffle.d.ts +5 -1
  258. package/dist/types/markers/basic/dot.d.ts +4 -1
  259. package/dist/types/markers/basic/text.d.ts +25 -21
  260. package/dist/types/markers/channels/commonMarkerConfig.d.ts +6 -2
  261. package/dist/types/markers/channels/commonMarkerConfigWithLabel.d.ts +5 -9
  262. package/dist/types/markers/channels/commonMarkerConfigWithOrientation.d.ts +5 -0
  263. package/dist/types/markers/channels/commonMarkerConfigWithOrientation.js +1 -0
  264. package/dist/types/markers/common.d.ts +1 -0
  265. package/dist/types/markers/common.js +1 -0
  266. package/dist/types/markers/labels/box.d.ts +57 -0
  267. package/dist/types/markers/labels/box.js +1 -0
  268. package/dist/types/markers/labels/common.d.ts +15 -0
  269. package/dist/types/markers/labels/common.js +1 -0
  270. package/dist/types/markers/labels/path.d.ts +52 -0
  271. package/dist/types/markers/labels/path.js +1 -0
  272. package/dist/types/markers/labels/point.d.ts +40 -0
  273. package/dist/types/markers/labels/point.js +1 -0
  274. package/dist/types/markers/traits.d.ts +10 -0
  275. package/dist/types/phases/context/phase.d.ts +7 -0
  276. package/dist/types/phases/context/phase.js +1 -0
  277. package/dist/types/phases/data/phase.d.ts +2 -2
  278. package/dist/types/phases/hover/phase.d.ts +10 -7
  279. package/dist/types/phases/index.d.ts +2 -1
  280. package/dist/types/phases/kind.d.ts +11 -8
  281. package/dist/types/phases/mapping/phase.d.ts +2 -2
  282. package/dist/types/phases/markers/phase.d.ts +3 -10
  283. package/dist/types/phases/scales/phase.d.ts +4 -4
  284. package/dist/types/phases/stage.d.ts +3 -3
  285. package/dist/types/phases/state.d.ts +1 -1
  286. package/dist/types/phases/statistics/phase.d.ts +8 -3
  287. package/dist/types/phases/styles/phase.d.ts +18 -5
  288. package/dist/types/phases/transforms/phase.d.ts +4 -2
  289. package/dist/types/plots/constants.d.ts +3 -17
  290. package/dist/types/plots/correlation/heatmap/props.d.ts +3 -2
  291. package/dist/types/plots/correlation/heatmap/state.d.ts +2 -2
  292. package/dist/types/plots/correlation/scatter/props.d.ts +3 -2
  293. package/dist/types/plots/correlation/scatter/state.d.ts +2 -2
  294. package/dist/types/plots/distribution/box/props.d.ts +28 -2
  295. package/dist/types/plots/distribution/box/state.d.ts +6 -17
  296. package/dist/types/plots/distribution/density/props.d.ts +2 -1
  297. package/dist/types/plots/distribution/density/state.d.ts +2 -2
  298. package/dist/types/plots/distribution/histogram/props.d.ts +16 -2
  299. package/dist/types/plots/distribution/histogram/state.d.ts +2 -2
  300. package/dist/types/plots/distribution/pyramid/props.d.ts +3 -2
  301. package/dist/types/plots/distribution/pyramid/state.d.ts +2 -2
  302. package/dist/types/plots/distribution/violin/props.d.ts +6 -2
  303. package/dist/types/plots/distribution/violin/state.d.ts +2 -2
  304. package/dist/types/plots/evolution/area/props.d.ts +3 -2
  305. package/dist/types/plots/evolution/area/state.d.ts +2 -2
  306. package/dist/types/plots/evolution/line/props.d.ts +3 -2
  307. package/dist/types/plots/evolution/line/state.d.ts +2 -2
  308. package/dist/types/plots/evolution/slope/state.d.ts +2 -2
  309. package/dist/types/plots/evolution/sparkline/state.d.ts +2 -2
  310. package/dist/types/plots/generic/props.d.ts +16 -0
  311. package/dist/types/plots/generic/props.js +1 -0
  312. package/dist/types/plots/generic/state.d.ts +4 -0
  313. package/dist/types/plots/generic/state.js +1 -0
  314. package/dist/types/plots/map/geo/state.d.ts +1 -1
  315. package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +18 -6
  316. package/dist/types/plots/part-of-a-whole/treemap/state.d.ts +2 -2
  317. package/dist/types/plots/props.d.ts +3 -0
  318. package/dist/types/plots/ranking/bar/props.d.ts +3 -2
  319. package/dist/types/plots/ranking/bar/state.d.ts +2 -2
  320. package/dist/types/plots/ranking/bullet/state.d.ts +2 -2
  321. package/dist/types/plots/ranking/cleveland/props.d.ts +3 -2
  322. package/dist/types/plots/ranking/cleveland/state.d.ts +2 -2
  323. package/dist/types/plots/ranking/dumbbell/props.d.ts +3 -2
  324. package/dist/types/plots/ranking/dumbbell/state.d.ts +2 -2
  325. package/dist/types/plots/ranking/forest/props.d.ts +5 -2
  326. package/dist/types/plots/ranking/forest/state.d.ts +2 -2
  327. package/dist/types/plots/ranking/lollipop/props.d.ts +3 -2
  328. package/dist/types/plots/ranking/lollipop/state.d.ts +2 -2
  329. package/docs/architecture.md +9 -9
  330. package/docs/markers.md +36 -6
  331. package/docs/plots/evolution/line.md +1 -1
  332. package/docs/plots/evolution/slope.md +1 -1
  333. package/docs/plots/part-of-a-whole/treemap.md +36 -2
  334. package/docs/plots/ranking/bar.md +1 -0
  335. package/docs/plots/ranking/cleveland.md +1 -1
  336. package/docs/state.md +33 -0
  337. package/docs/styles-and-segments.md +2 -15
  338. package/docs/theming.md +2 -1
  339. package/docs/tooltip-and-hover.md +81 -3
  340. package/docs/value-labels.md +159 -0
  341. package/examples/BarValues.svelte +1 -1
  342. package/examples/LineDates.svelte +1 -1
  343. package/examples/ResponsiveLine.svelte +3 -1
  344. package/examples/TreemapHover.svelte +25 -0
  345. package/examples/ValueLabels.svelte +1 -1
  346. package/llms-full.txt +9 -7
  347. package/llms.txt +3 -1
  348. package/package.json +3 -1
  349. package/dist/markers/utils/BoxLabel.d.ts +0 -58
  350. package/dist/markers/utils/BoxLabel.js +0 -175
  351. package/dist/markers/utils/MarkerLabel.svelte +0 -33
  352. package/dist/markers/utils/MarkerLabel.svelte.d.ts +0 -10
  353. /package/dist/layout/plot/{Plot.svelte → AbstractPlot.svelte} +0 -0
@@ -4,7 +4,6 @@ import { GAP_KIND, GAP_VALUE, SERIES_ID_KEY } from '../../../phases/transforms/T
4
4
  import { seriesIdOf } from '../../../utils/grouping';
5
5
  import { resolveGapAreaStyle } from '../../utils/gaps';
6
6
  import { PlotAxes } from '../../../phases/data/PlotAxes';
7
- import { ValueLabels } from '../../../layout/styles/ValueLabels';
8
7
  const GAP_KINDS = ['start', 'middle', 'end'];
9
8
  /**
10
9
  * Where a bar plot's bars sit, read off the state its phases leave: each
@@ -46,8 +45,8 @@ export function buildBarGeometry(state, seriesPadding) {
46
45
  */
47
46
  export function buildHitAreas(state,
48
47
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
49
- hover, ctx) {
50
- const { categoryOf, sliceOf } = buildBarGeometry(state, ctx.cfg.bar.seriesPadding);
48
+ hover, env) {
49
+ const { categoryOf, sliceOf } = buildBarGeometry(state, env.cfg.bar.seriesPadding);
51
50
  const isHorizontal = state.axes?.isHorizontal ?? false;
52
51
  return hover.points.map(({ row, series }) => {
53
52
  const slice = series === undefined ? undefined : sliceOf(series);
@@ -57,7 +56,7 @@ hover, ctx) {
57
56
  isHorizontal,
58
57
  data: [row],
59
58
  category: categoryOf(row),
60
- hover: hover.active,
59
+ hover: hover.active && 'trigger',
61
60
  ...(slice
62
61
  ? isHorizontal
63
62
  ? { insetTop: slice.start, insetBottom: slice.end }
@@ -72,11 +71,11 @@ hover, ctx) {
72
71
  * whatever the "statistics" phase already put in `state.markers`, and its
73
72
  * value labels on top of everything.
74
73
  */
75
- export function buildMarks(state, ctx) {
74
+ export function buildMarks(state, env) {
76
75
  const { gapFillMaps, colorForSeries, processedData } = state;
77
76
  const isHorizontal = state.axes?.isHorizontal ?? false;
78
77
  const [categoryAxis, valueAxis] = isHorizontal ? ['y', 'x'] : ['x', 'y'];
79
- const geometry = buildBarGeometry(state, ctx.cfg.bar.seriesPadding);
78
+ const geometry = buildBarGeometry(state, env.cfg.bar.seriesPadding);
80
79
  const { channels } = processedData;
81
80
  const gapDefaults = getConfiguration().bar.gap;
82
81
  // Forwarded raw when the transforms left a plain channel (a field key keeps
@@ -89,21 +88,14 @@ export function buildMarks(state, ctx) {
89
88
  // which stays a field key whenever the plot has no transforms.
90
89
  const valueOf = (channel) => (geometry.stacked || channel === undefined ? top : channel);
91
90
  const gapValue = valueOf(channels[valueAxis]);
92
- // What each bar writes in itself: its value, anchored along the bar by `anchor` - past its tip
93
- // (`'outside'`), just inside it (`'start'`), at its base (`'end'`) or in the middle. A stacked bar's
94
- // label is always in the middle of its segment.
95
- const labels = state.valueLabels?.show ? state.valueLabels : undefined;
96
- const valueRead = ValueLabels.valueOf(state);
97
- const turns = !!labels && !geometry.stacked && ValueLabels.followsSign(labels.anchor);
98
- const labelAnchor = (negative) => ValueLabels.boxAnchor(labels?.anchor ?? 'outside', {
99
- isHorizontal,
100
- negative,
101
- stacked: geometry.stacked
102
- });
103
- const labelFor = (name, slice, negative) => labels && {
104
- ...labels.shapeLabel(ctx, (d) => labels.format(Number(valueRead(d)), name, d), {
91
+ // What each bar writes about itself: its value, in the layout of `styles.values` - by default past its tip, or
92
+ // in the middle of a stacked bar's segment.
93
+ const labels = state.valueLabels?.show && state.valueLabels.writes('value') ? state.valueLabels : undefined;
94
+ const labelFor = (name, slice) => labels && {
95
+ ...labels.label(env, (d) => labels.text(d), {
105
96
  fill: 'currentColor',
106
- ...labelAnchor(negative)
97
+ labelled: state.labelled,
98
+ seriesColor: () => colorForSeries(name)
107
99
  }),
108
100
  bandSlice: slice
109
101
  };
@@ -117,6 +109,7 @@ export function buildMarks(state, ctx) {
117
109
  isHorizontal,
118
110
  data,
119
111
  styles,
112
+ hover: 'style',
120
113
  ...(label ? { label } : {}),
121
114
  ...(isHorizontal
122
115
  ? { y: category, x1: from, x2: value }
@@ -138,7 +131,7 @@ export function buildMarks(state, ctx) {
138
131
  const name = group.series.name;
139
132
  const slice = geometry.sliceOf(name);
140
133
  const defaultColor = colorForSeries(name);
141
- const disabledFill = ctx.interaction?.fillFor(name);
134
+ const disabledFill = env.interaction?.fillFor(name);
142
135
  for (const seg of group.visualSegments) {
143
136
  const fill = disabledFill?.fill ?? seg.styles.fill ?? defaultColor;
144
137
  const styles = {
@@ -154,18 +147,9 @@ export function buildMarks(state, ctx) {
154
147
  };
155
148
  const real = seg.data.filter(isReal);
156
149
  const value = valueOf(group.series[valueAxis]);
157
- // A label past the tip turns with the sign of its value, so the bars below zero are a marker of their own.
158
- const parts = turns
159
- ? [false, true].map((negative) => ({
160
- negative,
161
- rows: real.filter((row) => Number(valueRead(row)) < 0 === negative)
162
- }))
163
- : [{ negative: false, rows: real }];
164
- for (const { negative, rows } of parts) {
165
- const marker = makeMarker(rows, slice, value, styles, labelFor(name, slice, negative));
166
- if (marker)
167
- segmentMarkers.push(marker);
168
- }
150
+ const marker = makeMarker(real, slice, value, styles, labelFor(name, slice));
151
+ if (marker)
152
+ segmentMarkers.push(marker);
169
153
  }
170
154
  const id = seriesIdOf(group.series);
171
155
  const fills = [...(gapFillMaps.get(id)?.values() ?? [])];
@@ -1,5 +1,5 @@
1
1
  <script lang="ts" generics="TData extends Record<string, unknown>">
2
- import Plot from '../../../layout/plot/Plot.svelte';
2
+ import AbstractPlot from '../../../layout/plot/AbstractPlot.svelte';
3
3
  import { buildBulletDefaults } from './defaults';
4
4
  import type { BulletPlotProps, BulletPlotCoreProps } from '../../../types/plots/ranking/bullet/props';
5
5
 
@@ -25,7 +25,7 @@
25
25
  }: BulletPlotProps<TData> = $props();
26
26
  </script>
27
27
 
28
- <Plot
28
+ <AbstractPlot
29
29
  core={core as BulletPlotCoreProps<TData>}
30
30
  defaults={buildBulletDefaults}
31
31
  bind:margins
@@ -1,4 +1,3 @@
1
- import Plot from '../../../layout/plot/Plot.svelte';
2
1
  import type { BulletPlotProps } from '../../../types/plots/ranking/bullet/props';
3
2
  declare function $$render<TData extends Record<string, unknown>>(): {
4
3
  props: BulletPlotProps<TData>;
@@ -1,8 +1,8 @@
1
1
  import type { AxisPlotDefaults } from '../../../types/phases';
2
- import type { BulletPlotState, BulletPlotCtx } from '../../../types/plots/ranking/bullet/state';
2
+ import type { BulletPlotState, BulletPlotEnv } from '../../../types/plots/ranking/bullet/state';
3
3
  /**
4
4
  * BulletPlot on the shared pipeline: a BarPlot whose bars are drawn thinner
5
5
  * over `ranges` - bands that grade the value - with a tick at each `target`.
6
6
  * Its value axis fits them along with the bars.
7
7
  */
8
- export declare function buildBulletDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<BulletPlotState<TData>, BulletPlotCtx>;
8
+ export declare function buildBulletDefaults<TData extends Record<string, unknown>>(): AxisPlotDefaults<BulletPlotState<TData>, BulletPlotEnv>;
@@ -1,3 +1,5 @@
1
+ import { ValueLabels } from '../../../layout/styles/ValueLabels';
2
+ import { RowNumbers } from '../../utils/RowNumbers';
1
3
  import { buildBarDefaults, fitValueDomain } from '../bar/defaults';
2
4
  import { buildMarks, buildReach } from './markers';
3
5
  /**
@@ -11,13 +13,31 @@ export function buildBulletDefaults() {
11
13
  ...bar,
12
14
  scales: {
13
15
  ...bar.scales,
14
- defaults: (_state, ctx) => ({
16
+ defaults: (_state, env) => ({
15
17
  category: {
16
- paddingInner: ctx.cfg.bullet.paddingInner,
17
- paddingOuter: ctx.cfg.bullet.paddingOuter
18
+ paddingInner: env.cfg.bullet.paddingInner,
19
+ paddingOuter: env.cfg.bullet.paddingOuter
18
20
  }
19
21
  }),
20
- fit: (state, ctx) => fitValueDomain(state, buildReach(state, ctx))
22
+ fit: (state, env) => fitValueDomain(state, buildReach(state, env))
23
+ },
24
+ // Each bar's target and range bounds, for its tooltip, hover and value labels to read.
25
+ context: (state) => ((row) => ({
26
+ target: RowNumbers.of(state.target, row),
27
+ ranges: (state.ranges ?? [])
28
+ .map((range) => RowNumbers.of(range, row))
29
+ .filter((bound) => bound !== undefined)
30
+ .sort((a, b) => a - b)
31
+ })),
32
+ styles: {
33
+ ...bar.styles,
34
+ values: {
35
+ ...bar.styles?.values,
36
+ parts: {
37
+ placements: (state) => ValueLabels.besideBand(state, ['target', 'ranges']),
38
+ default: ['value']
39
+ }
40
+ }
21
41
  },
22
42
  markers: { ...bar.markers, marks: buildMarks }
23
43
  };
@@ -1,10 +1,10 @@
1
1
  import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
2
- import type { BulletPlotState, BulletPlotCtx } from '../../../types/plots/ranking/bullet/state';
2
+ import type { BulletPlotState, BulletPlotEnv } from '../../../types/plots/ranking/bullet/state';
3
3
  /** Every value the axis has to reach beyond the bars. */
4
- export declare function buildReach<TData extends Record<string, unknown>>(state: BulletPlotState<TData>, ctx: BulletPlotCtx): number[];
4
+ export declare function buildReach<TData extends Record<string, unknown>>(state: BulletPlotState<TData>, env: BulletPlotEnv): number[];
5
5
  /**
6
6
  * BulletPlot's "markers" phase, back to front: a rule per range, the bars of a
7
7
  * bar plot - thinner, so the ranges show around them - and a tick at each
8
8
  * target.
9
9
  */
10
- export declare function buildMarks<TData extends Record<string, unknown>>(state: BulletPlotState<TData>, ctx: BulletPlotCtx): AxisBasedMarkersConfig[];
10
+ export declare function buildMarks<TData extends Record<string, unknown>>(state: BulletPlotState<TData>, env: BulletPlotEnv): AxisBasedMarkersConfig[];
@@ -1,9 +1,10 @@
1
+ import { ValueLabels } from '../../../layout/styles/ValueLabels';
1
2
  import { buildMarks as buildBarMarks, buildBarGeometry } from '../bar/markers';
2
3
  import { GAP_VALUE } from '../../../phases/transforms/TransformsPhase';
3
4
  import { RowNumbers } from '../../utils/RowNumbers';
4
5
  /** Each category's target and range bounds, read off the rows the bars draw. */
5
- function buildMeasures(state, ctx) {
6
- const geometry = buildBarGeometry(state, ctx.cfg.bar.seriesPadding);
6
+ function buildMeasures(state, env) {
7
+ const geometry = buildBarGeometry(state, env.cfg.bar.seriesPadding);
7
8
  return (state.processedData?.data ?? [])
8
9
  .filter((row) => row[GAP_VALUE] === undefined && geometry.spanOf(row) !== undefined)
9
10
  .map((row) => ({
@@ -16,8 +17,8 @@ function buildMeasures(state, ctx) {
16
17
  }));
17
18
  }
18
19
  /** Every value the axis has to reach beyond the bars. */
19
- export function buildReach(state, ctx) {
20
- return buildMeasures(state, ctx).flatMap(({ target, bounds }) => [
20
+ export function buildReach(state, env) {
21
+ return buildMeasures(state, env).flatMap(({ target, bounds }) => [
21
22
  ...(target === undefined ? [] : [target]),
22
23
  ...bounds
23
24
  ]);
@@ -27,8 +28,8 @@ export function buildReach(state, ctx) {
27
28
  * bar plot - thinner, so the ranges show around them - and a tick at each
28
29
  * target.
29
30
  */
30
- export function buildMarks(state, ctx) {
31
- const configured = ctx.cfg.bullet;
31
+ export function buildMarks(state, env) {
32
+ const configured = env.cfg.bullet;
32
33
  const own = (state.styles ?? {});
33
34
  const rangeColors = own.ranges?.colors ?? configured.rangeColors;
34
35
  const rangeWidth = own.ranges?.width ?? configured.rangeWidth;
@@ -38,8 +39,8 @@ export function buildMarks(state, ctx) {
38
39
  length: own.target?.length ?? configured.targetLength
39
40
  };
40
41
  const isHorizontal = state.axes?.isHorizontal ?? false;
41
- const baseline = buildBarGeometry(state, ctx.cfg.bar.seriesPadding).baseline;
42
- const measures = buildMeasures(state, ctx);
42
+ const baseline = buildBarGeometry(state, env.cfg.bar.seriesPadding).baseline;
43
+ const measures = buildMeasures(state, env);
43
44
  // Each bound is a band from the baseline, drawn widest first so the narrower ones lie over it.
44
45
  const rows = measures.flatMap(({ category, bounds }) => bounds
45
46
  .map((bound, rank) => ({
@@ -63,7 +64,7 @@ export function buildMarks(state, ctx) {
63
64
  }
64
65
  ];
65
66
  // The bars narrowed to a thickness of their own, centered in their band.
66
- const bars = buildBarMarks(state, ctx).map((marker) => marker.type === 'bar' && marker.role === 'segment'
67
+ const bars = buildBarMarks(state, env).map((marker) => marker.type === 'bar' && marker.role === 'segment'
67
68
  ? {
68
69
  ...marker,
69
70
  thickness: own.bar?.thickness ?? configured.barThickness
@@ -85,5 +86,10 @@ export function buildMarks(state, ctx) {
85
86
  }
86
87
  }
87
88
  ];
88
- return [...ranges, ...bars, ...ticks];
89
+ // Its other parts `styles.values` labels - the target, the range bounds - beside the band; the bars write the value.
90
+ const geometry = buildBarGeometry(state, env.cfg.bar.seriesPadding);
91
+ const labels = state.valueLabels?.show
92
+ ? state.valueLabels.partMarkers(env, (state.processedData?.data ?? []).filter((row) => row[GAP_VALUE] === undefined && geometry.spanOf(row) !== undefined), ValueLabels.bandPoint(state, geometry.categoryOf), { skip: ['value'] })
93
+ : [];
94
+ return [...ranges, ...bars, ...ticks, ...labels];
89
95
  }
@@ -1,6 +1,6 @@
1
1
  import { ValueLabels } from '../../../layout/styles/ValueLabels';
2
- import type { ClevelandPlotState, ClevelandPlotCtx, ClevelandOptions } from '../../../types/plots/ranking/cleveland/state';
3
- import type { AxisBasedMarkersConfig, TextMarkerConfig } from '../../../types/markers/common';
2
+ import type { ClevelandPlotState, ClevelandPlotEnv, ClevelandOptions } from '../../../types/plots/ranking/cleveland/state';
3
+ import type { AxisBasedMarkersConfig } from '../../../types/markers/common';
4
4
  import type { EdgeBox } from '../../../types/layout/box';
5
5
  /**
6
6
  * The marks of the Cleveland family of plots, which differ only by their
@@ -8,7 +8,7 @@ import type { EdgeBox } from '../../../types/layout/box';
8
8
  * highest value (from the baseline, for a lollipop) with a dot at each value.
9
9
  * A category with one dot gets a stem in that dot's series color, restyled by
10
10
  * the segment its dot belongs to; a category with several gets one neutral
11
- * connector. The "markers" phase takes its `marks`, `valueLabels` and `reach`.
11
+ * connector. The "markers" phase takes its `marks` and `reach`.
12
12
  */
13
13
  export declare class ClevelandMarkers {
14
14
  #private;
@@ -16,14 +16,7 @@ export declare class ClevelandMarkers {
16
16
  /** Forgets what was warned about; for tests. */
17
17
  static resetWarnings(): void;
18
18
  /** The plot's connectors, then its dots, which draw on top of them. */
19
- marks: <TData extends Record<string, unknown>>(state: ClevelandPlotState<TData>, ctx: ClevelandPlotCtx) => AxisBasedMarkersConfig[];
20
- /**
21
- * The value labels of the dots `styles.values.of` picks, one `'text'` marker
22
- * per place a dot can hold in its range - past the top end (above, or right
23
- * of it), past the bottom end (below, or left of it) and, for the dots
24
- * between, beside it - and per series, when they take their series' color.
25
- */
26
- valueLabels: <TData extends Record<string, unknown>>(labels: ValueLabels, state: ClevelandPlotState<TData>, ctx: ClevelandPlotCtx) => TextMarkerConfig[];
19
+ marks: <TData extends Record<string, unknown>>(state: ClevelandPlotState<TData>, env: ClevelandPlotEnv) => AxisBasedMarkersConfig[];
27
20
  /**
28
21
  * Room for the labels past the dots at the end of the value axis, so the
29
22
  * farthest one fits inside the figure instead of crossing its edge. Only the
@@ -1,3 +1,4 @@
1
+ import { isGapValue } from '../../utils/gaps';
1
2
  import { PlotAxes } from '../../../phases/data/PlotAxes';
2
3
  import { ProcessedPositions } from '../../../phases/transforms/ProcessedPositions';
3
4
  import { SERIES_KEY } from '../../../phases/transforms/TransformsPhase';
@@ -5,6 +6,7 @@ import { ValueLabels } from '../../../layout/styles/ValueLabels';
5
6
  import { ClevelandRanges } from './ClevelandRanges';
6
7
  import { ClevelandConnector } from './ClevelandConnector';
7
8
  import { BasicStyles } from '../../../layout/styles/BasicStyles';
9
+ import { PointLayout } from '../../../markers/labels/layouts/PointLayout';
8
10
  /** The messages already warned about, so a plot that redraws warns once. */
9
11
  const warned = new Set();
10
12
  /**
@@ -13,7 +15,7 @@ const warned = new Set();
13
15
  * highest value (from the baseline, for a lollipop) with a dot at each value.
14
16
  * A category with one dot gets a stem in that dot's series color, restyled by
15
17
  * the segment its dot belongs to; a category with several gets one neutral
16
- * connector. The "markers" phase takes its `marks`, `valueLabels` and `reach`.
18
+ * connector. The "markers" phase takes its `marks` and `reach`.
17
19
  */
18
20
  export class ClevelandMarkers {
19
21
  #options;
@@ -25,8 +27,8 @@ export class ClevelandMarkers {
25
27
  warned.clear();
26
28
  }
27
29
  /** The plot's connectors, then its dots, which draw on top of them. */
28
- marks = (state, ctx) => {
29
- const { cfg, interaction } = ctx;
30
+ marks = (state, env) => {
31
+ const { cfg, interaction } = env;
30
32
  const style = cfg[this.#options.config];
31
33
  const { isHorizontal } = ClevelandMarkers.#geometry(state);
32
34
  const ranges = ClevelandRanges.of(state, this.#options.fromBaseline ?? false, ClevelandConnector.ends(state), this.#options.interval ?? false);
@@ -187,6 +189,7 @@ export class ClevelandMarkers {
187
189
  type: 'dot',
188
190
  series: name,
189
191
  data: segment.data,
192
+ hover: 'style',
190
193
  ...(isHorizontal ? { x: value, y: category } : { x: category, y: value }),
191
194
  r,
192
195
  styles: {
@@ -201,12 +204,24 @@ export class ClevelandMarkers {
201
204
  };
202
205
  });
203
206
  });
207
+ const values = state.valueLabels?.show ? state.valueLabels : undefined;
208
+ const labels = values?.writes('value') ? this.#valueLabels(values, state, env) : undefined;
209
+ // The other parts of a row it labels - an interval's ends - beside them; the dots write the value.
210
+ const processed = state.processedData;
211
+ const position = ProcessedPositions.of(processed, PlotAxes.valueOf(state));
212
+ const parts = values
213
+ ? values.partMarkers(env, processed.data.filter((row) => !isGapValue(position[PlotAxes.valueOf(state)](row))), ValueLabels.bandPoint(state, position[PlotAxes.categoryOf(state)]), {
214
+ skip: ['value'],
215
+ seriesColor: (row) => state.colorForSeries(String(row[SERIES_KEY]))
216
+ })
217
+ : [];
204
218
  return [
205
219
  ...rules,
206
220
  ...caps,
207
221
  ...arrows,
208
- ...dots,
209
- ...this.#connectorLabels(state, ctx, connector, looks, isHorizontal)
222
+ ...ValueLabels.onMarkers(dots, 'dot', labels),
223
+ ...this.#connectorLabels(state, env, connector, looks, isHorizontal),
224
+ ...parts
210
225
  ];
211
226
  };
212
227
  /** The dash, cap and join a connector is drawn with, leaving out what is not set. */
@@ -243,7 +258,7 @@ export class ClevelandMarkers {
243
258
  }));
244
259
  }
245
260
  /** The label on each connector, when `styles.connector.label` asks for one: written at its middle, beside it or on it. */
246
- #connectorLabels(state, ctx, connector, looks, isHorizontal) {
261
+ #connectorLabels(state, env, connector, looks, isHorizontal) {
247
262
  const label = connector.label;
248
263
  if (!label)
249
264
  return [];
@@ -255,7 +270,7 @@ export class ClevelandMarkers {
255
270
  return [];
256
271
  const font = label.fontStyle;
257
272
  // Beside a connector: clear of half its thickest, and a few px.
258
- const clear = Math.max(...data.map((row) => Number(row.strokeWidth))) / 2 + ctx.cfg.connector.labelGap;
273
+ const clear = Math.max(...data.map((row) => Number(row.strokeWidth))) / 2 + env.cfg.connector.labelGap;
259
274
  const inside = label.anchor === 'middle';
260
275
  const at = inside
261
276
  ? { dx: 0, dy: 0, textAnchor: 'middle', lineAnchor: 'middle' }
@@ -271,7 +286,7 @@ export class ClevelandMarkers {
271
286
  styles: {
272
287
  ...font,
273
288
  fill: font?.fill ?? 'currentColor',
274
- fontSize: font?.fontSize ?? ctx.cfg.connector.labelFontSize,
289
+ fontSize: font?.fontSize ?? env.cfg.connector.labelFontSize,
275
290
  dx: font?.dx ?? at.dx,
276
291
  dy: font?.dy ?? at.dy,
277
292
  textAnchor: font?.textAnchor && font.textAnchor !== 'outside' ? font.textAnchor : at.textAnchor,
@@ -281,68 +296,72 @@ export class ClevelandMarkers {
281
296
  ];
282
297
  }
283
298
  /**
284
- * The value labels of the dots `styles.values.of` picks, one `'text'` marker
285
- * per place a dot can hold in its range - past the top end (above, or right
286
- * of it), past the bottom end (below, or left of it) and, for the dots
287
- * between, beside it - and per series, when they take their series' color.
299
+ * The value labels of the dots `styles.values` picks, placed by where each dot sits in its range - or on the
300
+ * `side` the author asks of them all, or around each dot's rim (`'path'`).
288
301
  */
289
- valueLabels = (labels, state, ctx) => {
302
+ #valueLabels(labels, state, env) {
290
303
  if (!state.processedData?.data.length)
291
304
  return [];
292
305
  const { isHorizontal } = ClevelandMarkers.#geometry(state);
293
- const { category, value } = ClevelandMarkers.#channels(state);
294
306
  const { font, format } = labels;
295
307
  const read = ValueLabels.valueOf(state);
296
308
  const valueOf = ProcessedPositions.of(state.processedData, PlotAxes.valueOf(state))[PlotAxes.valueOf(state)];
297
- const gap = labels.offset(isHorizontal ? 'x' : 'y', ctx.cfg[this.#options.config].labelGap);
309
+ const gap = labels.offset(env.cfg[this.#options.config].labelGap);
298
310
  const nameOf = (d) => String(d[SERIES_KEY]);
299
311
  const picked = this.#picked(state);
300
- // Where a label sits from its dot, by role: along the range (past an end) or across it (between).
301
- const placement = {
302
- max: isHorizontal
303
- ? { dx: gap, dy: 0, textAnchor: 'start', lineAnchor: 'middle' }
304
- : { dx: 0, dy: -gap, textAnchor: 'middle', lineAnchor: 'bottom' },
305
- min: isHorizontal
306
- ? { dx: -gap, dy: 0, textAnchor: 'end', lineAnchor: 'middle' }
307
- : { dx: 0, dy: gap, textAnchor: 'middle', lineAnchor: 'top' },
308
- between: isHorizontal
309
- ? { dx: 0, dy: -gap, textAnchor: 'middle', lineAnchor: 'bottom' }
310
- : { dx: gap, dy: 0, textAnchor: 'start', lineAnchor: 'middle' }
311
- };
312
- // What fills the labels of a series: the one fill all share, its own color, or the axis'.
313
- const fillOf = (series) => labels.fill ??
314
- (labels.color === 'series' ? state.colorForSeries(series) : undefined) ??
315
- 'currentColor';
316
- const names = labels.color === 'series' && !labels.fill
317
- ? (state.resolvedSeries ?? []).map((s) => s.name)
318
- : [''];
319
- return ['max', 'min', 'between'].flatMap((role) => names.flatMap((name) => {
320
- const data = picked
321
- .filter(({ entry, dot }) => ClevelandRanges.roleOf(entry, dot.value) === role &&
322
- (name === '' || dot.series === name))
323
- .map(({ dot }) => dot.row);
324
- if (data.length === 0)
312
+ // Along the range past an end, across it between them.
313
+ const side = labels.placement.side;
314
+ const own = side && { ...PointLayout.sideOf(side, gap) };
315
+ const placement = own
316
+ ? { max: own, min: own, between: own }
317
+ : {
318
+ max: isHorizontal
319
+ ? { dx: gap, dy: 0, textAnchor: 'start', lineAnchor: 'middle' }
320
+ : { dx: 0, dy: -gap, textAnchor: 'middle', lineAnchor: 'bottom' },
321
+ min: isHorizontal
322
+ ? { dx: -gap, dy: 0, textAnchor: 'end', lineAnchor: 'middle' }
323
+ : { dx: 0, dy: gap, textAnchor: 'middle', lineAnchor: 'top' },
324
+ between: isHorizontal
325
+ ? { dx: 0, dy: -gap, textAnchor: 'middle', lineAnchor: 'bottom' }
326
+ : { dx: gap, dy: 0, textAnchor: 'start', lineAnchor: 'middle' }
327
+ };
328
+ const fill = labels.fill ??
329
+ (labels.color === 'series'
330
+ ? (d) => state.colorForSeries(nameOf(d))
331
+ : 'currentColor');
332
+ if (labels.layout === 'path') {
333
+ const text = (d) => format(Number(read(d) ?? valueOf(d)), d, nameOf(d));
334
+ const rim = labels.label(env, text, { fontSize: 12 });
335
+ return [{ ...rim, styles: { ...rim.styles, fill: font?.fill ?? fill } }];
336
+ }
337
+ const { styles: shared, ...hooks } = labels.hooks(env);
338
+ return ['max', 'min', 'between'].flatMap((role) => {
339
+ const rows = new Set(picked
340
+ .filter(({ entry, dot }) => ClevelandRanges.roleOf(entry, dot.value) === role)
341
+ .map(({ dot }) => dot.row));
342
+ if (rows.size === 0)
325
343
  return [];
326
344
  const at = placement[role];
327
345
  return [
328
346
  {
329
- type: 'text',
330
- data,
331
- ...(isHorizontal ? { x: value, y: category } : { x: category, y: value }),
332
- text: (d) => format(Number(read(d) ?? valueOf(d)), nameOf(d), d),
347
+ ...hooks,
348
+ layout: 'point',
349
+ select: (row) => rows.has(row),
350
+ text: (d) => format(Number(read(d) ?? valueOf(d)), d, nameOf(d)),
333
351
  styles: {
352
+ ...shared,
334
353
  ...font,
335
- fill: fillOf(name),
354
+ fill,
336
355
  fontSize: font?.fontSize ?? 12,
337
- dx: font?.dx ?? at.dx,
338
- dy: font?.dy ?? at.dy,
339
- textAnchor: labels.textAnchor ?? at.textAnchor,
340
- lineAnchor: font?.lineAnchor ?? at.lineAnchor
356
+ dx: at.dx,
357
+ dy: at.dy,
358
+ textAnchor: at.textAnchor,
359
+ lineAnchor: at.lineAnchor
341
360
  }
342
361
  }
343
362
  ];
344
- }));
345
- };
363
+ });
364
+ }
346
365
  /**
347
366
  * Room for the labels past the dots at the end of the value axis, so the
348
367
  * farthest one fits inside the figure instead of crossing its edge. Only the
@@ -354,11 +373,11 @@ export class ClevelandMarkers {
354
373
  if (top.length === 0)
355
374
  return [];
356
375
  if (!state.axes?.isHorizontal) {
357
- const at = { y: -labels.offset('y', gap) };
376
+ const at = { y: -labels.offset(gap) };
358
377
  return [labels.edgeBox('0', { x: 'middle', y: 'before' }, at, ['top'])];
359
378
  }
360
- const at = { x: labels.offset('x', gap) };
361
- const texts = new Set(top.map(({ dot }) => labels.format(dot.value, dot.series, dot.row)));
379
+ const at = { x: labels.offset(gap) };
380
+ const texts = new Set(top.map(({ dot }) => labels.format(dot.value, dot.row, dot.series)));
362
381
  return [...texts].map((text) => labels.edgeBox(text, { x: 'after', y: 'middle' }, at, ['right']));
363
382
  };
364
383
  /**
@@ -1,5 +1,5 @@
1
1
  <script lang="ts" generics="TData extends Record<string, unknown>">
2
- import Plot from '../../../layout/plot/Plot.svelte';
2
+ import AbstractPlot from '../../../layout/plot/AbstractPlot.svelte';
3
3
  import { buildClevelandDefaults } from './defaults';
4
4
  import type {
5
5
  ClevelandPlotProps,
@@ -28,7 +28,7 @@
28
28
  }: ClevelandPlotProps<TData> = $props();
29
29
  </script>
30
30
 
31
- <Plot
31
+ <AbstractPlot
32
32
  core={core as ClevelandPlotCoreProps<TData>}
33
33
  defaults={buildClevelandDefaults}
34
34
  bind:margins
@@ -1,4 +1,3 @@
1
- import Plot from '../../../layout/plot/Plot.svelte';
2
1
  import type { ClevelandPlotProps } from '../../../types/plots/ranking/cleveland/props';
3
2
  declare function $$render<TData extends Record<string, unknown>>(): {
4
3
  props: ClevelandPlotProps<TData>;
@@ -1,5 +1,5 @@
1
1
  import type { AxisPlotDefaults } from '../../../types/phases';
2
- import type { ClevelandOptions, ClevelandPlotState, ClevelandPlotCtx } from '../../../types/plots/ranking/cleveland/state';
2
+ import type { ClevelandOptions, ClevelandPlotState, ClevelandPlotEnv } from '../../../types/plots/ranking/cleveland/state';
3
3
  /**
4
4
  * ClevelandPlot on the shared pipeline, and the base of its wrappers: per
5
5
  * category along one category axis - `x`, or `y` for sideways rows, as the
@@ -10,4 +10,4 @@ import type { ClevelandOptions, ClevelandPlotState, ClevelandPlotCtx } from '../
10
10
  * what it checks about the series before drawing. Its plot defaults to hover
11
11
  * along the category axis.
12
12
  */
13
- export declare function buildClevelandDefaults<TData extends Record<string, unknown>>(options?: ClevelandOptions): AxisPlotDefaults<ClevelandPlotState<TData>, ClevelandPlotCtx>;
13
+ export declare function buildClevelandDefaults<TData extends Record<string, unknown>>(options?: ClevelandOptions): AxisPlotDefaults<ClevelandPlotState<TData>, ClevelandPlotEnv>;
@@ -1,4 +1,7 @@
1
+ import { ValueLabels } from '../../../layout/styles/ValueLabels';
2
+ import { RowNumbers } from '../../utils/RowNumbers';
1
3
  import { ClevelandMarkers } from './ClevelandMarkers';
4
+ import { HoverDefaults } from '../../../layout/hover/HoverDefaults';
2
5
  import { ClevelandRanges } from './ClevelandRanges';
3
6
  import { NiceTicks } from '../../../layout/scales/NiceTicks';
4
7
  import { PlotAxes } from '../../../phases/data/PlotAxes';
@@ -53,16 +56,47 @@ export function buildClevelandDefaults(options = { name: 'ClevelandPlot', config
53
56
  fit: options.interval
54
57
  ? (state) => fitInterval(state, options.fromBaseline ?? false)
55
58
  : undefined,
56
- defaults: (_state, ctx) => ({
59
+ defaults: (_state, env) => ({
57
60
  category: {
58
- paddingInner: ctx.cfg[options.config].paddingInner,
59
- paddingOuter: ctx.cfg[options.config].paddingOuter
61
+ paddingInner: env.cfg[options.config].paddingInner,
62
+ paddingOuter: env.cfg[options.config].paddingOuter
60
63
  }
61
64
  })
62
65
  },
63
66
  // A dot is labelled by what its category's dots say: the first, the highest... of each.
64
67
  transforms: { labels: { group: 'category', skip: ClevelandRanges.skipGaps } },
65
- styles: { values: { reach: markers.reach } },
66
- markers: { marks: markers.marks, valueLabels: markers.valueLabels }
68
+ // An interval's ends, for its tooltip, hover and value labels to read.
69
+ context: options.interval
70
+ ? (state) => {
71
+ const valueOf = ValueLabels.valueOf(state);
72
+ return ((row) => {
73
+ const [lower, upper] = RowNumbers.interval(state, row, Number(valueOf(row)));
74
+ return { lower, upper };
75
+ });
76
+ }
77
+ : undefined,
78
+ styles: {
79
+ values: {
80
+ layout: 'point',
81
+ layouts: { path: { side: 'outside' } },
82
+ // An interval's ends sit past it, each on its own side.
83
+ parts: options.interval
84
+ ? {
85
+ placements: (state) => {
86
+ const sideways = state.axes?.isHorizontal;
87
+ return {
88
+ lower: { side: sideways ? 'before' : 'below' },
89
+ upper: { side: sideways ? 'after' : 'above' }
90
+ };
91
+ },
92
+ default: ['value']
93
+ }
94
+ : undefined,
95
+ reach: (labels, state) => (labels.layout === 'point' ? markers.reach(labels, state) : [])
96
+ }
97
+ },
98
+ markers: { marks: markers.marks },
99
+ // A rule along the value axis at the hovered dot, and a dot and a label on each one of its category.
100
+ hover: { marker: (state) => HoverDefaults.valueRule(PlotAxes.valueOf(state)) }
67
101
  };
68
102
  }