@fundar/data-chart-telling 1.16.0 → 1.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (330) hide show
  1. package/CHANGELOG.md +56 -0
  2. package/dist/configuration/ConfigVars.svelte +14 -0
  3. package/dist/configuration/ConfigVars.svelte.d.ts +3 -0
  4. package/dist/configuration/config.svelte.d.ts +5 -0
  5. package/dist/configuration/config.svelte.js +20 -6
  6. package/dist/configuration/themes/dark.js +1 -1
  7. package/dist/configuration/themes/editorial.js +1 -1
  8. package/dist/index.d.ts +12 -4
  9. package/dist/index.js +4 -1
  10. package/dist/layout/base/BasePlotLayout.svelte +1 -1
  11. package/dist/layout/figure/Figure.svelte +5 -12
  12. package/dist/layout/figure/FigureChrome.svelte +2 -10
  13. package/dist/layout/geometry/GeometryLayout.svelte +219 -44
  14. package/dist/layout/hover/HoverDefaults.d.ts +52 -0
  15. package/dist/layout/hover/HoverDefaults.js +96 -0
  16. package/dist/layout/hover/HoverLayers.d.ts +35 -0
  17. package/dist/layout/hover/HoverLayers.js +122 -0
  18. package/dist/layout/hover/HoverSettings.js +4 -1
  19. package/dist/layout/hover/HoverShapes.d.ts +44 -0
  20. package/dist/layout/hover/HoverShapes.js +103 -0
  21. package/dist/layout/hover/PlotHover.svelte.d.ts +18 -0
  22. package/dist/layout/hover/PlotHover.svelte.js +54 -1
  23. package/dist/layout/legend/DisabledStyle.d.ts +1 -1
  24. package/dist/layout/legend/DisabledStyle.js +1 -1
  25. package/dist/layout/legend/DiscreteBadgeItem.svelte +1 -1
  26. package/dist/layout/legend/DiscreteSection.svelte +1 -1
  27. package/dist/layout/legend/LegendState.svelte.d.ts +14 -2
  28. package/dist/layout/legend/LegendState.svelte.js +23 -4
  29. package/dist/layout/legend/LegendText.d.ts +4 -1
  30. package/dist/layout/legend/LegendText.js +7 -1
  31. package/dist/layout/margins/PlotMargins.svelte.d.ts +2 -2
  32. package/dist/layout/margins/PlotMargins.svelte.js +2 -2
  33. package/dist/layout/plot/Core.svelte +2 -2
  34. package/dist/layout/plot/Plot.svelte +4 -2
  35. package/dist/layout/plot/Plot.svelte.d.ts +2 -1
  36. package/dist/layout/plot/PublicPlotContext.d.ts +6 -0
  37. package/dist/layout/plot/PublicPlotContext.js +8 -0
  38. package/dist/layout/scales/ScalesLayout.svelte +1 -1
  39. package/dist/layout/styles/ValueLabels.d.ts +43 -4
  40. package/dist/layout/styles/ValueLabels.js +87 -19
  41. package/dist/layout/timeline/Timeline.svelte +5 -1
  42. package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -9
  43. package/dist/layout/tooltip/TooltipState.svelte.js +28 -29
  44. package/dist/markers/MarkerKinds.d.ts +5 -0
  45. package/dist/markers/MarkerKinds.js +1 -0
  46. package/dist/markers/area/AreaMarker.svelte +3 -0
  47. package/dist/markers/arrow/ArrowMarker.svelte +9 -5
  48. package/dist/markers/band/BandMarker.svelte +74 -0
  49. package/dist/markers/band/BandMarker.svelte.d.ts +7 -0
  50. package/dist/markers/band/Bands.d.ts +16 -0
  51. package/dist/markers/band/Bands.js +48 -0
  52. package/dist/markers/bar/BarMarker.svelte +50 -96
  53. package/dist/markers/bollinger/BollingerMarker.svelte +3 -0
  54. package/dist/markers/box/BoxMarker.svelte +3 -1
  55. package/dist/markers/cell/CellMarker.svelte +11 -7
  56. package/dist/markers/contour/ContourMarker.svelte +3 -0
  57. package/dist/markers/delaunay/DelaunayLinkMarker.svelte +9 -5
  58. package/dist/markers/delaunay/DelaunayMeshMarker.svelte +3 -0
  59. package/dist/markers/density/DensityMarker.svelte +3 -0
  60. package/dist/markers/difference/DifferenceMarker.svelte +3 -0
  61. package/dist/markers/dot/DotMarker.svelte +11 -6
  62. package/dist/markers/geo/GraticuleMarker.svelte +3 -0
  63. package/dist/markers/geo/SphereMarker.svelte +3 -0
  64. package/dist/markers/hover/HoverMarker.svelte +7 -249
  65. package/dist/markers/hover/HoverMarker.svelte.d.ts +4 -27
  66. package/dist/markers/hull/HullMarker.svelte +3 -0
  67. package/dist/markers/image/ImageMarker.svelte +3 -0
  68. package/dist/markers/line/LineMarker.svelte +3 -0
  69. package/dist/markers/link/LinkMarker.svelte +3 -0
  70. package/dist/markers/raster/RasterMarker.svelte +3 -0
  71. package/dist/markers/rect/RectMarker.svelte +25 -17
  72. package/dist/markers/regression/RegressionMarker.svelte +3 -0
  73. package/dist/markers/rule/RuleMarker.svelte +15 -5
  74. package/dist/markers/text/TextFit.d.ts +44 -0
  75. package/dist/markers/text/TextFit.js +86 -0
  76. package/dist/markers/text/TextMarker.svelte +186 -90
  77. package/dist/markers/text/TextMarker.svelte.d.ts +2 -0
  78. package/dist/markers/tick/TickMarker.svelte +9 -3
  79. package/dist/markers/trail/TrailMarker.svelte +3 -0
  80. package/dist/markers/utils/BoxLabel.d.ts +58 -0
  81. package/dist/markers/utils/BoxLabel.js +175 -0
  82. package/dist/markers/utils/MarkerEvents.d.ts +23 -0
  83. package/dist/markers/utils/MarkerEvents.js +44 -0
  84. package/dist/markers/utils/MarkerLabel.svelte +33 -0
  85. package/dist/markers/utils/MarkerLabel.svelte.d.ts +10 -0
  86. package/dist/markers/utils/PointPixel.d.ts +37 -0
  87. package/dist/markers/utils/PointPixel.js +44 -0
  88. package/dist/markers/utils/RowStroke.d.ts +9 -21
  89. package/dist/markers/utils/RowStroke.js +10 -21
  90. package/dist/markers/utils/RowStyle.d.ts +26 -0
  91. package/dist/markers/utils/RowStyle.js +55 -0
  92. package/dist/markers/vector/VectorMarker.svelte +3 -0
  93. package/dist/markers/voronoi/VoronoiMarker.svelte +9 -5
  94. package/dist/markers/voronoi/VoronoiMeshMarker.svelte +3 -0
  95. package/dist/markers/waffle/WaffleMarker.svelte +9 -5
  96. package/dist/phases/Pipeline.d.ts +10 -8
  97. package/dist/phases/Pipeline.js +13 -9
  98. package/dist/phases/context/ContextPhase.d.ts +22 -0
  99. package/dist/phases/context/ContextPhase.js +23 -0
  100. package/dist/phases/context/RowContext.d.ts +35 -0
  101. package/dist/phases/context/RowContext.js +95 -0
  102. package/dist/phases/data/DataPhase.d.ts +4 -4
  103. package/dist/phases/data/DataPhase.js +53 -12
  104. package/dist/phases/hover/HoverPhase.d.ts +6 -7
  105. package/dist/phases/hover/HoverPhase.js +28 -15
  106. package/dist/phases/mapping/MappingPhase.d.ts +4 -4
  107. package/dist/phases/mapping/MappingPhase.js +4 -3
  108. package/dist/phases/markers/MarkerStyles.d.ts +26 -0
  109. package/dist/phases/markers/MarkerStyles.js +126 -0
  110. package/dist/phases/markers/MarkersPhase.d.ts +5 -5
  111. package/dist/phases/markers/MarkersPhase.js +8 -6
  112. package/dist/phases/scales/ScalesPhase.d.ts +4 -4
  113. package/dist/phases/scales/ScalesPhase.js +4 -4
  114. package/dist/phases/sharedScales/SharedScalesPhase.d.ts +2 -2
  115. package/dist/phases/sharedScales/SharedScalesPhase.js +2 -2
  116. package/dist/phases/statistics/MarkerGrouping.d.ts +0 -9
  117. package/dist/phases/statistics/MarkerGrouping.js +0 -16
  118. package/dist/phases/statistics/StatisticsPhase.js +1 -1
  119. package/dist/phases/styles/StylesPhase.d.ts +3 -3
  120. package/dist/phases/styles/StylesPhase.js +2 -2
  121. package/dist/phases/tooltip/TooltipPhase.d.ts +4 -4
  122. package/dist/phases/tooltip/TooltipPhase.js +10 -7
  123. package/dist/phases/transforms/Transforms.js +3 -1
  124. package/dist/phases/transforms/TransformsPhase.d.ts +3 -3
  125. package/dist/phases/transforms/TransformsPhase.js +60 -6
  126. package/dist/phases/transforms/methods/TreemapTransform.d.ts +28 -0
  127. package/dist/phases/transforms/methods/TreemapTransform.js +119 -0
  128. package/dist/plots/correlation/heatmap/defaults.d.ts +2 -2
  129. package/dist/plots/correlation/heatmap/defaults.js +23 -8
  130. package/dist/plots/correlation/heatmap/markers.d.ts +2 -10
  131. package/dist/plots/correlation/heatmap/markers.js +11 -37
  132. package/dist/plots/correlation/scatter/defaults.d.ts +2 -2
  133. package/dist/plots/correlation/scatter/defaults.js +9 -3
  134. package/dist/plots/correlation/scatter/markers.d.ts +3 -3
  135. package/dist/plots/correlation/scatter/markers.js +6 -5
  136. package/dist/plots/distribution/box/BoxSummaries.d.ts +17 -8
  137. package/dist/plots/distribution/box/BoxSummaries.js +90 -40
  138. package/dist/plots/distribution/box/defaults.d.ts +2 -2
  139. package/dist/plots/distribution/box/defaults.js +9 -6
  140. package/dist/plots/distribution/box/markers.d.ts +2 -2
  141. package/dist/plots/distribution/box/markers.js +3 -3
  142. package/dist/plots/distribution/density/defaults.d.ts +2 -2
  143. package/dist/plots/distribution/density/defaults.js +17 -1
  144. package/dist/plots/distribution/density/markers.d.ts +2 -2
  145. package/dist/plots/distribution/density/markers.js +4 -4
  146. package/dist/plots/distribution/histogram/defaults.d.ts +2 -2
  147. package/dist/plots/distribution/histogram/defaults.js +22 -27
  148. package/dist/plots/distribution/histogram/markers.d.ts +3 -12
  149. package/dist/plots/distribution/histogram/markers.js +21 -62
  150. package/dist/plots/distribution/pyramid/defaults.d.ts +2 -2
  151. package/dist/plots/distribution/pyramid/defaults.js +7 -4
  152. package/dist/plots/distribution/pyramid/markers.d.ts +2 -12
  153. package/dist/plots/distribution/pyramid/markers.js +16 -66
  154. package/dist/plots/distribution/violin/defaults.d.ts +2 -2
  155. package/dist/plots/distribution/violin/defaults.js +9 -7
  156. package/dist/plots/distribution/violin/markers.d.ts +2 -2
  157. package/dist/plots/distribution/violin/markers.js +4 -4
  158. package/dist/plots/evolution/area/defaults.d.ts +2 -2
  159. package/dist/plots/evolution/area/defaults.js +1 -1
  160. package/dist/plots/evolution/area/markers.d.ts +2 -2
  161. package/dist/plots/evolution/area/markers.js +4 -4
  162. package/dist/plots/evolution/line/defaults.d.ts +2 -2
  163. package/dist/plots/evolution/line/defaults.js +1 -1
  164. package/dist/plots/evolution/line/markers.d.ts +2 -2
  165. package/dist/plots/evolution/line/markers.js +3 -3
  166. package/dist/plots/evolution/slope/defaults.d.ts +2 -2
  167. package/dist/plots/evolution/slope/defaults.js +8 -4
  168. package/dist/plots/evolution/slope/markers.d.ts +2 -2
  169. package/dist/plots/evolution/slope/markers.js +3 -3
  170. package/dist/plots/evolution/sparkline/defaults.d.ts +2 -2
  171. package/dist/plots/evolution/sparkline/defaults.js +5 -2
  172. package/dist/plots/evolution/sparkline/markers.d.ts +2 -2
  173. package/dist/plots/evolution/sparkline/markers.js +3 -3
  174. package/dist/plots/map/geo/Core.svelte +3 -3
  175. package/dist/plots/map/geo/defaults.d.ts +2 -2
  176. package/dist/plots/map/geo/phases/data.d.ts +1 -1
  177. package/dist/plots/map/geo/phases/data.js +1 -1
  178. package/dist/plots/map/geo/phases/hover.d.ts +2 -2
  179. package/dist/plots/map/geo/phases/hover.js +3 -3
  180. package/dist/plots/map/geo/phases/markers.d.ts +2 -2
  181. package/dist/plots/map/geo/phases/markers.js +5 -4
  182. package/dist/plots/map/geo/phases/scales.d.ts +2 -2
  183. package/dist/plots/map/geo/phases/scales.js +2 -2
  184. package/dist/plots/part-of-a-whole/treemap/Plot.svelte +47 -0
  185. package/dist/plots/part-of-a-whole/treemap/Plot.svelte.d.ts +26 -0
  186. package/dist/plots/part-of-a-whole/treemap/defaults.d.ts +10 -0
  187. package/dist/plots/part-of-a-whole/treemap/defaults.js +183 -0
  188. package/dist/plots/ranking/bar/defaults.d.ts +2 -2
  189. package/dist/plots/ranking/bar/defaults.js +15 -9
  190. package/dist/plots/ranking/bar/markers.d.ts +4 -14
  191. package/dist/plots/ranking/bar/markers.js +45 -86
  192. package/dist/plots/ranking/bullet/defaults.d.ts +2 -2
  193. package/dist/plots/ranking/bullet/defaults.js +4 -4
  194. package/dist/plots/ranking/bullet/markers.d.ts +3 -3
  195. package/dist/plots/ranking/bullet/markers.js +11 -12
  196. package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +3 -3
  197. package/dist/plots/ranking/cleveland/ClevelandMarkers.js +28 -23
  198. package/dist/plots/ranking/cleveland/defaults.d.ts +2 -2
  199. package/dist/plots/ranking/cleveland/defaults.js +7 -4
  200. package/dist/plots/ranking/dumbbell/defaults.d.ts +2 -2
  201. package/dist/plots/ranking/forest/defaults.d.ts +2 -2
  202. package/dist/plots/ranking/lollipop/defaults.d.ts +2 -2
  203. package/dist/types/configuration/styling.d.ts +31 -2
  204. package/dist/types/layout/context.d.ts +21 -0
  205. package/dist/types/layout/context.js +1 -0
  206. package/dist/types/layout/hover.d.ts +3 -0
  207. package/dist/types/layout/legend.d.ts +8 -1
  208. package/dist/types/layout/mapping.d.ts +12 -3
  209. package/dist/types/layout/scales.d.ts +6 -0
  210. package/dist/types/layout/styles/values.d.ts +8 -2
  211. package/dist/types/layout/tooltip.d.ts +11 -4
  212. package/dist/types/markers/axis/arrow.d.ts +2 -8
  213. package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
  214. package/dist/types/markers/axis/band.d.ts +24 -0
  215. package/dist/types/markers/axis/band.js +1 -0
  216. package/dist/types/markers/axis/bar.d.ts +6 -10
  217. package/dist/types/markers/axis/cell.d.ts +5 -5
  218. package/dist/types/markers/axis/delaunayLink.d.ts +2 -2
  219. package/dist/types/markers/axis/hover.d.ts +60 -15
  220. package/dist/types/markers/axis/rect.d.ts +4 -8
  221. package/dist/types/markers/axis/rule.d.ts +2 -16
  222. package/dist/types/markers/axis/tick.d.ts +2 -2
  223. package/dist/types/markers/axis/voronoi.d.ts +2 -2
  224. package/dist/types/markers/axis/waffle.d.ts +4 -3
  225. package/dist/types/markers/basic/dot.d.ts +2 -2
  226. package/dist/types/markers/basic/text.d.ts +56 -14
  227. package/dist/types/markers/channels/commonMarkerConfig.d.ts +8 -1
  228. package/dist/types/markers/channels/commonMarkerConfigWithArea.d.ts +1 -2
  229. package/dist/types/markers/channels/commonMarkerConfigWithLabel.d.ts +10 -0
  230. package/dist/types/markers/channels/commonMarkerConfigWithLabel.js +1 -0
  231. package/dist/types/markers/channels/commonMarkerEvents.d.ts +17 -0
  232. package/dist/types/markers/channels/commonMarkerEvents.js +13 -0
  233. package/dist/types/markers/common.d.ts +1 -0
  234. package/dist/types/markers/common.js +1 -0
  235. package/dist/types/markers/geo/contour.d.ts +2 -1
  236. package/dist/types/markers/geo/graticule.d.ts +2 -1
  237. package/dist/types/markers/geo/link.d.ts +2 -1
  238. package/dist/types/markers/geo/sphere.d.ts +2 -1
  239. package/dist/types/markers/geo/vector.d.ts +2 -1
  240. package/dist/types/phases/context/phase.d.ts +7 -0
  241. package/dist/types/phases/context/phase.js +1 -0
  242. package/dist/types/phases/data/phase.d.ts +7 -2
  243. package/dist/types/phases/hover/phase.d.ts +10 -5
  244. package/dist/types/phases/index.d.ts +2 -1
  245. package/dist/types/phases/kind.d.ts +11 -8
  246. package/dist/types/phases/mapping/phase.d.ts +2 -2
  247. package/dist/types/phases/markers/phase.d.ts +3 -3
  248. package/dist/types/phases/scales/phase.d.ts +4 -4
  249. package/dist/types/phases/stage.d.ts +3 -3
  250. package/dist/types/phases/state.d.ts +8 -1
  251. package/dist/types/phases/statistics/phase.d.ts +2 -1
  252. package/dist/types/phases/styles/phase.d.ts +3 -2
  253. package/dist/types/phases/transforms/phase.d.ts +13 -2
  254. package/dist/types/plots/constants.d.ts +17 -19
  255. package/dist/types/plots/correlation/heatmap/props.d.ts +3 -3
  256. package/dist/types/plots/correlation/heatmap/state.d.ts +2 -2
  257. package/dist/types/plots/correlation/scatter/props.d.ts +3 -3
  258. package/dist/types/plots/correlation/scatter/state.d.ts +2 -2
  259. package/dist/types/plots/data/common.d.ts +19 -6
  260. package/dist/types/plots/data/geo.d.ts +1 -1
  261. package/dist/types/plots/distribution/box/props.d.ts +25 -3
  262. package/dist/types/plots/distribution/box/state.d.ts +6 -17
  263. package/dist/types/plots/distribution/density/props.d.ts +3 -11
  264. package/dist/types/plots/distribution/density/state.d.ts +2 -2
  265. package/dist/types/plots/distribution/histogram/props.d.ts +16 -11
  266. package/dist/types/plots/distribution/histogram/state.d.ts +2 -2
  267. package/dist/types/plots/distribution/pyramid/props.d.ts +3 -3
  268. package/dist/types/plots/distribution/pyramid/state.d.ts +2 -2
  269. package/dist/types/plots/distribution/violin/props.d.ts +4 -3
  270. package/dist/types/plots/distribution/violin/state.d.ts +2 -2
  271. package/dist/types/plots/evolution/area/props.d.ts +3 -3
  272. package/dist/types/plots/evolution/area/state.d.ts +2 -2
  273. package/dist/types/plots/evolution/line/props.d.ts +3 -3
  274. package/dist/types/plots/evolution/line/state.d.ts +2 -2
  275. package/dist/types/plots/evolution/slope/state.d.ts +2 -2
  276. package/dist/types/plots/evolution/sparkline/state.d.ts +2 -2
  277. package/dist/types/plots/map/geo/state.d.ts +1 -1
  278. package/dist/types/plots/part-of-a-whole/treemap/props.d.ts +29 -0
  279. package/dist/types/plots/part-of-a-whole/treemap/props.js +1 -0
  280. package/dist/types/plots/part-of-a-whole/treemap/state.d.ts +6 -0
  281. package/dist/types/plots/part-of-a-whole/treemap/state.js +1 -0
  282. package/dist/types/plots/props.d.ts +10 -4
  283. package/dist/types/plots/ranking/bar/props.d.ts +3 -3
  284. package/dist/types/plots/ranking/bar/state.d.ts +2 -2
  285. package/dist/types/plots/ranking/bullet/state.d.ts +2 -2
  286. package/dist/types/plots/ranking/cleveland/props.d.ts +3 -3
  287. package/dist/types/plots/ranking/cleveland/state.d.ts +2 -2
  288. package/dist/types/plots/ranking/dumbbell/props.d.ts +3 -3
  289. package/dist/types/plots/ranking/dumbbell/state.d.ts +2 -2
  290. package/dist/types/plots/ranking/forest/props.d.ts +3 -3
  291. package/dist/types/plots/ranking/forest/state.d.ts +2 -2
  292. package/dist/types/plots/ranking/lollipop/props.d.ts +3 -3
  293. package/dist/types/plots/ranking/lollipop/state.d.ts +2 -2
  294. package/dist/types/plots/styling.d.ts +24 -0
  295. package/dist/types/transforms/index.d.ts +3 -1
  296. package/dist/types/transforms/treemap.d.ts +32 -0
  297. package/dist/types/transforms/treemap.js +5 -0
  298. package/dist/utils/color/ColorTones.d.ts +19 -0
  299. package/dist/utils/color/ColorTones.js +64 -0
  300. package/dist/utils/color/CssColor.d.ts +14 -5
  301. package/dist/utils/color/CssColor.js +69 -27
  302. package/dist/utils/color/index.d.ts +4 -0
  303. package/dist/utils/color/index.js +4 -0
  304. package/dist/utils/grouping.d.ts +18 -1
  305. package/dist/utils/grouping.js +31 -0
  306. package/docs/concepts.md +3 -2
  307. package/docs/legend.md +8 -5
  308. package/docs/markers.md +110 -28
  309. package/docs/plots/evolution/line.md +1 -1
  310. package/docs/plots/evolution/slope.md +1 -1
  311. package/docs/plots/part-of-a-whole/treemap.md +103 -0
  312. package/docs/plots/ranking/bar.md +2 -1
  313. package/docs/plots/ranking/cleveland.md +1 -1
  314. package/docs/plots.md +21 -20
  315. package/docs/scales.md +3 -0
  316. package/docs/state.md +34 -1
  317. package/docs/styles-and-segments.md +20 -19
  318. package/docs/theming.md +6 -12
  319. package/docs/tooltip-and-hover.md +81 -3
  320. package/docs/transforms-and-statistics.md +17 -16
  321. package/examples/LineDates.svelte +1 -1
  322. package/examples/ResponsiveLine.svelte +3 -1
  323. package/examples/Treemap.svelte +13 -0
  324. package/examples/TreemapHover.svelte +25 -0
  325. package/examples/ValueLabels.svelte +1 -1
  326. package/examples/datasets/economic-activity.ts +40 -0
  327. package/examples/datasets/index.ts +1 -0
  328. package/llms-full.txt +11 -9
  329. package/llms.txt +4 -1
  330. package/package.json +3 -1
