@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
@@ -13,7 +13,7 @@ export class MappingPhase {
13
13
  constructor(options = {}) {
14
14
  this.#options = options;
15
15
  }
16
- run = (state, ctx) => {
16
+ run = (state, env) => {
17
17
  const first = state.resolvedSeries?.[0];
18
18
  const identity = { accessor: (d) => d };
19
19
  const size = (value) => typeof value === 'number' ? value : MappingPhase.#channel(value);
@@ -25,10 +25,11 @@ export class MappingPhase {
25
25
  opacity: MappingPhase.#channel(state.opacity),
26
26
  symbol: MappingPhase.#channel(state.symbol),
27
27
  r: size(state.r),
28
- length: size(state.length)
28
+ length: size(state.length),
29
+ value: MappingPhase.#channel(state.value)
29
30
  };
30
31
  const next = { ...state, channels };
31
- return this.#options.extend ? this.#options.extend(next, ctx) : next;
32
+ return this.#options.extend ? this.#options.extend(next, env) : next;
32
33
  };
33
34
  /** A channel prop resolved to a row accessor, keeping it as `source`, or left out when unset. */
34
35
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
@@ -0,0 +1,26 @@
1
+ import type { PlotStylesConfig } from '../../types/configuration/styling';
2
+ /**
3
+ * A plot's markers with their styles as svelteplot reads them, before any is drawn: a named line style
4
+ * (`strokeDasharray: 'dashed'`) is the SVG dash pattern it stands for, wherever in a marker's config it is
5
+ * set - its `styles`, a label's, a part's (a box's whiskers) - and a label inside its shape with no `fill` of its
6
+ * own is written in the color that reads best on the shape's. A marker component draws what it is given.
7
+ */
8
+ export declare class MarkerStyles {
9
+ #private;
10
+ /**
11
+ * Every marker of `markers`, resolved. A marker with nothing to resolve is kept as it is. `rows` are what a
12
+ * marker with no `data` of its own draws.
13
+ */
14
+ static resolveAll<T>(markers: T[], plot?: {
15
+ cfg?: PlotStylesConfig;
16
+ rows?: unknown[];
17
+ }): T[];
18
+ /**
19
+ * `marker` resolved again after its styles changed (as the hover restyles a shape): a label written in the color
20
+ * that read best on the shape's old one reads best on its new one.
21
+ */
22
+ static restyle<T>(marker: T, plot?: {
23
+ cfg?: PlotStylesConfig;
24
+ rows?: unknown[];
25
+ }): T;
26
+ }
@@ -0,0 +1,126 @@
1
+ import { MarkerChannels } from '../../markers/utils/MarkerChannels';
2
+ import { RowStyle } from '../../markers/utils/RowStyle';
3
+ import { CssColor } from '../../utils/color/CssColor';
4
+ /**
5
+ * A plot's markers with their styles as svelteplot reads them, before any is drawn: a named line style
6
+ * (`strokeDasharray: 'dashed'`) is the SVG dash pattern it stands for, wherever in a marker's config it is
7
+ * set - its `styles`, a label's, a part's (a box's whiskers) - and a label inside its shape with no `fill` of its
8
+ * own is written in the color that reads best on the shape's. A marker component draws what it is given.
9
+ */
10
+ export class MarkerStyles {
11
+ /** The SVG dash pattern each named line style stands for; a solid line has none. */
12
+ static #DASHES = {
13
+ solid: undefined,
14
+ dashed: '6 4',
15
+ dotted: '2 3',
16
+ dashdot: '6 3 2 3'
17
+ };
18
+ /** The style fields that take a dash pattern. */
19
+ static #DASH_KEYS = new Set(['strokeDasharray', 'dotStrokeDasharray']);
20
+ /** The label colors this class chose for a shape's color, which a restyled shape chooses again. */
21
+ static #contrasts = new WeakSet();
22
+ /** Fields that hold rows rather than config, which are never walked. */
23
+ static #ROW_KEYS = new Set(['data', 'features']);
24
+ /**
25
+ * Every marker of `markers`, resolved. A marker with nothing to resolve is kept as it is. `rows` are what a
26
+ * marker with no `data` of its own draws.
27
+ */
28
+ static resolveAll(markers, plot = {}) {
29
+ return markers.map((marker) => MarkerStyles.#contrasted(MarkerStyles.#walk(marker), plot));
30
+ }
31
+ /**
32
+ * `marker` resolved again after its styles changed (as the hover restyles a shape): a label written in the color
33
+ * that read best on the shape's old one reads best on its new one.
34
+ */
35
+ static restyle(marker, plot = {}) {
36
+ const label = marker.label;
37
+ const fill = label?.styles?.fill;
38
+ const fresh = typeof fill === 'function' && MarkerStyles.#contrasts.has(fill)
39
+ ? { ...marker, label: { ...label, styles: { ...label.styles, fill: undefined } } }
40
+ : marker;
41
+ return MarkerStyles.resolveAll([fresh], plot)[0];
42
+ }
43
+ /** The marker with its label inside its shape written in the candidate that reads best on each row's color. */
44
+ static #contrasted(marker, plot) {
45
+ const { cfg } = plot;
46
+ if (!cfg || !MarkerStyles.#isPlain(marker))
47
+ return marker;
48
+ const label = marker.label;
49
+ if (!MarkerStyles.#isPlain(label) || label.outside || label.styles?.fill !== undefined) {
50
+ return marker;
51
+ }
52
+ const colorOf = MarkerStyles.#shapeColor(marker, marker.data ?? plot.rows ?? [], cfg);
53
+ if (!colorOf)
54
+ return marker;
55
+ const candidates = cfg.text.label.contrast;
56
+ const opacityOf = MarkerStyles.#opacity(marker.styles?.fillOpacity);
57
+ // What the label is read on: the shape's color, blended with the plot's background as far as it is see-through.
58
+ const fill = (row) => {
59
+ const color = colorOf(row);
60
+ if (!color)
61
+ return undefined;
62
+ const seen = CssColor.composite(color, opacityOf(row), cfg.background);
63
+ return CssColor.contrastText(seen, candidates);
64
+ };
65
+ MarkerStyles.#contrasts.add(fill);
66
+ return { ...marker, label: { ...label, styles: { ...label.styles, fill } } };
67
+ }
68
+ /** The opacity each row's shape is drawn with: a number, the field of the rows a string names, a function of the row. */
69
+ static #opacity(style) {
70
+ const read = typeof style === 'function'
71
+ ? (row) => style(row)
72
+ : typeof style === 'string'
73
+ ? (row) => row?.[style]
74
+ : () => style;
75
+ return (row) => {
76
+ const value = Number(read(row) ?? 1);
77
+ return Number.isFinite(value) ? value : 1;
78
+ };
79
+ }
80
+ /** The color each row's shape is drawn with: the marker's `color` channel, else its `styles.fill`. */
81
+ static #shapeColor(marker, rows, cfg) {
82
+ const fill = marker.styles?.fill;
83
+ return (MarkerChannels.buildFill(rows, marker.color, marker.scales, cfg) ??
84
+ RowStyle.colorOf(fill, rows) ??
85
+ (marker.type === 'waffle' ? () => cfg.palette[0] : undefined));
86
+ }
87
+ /** A dash pattern for `style`: a named line style's, any other as it is; a function of the row gives each row's. */
88
+ static #dash(style) {
89
+ if (typeof style === 'function')
90
+ return (...args) => MarkerStyles.#pattern(style(...args)) ?? 'none';
91
+ return MarkerStyles.#pattern(style);
92
+ }
93
+ static #pattern(style) {
94
+ return typeof style === 'string' && style in MarkerStyles.#DASHES
95
+ ? MarkerStyles.#DASHES[style]
96
+ : style;
97
+ }
98
+ /** `value` with its dash styles resolved: plain objects and arrays walked, copied only where something changes. */
99
+ static #walk(value) {
100
+ if (Array.isArray(value)) {
101
+ const next = value.map((item) => MarkerStyles.#walk(item));
102
+ return next.some((item, i) => item !== value[i]) ? next : value;
103
+ }
104
+ if (!MarkerStyles.#isPlain(value))
105
+ return value;
106
+ let copy;
107
+ for (const [key, own] of Object.entries(value)) {
108
+ if (MarkerStyles.#ROW_KEYS.has(key))
109
+ continue;
110
+ const next = MarkerStyles.#DASH_KEYS.has(key)
111
+ ? MarkerStyles.#dash(own)
112
+ : MarkerStyles.#walk(own);
113
+ if (next === own)
114
+ continue;
115
+ copy ??= { ...value };
116
+ copy[key] = next;
117
+ }
118
+ return copy ?? value;
119
+ }
120
+ static #isPlain(value) {
121
+ if (typeof value !== 'object' || value === null)
122
+ return false;
123
+ const proto = Object.getPrototypeOf(value);
124
+ return proto === Object.prototype || proto === null;
125
+ }
126
+ }
@@ -1,14 +1,14 @@
1
- import type { AxisPlotCtx, AxisPlotState, MarkersStageOptions, PhaseStage } from '../../types/phases';
1
+ import type { AxisPlotEnv, AxisPlotState, MarkersStageOptions, PhaseStage } from '../../types/phases';
2
2
  /**
3
3
  * The shared "markers" phase: everything the plot draws, bottom to top - the
4
4
  * plot kind's own marks, then what the "statistics" phase left in
5
5
  * `state.markers` (the author's markers and the plot's statistics), then its
6
6
  * value labels when `styles.values.show` turns them on, each with what every
7
- * label shares ({@link ValueLabels.hooks}).
7
+ * label shares ({@link ValueLabels.hooks}), and every style as svelteplot reads it ({@link MarkerStyles}).
8
8
  */
