@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
@@ -0,0 +1,86 @@
1
+ const ELLIPSIS = '…';
2
+ /**
3
+ * How a label that may be too big for its box is written: a smaller size first; failing that the text cut short
4
+ * with an ellipsis on its last line, at the smallest size; failing that its `fallback`; failing that nothing.
5
+ */
6
+ export class TextFit {
7
+ static fit(options) {
8
+ const whole = TextFit.#shrunk(options.text, options);
9
+ if (whole)
10
+ return whole;
11
+ const size = options.minFontSize;
12
+ const lines = TextFit.wrap(options.text, TextFit.#room(options, size), true, options.minLetters, (t) => options.measure(t, size));
13
+ if (lines)
14
+ return { text: lines.join('\n'), fontSize: size };
15
+ return options.fallback === undefined ? undefined : TextFit.#shrunk(options.fallback, options);
16
+ }
17
+ /** `text` as it is, at the biggest size that holds it all: no cut, or `undefined` at none. */
18
+ static #shrunk(text, options) {
19
+ for (let size = options.fontSize; size >= options.minFontSize; size--) {
20
+ const lines = TextFit.wrap(text, TextFit.#room(options, size), false, options.minLetters, (t) => options.measure(t, size));
21
+ if (lines)
22
+ return { text: lines.join('\n'), fontSize: size };
23
+ }
24
+ return undefined;
25
+ }
26
+ /** How wide the lines are, and how many there are, at `size`. */
27
+ static #room(options, size) {
28
+ return {
29
+ width: options.width,
30
+ lines: Math.floor(options.height / (size * options.lineHeight))
31
+ };
32
+ }
33
+ /**
34
+ * `text` on at most `room.lines` lines of `room.width`: whole words per line, a new line after each newline. With `cut`,
35
+ * what does not fit is cut short - the rest of the text on the last line, or a word wider than any line - with an
36
+ * ellipsis; without it, a text that does not fit comes to `undefined`, and so does one whose first line shows
37
+ * under `minLetters` letters.
38
+ */
39
+ static wrap(text, room, cut, minLetters, measure) {
40
+ if (room.lines < 1)
41
+ return undefined;
42
+ const all = [];
43
+ let overlong = false;
44
+ for (const paragraph of text.split('\n')) {
45
+ let line = '';
46
+ for (const word of paragraph.split(/ +/).filter(Boolean)) {
47
+ const next = line ? `${line} ${word}` : word;
48
+ if (measure(next) <= room.width) {
49
+ line = next;
50
+ continue;
51
+ }
52
+ if (line)
53
+ all.push(line);
54
+ // A word wider than a line goes on one of its own.
55
+ if (measure(word) > room.width) {
56
+ overlong = true;
57
+ all.push(word);
58
+ line = '';
59
+ }
60
+ else {
61
+ line = word;
62
+ }
63
+ }
64
+ if (line)
65
+ all.push(line);
66
+ }
67
+ if (!cut)
68
+ return !overlong && all.length <= room.lines ? all : undefined;
69
+ const lines = all.slice(0, room.lines);
70
+ // The rest of the text goes on the last line, to be cut short there.
71
+ if (all.length > room.lines)
72
+ lines[room.lines - 1] = all.slice(room.lines - 1).join(' ');
73
+ const written = lines.map((line) => TextFit.cut(line, room.width, measure));
74
+ const first = written[0]?.replace(ELLIPSIS, '').replace(/\s/g, '') ?? '';
75
+ return first.length >= minLetters ? written : undefined;
76
+ }
77
+ /** `text` as it fits `width`: as it is, or cut short with an ellipsis. */
78
+ static cut(text, width, measure) {
79
+ if (measure(text) <= width)
80
+ return text;
81
+ let end = text.length;
82
+ while (end > 0 && measure(`${text.slice(0, end).trimEnd()}${ELLIPSIS}`) > width)
83
+ end--;
84
+ return end > 0 ? `${text.slice(0, end).trimEnd()}${ELLIPSIS}` : '';
85
+ }
86
+ }
@@ -1,4 +1,6 @@
1
1
  <script lang="ts" generics="TData = Record<string, unknown>">