@@ -1,267 +1,25 @@
1
1
  <script lang="ts">
2
2
  import { usePlot } from '../../layout/plot/usePlot';
3
- import DotMarker from '../dot/DotMarker.svelte';
4
- import TextMarker from '../text/TextMarker.svelte';
5
- import RuleMarker from '../rule/RuleMarker.svelte';
6
- import BarMarker from '../bar/BarMarker.svelte';
7
- import { getConfiguration } from '../../configuration/config.svelte';
8
- import { NumberFormat } from '../../utils/NumberFormat';
9
- import { BandNudge } from '../utils/BandNudge';
10
- import type { BandSlice } from '../../types/layout/hover';
11
- import type { HoverMarkerConfig } from '../../types/markers/common';
3
+ import { PointPixel } from '../utils/PointPixel';
12
4
  import type { HoverDisplayPoint } from '../../types/layout/hover';
13
5
 
14
6
  /**
15
- * In-SVG hover highlight, rendered *inside* a `<Plot>`. Because it positions
16
- * itself through the host plot's scales, it places the same coordinate
17
- * correctly in every facet - that is what makes cross-facet sync work without
18
- * any pixel math. Draws optional x/y crosshair rules plus a dot + value label
19
- * for each matched point.
20
- *
21
- * Takes the raw `marker` config plus the couple of things it can't know on
22
- * its own - `activePoint` (the specific matched point actually under the
23
- * cursor, for the crosshair position; see `controller.svelte.ts`'s own doc
24
- * comment) and whether the active hover strategy implies a crosshair on
25
- * each axis by default - the same "component owns its own rendering"
26
- * pattern `BarMarker`/`RuleMarker` follow. `activePoint`/
27
- * `impliesCrosshairX`/`impliesCrosshairY` are all optional and default to
28
- * "no crosshair".
29
- *
30
- * `areaX`/`areaY` are a separate, always-explicit opt-in (no implied
31
- * default) for a thickened area highlight in place of the thin crosshair -
32
- * see `HoverMarkerConfig`'s own doc comment. Rendered via `BarMarker`'s
33
- * `role: 'highlight'`, so it renders nothing on an axis without a band
34
- * scale (e.g. a line/scatter plot's continuous axis).
7
+ * Where the hover is, rendered *inside* a `<Plot>`: it reports the pixel position of the point under the pointer,
8
+ * through the host plot's scales, so a synced plot's tooltip can sit on it. It draws nothing itself - the
9
+ * `hover` marker's `back` and `front` markers are drawn by `GeometryLayout`, as every other marker.
35
10
  */