9
- export declare class MarkersPhase<TState extends AxisPlotState<any, any, any, any>, TCtx extends AxisPlotCtx> implements PhaseStage<TState, TCtx> {
9
+ export declare class MarkersPhase<TState extends AxisPlotState<any, any, any, any>, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
10
10
  #private;
11
11
  readonly phase: "markers";
12
- constructor(options: MarkersStageOptions<TState, TCtx>);
13
- run: (state: TState, ctx: TCtx) => TState;
12
+ constructor(options: MarkersStageOptions<TState, TEnv>);
13
+ run: (state: TState, env: TEnv) => TState;
14
14
  }
@@ -1,10 +1,11 @@
1
1
  import { MarkerChannels } from '../../markers/utils/MarkerChannels';
2
+ import { MarkerStyles } from './MarkerStyles';
2
3
  /**
3
4
  * The shared "markers" phase: everything the plot draws, bottom to top - the
4
5
  * plot kind's own marks, then what the "statistics" phase left in
5
6
  * `state.markers` (the author's markers and the plot's statistics), then its
6
7
  * value labels when `styles.values.show` turns them on, each with what every
7
- * label shares ({@link ValueLabels.hooks}).
8
+ * label shares ({@link ValueLabels.hooks}), and every style as svelteplot reads it ({@link MarkerStyles}).
8
9
  */