2
+ import { RowStyle } from '../utils/RowStyle';
3
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
4
  import { Text } from 'svelteplot';
3
5
  import { usePlot } from '../../layout/plot/usePlot';
4
6
  import { getConfiguration } from '../../configuration/config.svelte';
@@ -6,10 +8,13 @@
6
8
  import { RowOffset } from '../utils/RowOffset';
7
9
  import RowOffsetMarks from '../utils/RowOffsetMarks.svelte';
8
10
  import { Declutter } from './Declutter';
11
+ import { SvelteMap } from 'svelte/reactivity';
12
+ import { TextFit, type FittedText } from './TextFit';
9
13
  import { NumberFormat } from '../../utils/NumberFormat';
10
14
  import { PlotMargins } from '../../layout/margins/PlotMargins.svelte';
11
15
  import { Box } from '../../layout/margins/Box';
12
16
  import type { TextMarkerConfig } from '../../types/markers/common';
17
+ import type { BoxChannels, BoxSizer } from '../utils/BoxLabel';
13
18
  import type { TextAnchor } from '../../types/plots/constants';
14
19
 
15
20
  /**
@@ -20,7 +25,8 @@
20
25
  * draws one label per row, inside the plot's content box. With
21
26
  * `fitMargins`, the plot's margins grow until the labels fit.
22
27
  */
23
- const { marker }: { marker: TextMarkerConfig } = $props();
28
+ const { marker, box }: { marker: TextMarkerConfig; box?: BoxChannels | BoxSizer } = $props();
29
+ const events = MarkerEvents.use(() => marker);
24
30
 
25
31
  // A text's anchors as the side of its point it sits on, and back.
26
32
  const TEXT_SIDES = { start: 'after', middle: 'middle', end: 'before' } as const;
@@ -47,15 +53,16 @@
47
53
  data.length > 0 ? data : placedByRows(x) || placedByRows(y) ? [] : [{} as TData]
48
54
  );
49
55
  // Per-row accessors give literal values; an empty one takes the flat default.
50
- const flatFill = $derived(styles?.fill ?? 'currentColor');
51
56
  const fill = $derived.by(() => {
52
- const own = marker.fill;
53
- if (typeof own !== 'function') return own ?? flatFill;
54
- return { value: (d: TData) => own(d) ?? flatFill, scale: null };
57
+ const own = styles?.fill;
58
+ if (typeof own !== 'function') return RowStyle.of(own, displayData) ?? 'currentColor';
59
+ return { value: (d: TData) => own(d) ?? 'currentColor', scale: null };
55
60
  });
56
61
  const fillOpacity = $derived.by(() => {
57
- const own = marker.fillOpacity;
58
- return typeof own === 'function' ? { value: (d: TData) => own(d) ?? 1, scale: null } : own;
62
+ const own = styles?.fillOpacity;
63
+ return typeof own === 'function'
64
+ ? { value: (d: TData) => own(d) ?? 1, scale: null }
65
+ : RowStyle.opacity(own);
59
66
  });
60
67
  const fontSize = $derived(styles?.fontSize ?? 12);
61
68
  const fontWeight = $derived(styles?.fontWeight ?? 'normal');
@@ -97,11 +104,7 @@
97
104
  };
98
105
  });
99
106
  const perRow = $derived(
100
- !!declutter ||
101
- !!marker.edgeAware ||
102
- !!marker.onPointerEnter ||
103
- !!marker.onPointerLeave ||
104
- typeof marker.textAnchor === 'function'
107
+ !!declutter || !!marker.edgeAware || events.any || typeof marker.textAnchor === 'function'
105
108
  );
106
109
  const dir = $derived(Math.sign(dx) || 1);
107
110
 
@@ -128,9 +131,101 @@
128
131
  return typeof value === 'number' ? numberText(value) : String(value ?? '');
129
132
  }
130
133
 