36
11
  interface Props {
37
- data?: HoverDisplayPoint[];
38
- /** Narrowed to just the fields this component reads - `HoverMarkerConfig` also carries routing/scoping fields (`series`/`scope`/`strategy`/`sync`) it has no use for. */
39
- marker: Pick<
40
- HoverMarkerConfig,
41
- | 'ruleX'
42
- | 'ruleY'
43
- | 'areaX'
44
- | 'areaY'
45
- | 'showLabels'
46
- | 'format'
47
- | 'rule'
48
- | 'area'
49
- | 'dot'
50
- | 'text'
51
- | 'decimals'
52
- | 'prefix'
53
- | 'suffix'
54
- | 'signDisplay'
55
- >;
56
12
  activePoint?: HoverDisplayPoint | null;
57
- impliesCrosshairX?: boolean;
58
- impliesCrosshairY?: boolean;
59
- /** Reports `activePoint`'s real pixel position within this facet's own box, or `null` when nothing's matched. */
13
+ /** Reports `activePoint`'s pixel position within this facet's own box, or `null` when nothing's matched. */
60
14
  onActivePointPixel?: (pos: { x: number; y: number } | null) => void;
61
15
  }
62
16
 
63
- let {
64
- data = [],
65
- marker,
66
- activePoint = null,
67
- impliesCrosshairX = false,
68
- impliesCrosshairY = false,
69
- onActivePointPixel
70
- }: Props = $props();
71
-
72
- const cfg = $derived(getConfiguration());
17
+ let { activePoint = null, onActivePointPixel }: Props = $props();
73
18
  const plot = usePlot().svelteplot;