9
10
  export class MarkersPhase {
10
11
  phase = 'markers';
@@ -12,17 +13,18 @@ export class MarkersPhase {
12
13
  constructor(options) {
13
14
  this.#options = options;
14
15
  }
15
- run = (state, ctx) => {
16
+ run = (state, env) => {
16
17
  const options = this.#options;
17
18
  const labels = state.valueLabels;
18
19
  const valueLabels = labels?.show && options.valueLabels
19
- ? options
20
- .valueLabels(labels, state, ctx)
21
- .map((marker) => ({ ...labels.hooks(ctx), ...marker }))
20
+ ? options.valueLabels(labels, state, env).map((marker) => {
21
+ const { styles, ...hooks } = labels.hooks(env);
22
+ return { ...hooks, ...marker, styles: { ...styles, ...marker.styles } };
23
+ })
22
24
  : [];
23
25
  return {
24
26
  ...state,
25
- markers: MarkerChannels.inheritPosition(MarkerChannels.inheritAll([...options.marks(state, ctx), ...(state.markers ?? []), ...valueLabels], state.scales), state.processedData)
27
+ markers: MarkerStyles.resolveAll(MarkerChannels.inheritPosition(MarkerChannels.inheritAll([...options.marks(state, env), ...(state.markers ?? []), ...valueLabels], state.scales), state.processedData), { cfg: env.cfg, rows: state.processedData?.data })
26
28
  };
27
29
  };
28
30
  }
@@ -1,6 +1,6 @@
1
1
  import { PlotAxes } from '../data/PlotAxes';
2
2
  import type { AxisChannelName } from '../../types/layout/mapping';
3
- import type { AxisPlotState, AxisPlotCtx, PhaseStage, ScalesStageOptions } from '../../types/phases';
3
+ import type { AxisPlotState, AxisPlotEnv, PhaseStage, ScalesStageOptions } from '../../types/phases';
4
4
  type AnyAxisState = AxisPlotState<any, any, any, any>;
5
5
  /**
6
6
  * The shared "scales" phase. Each axis the kind lays out as categories
@@ -10,10 +10,10 @@ type AnyAxisState = AxisPlotState<any, any, any, any>;
10
10
  * transforms gave the rows - from zero on the axes `zero` names. The author's
11
11
  * `scales` always win, and a kind adds its own on top (`defaults`, `fit`, `extend`).
12
12
  */
13
- export declare class ScalesPhase<TState extends AnyAxisState, TCtx extends AxisPlotCtx> implements PhaseStage<TState, TCtx> {
13
+ export declare class ScalesPhase<TState extends AnyAxisState, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
14
14
  #private;
15
15
  readonly phase: "scales";
16
- constructor(options?: ScalesStageOptions<TState, TCtx>);
16
+ constructor(options?: ScalesStageOptions<TState, TEnv>);
17
17
  /** The axes whose marks grow from zero, in this state. */
18
18
  zeroAxes(state: {
19
19
  axes?: PlotAxes;
@@ -24,6 +24,6 @@ export declare class ScalesPhase<TState extends AnyAxisState, TCtx extends AxisP
24
24
  }): AxisChannelName[];
25
25
  /** Whether the kind keeps its categories in the order the data gives them. */
26
26
  get keepsDataOrder(): boolean;
27
- run: (state: TState, ctx: TCtx) => TState;
27
+ run: (state: TState, env: TEnv) => TState;
28
28
  }
29
29
  export {};
@@ -44,10 +44,10 @@ export class ScalesPhase {
44
44
  get keepsDataOrder() {
45
45
  return this.#options.bandOrder === 'data';
46
46
  }
47
- run = (state, ctx) => {
47
+ run = (state, env) => {
48
48
  const options = this.#options;
49
49
  const { axes, processedData, markers = [] } = state;
50
- const defaults = options.defaults?.(state, ctx) ?? {};
50
+ const defaults = options.defaults?.(state, env) ?? {};
51
51
  const symmetric = new Set(this.symmetricAxes(state));
52
52
  const zero = new Set(this.zeroAxes(state));
53
53
  const scales = { ...state.scales };
@@ -72,7 +72,7 @@ export class ScalesPhase {
72
72
  scales[axis] = { ...scales[axis], domain: [-reach, reach] };
73
73
  }
74
74
  }
75
- const fitted = options.fit?.({ ...state, scales }, ctx) ?? {};
75
+ const fitted = options.fit?.({ ...state, scales }, env) ?? {};
76
76
  const fittedAxes = [];
77
77
  for (const axis of AXES) {
78
78
  if (!fitted[axis])
@@ -111,7 +111,7 @@ export class ScalesPhase {
111
111
  : { ...author, domain: [lo, hi], nice: author?.nice ?? true };
112
112
  }
113
113
  const next = { ...state, scales, ...(fittedAxes.length ? { fittedAxes } : {}) };
114
- return options.extend ? options.extend(next, ctx) : next;
114
+ return options.extend ? options.extend(next, env) : next;
115
115
  };
116
116
  /** A category axis as a band scale: the kind's options under the author's, in the order the kind asks for. */
117
117
  #band(author, own, state, axis) {
@@ -30,11 +30,11 @@ type SharedScalesState = FacetStageState & {
30
30
  * can't happen there. Without options, a kind still shares its domains: it just
31
31
  * has no bands and nothing that starts from zero.
32
32
  */
33
- export declare class SharedScalesPhase<TState extends SharedScalesState, TCtx> implements PhaseStage<TState, TCtx> {
33
+ export declare class SharedScalesPhase<TState extends SharedScalesState, TEnv> implements PhaseStage<TState, TEnv> {
34
34
  #private;
35
35
  readonly phase: "sharedScales";
36
36
  constructor(options: SharedScalesOptions | undefined, scales?: ScalesPhase<any, any>);
37
- run: (state: TState, ctx: TCtx) => TState;
37
+ run: (state: TState, env: TEnv) => TState;
38
38
  /**
39
39
  * One axis' domain over some slices: sorted values on a band axis, `[min, max]`
40
40
  * otherwise, or `undefined`. A numeric extent is niced here, once, so every
@@ -34,7 +34,7 @@ export class SharedScalesPhase {
34
34
  this.#scales = scales;
35
35
  this.#kindScales = new Pipeline([scales]);
36
36
  }
37
- run = (state, ctx) => {
37
+ run = (state, env) => {
38
38
  const facet = state.facet;
39
39
  const panels = facet ? (state.panels ?? []) : [];
40
40
  // A symmetric axis has no domain but the one the kind's "scales" phase gives it.
@@ -54,7 +54,7 @@ export class SharedScalesPhase {
54
54
  const domainOver = (channel, members) => {
55
55
  if (fromPhase.has(channel)) {
56
56
  const scoped = members ? FacetPanels.narrowToPanels(state, members) : state;
57
- const scales = this.#kindScales.run(scoped, ctx).scales;
57
+ const scales = this.#kindScales.run(scoped, env).scales;
58
58
  const domain = scales?.[channel]?.domain;
59
59
  return domain === undefined ? undefined : { domain };
60
60
  }
@@ -35,14 +35,5 @@ export declare class MarkerGrouping {
35
35
  color?: unknown;
36
36
  defaultColor?: string;
37
37
  }): TMarker[];
38
- /**
39
- * Gives a scoped hover marker its series color through its own `dot` and
40
- * `text` styles, the way `withSeriesColor` does for other markers. A style the
41
- * marker sets itself keeps its own color.
42
- */
43
- static withHoverSeriesColor<T extends {
44
- dot?: object;
45
- text?: object;
46
- }>(marker: T, color: string | undefined): T;
47
38
  }
48
39
  export {};
@@ -94,20 +94,4 @@ export class MarkerGrouping {
94
94
  return Object.keys(updates).length ? { ...m, ...updates } : marker;
95
95
  });
96
96
  }
97
- /**
98
- * Gives a scoped hover marker its series color through its own `dot` and
99
- * `text` styles, the way `withSeriesColor` does for other markers. A style the
100
- * marker sets itself keeps its own color.
101
- */
102
- static withHoverSeriesColor(marker, color) {
103
- if (!color)
104
- return marker;
105
- const dot = (marker.dot ?? {});
106
- const text = (marker.text ?? {});
107
- return {
108
- ...marker,
109
- dot: { ...dot, dotFill: dot.dotFill ?? color, dotStroke: dot.dotStroke ?? color },
110
- text: { ...text, fill: text.fill ?? color }
111
- };
112
- }
113
97
  }
@@ -68,7 +68,7 @@ export class StatisticsPhase {
68
68
  colorFor: colorForSeries
69
69
  }),
70
70
  ...Statistics.expandMarkers(AuthorMarkers.prepare(positioned, {
71
- grouping: inheritGrouping ? state.grouping : undefined,
71
+ grouping: inheritGrouping ? state.seriesGrouping : undefined,
72
72
  color: inheritGrouping ? state.color : undefined,
73
73
  defaultColor,
74
74
  flat,
@@ -1,13 +1,13 @@
1
- import type { AxisPlotState, AxisPlotCtx, PhaseStage } from '../../types/phases';
1
+ import type { AxisPlotState, AxisPlotEnv, PhaseStage } from '../../types/phases';
2
2
  import type { StylesStageOptions } from '../../types/phases/styles/phase';
3
3
  /**
4
4
  * The shared "styles" phase: resolves the plot's `styles` against the plot
5
5
  * kind's own defaults - its value labels (`valueLabels`), with how far they
6
6
  * are expected to reach out, which its margins start from.
7
7
  */
8
- export declare class StylesPhase<TState extends AxisPlotState<any, any, any, any>, TCtx extends AxisPlotCtx> implements PhaseStage<TState, TCtx> {
8
+ export declare class StylesPhase<TState extends AxisPlotState<any, any, any, any>, TEnv extends AxisPlotEnv> implements PhaseStage<TState, TEnv> {
9
9
  #private;
10
10
  readonly phase: "styles";
11
11
  constructor(options?: StylesStageOptions<TState>);
12
- run: (state: TState, ctx: TCtx) => TState;
12
+ run: (state: TState, env: TEnv) => TState;
13
13
  }
@@ -10,8 +10,8 @@ export class StylesPhase {
10
10
  constructor(options = {}) {
11
11
  this.#options = options;
12
12
  }
13
- run = (state, ctx) => ({
13
+ run = (state, env) => ({
14
14
  ...state,
15
- valueLabels: ValueLabels.build(state.values, ctx.cfg, this.#options.values ?? {}, state)
15
+ valueLabels: ValueLabels.build(state.values, env.cfg, this.#options.values ?? {}, state)
16
16
  });
17
17
  }
@@ -1,15 +1,15 @@
1
- import type { AxisPlotCtx, AxisPlotState, PhaseStage } from '../../types/phases';
1
+ import type { AxisPlotEnv, AxisPlotState, PhaseStage } from '../../types/phases';
2
2
  type AnyAxisState = AxisPlotState<any, any, any, any>;
3
3
  /**
4
4
  * The "tooltip" phase every axis-based plot shares: how a hovered row reads,
5
5
  * as `tooltipFormat` - the same default on every plot, {@link TooltipState.default} -
6
6
  * and the order its rows read in, as `tooltipSort`: highest value first, by
7
- * each row's own value (a stacked row's share, not its running total). The value reads as the tooltip's
7
+ * the value each row's context gives it (a stacked row's own, not its running total). The value reads as the tooltip's
8
8
  * `decimals`, `prefix`, `suffix` and `signDisplay` ask. It
9
9
  * runs after the scales, which say which axis holds categories.
10
10
  */
11
- export declare class TooltipPhase<TState extends AnyAxisState> implements PhaseStage<TState, AxisPlotCtx> {
11
+ export declare class TooltipPhase<TState extends AnyAxisState> implements PhaseStage<TState, AxisPlotEnv> {
12
12
  readonly phase: "tooltip";
13
- run: (state: TState, ctx: AxisPlotCtx) => TState;
13
+ run: (state: TState, env: AxisPlotEnv) => TState;
14
14
  }
15
15
  export {};
@@ -1,19 +1,22 @@
1
1
  import { TooltipState } from '../../layout/tooltip/TooltipState.svelte';
2
- import { ValueLabels } from '../../layout/styles/ValueLabels';
2
+ import { RowContext } from '../context/RowContext';
3
3
  import { NumberFormat } from '../../utils/NumberFormat';
4
4
  /**
5
5
  * The "tooltip" phase every axis-based plot shares: how a hovered row reads,
6
6
  * as `tooltipFormat` - the same default on every plot, {@link TooltipState.default} -
7
7
  * and the order its rows read in, as `tooltipSort`: highest value first, by
8
- * each row's own value (a stacked row's share, not its running total). The value reads as the tooltip's
8
+ * the value each row's context gives it (a stacked row's own, not its running total). The value reads as the tooltip's
9
9
  * `decimals`, `prefix`, `suffix` and `signDisplay` ask. It
10
10
  * runs after the scales, which say which axis holds categories.
11
11
  */
12
12
  export class TooltipPhase {
13
13
  phase = 'tooltip';
14
- run = (state, ctx) => ({
15
- ...state,
16
- tooltipFormat: TooltipState.default(state, NumberFormat.maybe(NumberFormat.displayOf(state.tooltip), ctx.cfg)),
17
- tooltipSort: TooltipState.descending(ValueLabels.valueOf(state))
18
- });
14
+ run = (state, env) => {
15
+ const contextOf = RowContext.reader(state);
16
+ return {
17
+ ...state,
18
+ tooltipFormat: TooltipState.default(state, NumberFormat.maybe(NumberFormat.displayOf(state.tooltip), env.cfg)),
19
+ tooltipSort: TooltipState.descending((row) => contextOf(row).value)
20
+ };
21
+ };
19
22
  }
@@ -6,6 +6,7 @@ import { NormalizeTransform } from './methods/NormalizeTransform';
6
6
  import { PositionTransform } from './methods/PositionTransform';
7
7
  import { OrderTransform } from './methods/OrderTransform';
8
8
  import { GroupTransform } from './methods/GroupTransform';
9
+ import { TreemapTransform } from './methods/TreemapTransform';
9
10
  /** Each transform type's adapter: its channels, how it runs, and its own fixes. */
10
11
  const ADAPTERS = {
11
12
  stackX: StackTransform.x,
@@ -47,7 +48,8 @@ const ADAPTERS = {
47
48
  groupX: GroupTransform.x,
48
49
  groupY: GroupTransform.y,
49
50
  groupZ: GroupTransform.z,
50
- group: GroupTransform.grid
51
+ group: GroupTransform.grid,
52
+ treemap: TreemapTransform.adapter
51
53
  };
52
54
  /** Runs a marker's or a plot's transforms through svelteplot, one type's adapter at a time. */
53
55
  export class Transforms {
@@ -18,10 +18,10 @@ export declare const GAP_KIND = "__gapKind";
18
18
  * `styles.gaps` fills is read at its interpolated value, so it takes its place
19
19
  * in a stack the way a real value would, and keeps its gap kind.
20
20
  */
21
- export declare class TransformsPhase<TState extends TransformsStageState, TCtx = unknown> implements PhaseStage<TState, TCtx> {
21
+ export declare class TransformsPhase<TState extends TransformsStageState, TEnv = unknown> implements PhaseStage<TState, TEnv> {
22
22
  #private;
23
23
  readonly phase: "transforms";
24
24
  /** `connect`: whether a series' visual segments bridge into each other, as the kind's "data" phase splits them. */
25
- constructor(options?: TransformsStageOptions<TState, TCtx>, connect?: boolean);
26
- run: (state: TState, ctx: TCtx) => TState;
25
+ constructor(options?: TransformsStageOptions<TState, TEnv>, connect?: boolean);
26
+ run: (state: TState, env: TEnv) => TState;
27
27
  }
@@ -37,9 +37,14 @@ export class TransformsPhase {
37
37
  this.#options = options;
38
38
  this.#connect = connect;
39
39
  }
40
- run = (state, ctx) => {
40
+ run = (state, env) => {
41
41
  const options = this.#options;
42
- const series = (state.resolvedSeries ?? []);
42
+ const visible = (state.resolvedSeries ?? []);
43
+ // An omitted part of a whole is laid out with the rest, so they keep their places; it is dropped after.
44
+ const removed = state.removedSeries;
45
+ const kept = options.keepsOmitted && removed?.mode === 'omit' ? removed.series : [];
46
+ const series = [...visible, ...kept];
47
+ const omittedIds = new Set(kept.map(seriesIdOf));
43
48
  // A gap `styles.gaps` fills carries its filled value and kind, and reads at that value.
44
49
  const fillsOf = (s) => state.gapFillMaps?.get(seriesIdOf(s));
45
50
  const data = series.flatMap((s) => s.data.map((row) => ({
@@ -60,13 +65,21 @@ export class TransformsPhase {
60
65
  const read = resolveAccessor(own);
61
66
  shared[valueAxis] = (row) => row[GAP_VALUE] ?? read(row);
62
67
  }
63
- const { x, y } = shared;
64
68
  const transforms = options.transforms
65
- ? options.transforms(state, ctx)
69
+ ? options.transforms(state, env)
66
70
  : (state.transforms ?? []);
71
+ const rescaled = TransformsPhase.#rescaled(state, transforms, shared, valueAxis);
72
+ if (rescaled)
73
+ shared[valueAxis] = rescaled;
74
+ const { x, y } = shared;
67
75
  if (!transforms.length) {
68
76
  const channels = Object.fromEntries(Object.entries({ x, y }).filter(([, channel]) => channel !== undefined));
69
- const processedData = { data, channels, options: {}, transforms };
77
+ const processedData = {
78
+ data: data.filter((row) => !omittedIds.has(row[SERIES_ID_KEY])),
79
+ channels,
80
+ options: {},
81
+ transforms
82
+ };
70
83
  return this.#withGroups({ ...state, processedData });
71
84
  }
72
85
  const out = TransformsPhase.#runByPanel(data, (rows) => Transforms.resolve({ data: rows, x, y, grouping: SERIES_ID_KEY, transforms }, rows));
@@ -82,7 +95,7 @@ export class TransformsPhase {
82
95
  }
83
96
  // An aggregating transform (bin, group) keeps only its `z`, the series id: put the name back.
84
97
  const nameById = new Map(series.map((s) => [seriesIdOf(s), s.name]));
85
- const rows = out.data;
98
+ const rows = out.data.filter((row) => !omittedIds.has(row[SERIES_ID_KEY]));
86
99
  for (const row of rows) {
87
100
  if (row[SERIES_KEY] === undefined && row[SERIES_ID_KEY] !== undefined) {
88
101
  row[SERIES_KEY] = nameById.get(row[SERIES_ID_KEY]);
@@ -147,6 +160,47 @@ export class TransformsPhase {
147
160
  labelSelects: ValueSelection.selectors(select)
148
161
  };
149
162
  }
163
+ /**
164
+ * The value channel of a stack whose legend rescales some of its series: each visible row's value scaled by
165
+ * how much of its category's total (in its facet panel) those series took, so the visible parts make the
166
+ * whole the category had. `undefined` for a plot that stacks nothing on its value axis, or rescales nothing.
167
+ */
168
+ static #rescaled(state, transforms, shared, valueAxis) {
169
+ const removed = state.removedSeries;
170
+ const rescaled = removed?.mode === 'rescale' ? removed.series : [];
171
+ const stack = valueAxis === 'y' ? 'stackY' : 'stackX';
172
+ const own = shared[valueAxis];
173
+ const category = shared[valueAxis === 'y' ? 'x' : 'y'];
174
+ if (!rescaled.length || own === undefined || category === undefined)
175
+ return undefined;
176
+ if (!transforms.some((t) => t.type === stack))
177
+ return undefined;
178
+ const value = resolveAccessor(own);
179
+ const categoryOf = resolveAccessor(category);
180
+ const keyOf = (row, panel) => JSON.stringify([panel, categoryOf(row)]);
181
+ const totals = (series) => {
182
+ const sums = new Map();
183
+ for (const s of series) {
184
+ for (const row of s.data) {
185
+ const amount = Number(value(row));
186
+ if (!Number.isFinite(amount))
187
+ continue;
188
+ const key = keyOf(row, s.panel);
189
+ sums.set(key, (sums.get(key) ?? 0) + amount);
190
+ }
191
+ }
192
+ return sums;
193
+ };
194
+ const visible = (state.resolvedSeries ?? []);
195
+ const shown = totals(visible);
196
+ const whole = totals([...visible, ...rescaled]);
197
+ return (row) => {
198
+ const amount = Number(value(row));
199
+ const key = keyOf(row, row[PANEL_KEY]);
200
+ const part = shown.get(key) ?? 0;
201
+ return part === 0 ? amount : (amount * (whole.get(key) ?? part)) / part;
202
+ };
203
+ }
150
204
  /** What a gap-filled row carries: its interpolated value and the kind of zone that filled it. */
151
205
  static #fillTags(fill) {
152
206
  return fill ? { [GAP_VALUE]: fill.value, [GAP_KIND]: fill.kind } : {};
@@ -0,0 +1,28 @@
1
+ import type { Row, TransformAdapter } from '../../../types/phases/transforms/adapter';
2
+ /** What a treemap leaves on each row it produces, and the channels it reads them back by. */
3
+ export declare const TREEMAP_ROW: {
4
+ /** The tile's name: the value at its last level. */
5
+ readonly name: symbol;
6
+ /** The value at every level of the tile, outermost first. */
7
+ readonly path: symbol;
8
+ /** The tile's summed `value`. */
9
+ readonly value: symbol;
10
+ /** The tile's part of the whole, from `0` to `1`. */
11
+ readonly share: symbol;
12
+ readonly x1: symbol;
13
+ readonly x2: symbol;
14
+ readonly y1: symbol;
15
+ readonly y2: symbol;
16
+ readonly x: symbol;
17
+ readonly y: symbol;
18
+ };
19
+ /** A treemap as a transform: the layout of d3-hierarchy, in the shape every other transform returns. */
20
+ export declare class TreemapTransform {
21
+ static readonly adapter: TransformAdapter;
22
+ /**
23
+ * A row per tile of `channels.data`, biggest first within its group, placed in the unit square. A row whose
24
+ * value is not a positive number has no area, so it makes no tile. The layout is `aspect` wide while it is
25
+ * computed and scaled back after, so its tiles are shaped after the box they fill.
26
+ */
27
+ static layout(channels: Row, options: Row): Row;
28
+ }