134
+ /** The pixel size of the box a row's label is fitted to - from the edges it names, or measured by the shape it labels. */
135
+ const boxSizeOf = $derived.by(() => {
136
+ const fit = marker.fit === true ? {} : marker.fit;
137
+ if (!fit) return undefined;
138
+ const own = typeof box === 'function' ? undefined : box;
139
+ const [x1, x2, y1, y2] = [
140
+ fit.x1 ?? own?.x1,
141
+ fit.x2 ?? own?.x2,
142
+ fit.y1 ?? own?.y1,
143
+ fit.y2 ?? own?.y2
144
+ ];
145
+ const xScale = plot.scales.x?.fn;
146
+ const yScale = plot.scales.y?.fn;
147
+ if (![x1, x2, y1, y2].includes(undefined)) {
148
+ if (!xScale || !yScale) return undefined;
149
+ const [left, right, top, bottom] = [x1, x2, y1, y2].map(channel);
150
+ const span = (
151
+ scale: typeof xScale,
152
+ from: (d: TData) => unknown,
153
+ to: (d: TData) => unknown,
154
+ d: TData
155
+ ) => Math.abs(Number(scale(to(d) as never)) - Number(scale(from(d) as never)));
156
+ return (d: TData) => ({
157
+ width: span(xScale, left, right, d),
158
+ height: span(yScale, top, bottom, d)
159
+ });
160
+ }
161
+ return typeof box === 'function' ? (d: TData) => box(d, plot.scales as never) : undefined;
162
+ });
163
+
164
+ /**
165
+ * What each label is written as and at, fitted to its box (`fit`), less the padding. A label with no room is left
166
+ * out, with `undefined`; one with no box to measure is written as it is.
167
+ */
168
+ const fitted = $derived.by(() => {
169
+ const fit = marker.fit === true ? {} : marker.fit;
170
+ if (!fit || !boxSizeOf) return undefined;
171
+ const padding = fit.padding ?? cfg.text.label.padding;
172
+ const measure = (text: string, size: number) => Box.ofText(text, size, cfg).width;
173
+ const fallback = fit.fallback;
174
+ const fallbackOf = (d: TData) => {
175
+ // As `text` is: a function's result, a field of the row, else the text itself.
176
+ const value =
177
+ typeof fallback === 'function'
178
+ ? fallback(d)
179
+ : typeof fallback === 'string' && typeof d === 'object' && d !== null && fallback in d
180
+ ? (d as Record<string, unknown>)[fallback]
181
+ : fallback;
182
+ return typeof value === 'number' ? numberText(value) : String(value);
183
+ };
184
+ // Built whole inside this derivation and never changed after it, so it has nothing to react to.
185
+ // eslint-disable-next-line svelte/prefer-svelte-reactivity
186
+ const out = new Map<TData, FittedText | undefined>();
187
+ for (const d of displayData) {
188
+ const size = boxSizeOf(d);
189
+ out.set(
190
+ d,
191
+ size
192
+ ? TextFit.fit({
193
+ text: textOf(d),
194
+ fallback: fallback === undefined ? undefined : fallbackOf(d),
195
+ width: size.width - 2 * padding,
196
+ height: size.height - 2 * padding,
197
+ fontSize,
198
+ minFontSize: fit.minFontSize ?? cfg.text.label.minFontSize,
199
+ lineHeight: styles?.lineHeight ?? 1.2,
200
+ minLetters: fit.minLetters ?? cfg.text.label.minLetters,
201
+ measure
202
+ })
203
+ : { text: textOf(d), fontSize }
204
+ );
205
+ }
206
+ return out;
207
+ });
208
+ /** `rows` by the size their labels are written at: svelteplot takes one size for a mark, and a function of the row sets its scales off in a loop. */
209
+ function sizeGroups(rows: TData[]): { size: number; rows: TData[]; texts?: string[] }[] {
210
+ if (!fitted) return [{ size: fontSize, rows }];
211
+ const bySize = new SvelteMap<number, { rows: TData[]; texts: string[] }>();
212
+ for (const d of rows) {
213
+ const own = fitted.get(d);
214
+ const group = bySize.get(own?.fontSize ?? fontSize) ?? { rows: [], texts: [] };
215
+ group.rows.push(d);
216
+ group.texts.push(own?.text ?? '');
217
+ bySize.set(own?.fontSize ?? fontSize, group);
218
+ }
219
+ return [...bySize].map(([size, group]) => ({ size, ...group }));
220
+ }
221
+
222
+ /** The rows with room for a label. */
223
+ const shown = $derived(fitted ? displayData.filter((d) => fitted.get(d)) : displayData);
224
+
131
225
  function opacityOf(d: TData): number | undefined {
132
- const value = marker.fillOpacity;
133
- return typeof value === 'function' ? value(d) : value;
226
+ const value = styles?.fillOpacity;
227
+ if (typeof value === 'function') return value(d);
228
+ return typeof value === 'string' ? (d as Record<string, number>)[value] : value;
134
229
  }