74
19
 
75
- /** Scaled pixel position of `value`, centered within its band for a band scale. */
76
- function scaledPixel(
77
- scale: { type?: string; fn?: (v: never) => unknown } | undefined,
78
- value: unknown
79
- ): number | null {
80
- if (!scale?.fn || value == null) return null;
81
- const raw = Number(scale.fn(value as never));
82
- if (!Number.isFinite(raw)) return null;
83
- if (scale.type === 'band') {
84
- const bandwidth = (scale.fn as { bandwidth?: () => number }).bandwidth?.() ?? 0;
85
- return raw + bandwidth / 2;
86
- }
87
- return raw;
88
- }
89
-
90
- const nudgeOf = (point: { areaInset?: BandSlice } | null | undefined) =>
91
- BandNudge.of(plot.scales, point?.areaInset);
92
-
93
- const activePixel = $derived.by((): { x: number; y: number } | null => {
94
- if (!activePoint) return null;
95
- const x = scaledPixel(plot.scales.x, activePoint.x);
96
- const y = scaledPixel(plot.scales.y, activePoint.y);
97
- if (x == null || y == null) return null;
98
- const nudge = nudgeOf(activePoint);
99
- return { x: x + nudge.dx, y: y + nudge.dy };
100
- });
20
+ const activePixel = $derived(activePoint ? PointPixel.of(plot.scales, activePoint) : null);
101
21
 
102
22
  $effect(() => {
103
23
  onActivePointPixel?.(activePixel);
104
24
  });
105
-
106
- const showCrosshairX = $derived(
107
- marker.ruleX !== false && (impliesCrosshairX || marker.ruleX === true)
108
- );
109
- const showCrosshairY = $derived(
110
- marker.ruleY !== false && (impliesCrosshairY || marker.ruleY === true)
111
- );
112
- const ruleX = $derived(showCrosshairX ? (activePoint?.x ?? null) : null);
113
- const ruleY = $derived(showCrosshairY ? (activePoint?.y ?? null) : null);
114
- // areaX/areaY have no implied default - always off unless explicitly set.
115
- const areaX = $derived(marker.areaX === true ? (activePoint?.x ?? null) : null);
116
- const areaY = $derived(marker.areaY === true ? (activePoint?.y ?? null) : null);
117
- const showLabels = $derived(marker.showLabels ?? true);
118
- const format = $derived(marker.format);
119
- /** The hovered value as the marker's display fields ask; `undefined` while nothing does, so the plot's own label stays. */
120
- const numberOf = $derived(NumberFormat.maybe(NumberFormat.displayOf(marker), cfg));
121
- const number = $derived(numberOf ?? NumberFormat.of(undefined, cfg));
122
- const labelOf = (d: HoverDisplayPoint): string => {
123
- if (format) return format(d, number);
124
- const value = Number(d.label);
125
- return numberOf && d.label !== undefined && d.label !== '' && Number.isFinite(value)
126
- ? numberOf(value)
127
- : (d.label ?? '');
128
- };
129
- const ruleStyle = $derived(marker.rule);
130
- const areaStyle = $derived({ ...cfg.hover.area, ...marker.area });
131
- const dotStyle = $derived(marker.dot);
132
- const fontStyle = $derived(marker.text);
133
-
134
- /** Explicit style wins; otherwise fall back to the point's own resolved color. */
135
- const resolveColor = (explicit: string | undefined, point: HoverDisplayPoint) =>
136
- explicit ?? point.color;
137
-
138
- // Horizontal gap between the dot's edge and an 'outside'-anchored label -
139
- // scales with the dot's own resolved radius so the label clears it.
140
- const dotRadius = $derived(dotStyle?.dotRadius ?? cfg.hover.dot.dotRadius ?? 5);
141
-
142
- /**
143
- * Resolves `text.textAnchor: 'outside'` into a per-point anchor +
144
- * offset, mirroring the value-label `'outside'` anchor's own left/right
145
- * split (see pyramid/bar's own `ValueAnchor` handling): a positive `x`
146
- * anchors `'start'` and nudges right, a negative `x` anchors `'end'` and
147
- * nudges left - so a diverging mark's label sits on the side of the dot
148
- * away from zero, on whichever side that dot itself landed. Only
149
- * meaningful when the point's `x` is numeric (e.g. pyramid's magnitude
150
- * axis); anything else falls through to the plain `text` style unchanged.
151
- *
152
- * Also overrides `cfg.hover.font`'s default `dy: -18` (meant for a label
153
- * floating *above* the dot) back to vertically centered, and clears the
154
- * dot's own radius horizontally instead of the flat default nudge, so the
155
- * label doesn't collide with the dot it's labeling.
156
- */
157
- function resolveFontStyle(point: HoverDisplayPoint) {
158
- if (fontStyle?.textAnchor !== 'outside' || typeof point.x !== 'number') {
159
- return { ...cfg.hover.font, ...fontStyle, fill: resolveColor(fontStyle?.fill, point) };
160
- }
161
- const outward = point.x >= 0;
162
- const gap = dotRadius + 5;
163
- return {
164
- ...cfg.hover.font,
165
- ...fontStyle,
166
- fill: resolveColor(fontStyle?.fill, point),
167
- textAnchor: outward ? ('start' as const) : ('end' as const),
168
- lineAnchor: fontStyle?.lineAnchor ?? ('middle' as const),
169
- dx: fontStyle?.dx ?? (outward ? gap : -gap),
170
- dy: fontStyle?.dy ?? 0
171
- };
172
- }
173
25
  </script>