135
230
 
136
231
  /** Each row's pixel position, once both scales resolve. */
@@ -188,10 +283,10 @@
188
283
  let groupEl: SVGGElement | undefined = $state();
189
284
 
190
285
  // The plot measures what it draws: how far it reaches out, and with `fitMargins` its margins grow to fit it.
191
- const measured = $derived(!!plotMargins && (!!marker.onOverflow || !!marker.fitMargins));
286
+ const measured = $derived(!!plotMargins && (!!marker.onoverflow || !!marker.fitMargins));
192
287
  plotMargins?.watch(() => (measured ? groupEl : undefined), {
193
288
  grow: () => !!marker.fitMargins,
194
- onOverflow: (overflow) => marker.onOverflow?.(overflow),
289
+ onoverflow: (overflow) => marker.onoverflow?.(overflow),
195
290
  // The box isn't tracked reactively: a new layout measures again.
196
291
  deps: () => [marker, points]
197
292
  });
@@ -205,38 +300,41 @@
205
300
  rowLineAnchor: typeof lineAnchor
206
301
  )}
207
302
  <g transform={projected ? `translate(${rowDx},${rowDy})` : undefined}>
208
- <Text
209
- data={rows}
210
- x={x ?? (marker.frameAnchor ? undefined : 0)}
211
- y={y ?? (marker.frameAnchor ? undefined : 0)}
212
- frameAnchor={marker.frameAnchor}
213
- text={((d: TData) => {
214
- const value = valueOf(d);
215
- return typeof value === 'number' ? numberText(value) : value;
216
- }) as (d: TData) => string}
217
- dx={projected ? 0 : rowDx}
218
- dy={projected ? 0 : rowDy}
219
- fill={fill as never}
220
- fillOpacity={fillOpacity as never}
221
- {fontSize}
222
- {fontWeight}
223
- textAnchor={rowAnchor}
224
- lineAnchor={rowLineAnchor}
225
- fontStyle={fontStyleProp}
226
- lineHeight={styles?.lineHeight}
227
- rotate={styles?.rotate}
228
- stroke={styles?.stroke}
229
- strokeWidth={styles?.strokeWidth}
230
- paintOrder={styles?.paintOrder}
231
- class={styles?.class}
232
- textClass={styles?.textClass}
233
- />
303
+ {#each sizeGroups(rows) as group (group.size)}
304
+ <Text
305
+ data={group.rows}
306
+ x={x ?? (marker.frameAnchor ? undefined : 0)}
307
+ y={y ?? (marker.frameAnchor ? undefined : 0)}
308
+ frameAnchor={marker.frameAnchor}
309
+ text={((d: TData, index: number) => {
310
+ if (group.texts) return group.texts[index];
311
+ const value = valueOf(d);
312
+ return typeof value === 'number' ? numberText(value) : value;
313
+ }) as (d: TData) => string}
314
+ dx={projected ? 0 : rowDx}
315
+ dy={projected ? 0 : rowDy}
316
+ fill={fill as never}
317
+ fillOpacity={fillOpacity as never}
318
+ fontSize={group.size}
319
+ {fontWeight}
320
+ textAnchor={rowAnchor}
321
+ lineAnchor={rowLineAnchor}
322
+ fontStyle={fontStyleProp}
323
+ lineHeight={styles?.lineHeight}
324
+ rotate={styles?.rotate}
325
+ stroke={RowStyle.of(styles?.stroke, rows)}
326
+ strokeWidth={RowStyle.field(styles?.strokeWidth)}
327
+ paintOrder={styles?.paintOrder}
328
+ class={styles?.class}
329
+ textClass={styles?.textClass}
330
+ />
331
+ {/each}
234
332
  </g>
235
333
  {/snippet}
236
334
 
237
335
  {#snippet labels()}
238
336
  {#if !perRow}
239
- <RowOffsetMarks {marker} rows={displayData}>
337
+ <RowOffsetMarks {marker} rows={shown}>
240
338
  {#snippet mark(rows)}
241
339
  {@render label(rows, dx, dy, textAnchor, lineAnchor)}
242
340
  {/snippet}
@@ -244,54 +342,52 @@
244
342
  {:else if (!declutter && !marker.edgeAware) || points}
245
343
  <!-- A decluttered or edge-aware label waits for both scales. -->
246
344
  {#each displayData as d, i (i)}
247
- {@const lane = lanes?.get(i)}
248
- {@const placement = placements?.[i]}
249
- {@const extraDy = lane?.extraDy ?? 0}
250
- {@const laneDir = lane?.aligned ? lane.dir : dir}
251
- {@const labelDx = lane?.aligned ? laneDir * lane.reach : dx}
252
- {#if declutter && points && (lane?.aligned || extraDy !== 0)}
253
- {@const { px, py } = points[i]}
254
- {@const laneX = lane?.aligned ? px + laneDir * lane.laneReach : px + labelDx}
255
- {@const connector = declutter.connector}
256
- <path
257
- d={`M ${px} ${py} H ${laneX} V ${py + extraDy} H ${px + labelDx}`}
258
- fill="none"
259
- stroke={connector.stroke}
260
- stroke-width={connector.strokeWidth}
261
- stroke-opacity={connector.strokeOpacity ?? opacityOf(d) ?? 1}
262
- stroke-dasharray={connector.strokeDasharray}
263
- stroke-linecap={connector.strokeLinecap ?? 'square'}
264
- stroke-linejoin={connector.strokeLinejoin ?? 'miter'}
265
- />
345
+ {#if !fitted || fitted.get(d)}
346
+ {@const lane = lanes?.get(i)}
347
+ {@const placement = placements?.[i]}
348
+ {@const extraDy = lane?.extraDy ?? 0}
349
+ {@const laneDir = lane?.aligned ? lane.dir : dir}
350
+ {@const labelDx = lane?.aligned ? laneDir * lane.reach : dx}
351
+ {#if declutter && points && (lane?.aligned || extraDy !== 0)}
352
+ {@const { px, py } = points[i]}
353
+ {@const laneX = lane?.aligned ? px + laneDir * lane.laneReach : px + labelDx}
354
+ {@const connector = declutter.connector}
355
+ <path
356
+ d={`M ${px} ${py} H ${laneX} V ${py + extraDy} H ${px + labelDx}`}
357
+ fill="none"
358
+ stroke={connector.stroke}
359
+ stroke-width={connector.strokeWidth}
360
+ stroke-opacity={connector.strokeOpacity ?? opacityOf(d) ?? 1}
361
+ stroke-dasharray={connector.strokeDasharray}
362
+ stroke-linecap={connector.strokeLinecap ?? 'square'}
363
+ stroke-linejoin={connector.strokeLinejoin ?? 'miter'}
364
+ />
365
+ {/if}
366
+ <!-- svelteplot's Text never wires pointer handlers to its DOM node; a wrapping <g> catches them. -->
367
+ <g role="presentation" {...events.forRow(d, i)}>
368
+ <RowOffsetMarks {marker} rows={[d]}>
369
+ {#snippet mark(rows)}
370
+ {#if placement}
371
+ {@render label(
372
+ rows,
373
+ placement.dx,
374
+ placement.dy + extraDy,
375
+ placement.textAnchor,
376
+ placement.lineAnchor
377
+ )}
378
+ {:else}
379
+ {@render label(
380
+ rows,
381
+ labelDx,
382
+ dy + extraDy,
383
+ lane?.aligned && laneDir !== dir ? flipAnchor(anchorAt(d)) : anchorAt(d),
384
+ lineAnchor
385
+ )}
386
+ {/if}
387
+ {/snippet}
388
+ </RowOffsetMarks>
389
+ </g>
266
390
  {/if}
267
- <!-- svelteplot's Text never wires pointer handlers to its DOM node; a wrapping <g> catches them. -->
268
- <g
269
- role="presentation"
270
- onpointerenter={marker.onPointerEnter && (() => marker.onPointerEnter?.(d))}
271
- onpointerleave={marker.onPointerLeave && (() => marker.onPointerLeave?.(d))}
272
- >
273
- <RowOffsetMarks {marker} rows={[d]}>
274
- {#snippet mark(rows)}
275
- {#if placement}
276
- {@render label(
277
- rows,
278
- placement.dx,
279
- placement.dy + extraDy,
280
- placement.textAnchor,
281
- placement.lineAnchor
282
- )}
283
- {:else}
284
- {@render label(
285
- rows,
286
- labelDx,
287
- dy + extraDy,
288
- lane?.aligned && laneDir !== dir ? flipAnchor(anchorAt(d)) : anchorAt(d),
289
- lineAnchor
290
- )}
291
- {/if}
292
- {/snippet}
293
- </RowOffsetMarks>
294
- </g>
295
391
  {/each}
296
392
  {/if}
297
393
  {/snippet}
@@ -1,6 +1,8 @@
1
1
  import type { TextMarkerConfig } from '../../types/markers/common';
2
+ import type { BoxChannels, BoxSizer } from '../utils/BoxLabel';
2
3
  type $$ComponentProps = {
3
4
  marker: TextMarkerConfig;
5
+ box?: BoxChannels | BoxSizer;
4
6
  };
5
7
  declare function $$render<TData = Record<string, unknown>>(): {
6
8
  props: $$ComponentProps;
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">
2
+ import { RowStyle } from '../utils/RowStyle';
3
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
4
  import { TickX, TickY } from 'svelteplot';
3
5
  import { usePlot } from '../../layout/plot/usePlot';
4
6
  import { MarkerChannels } from '../utils/MarkerChannels';
@@ -7,6 +9,7 @@
7
9
 
8
10
  /** Renders one `'tick'` marker as `<TickX>` or `<TickY>`, picked from the way the plot runs (`usePlot().axes`). */
9
11
  let { marker }: { marker: TickMarkerConfig } = $props();
12
+ const events = MarkerEvents.use(() => marker);
10
13
 
11
14
  const plot = usePlot();
12
15
  const isHorizontal = $derived(plot.axes?.isHorizontal ?? false);
@@ -15,7 +18,9 @@
15
18
  const cfg = $derived(getConfiguration());
16
19
  const data = $derived(marker.data ?? []);
17
20
  const channelStroke = $derived(MarkerChannels.buildFill(data, marker.color, marker.scales, cfg));
18
- const stroke = $derived(channelStroke ?? marker.styles?.stroke ?? 'currentColor');
21
+ const stroke = $derived(
22
+ channelStroke ?? RowStyle.of(marker.styles?.stroke, data) ?? 'currentColor'
23
+ );
19
24
 
20
25
  /**
21
26
  * A tick across a band axis spans the whole band, whatever `tickLength` says -
@@ -33,14 +38,15 @@
33
38
  </script>
34
39
 
35
40
  <TickMark
41
+ {...events.props}
36
42
  {data}
37
43
  x={marker.x}
38
44
  y={marker.y}
39
45
  tickLength={marker.tickLength}
40
46
  {...insetProps}
41
47
  {stroke}
42
- strokeWidth={marker.styles?.strokeWidth}
43
- strokeOpacity={marker.styles?.strokeOpacity}
48
+ strokeWidth={RowStyle.field(marker.styles?.strokeWidth)}
49
+ strokeOpacity={RowStyle.opacity(marker.styles?.strokeOpacity)}
44
50
  strokeDasharray={marker.styles?.strokeDasharray}
45
51
  strokeLinecap={marker.styles?.strokeLinecap}
46
52
  />
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { Trail } from 'svelteplot';
3
4
  import { MarkerChannels } from '../utils/MarkerChannels';
4
5
  import { getConfiguration } from '../../configuration/config.svelte';
@@ -6,6 +7,7 @@
6
7
 
7
8
  /** Renders one `'trail'` marker as `<Trail>` - a ribbon whose width follows `r`. */
8
9
  let { marker }: { marker: TrailMarkerConfig } = $props();
10
+ const events = MarkerEvents.use(() => marker);
9
11
 
10
12
  const cfg = $derived(getConfiguration());
11
13
  const data = $derived(marker.data ?? []);
@@ -13,6 +15,7 @@
13
15
  </script>
14
16
 
15
17
  <Trail
18
+ {...events.props}
16
19
  {data}
17
20
  x={marker.x}
18
21
  y={marker.y}
@@ -0,0 +1,58 @@
1
+ import type { TextMarkerConfig } from '../../types/markers/common';
2
+ import type { TextLabelConfig } from '../../types/markers/basic/text';
3
+ /** Where a row's edge along an axis is: a field of the rows, the symbol a transform keyed it by, a function of the row, or a literal. */
4
+ type Edge = unknown;
5
+ /** The edges of the box each row spans, in the data's own terms. */
6
+ export type BoxChannels = {
7
+ x1: Edge;
8
+ x2: Edge;
9
+ y1: Edge;
10
+ y2: Edge;
11
+ };
12
+ /** The scales a box is measured on. */
13
+ export type BoxScales = Record<string, {
14
+ type?: string;
15
+ fn: any;
16
+ } | undefined>;
17
+ /** The pixel size of the box of a row, for the markers whose boxes are bands of a category axis rather than edges. */
18
+ export type BoxSizer = (row: unknown, scales: BoxScales) => {
19
+ width: number;
20
+ height: number;
21
+ } | undefined;
22
+ /** The `text` marker that labels the boxes a marker draws, and where each label's box is. */
23
+ export type BoxLabelMarker = {
24
+ marker: TextMarkerConfig;
25
+ box: BoxChannels | BoxSizer;
26
+ };
27
+ /** What a marker has to say for its boxes to be labelled. */
28
+ export type Labelled = {
29
+ type?: string;
30
+ data?: unknown[];
31
+ label?: TextLabelConfig;
32
+ x?: Edge;
33
+ y?: Edge;
34
+ x1?: Edge;
35
+ x2?: Edge;
36
+ y1?: Edge;
37
+ y2?: Edge;
38
+ isHorizontal?: boolean;
39
+ role?: string;
40
+ thickness?: number;
41
+ /** The marker's styles: the insets of a cell or a bar are read off them. */
42
+ styles?: object;
43
+ };
44
+ /**
45
+ * How a marker that draws a box per row writes a label in each: the `text` marker for them, centred on the box,
46
+ * and where the box is for it to fit to. A `rect` says it with its edges, a `cell` is a band of each axis, and a bar
47
+ * or a waffle is a band of its category axis and the stretch of its value.
48
+ */
49
+ export declare class BoxLabel {
50
+ #private;
51
+ /** `undefined` when the marker has no label, or does not say where its boxes are. */
52
+ static of(marker: Labelled, plot?: {
53
+ isHorizontal?: boolean;
54
+ scales?: () => BoxScales | undefined;
55
+ gap?: number;
56
+ }): BoxLabelMarker | undefined;
57
+ }
58
+ export {};