174
-
175
- {#if areaX != null}
176
- <BarMarker
177
- marker={{
178
- type: 'bar',
179
- role: 'highlight',
180
- isHorizontal: false,
181
- data: [],
182
- category: areaX,
183
- insetLeft: activePoint?.areaInset?.start,
184
- insetRight: activePoint?.areaInset?.end,
185
- styles: areaStyle
186
- }}
187
- />
188
- {/if}
189
-
190
- {#if areaY != null}
191
- <BarMarker
192
- marker={{
193
- type: 'bar',
194
- role: 'highlight',
195
- isHorizontal: true,
196
- data: [],
197
- category: areaY,
198
- insetTop: activePoint?.areaInset?.start,
199
- insetBottom: activePoint?.areaInset?.end,
200
- styles: areaStyle
201
- }}
202
- />
203
- {/if}
204
-
205
- {#if ruleX != null}
206
- <g transform="translate({nudgeOf(activePoint).dx}, {nudgeOf(activePoint).dy})">
207
- <RuleMarker
208
- marker={{
209
- type: 'rule',
210
- axis: 'x',
211
- value: ruleX,
212
- styles: { ...cfg.hover.rule, ...ruleStyle }
213
- }}
214
- />
215
- </g>
216
- {/if}
217
-
218
- {#if ruleY != null}
219
- <g transform="translate({nudgeOf(activePoint).dx}, {nudgeOf(activePoint).dy})">
220
- <RuleMarker
221
- marker={{
222
- type: 'rule',
223
- axis: 'y',
224
- value: ruleY,
225
- styles: { ...cfg.hover.rule, ...ruleStyle }
226
- }}
227
- />
228
- </g>
229
- {/if}
230
-
231
- {#if data.length > 0}
232
- {#each data as point (`${point.series ?? ''}_${point.x}_${point.y}`)}
233
- <!-- A grouped bar's point sits in its series' slice of the band (`areaInset`), not at the band's middle. -->
234
- <g transform="translate({nudgeOf(point).dx}, {nudgeOf(point).dy})">
235
- <DotMarker
236
- marker={{
237
- type: 'dot',
238
- data: [point],
239
- x: (d) => d.x,
240
- y: (d) => d.y,
241
- styles: {
242
- ...cfg.hover.dot,
243
- ...dotStyle,
244
- dotFill: resolveColor(dotStyle?.dotFill, point),
245
- dotStroke: resolveColor(dotStyle?.dotStroke, point)
246
- }
247
- }}
248
- />
249
- </g>
250
- {/each}
251
- {#if showLabels}
252
- {#each data as point (`${point.series ?? ''}_${point.x}_${point.y}`)}
253
- <g transform="translate({nudgeOf(point).dx}, {nudgeOf(point).dy})">
254
- <TextMarker
255
- marker={{
256
- type: 'text',
257
- data: [point],
258
- x: (d: HoverDisplayPoint) => d.x,
259
- y: (d: HoverDisplayPoint) => d.y,
260
- text: labelOf,
261
- styles: resolveFontStyle(point)
262
- }}
263
- />
264
- </g>
265
- {/each}
266
- {/if}
267
- {/if}
@@ -1,35 +1,12 @@
1
- import type { HoverMarkerConfig } from '../../types/markers/common';
2
1
  import type { HoverDisplayPoint } from '../../types/layout/hover';
3
2
  /**
4
- * In-SVG hover highlight, rendered *inside* a `<Plot>`. Because it positions
5
- * itself through the host plot's scales, it places the same coordinate
6
- * correctly in every facet - that is what makes cross-facet sync work without
7
- * any pixel math. Draws optional x/y crosshair rules plus a dot + value label
8
- * for each matched point.
9
- *
10
- * Takes the raw `marker` config plus the couple of things it can't know on
11
- * its own - `activePoint` (the specific matched point actually under the
12
- * cursor, for the crosshair position; see `controller.svelte.ts`'s own doc
13
- * comment) and whether the active hover strategy implies a crosshair on
14
- * each axis by default - the same "component owns its own rendering"
15
- * pattern `BarMarker`/`RuleMarker` follow. `activePoint`/
16
- * `impliesCrosshairX`/`impliesCrosshairY` are all optional and default to
17
- * "no crosshair".
18
- *
19
- * `areaX`/`areaY` are a separate, always-explicit opt-in (no implied
20
- * default) for a thickened area highlight in place of the thin crosshair -
21
- * see `HoverMarkerConfig`'s own doc comment. Rendered via `BarMarker`'s
22
- * `role: 'highlight'`, so it renders nothing on an axis without a band
23
- * scale (e.g. a line/scatter plot's continuous axis).
3
+ * Where the hover is, rendered *inside* a `<Plot>`: it reports the pixel position of the point under the pointer,
4
+ * through the host plot's scales, so a synced plot's tooltip can sit on it. It draws nothing itself - the
5
+ * `hover` marker's `back` and `front` markers are drawn by `GeometryLayout`, as every other marker.
24
6
  */
25
7
  interface Props {
26
- data?: HoverDisplayPoint[];
27
- /** Narrowed to just the fields this component reads - `HoverMarkerConfig` also carries routing/scoping fields (`series`/`scope`/`strategy`/`sync`) it has no use for. */
28
- marker: Pick<HoverMarkerConfig, 'ruleX' | 'ruleY' | 'areaX' | 'areaY' | 'showLabels' | 'format' | 'rule' | 'area' | 'dot' | 'text' | 'decimals' | 'prefix' | 'suffix' | 'signDisplay'>;
29
8
  activePoint?: HoverDisplayPoint | null;
30
- impliesCrosshairX?: boolean;
31
- impliesCrosshairY?: boolean;
32
- /** Reports `activePoint`'s real pixel position within this facet's own box, or `null` when nothing's matched. */
9
+ /** Reports `activePoint`'s pixel position within this facet's own box, or `null` when nothing's matched. */
33
10
  onActivePointPixel?: (pos: {
34
11
  x: number;
35
12
  y: number;
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { Hull } 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 `'hull'` marker as `<Hull>` - the convex hull around a cluster of points. */
8
9
  let { marker }: { marker: HullMarkerConfig } = $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
  <Hull
18
+ {...events.props}
16
19
  {data}
17
20
  x={marker.x}
18
21
  y={marker.y}
@@ -1,10 +1,12 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { Image } from 'svelteplot';
3
4
  import RowOffsetMarks from '../utils/RowOffsetMarks.svelte';
4
5
  import type { ImageMarkerConfig } from '../../types/markers/common';
5
6
 
6
7
  /** Renders one `'image'` marker as `<Image>` - an image centered on each row's `x`/`y`. */
7
8
  let { marker }: { marker: ImageMarkerConfig } = $props();
9
+ const events = MarkerEvents.use(() => marker);
8
10
 
9
11
  const data = $derived(marker.data ?? []);
10
12
  </script>
@@ -12,6 +14,7 @@
12
14
  <RowOffsetMarks {marker} rows={data}>
13
15
  {#snippet mark(rows)}
14
16
  <Image
17
+ {...events.props}
15
18
  data={rows}
16
19
  x={marker.x}
17
20
  y={marker.y}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { Line } from 'svelteplot';
3
4
  import { MarkerChannels } from '../utils/MarkerChannels';
4
5
  import { getConfiguration } from '../../configuration/config.svelte';
@@ -10,6 +11,7 @@
10
11
  * its color, so each `grouping`'s line takes its group's color.
11
12
  */
12
13
  let { marker }: { marker: LineMarkerConfig } = $props();
14
+ const events = MarkerEvents.use(() => marker);
13
15
 
14
16
  const cfg = $derived(getConfiguration());
15
17
  const data = $derived(marker.data ?? []);
@@ -17,6 +19,7 @@
17
19
  </script>
18
20
 
19
21
  <Line
22
+ {...events.props}
20
23
  {data}
21
24
  x={marker.x}
22
25
  y={marker.y}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { Geo } from 'svelteplot';
3
4
  import { geoPath } from 'd3-geo';
4
5
  import { resolveAccessor } from '../../utils/accessors';
@@ -14,6 +15,7 @@
14
15
  * projected positions.
15
16
  */
16
17
  let { marker }: { marker: GeoLinkMarkerConfig } = $props();
18
+ const events = MarkerEvents.use(() => marker);
17
19
 
18
20
  type Point = [number, number];
19
21
  const STEPS = 64;
@@ -181,6 +183,7 @@
181
183
  {:else}
182
184
  <!-- No `fill` prop: svelteplot treats any string as scale-worthy unless it's a real CSS color, so a literal `'none'` would run through the color scale instead of staying unfilled. Omitting it leaves svelteplot's own unfilled default in place. -->
183
185
  <Geo
186
+ {...events.props}
184
187
  class="link"
185
188
  data={arcFeatures}
186
189
  stroke={marker.styles?.stroke ?? 'currentColor'}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { Raster } from 'svelteplot';
3
4
  import type { RasterMarkerConfig } from '../../types/markers/common';
4
5
 
@@ -8,11 +9,13 @@
8
9
  * so it is forwarded as `null` rather than an empty array.
9
10
  */
10
11
  let { marker }: { marker: RasterMarkerConfig } = $props();
12
+ const events = MarkerEvents.use(() => marker);
11
13
 
12
14
  const data = $derived(marker.data?.length ? marker.data : null);
13
15
  </script>
14
16
 
15
17
  <Raster
18
+ {...events.props}
16
19
  {data}
17
20
  x={marker.x}
18
21
  y={marker.y}
@@ -1,7 +1,9 @@
1
1
  <script lang="ts">
2
+ import { RowStyle } from '../utils/RowStyle';
2
3
  import { Rect } from 'svelteplot';
3
4
  import { MarkerChannels } from '../utils/MarkerChannels';
4
5
  import { getConfiguration } from '../../configuration/config.svelte';
6
+ import { MarkerEvents } from '../utils/MarkerEvents';
5
7
  import type { RectMarkerConfig } from '../../types/markers/common';
6
8
 
7
9
  /** Renders one `'rect'` marker as a `<Rect>` call - an arbitrary rectangle, unlike `BarMarker`'s category-band-anchored bar. */
@@ -13,6 +15,8 @@
13
15
  const opacityBuckets = $derived(
14
16
  MarkerChannels.buildOpacityBuckets(data, marker.opacity, marker.scales, cfg)
15
17
  );
18
+
19
+ const events = MarkerEvents.use(() => marker);
16
20
  </script>
17
21
 
18
22
  {#if opacityBuckets}
@@ -26,16 +30,18 @@
26
30
  y1={marker.y1}
27
31
  y2={marker.y2}
28
32
  interval={marker.interval}
29
- insetLeft={marker.insetLeft}
30
- insetRight={marker.insetRight}
31
- insetTop={marker.insetTop}
32
- insetBottom={marker.insetBottom}
33
- fill={channelFill ?? marker.styles?.fill}
33
+ insetLeft={RowStyle.field(marker.styles?.insetLeft)}
34
+ insetRight={RowStyle.field(marker.styles?.insetRight)}
35
+ insetTop={RowStyle.field(marker.styles?.insetTop)}
36
+ insetBottom={RowStyle.field(marker.styles?.insetBottom)}
37
+ fill={channelFill ?? RowStyle.of(marker.styles?.fill, data)}
34
38
  fillOpacity={bucket.value}
35
- stroke={marker.styles?.stroke}
36
- strokeWidth={marker.styles?.strokeWidth}
37
- strokeOpacity={marker.styles?.strokeOpacity}
39
+ stroke={RowStyle.of(marker.styles?.stroke, data)}
40
+ strokeWidth={RowStyle.field(marker.styles?.strokeWidth)}
41
+ strokeOpacity={RowStyle.opacity(marker.styles?.strokeOpacity)}
38
42
  strokeDasharray={marker.styles?.strokeDasharray}
43
+ borderRadius={RowStyle.field(marker.styles?.borderRadius)}
44
+ {...events.props}
39
45
  />
40
46
  {/each}
41
47
  {:else}
@@ -48,15 +54,17 @@
48
54
  y1={marker.y1}
49
55
  y2={marker.y2}
50
56
  interval={marker.interval}
51
- insetLeft={marker.insetLeft}
52
- insetRight={marker.insetRight}
53
- insetTop={marker.insetTop}
54
- insetBottom={marker.insetBottom}
55
- fill={channelFill ?? marker.styles?.fill}
56
- fillOpacity={marker.styles?.fillOpacity ?? 1}
57
- stroke={marker.styles?.stroke}
58
- strokeWidth={marker.styles?.strokeWidth}
59
- strokeOpacity={marker.styles?.strokeOpacity}
57
+ insetLeft={RowStyle.field(marker.styles?.insetLeft)}
58
+ insetRight={RowStyle.field(marker.styles?.insetRight)}
59
+ insetTop={RowStyle.field(marker.styles?.insetTop)}
60
+ insetBottom={RowStyle.field(marker.styles?.insetBottom)}
61
+ fill={channelFill ?? RowStyle.of(marker.styles?.fill, data)}
62
+ fillOpacity={RowStyle.opacity(marker.styles?.fillOpacity) ?? 1}
63
+ stroke={RowStyle.of(marker.styles?.stroke, data)}
64
+ strokeWidth={RowStyle.field(marker.styles?.strokeWidth)}
65
+ strokeOpacity={RowStyle.opacity(marker.styles?.strokeOpacity)}
60
66
  strokeDasharray={marker.styles?.strokeDasharray}
67
+ borderRadius={RowStyle.field(marker.styles?.borderRadius)}
68
+ {...events.props}
61
69
  />
62
70
  {/if}
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
3
  import { RegressionX, RegressionY } from 'svelteplot';
3
4
  import { usePlot } from '../../layout/plot/usePlot';
4
5
  import type { RegressionMarkerConfig } from '../../types/markers/common';
@@ -18,6 +19,7 @@
18
19
  * active, never exposed as its own style option.
19
20
  */
20
21
  let { marker }: { marker: RegressionMarkerConfig } = $props();
22
+ const events = MarkerEvents.use(() => marker);
21
23
 
22
24
  const plot = usePlot();
23
25
  const isHorizontal = $derived(plot.axes?.isHorizontal ?? false);
@@ -27,6 +29,7 @@
27
29
  </script>
28
30
 
29
31
  <RegressionMark
32
+ {...events.props}
30
33
  {data}
31
34
  x={marker.x}
32
35
  y={marker.y}
@@ -1,4 +1,6 @@
1
1
  <script lang="ts">
2
+ import { RowStyle } from '../utils/RowStyle';
3
+ import { MarkerEvents } from '../utils/MarkerEvents';
2
4
  import { RuleX, RuleY } from 'svelteplot';
3
5
  import type { AxisValue } from '../../types/layout/mapping';
4
6
  import { RowStroke } from '../utils/RowStroke';
@@ -14,6 +16,7 @@
14
16
  * straight through to svelteplot's own `RuleX`/`RuleY`.
15
17
  */
16
18
  const { marker }: { marker: RuleMarkerConfig } = $props();
19
+ const events = MarkerEvents.use(() => marker);
17
20
 
18
21
  const axis = $derived(marker.axis);
19
22
  const data = $derived(marker.data);
@@ -34,21 +37,28 @@
34
37
  */
35
38
  const position = $derived(data ? value : (d: { v: AxisValue }) => d.v);
36
39
 
37
- /** Each row's own stroke, over the marker's `styles`. */
40
+ /** Each row's stroke: the marker's `styles`, which can be functions of the row. */
38
41
  const row = $derived(
39
- RowStroke.of(marker, styles, { stroke: 'currentColor', strokeWidth: 1, strokeOpacity: 1 })
42
+ RowStroke.of(styles, rows, { stroke: 'currentColor', strokeWidth: 1, strokeOpacity: 1 })
40
43
  );
41
44
  </script>
42
45
 
43
46
  <RuleMark
47
+ {...events.props}
44
48
  data={rows}
45
49
  {...axis === 'x'
46
50
  ? { x: position, y1: marker.y1, y2: marker.y2 }
47
51
  : { y: position, x1: marker.x1, x2: marker.x2 }}
48
- inset={marker.inset}
52
+ inset={RowStyle.field(marker.styles?.inset)}
49
53
  {...axis === 'x'
50
- ? { insetTop: marker.insetTop, insetBottom: marker.insetBottom }
51
- : { insetLeft: marker.insetLeft, insetRight: marker.insetRight }}
54
+ ? {
55
+ insetTop: RowStyle.field(marker.styles?.insetTop),
56
+ insetBottom: RowStyle.field(marker.styles?.insetBottom)
57
+ }
58
+ : {
59
+ insetLeft: RowStyle.field(marker.styles?.insetLeft),
60
+ insetRight: RowStyle.field(marker.styles?.insetRight)
61
+ }}
52
62
  stroke={row.stroke}
53
63
  strokeWidth={row.strokeWidth}
54
64
  strokeOpacity={row.strokeOpacity}
@@ -0,0 +1,44 @@
1
+ /** What a label is once it is fitted: the text to write, on as many lines as it takes, and the size to write it at. */
2
+ export type FittedText = {
3
+ text: string;
4
+ fontSize: number;
5
+ };
6
+ /** What a label is fitted to. */
7
+ export type TextFitOptions = {
8
+ text: string;
9
+ /** What to write instead when `text` does not fit even cut short: a value alone, say. Hidden if that does not fit either. */
10
+ fallback?: string;
11
+ /** The room the label has, in px. */
12
+ width: number;
13
+ height: number;
14
+ /** The size the label is written at when it has the room for it. */
15
+ fontSize: number;
16
+ /** The smallest size it is written at, shrunk one px at a time down to it. */
17
+ minFontSize: number;
18
+ /** The height of a line, as a multiple of the font size. */
19
+ lineHeight: number;
20
+ /** How wide `text` writes at `fontSize`, in px. */
21
+ measure: (text: string, fontSize: number) => number;
22
+ /** The fewest letters of a text worth writing when it is cut short. */
23
+ minLetters: number;
24
+ };
25
+ /**
26
+ * How a label that may be too big for its box is written: a smaller size first; failing that the text cut short
27
+ * with an ellipsis on its last line, at the smallest size; failing that its `fallback`; failing that nothing.
28
+ */
29
+ export declare class TextFit {
30
+ #private;
31
+ static fit(options: TextFitOptions): FittedText | undefined;
32
+ /**
33
+ * `text` on at most `room.lines` lines of `room.width`: whole words per line, a new line after each newline. With `cut`,
34
+ * 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
35
+ * ellipsis; without it, a text that does not fit comes to `undefined`, and so does one whose first line shows
36
+ * under `minLetters` letters.
37
+ */
38
+ static wrap(text: string, room: {
39
+ width: number;
40
+ lines: number;
41
+ }, cut: boolean, minLetters: number, measure: (text: string) => number): string[] | undefined;
42
+ /** `text` as it fits `width`: as it is, or cut short with an ellipsis. */
43
+ static cut(text: string, width: number, measure: (text: string) => number): string;
44
+ }