@fundar/data-chart-telling 1.1.0 → 1.2.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 (524) hide show
  1. package/CHANGELOG.md +32 -0
  2. package/README.md +6 -6
  3. package/dist/configuration/config.svelte.d.ts +1 -1
  4. package/dist/configuration/config.svelte.js +165 -100
  5. package/dist/configuration/themes/index.d.ts +5 -1428
  6. package/dist/index.d.ts +23 -14
  7. package/dist/index.js +20 -11
  8. package/dist/layout/base/BasePlotLayout.svelte +115 -50
  9. package/dist/layout/base/BasePlotLayout.svelte.d.ts +1 -38
  10. package/dist/layout/coordinates/CoordinatesLayout.svelte +42 -40
  11. package/dist/layout/coordinates/CoordinatesLayout.svelte.d.ts +0 -2
  12. package/dist/layout/coordinates/ProjectionZoom.svelte +48 -0
  13. package/dist/layout/coordinates/ProjectionZoom.svelte.d.ts +10 -0
  14. package/dist/layout/coordinates/ZoomedProjection.d.ts +11 -0
  15. package/dist/layout/coordinates/ZoomedProjection.js +24 -0
  16. package/dist/layout/coordinates/camera.svelte.js +11 -8
  17. package/dist/layout/coordinates/projections/argentina.js +1 -1
  18. package/dist/layout/coordinates/projections/fit.d.ts +1 -1
  19. package/dist/layout/coordinates/projections/fit.js +1 -1
  20. package/dist/layout/coordinates/zoom.svelte.d.ts +4 -5
  21. package/dist/layout/coordinates/zoom.svelte.js +4 -5
  22. package/dist/layout/facet/FacetLayout.svelte +1 -1
  23. package/dist/layout/facet/config.js +1 -1
  24. package/dist/layout/figure/Figure.svelte +2 -0
  25. package/dist/layout/geometry/GeometryLayout.svelte +14 -9
  26. package/dist/layout/geometry/GeometryLayout.svelte.d.ts +0 -3
  27. package/dist/layout/geometry/MarkerOffset.svelte +28 -0
  28. package/dist/layout/geometry/MarkerOffset.svelte.d.ts +13 -0
  29. package/dist/layout/grid/GridCell.svelte +6 -8
  30. package/dist/layout/legend/ContinuousSection.svelte +44 -9
  31. package/dist/layout/legend/DiscreteBadgeItem.svelte +2 -2
  32. package/dist/layout/legend/DiscreteSection.svelte +2 -2
  33. package/dist/layout/legend/DiscreteSymbolIcon.svelte +1 -1
  34. package/dist/layout/legend/LegendChannels.js +36 -12
  35. package/dist/layout/legend/LegendLayout.svelte +9 -1
  36. package/dist/layout/legend/LegendState.svelte.d.ts +4 -0
  37. package/dist/layout/legend/LegendState.svelte.js +20 -3
  38. package/dist/layout/legend/SizeSection.svelte +1 -1
  39. package/dist/layout/margins/PlotMargins.svelte.d.ts +2 -5
  40. package/dist/layout/margins/PlotMargins.svelte.js +4 -8
  41. package/dist/layout/plot/Slice.d.ts +5 -1
  42. package/dist/layout/plot/Slice.js +14 -4
  43. package/dist/layout/scales/NiceTicks.d.ts +3 -0
  44. package/dist/layout/scales/NiceTicks.js +4 -0
  45. package/dist/layout/scales/ScalesLayout.svelte +72 -7
  46. package/dist/layout/scales/ScalesLayout.svelte.d.ts +5 -0
  47. package/dist/layout/scales/SveltePlotScale.d.ts +2 -2
  48. package/dist/layout/scales/SveltePlotScale.js +13 -6
  49. package/dist/layout/scales/TickLabels.d.ts +32 -0
  50. package/dist/layout/scales/TickLabels.js +55 -0
  51. package/dist/layout/styles/StylesLayout.svelte +2 -2
  52. package/dist/layout/styles/ValueLabels.d.ts +33 -5
  53. package/dist/layout/styles/ValueLabels.js +80 -21
  54. package/dist/layout/timeline/TimelineLayout.svelte +1 -1
  55. package/dist/layout/tooltip/Tooltip.svelte +4 -4
  56. package/dist/layout/tooltip/Tooltip.svelte.d.ts +4 -4
  57. package/dist/layout/tooltip/TooltipState.svelte.js +1 -1
  58. package/dist/markers/MarkerKinds.d.ts +5 -0
  59. package/dist/markers/MarkerKinds.js +1 -0
  60. package/dist/markers/area/AreaMarker.svelte +15 -63
  61. package/dist/markers/arrow/ArrowMarker.svelte +51 -9
  62. package/dist/markers/bar/BarMarker.svelte +8 -4
  63. package/dist/markers/bollinger/BollingerMarker.svelte +33 -18
  64. package/dist/markers/box/BoxMarker.svelte +40 -9
  65. package/dist/markers/delta/Delta.js +1 -1
  66. package/dist/markers/dot/DotMarker.svelte +24 -27
  67. package/dist/markers/image/ImageMarker.svelte +17 -12
  68. package/dist/markers/inset/InsetMarker.svelte +2 -2
  69. package/dist/markers/line/LineMarker.svelte +1 -0
  70. package/dist/markers/link/LinkMarker.svelte +174 -29
  71. package/dist/markers/regression/RegressionMarker.svelte +16 -33
  72. package/dist/markers/rule/RuleMarker.svelte +9 -3
  73. package/dist/markers/text/Declutter.d.ts +4 -0
  74. package/dist/markers/text/Declutter.js +26 -11
  75. package/dist/markers/text/TextMarker.svelte +91 -48
  76. package/dist/markers/tick/TickMarker.svelte +27 -25
  77. package/dist/markers/utils/MarkerChannels.d.ts +24 -0
  78. package/dist/markers/utils/MarkerChannels.js +42 -7
  79. package/dist/markers/utils/RowOffset.d.ts +23 -0
  80. package/dist/markers/utils/RowOffset.js +23 -0
  81. package/dist/markers/utils/RowOffsetMarks.svelte +30 -0
  82. package/dist/markers/utils/RowOffsetMarks.svelte.d.ts +33 -0
  83. package/dist/markers/utils/RowStroke.d.ts +31 -0
  84. package/dist/markers/utils/RowStroke.js +28 -0
  85. package/dist/markers/violin/ViolinMarker.svelte +75 -0
  86. package/dist/markers/violin/ViolinMarker.svelte.d.ts +7 -0
  87. package/dist/markers/violin/ViolinProfiles.d.ts +29 -0
  88. package/dist/markers/violin/ViolinProfiles.js +55 -0
  89. package/dist/markers/waffle/WaffleMarker.svelte +17 -37
  90. package/dist/phases/Pipeline.d.ts +5 -0
  91. package/dist/phases/Pipeline.js +5 -0
  92. package/dist/phases/data/DataPhase.js +3 -3
  93. package/dist/phases/data/PlotAxes.d.ts +10 -0
  94. package/dist/phases/data/PlotAxes.js +14 -1
  95. package/dist/phases/facet/FacetPanels.d.ts +1 -0
  96. package/dist/phases/facet/FacetPanels.js +1 -0
  97. package/dist/phases/mapping/MappingPhase.js +1 -1
  98. package/dist/phases/markers/MarkersPhase.js +2 -1
  99. package/dist/phases/scales/CategoryOrder.d.ts +23 -0
  100. package/dist/phases/scales/CategoryOrder.js +73 -0
  101. package/dist/phases/scales/ScalesPhase.js +21 -7
  102. package/dist/phases/sharedScales/SharedScalesPhase.d.ts +3 -2
  103. package/dist/phases/sharedScales/SharedScalesPhase.js +5 -2
  104. package/dist/phases/statistics/Statistics.d.ts +10 -6
  105. package/dist/phases/statistics/Statistics.js +20 -10
  106. package/dist/phases/statistics/StatisticsPhase.js +7 -2
  107. package/dist/phases/statistics/methods/BollingerStatistic.d.ts +1 -1
  108. package/dist/phases/statistics/methods/BollingerStatistic.js +13 -11
  109. package/dist/phases/statistics/methods/BoxStatistic.d.ts +1 -1
  110. package/dist/phases/statistics/methods/BoxStatistic.js +14 -12
  111. package/dist/phases/statistics/methods/Density2dStatistic.d.ts +1 -1
  112. package/dist/phases/statistics/methods/Density2dStatistic.js +13 -11
  113. package/dist/phases/statistics/methods/DensityStatistic.d.ts +1 -1
  114. package/dist/phases/statistics/methods/DensityStatistic.js +11 -9
  115. package/dist/phases/statistics/methods/DeviationStatistic.d.ts +8 -0
  116. package/dist/phases/statistics/methods/DeviationStatistic.js +111 -0
  117. package/dist/phases/statistics/methods/MovingAverageStatistic.d.ts +1 -1
  118. package/dist/phases/statistics/methods/MovingAverageStatistic.js +11 -9
  119. package/dist/phases/statistics/methods/RegressionStatistic.d.ts +1 -1
  120. package/dist/phases/statistics/methods/RegressionStatistic.js +16 -14
  121. package/dist/phases/transforms/ProcessedPositions.js +1 -1
  122. package/dist/phases/transforms/TransformsPhase.js +49 -3
  123. package/dist/phases/transforms/ValueSelection.d.ts +30 -0
  124. package/dist/phases/transforms/ValueSelection.js +53 -0
  125. package/dist/plots/{heatmap → correlation/heatmap}/Plot.svelte +5 -2
  126. package/dist/plots/{heatmap → correlation/heatmap}/Plot.svelte.d.ts +2 -2
  127. package/dist/plots/{heatmap → correlation/heatmap}/defaults.d.ts +2 -2
  128. package/dist/plots/{heatmap → correlation/heatmap}/defaults.js +5 -5
  129. package/dist/plots/{heatmap → correlation/heatmap}/markers.d.ts +4 -4
  130. package/dist/plots/{heatmap → correlation/heatmap}/markers.js +3 -3
  131. package/dist/plots/{scatter → correlation/scatter}/Plot.svelte +5 -2
  132. package/dist/plots/{scatter → correlation/scatter}/Plot.svelte.d.ts +2 -2
  133. package/dist/plots/{scatter → correlation/scatter}/defaults.d.ts +2 -2
  134. package/dist/plots/{scatter → correlation/scatter}/defaults.js +4 -4
  135. package/dist/plots/{scatter → correlation/scatter}/markers.d.ts +4 -4
  136. package/dist/plots/{scatter → correlation/scatter}/markers.js +3 -3
  137. package/dist/plots/{box → distribution/box}/BoxSummaries.d.ts +2 -2
  138. package/dist/plots/{box → distribution/box}/BoxSummaries.js +6 -6
  139. package/dist/plots/{box → distribution/box}/Plot.svelte +2 -2
  140. package/dist/plots/{box → distribution/box}/Plot.svelte.d.ts +2 -2
  141. package/dist/plots/{box → distribution/box}/defaults.d.ts +2 -2
  142. package/dist/plots/{box → distribution/box}/defaults.js +1 -1
  143. package/dist/plots/{box → distribution/box}/markers.d.ts +2 -2
  144. package/dist/plots/distribution/density/Plot.svelte +45 -0
  145. package/dist/plots/distribution/density/Plot.svelte.d.ts +26 -0
  146. package/dist/plots/distribution/density/defaults.d.ts +9 -0
  147. package/dist/plots/distribution/density/defaults.js +29 -0
  148. package/dist/plots/distribution/density/markers.d.ts +9 -0
  149. package/dist/plots/distribution/density/markers.js +42 -0
  150. package/dist/plots/{histogram → distribution/histogram}/Plot.svelte +2 -2
  151. package/dist/plots/{histogram → distribution/histogram}/Plot.svelte.d.ts +2 -2
  152. package/dist/plots/{histogram → distribution/histogram}/defaults.d.ts +2 -2
  153. package/dist/plots/{histogram → distribution/histogram}/defaults.js +3 -3
  154. package/dist/plots/{histogram → distribution/histogram}/markers.d.ts +3 -3
  155. package/dist/plots/{histogram → distribution/histogram}/markers.js +5 -5
  156. package/dist/plots/{pyramid → distribution/pyramid}/Plot.svelte +5 -2
  157. package/dist/plots/{pyramid → distribution/pyramid}/Plot.svelte.d.ts +2 -2
  158. package/dist/plots/{pyramid → distribution/pyramid}/defaults.d.ts +2 -2
  159. package/dist/plots/{pyramid → distribution/pyramid}/defaults.js +6 -6
  160. package/dist/plots/{pyramid → distribution/pyramid}/markers.d.ts +4 -4
  161. package/dist/plots/{pyramid → distribution/pyramid}/markers.js +6 -6
  162. package/dist/plots/distribution/violin/Plot.svelte +45 -0
  163. package/dist/plots/distribution/violin/Plot.svelte.d.ts +26 -0
  164. package/dist/plots/distribution/violin/defaults.d.ts +10 -0
  165. package/dist/plots/distribution/violin/defaults.js +58 -0
  166. package/dist/plots/distribution/violin/markers.d.ts +10 -0
  167. package/dist/plots/distribution/violin/markers.js +71 -0
  168. package/dist/plots/{area → evolution/area}/Plot.svelte +2 -2
  169. package/dist/plots/{area → evolution/area}/Plot.svelte.d.ts +2 -2
  170. package/dist/plots/{area → evolution/area}/defaults.d.ts +2 -2
  171. package/dist/plots/{area → evolution/area}/defaults.js +2 -0
  172. package/dist/plots/{area → evolution/area}/markers.d.ts +2 -2
  173. package/dist/plots/{area → evolution/area}/markers.js +1 -1
  174. package/dist/plots/{line → evolution/line}/Plot.svelte +2 -2
  175. package/dist/plots/{line → evolution/line}/Plot.svelte.d.ts +2 -2
  176. package/dist/plots/{line → evolution/line}/defaults.d.ts +2 -2
  177. package/dist/plots/{line → evolution/line}/defaults.js +2 -0
  178. package/dist/plots/{line → evolution/line}/markers.d.ts +11 -8
  179. package/dist/plots/{line → evolution/line}/markers.js +6 -4
  180. package/dist/plots/evolution/slope/Plot.svelte +42 -0
  181. package/dist/plots/evolution/slope/Plot.svelte.d.ts +26 -0
  182. package/dist/plots/evolution/slope/defaults.d.ts +8 -0
  183. package/dist/plots/evolution/slope/defaults.js +31 -0
  184. package/dist/plots/evolution/slope/markers.d.ts +16 -0
  185. package/dist/plots/evolution/slope/markers.js +79 -0
  186. package/dist/plots/evolution/sparkline/Plot.svelte +45 -0
  187. package/dist/plots/evolution/sparkline/Plot.svelte.d.ts +26 -0
  188. package/dist/plots/evolution/sparkline/defaults.d.ts +7 -0
  189. package/dist/plots/evolution/sparkline/defaults.js +23 -0
  190. package/dist/plots/evolution/sparkline/markers.d.ts +7 -0
  191. package/dist/plots/evolution/sparkline/markers.js +56 -0
  192. package/dist/plots/{geo → map/geo}/Core.svelte +11 -10
  193. package/dist/plots/{geo → map/geo}/Core.svelte.d.ts +1 -1
  194. package/dist/plots/map/geo/GeoFeatures.svelte.d.ts +9 -0
  195. package/dist/plots/map/geo/GeoFeatures.svelte.js +55 -0
  196. package/dist/plots/map/geo/GeoGeometry.d.ts +27 -0
  197. package/dist/plots/map/geo/GeoGeometry.js +142 -0
  198. package/dist/plots/map/geo/GeoSegments.d.ts +16 -0
  199. package/dist/plots/map/geo/GeoSegments.js +23 -0
  200. package/dist/plots/{geo → map/geo}/Plot.svelte +10 -10
  201. package/dist/plots/{geo → map/geo}/Plot.svelte.d.ts +2 -2
  202. package/dist/plots/{geo → map/geo}/defaults.d.ts +2 -2
  203. package/dist/plots/{geo → map/geo}/defaults.js +1 -1
  204. package/dist/plots/{geo → map/geo}/phases/data.d.ts +1 -1
  205. package/dist/plots/{geo → map/geo}/phases/data.js +7 -6
  206. package/dist/plots/{geo → map/geo}/phases/hover.d.ts +1 -1
  207. package/dist/plots/{geo → map/geo}/phases/hover.js +2 -2
  208. package/dist/plots/{geo → map/geo}/phases/markers.d.ts +1 -1
  209. package/dist/plots/{geo → map/geo}/phases/markers.js +6 -10
  210. package/dist/plots/{geo → map/geo}/phases/scales.d.ts +2 -2
  211. package/dist/plots/{geo → map/geo}/phases/scales.js +28 -12
  212. package/dist/plots/{geo → map/geo}/phases/tooltip.d.ts +1 -1
  213. package/dist/plots/map/geo/phases/tooltip.js +5 -0
  214. package/dist/plots/{geo → map/geo}/slices.d.ts +2 -2
  215. package/dist/plots/{geo → map/geo}/slices.js +2 -2
  216. package/dist/plots/{bar → ranking/bar}/Plot.svelte +2 -2
  217. package/dist/plots/{bar → ranking/bar}/Plot.svelte.d.ts +2 -2
  218. package/dist/plots/ranking/bar/defaults.d.ts +16 -0
  219. package/dist/plots/{bar → ranking/bar}/defaults.js +15 -9
  220. package/dist/plots/{bar → ranking/bar}/markers.d.ts +8 -8
  221. package/dist/plots/{bar → ranking/bar}/markers.js +8 -17
  222. package/dist/plots/ranking/bullet/Plot.svelte +42 -0
  223. package/dist/plots/ranking/bullet/Plot.svelte.d.ts +26 -0
  224. package/dist/plots/ranking/bullet/defaults.d.ts +8 -0
  225. package/dist/plots/ranking/bullet/defaults.js +24 -0
  226. package/dist/plots/ranking/bullet/markers.d.ts +10 -0
  227. package/dist/plots/ranking/bullet/markers.js +90 -0
  228. package/dist/plots/ranking/cleveland/ClevelandConnector.d.ts +48 -0
  229. package/dist/plots/ranking/cleveland/ClevelandConnector.js +140 -0
  230. package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +33 -0
  231. package/dist/plots/ranking/cleveland/ClevelandMarkers.js +375 -0
  232. package/dist/plots/ranking/cleveland/ClevelandRanges.d.ts +31 -0
  233. package/dist/plots/ranking/cleveland/ClevelandRanges.js +116 -0
  234. package/dist/plots/ranking/cleveland/Plot.svelte +45 -0
  235. package/dist/plots/ranking/cleveland/Plot.svelte.d.ts +26 -0
  236. package/dist/plots/ranking/cleveland/defaults.d.ts +13 -0
  237. package/dist/plots/ranking/cleveland/defaults.js +66 -0
  238. package/dist/plots/ranking/dumbbell/Plot.svelte +45 -0
  239. package/dist/plots/ranking/dumbbell/Plot.svelte.d.ts +26 -0
  240. package/dist/plots/ranking/dumbbell/defaults.d.ts +9 -0
  241. package/dist/plots/ranking/dumbbell/defaults.js +19 -0
  242. package/dist/plots/ranking/forest/Plot.svelte +42 -0
  243. package/dist/plots/ranking/forest/Plot.svelte.d.ts +26 -0
  244. package/dist/plots/ranking/forest/defaults.d.ts +11 -0
  245. package/dist/plots/ranking/forest/defaults.js +20 -0
  246. package/dist/plots/ranking/lollipop/Plot.svelte +45 -0
  247. package/dist/plots/ranking/lollipop/Plot.svelte.d.ts +26 -0
  248. package/dist/plots/ranking/lollipop/defaults.d.ts +9 -0
  249. package/dist/plots/ranking/lollipop/defaults.js +18 -0
  250. package/dist/plots/utils/RowNumbers.d.ts +16 -0
  251. package/dist/plots/utils/RowNumbers.js +24 -0
  252. package/dist/plots/utils/gaps.js +1 -1
  253. package/dist/plots/utils/segments.js +1 -1
  254. package/dist/types/configuration/styling.d.ts +276 -143
  255. package/dist/types/layout/coordinates.d.ts +5 -4
  256. package/dist/types/layout/legend.d.ts +21 -5
  257. package/dist/types/layout/plot.d.ts +44 -1
  258. package/dist/types/layout/scales.d.ts +39 -7
  259. package/dist/types/layout/statistics/deviation.d.ts +40 -0
  260. package/dist/types/layout/statistics/index.d.ts +7 -2
  261. package/dist/types/layout/styles/base.d.ts +18 -0
  262. package/dist/types/layout/styles/bullet.d.ts +25 -0
  263. package/dist/types/layout/styles/connector.d.ts +98 -0
  264. package/dist/types/layout/styles/curve.d.ts +11 -0
  265. package/dist/types/layout/styles/frame.d.ts +17 -0
  266. package/dist/types/layout/styles/gaps.d.ts +12 -0
  267. package/dist/types/layout/styles/geo.d.ts +55 -0
  268. package/dist/types/layout/styles/index.d.ts +8 -0
  269. package/dist/types/layout/styles/index.js +8 -0
  270. package/dist/types/layout/styles/values.d.ts +47 -0
  271. package/dist/types/layout/timeline.d.ts +5 -2
  272. package/dist/types/layout/tooltip.d.ts +6 -2
  273. package/dist/types/markers/axis/area.d.ts +2 -2
  274. package/dist/types/markers/axis/arrow.d.ts +3 -0
  275. package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
  276. package/dist/types/markers/axis/bar.d.ts +1 -1
  277. package/dist/types/markers/axis/box.d.ts +5 -0
  278. package/dist/types/markers/axis/difference.d.ts +2 -2
  279. package/dist/types/markers/axis/image.d.ts +3 -2
  280. package/dist/types/markers/axis/line.d.ts +2 -0
  281. package/dist/types/markers/axis/rule.d.ts +9 -0
  282. package/dist/types/markers/axis/trail.d.ts +2 -3
  283. package/dist/types/markers/axis/violin.d.ts +25 -0
  284. package/dist/types/markers/basic/dot.d.ts +3 -2
  285. package/dist/types/markers/basic/text.d.ts +13 -3
  286. package/dist/types/markers/channels/commonMarkerConfig.d.ts +7 -3
  287. package/dist/types/markers/channels/commonMarkerConfigWithRowOffset.d.ts +13 -0
  288. package/dist/types/markers/common.d.ts +1 -1
  289. package/dist/types/markers/common.js +1 -0
  290. package/dist/types/markers/geo/link.d.ts +5 -1
  291. package/dist/types/phases/index.d.ts +1 -1
  292. package/dist/types/phases/scales/phase.d.ts +5 -1
  293. package/dist/types/phases/state.d.ts +15 -2
  294. package/dist/types/phases/statistics/source.d.ts +3 -1
  295. package/dist/types/phases/transforms/phase.d.ts +22 -0
  296. package/dist/types/plots/{heatmap → correlation/heatmap}/props.d.ts +6 -6
  297. package/dist/types/plots/{heatmap → correlation/heatmap}/state.d.ts +4 -4
  298. package/dist/types/plots/{scatter → correlation/scatter}/props.d.ts +6 -6
  299. package/dist/types/plots/{scatter → correlation/scatter}/state.d.ts +2 -2
  300. package/dist/types/plots/{box → distribution/box}/props.d.ts +6 -6
  301. package/dist/types/plots/{box → distribution/box}/state.d.ts +3 -3
  302. package/dist/types/plots/distribution/density/props.d.ts +23 -0
  303. package/dist/types/plots/distribution/density/state.d.ts +6 -0
  304. package/dist/types/plots/{histogram → distribution/histogram}/props.d.ts +7 -7
  305. package/dist/types/plots/{histogram → distribution/histogram}/state.d.ts +2 -2
  306. package/dist/types/plots/distribution/histogram/state.js +1 -0
  307. package/dist/types/plots/{pyramid → distribution/pyramid}/props.d.ts +6 -6
  308. package/dist/types/plots/distribution/pyramid/props.js +1 -0
  309. package/dist/types/plots/{pyramid → distribution/pyramid}/state.d.ts +3 -3
  310. package/dist/types/plots/distribution/pyramid/state.js +1 -0
  311. package/dist/types/plots/distribution/violin/props.d.ts +23 -0
  312. package/dist/types/plots/distribution/violin/props.js +1 -0
  313. package/dist/types/plots/distribution/violin/state.d.ts +6 -0
  314. package/dist/types/plots/distribution/violin/state.js +1 -0
  315. package/dist/types/plots/{area → evolution/area}/props.d.ts +6 -6
  316. package/dist/types/plots/evolution/area/props.js +1 -0
  317. package/dist/types/plots/{area → evolution/area}/state.d.ts +2 -2
  318. package/dist/types/plots/evolution/area/state.js +1 -0
  319. package/dist/types/plots/evolution/line/props.d.ts +10 -0
  320. package/dist/types/plots/evolution/line/props.js +1 -0
  321. package/dist/types/plots/{line → evolution/line}/state.d.ts +3 -3
  322. package/dist/types/plots/evolution/line/state.js +1 -0
  323. package/dist/types/plots/evolution/slope/props.d.ts +5 -0
  324. package/dist/types/plots/evolution/slope/props.js +1 -0
  325. package/dist/types/plots/evolution/slope/state.d.ts +5 -0
  326. package/dist/types/plots/evolution/slope/state.js +1 -0
  327. package/dist/types/plots/evolution/sparkline/props.d.ts +5 -0
  328. package/dist/types/plots/evolution/sparkline/props.js +1 -0
  329. package/dist/types/plots/evolution/sparkline/state.d.ts +5 -0
  330. package/dist/types/plots/evolution/sparkline/state.js +1 -0
  331. package/dist/types/plots/{geo → map/geo}/props.d.ts +8 -8
  332. package/dist/types/plots/map/geo/props.js +1 -0
  333. package/dist/types/plots/{geo → map/geo}/state.d.ts +18 -11
  334. package/dist/types/plots/map/geo/state.js +1 -0
  335. package/dist/types/plots/props.d.ts +1 -1
  336. package/dist/types/plots/{bar → ranking/bar}/props.d.ts +6 -6
  337. package/dist/types/plots/ranking/bar/props.js +1 -0
  338. package/dist/types/plots/{bar → ranking/bar}/state.d.ts +2 -2
  339. package/dist/types/plots/ranking/bar/state.js +1 -0
  340. package/dist/types/plots/ranking/bullet/props.d.ts +22 -0
  341. package/dist/types/plots/ranking/bullet/props.js +1 -0
  342. package/dist/types/plots/ranking/bullet/state.d.ts +5 -0
  343. package/dist/types/plots/ranking/bullet/state.js +1 -0
  344. package/dist/types/plots/ranking/cleveland/props.d.ts +10 -0
  345. package/dist/types/plots/ranking/cleveland/props.js +1 -0
  346. package/dist/types/plots/ranking/cleveland/state.d.ts +49 -0
  347. package/dist/types/plots/ranking/cleveland/state.js +1 -0
  348. package/dist/types/plots/ranking/dumbbell/props.d.ts +10 -0
  349. package/dist/types/plots/ranking/dumbbell/props.js +1 -0
  350. package/dist/types/plots/ranking/dumbbell/state.d.ts +5 -0
  351. package/dist/types/plots/ranking/dumbbell/state.js +1 -0
  352. package/dist/types/plots/ranking/forest/props.d.ts +23 -0
  353. package/dist/types/plots/ranking/forest/props.js +1 -0
  354. package/dist/types/plots/ranking/forest/state.d.ts +5 -0
  355. package/dist/types/plots/ranking/forest/state.js +1 -0
  356. package/dist/types/plots/ranking/lollipop/props.d.ts +10 -0
  357. package/dist/types/plots/ranking/lollipop/props.js +1 -0
  358. package/dist/types/plots/ranking/lollipop/state.d.ts +5 -0
  359. package/dist/types/plots/ranking/lollipop/state.js +1 -0
  360. package/dist/types/plots/segments/common.d.ts +4 -1
  361. package/dist/utils/OpacityScale.d.ts +14 -0
  362. package/dist/utils/OpacityScale.js +43 -0
  363. package/dist/utils/{symbol.d.ts → SymbolPath.d.ts} +0 -12
  364. package/dist/utils/{symbol.js → SymbolPath.js} +0 -24
  365. package/dist/utils/SymbolScale.d.ts +18 -0
  366. package/dist/utils/SymbolScale.js +29 -0
  367. package/dist/utils/color/ColorRamp.d.ts +27 -0
  368. package/dist/utils/color/ColorRamp.js +120 -0
  369. package/dist/utils/color/CssColor.d.ts +19 -0
  370. package/dist/utils/color/CssColor.js +114 -0
  371. package/dist/utils/color/Palette.d.ts +21 -0
  372. package/dist/utils/color/Palette.js +52 -0
  373. package/dist/utils/color/index.d.ts +11 -3
  374. package/dist/utils/color/index.js +14 -3
  375. package/dist/utils/grouping.js +1 -1
  376. package/docs/architecture.md +1 -1
  377. package/docs/chrome.md +2 -2
  378. package/docs/composer.md +2 -2
  379. package/docs/concepts.md +1 -1
  380. package/docs/development.md +1 -1
  381. package/docs/facets.md +3 -3
  382. package/docs/getting-started.md +2 -2
  383. package/docs/legend.md +13 -11
  384. package/docs/markers.md +29 -27
  385. package/docs/plots/correlation/heatmap.md +26 -0
  386. package/docs/plots/correlation/scatter.md +35 -0
  387. package/docs/plots/distribution/box.md +28 -0
  388. package/docs/plots/distribution/density.md +26 -0
  389. package/docs/plots/distribution/histogram.md +33 -0
  390. package/docs/plots/distribution/pyramid.md +31 -0
  391. package/docs/plots/distribution/violin.md +35 -0
  392. package/docs/plots/evolution/area.md +32 -0
  393. package/docs/plots/evolution/line.md +93 -0
  394. package/docs/plots/evolution/slope.md +39 -0
  395. package/docs/plots/evolution/sparkline.md +34 -0
  396. package/docs/plots/ranking/bar.md +59 -0
  397. package/docs/plots/ranking/bullet.md +37 -0
  398. package/docs/plots/ranking/cleveland.md +54 -0
  399. package/docs/plots/ranking/dumbbell.md +39 -0
  400. package/docs/plots/ranking/forest.md +40 -0
  401. package/docs/plots/ranking/lollipop.md +39 -0
  402. package/docs/plots.md +22 -280
  403. package/docs/scales.md +30 -24
  404. package/docs/styles-and-segments.md +24 -21
  405. package/docs/theming.md +23 -20
  406. package/docs/timeline.md +3 -3
  407. package/docs/tooltip-and-hover.md +10 -10
  408. package/docs/transforms-and-statistics.md +13 -12
  409. package/examples/BarValues.svelte +1 -1
  410. package/examples/Box.svelte +1 -1
  411. package/examples/Bullet.svelte +17 -0
  412. package/examples/Chrome.svelte +1 -1
  413. package/examples/ChromeOrder.svelte +1 -1
  414. package/examples/Cleveland.svelte +15 -0
  415. package/examples/Composer.svelte +2 -2
  416. package/examples/CustomTooltip.svelte +1 -1
  417. package/examples/Density.svelte +7 -0
  418. package/examples/Dumbbell.svelte +16 -0
  419. package/examples/Facets.svelte +1 -1
  420. package/examples/FacetsCarousel.svelte +1 -1
  421. package/examples/FacetsRowsCols.svelte +1 -1
  422. package/examples/FirstPlot.svelte +1 -1
  423. package/examples/Forest.svelte +17 -0
  424. package/examples/Gaps.svelte +2 -2
  425. package/examples/GroupedBars.svelte +1 -1
  426. package/examples/Heatmap.svelte +3 -3
  427. package/examples/HeatmapSegments.svelte +8 -8
  428. package/examples/Histogram.svelte +1 -1
  429. package/examples/HorizontalBars.svelte +1 -1
  430. package/examples/LegendSections.svelte +1 -1
  431. package/examples/LegendToggle.svelte +1 -1
  432. package/examples/LineByRegion.svelte +1 -1
  433. package/examples/LineDates.svelte +1 -1
  434. package/examples/LineStep.svelte +16 -0
  435. package/examples/LineStepSegment.svelte +18 -0
  436. package/examples/Lollipop.svelte +17 -0
  437. package/examples/Markers.svelte +1 -1
  438. package/examples/MovingAverage.svelte +1 -1
  439. package/examples/Pyramid.svelte +9 -2
  440. package/examples/Regression.svelte +2 -2
  441. package/examples/ResponsiveLine.svelte +1 -1
  442. package/examples/Scales.svelte +1 -1
  443. package/examples/Scatter.svelte +2 -2
  444. package/examples/SegmentHighlight.svelte +1 -1
  445. package/examples/Segments.svelte +1 -1
  446. package/examples/SegmentsBySeries.svelte +1 -1
  447. package/examples/Slope.svelte +17 -0
  448. package/examples/Sparkline.svelte +14 -0
  449. package/examples/StackedArea.svelte +1 -1
  450. package/examples/StackedBars.svelte +1 -1
  451. package/examples/TimelinePlayer.svelte +1 -1
  452. package/examples/TimelineRule.svelte +1 -1
  453. package/examples/Tooltip.svelte +1 -1
  454. package/examples/ValueLabels.svelte +1 -1
  455. package/examples/Violin.svelte +14 -0
  456. package/examples/datasets/argentina-chile-trends.ts +34 -0
  457. package/examples/datasets/commodity-prices.ts +48 -0
  458. package/examples/datasets/countries-over-time.ts +368 -0
  459. package/examples/datasets/daily-temperature.ts +121 -0
  460. package/examples/datasets/earthquakes.ts +977 -0
  461. package/examples/datasets/flight-routes.ts +29 -0
  462. package/examples/datasets/height-density.ts +37 -0
  463. package/examples/datasets/heights.ts +370 -0
  464. package/examples/datasets/index.ts +24 -0
  465. package/examples/datasets/inflation-by-region.ts +44 -0
  466. package/examples/datasets/inflation-ranges.ts +34 -0
  467. package/examples/datasets/iris-flower.ts +207 -0
  468. package/examples/datasets/life-expectancy.ts +95 -0
  469. package/examples/datasets/napoleons-march.ts +182 -0
  470. package/examples/datasets/penguins.ts +54 -0
  471. package/examples/datasets/population-by-age-with-gaps.ts +23 -0
  472. package/examples/datasets/population-by-age.ts +890 -0
  473. package/examples/datasets/province-population.ts +521 -0
  474. package/examples/datasets/stock-prices.ts +63 -0
  475. package/examples/datasets/weather-stations-over-time.ts +31 -0
  476. package/examples/datasets/weather-stations.ts +22 -0
  477. package/examples/datasets/wind-vectors.ts +30 -0
  478. package/examples/datasets/world-temperature.ts +400 -0
  479. package/llms-full.txt +22 -11
  480. package/llms.txt +32 -4
  481. package/package.json +10 -1
  482. package/dist/plots/bar/defaults.d.ts +0 -9
  483. package/dist/plots/geo/features.svelte.d.ts +0 -5
  484. package/dist/plots/geo/features.svelte.js +0 -44
  485. package/dist/plots/geo/phases/tooltip.js +0 -5
  486. package/dist/plots/utils/geoAccessors.d.ts +0 -72
  487. package/dist/plots/utils/geoAccessors.js +0 -220
  488. package/dist/plots/utils/geoSegments.d.ts +0 -29
  489. package/dist/plots/utils/geoSegments.js +0 -37
  490. package/dist/types/layout/styles.d.ts +0 -122
  491. package/dist/types/markers/axis/curveName.d.ts +0 -2
  492. package/dist/types/plots/line/props.d.ts +0 -10
  493. package/dist/utils/color/contrast.d.ts +0 -9
  494. package/dist/utils/color/contrast.js +0 -40
  495. package/dist/utils/color/cssColor.d.ts +0 -4
  496. package/dist/utils/color/cssColor.js +0 -77
  497. package/dist/utils/color/ramp.d.ts +0 -17
  498. package/dist/utils/color/ramp.js +0 -110
  499. package/dist/utils/opacity.d.ts +0 -9
  500. package/dist/utils/opacity.js +0 -38
  501. package/examples/data.ts +0 -324
  502. /package/dist/plots/{box → distribution/box}/markers.js +0 -0
  503. /package/dist/types/layout/{styles.js → statistics/deviation.js} +0 -0
  504. /package/dist/types/{markers/axis/curveName.js → layout/styles/base.js} +0 -0
  505. /package/dist/types/{plots/area/props.js → layout/styles/bullet.js} +0 -0
  506. /package/dist/types/{plots/area/state.js → layout/styles/connector.js} +0 -0
  507. /package/dist/types/{plots/bar/props.js → layout/styles/curve.js} +0 -0
  508. /package/dist/types/{plots/bar/state.js → layout/styles/frame.js} +0 -0
  509. /package/dist/types/{plots/box/props.js → layout/styles/gaps.js} +0 -0
  510. /package/dist/types/{plots/box/state.js → layout/styles/geo.js} +0 -0
  511. /package/dist/types/{plots/geo/props.js → layout/styles/values.js} +0 -0
  512. /package/dist/types/{plots/geo/state.js → markers/axis/violin.js} +0 -0
  513. /package/dist/types/{plots/heatmap/props.js → markers/channels/commonMarkerConfigWithRowOffset.js} +0 -0
  514. /package/dist/types/plots/{histogram → correlation/heatmap}/props.js +0 -0
  515. /package/dist/types/plots/{heatmap → correlation/heatmap}/state.js +0 -0
  516. /package/dist/types/plots/{line → correlation/scatter}/props.js +0 -0
  517. /package/dist/types/plots/{histogram → correlation/scatter}/state.js +0 -0
  518. /package/dist/types/plots/{pyramid → distribution/box}/props.js +0 -0
  519. /package/dist/types/plots/{line → distribution/box}/state.js +0 -0
  520. /package/dist/types/plots/{scatter → distribution/density}/props.js +0 -0
  521. /package/dist/types/plots/{pyramid → distribution/density}/state.js +0 -0
  522. /package/dist/types/plots/{scatter/state.js → distribution/histogram/props.js} +0 -0
  523. /package/dist/{plots/utils → utils}/accessors.d.ts +0 -0
  524. /package/dist/{plots/utils → utils}/accessors.js +0 -0
@@ -5,6 +5,7 @@ import { MarkerKinds } from '../../markers/MarkerKinds';
5
5
  import { LegendChannels } from './LegendChannels';
6
6
  import { LegendText } from './LegendText';
7
7
  const LEGEND_KEY = Symbol('dct-legend');
8
+ const QUIET_KEY = Symbol('dct-legend-quiet');
8
9
  /**
9
10
  * A figure's legend, shared by every plot and legend under it: what the
10
11
  * reader turned off - each series' {@link LegendDisabledAction}, and the
@@ -29,6 +30,14 @@ export class LegendState {
29
30
  setContext(LEGEND_KEY, legend);
30
31
  return legend;
31
32
  }
33
+ /** Keeps the plots below out of the enclosing legend: they still follow its toggles, but add nothing to it. Call during component init. */
34
+ static silence() {
35
+ setContext(QUIET_KEY, true);
36
+ }
37
+ /** Whether the plots here are kept out of the enclosing legend (see {@link silence}). Call during component init. */
38
+ static isSilenced() {
39
+ return getContext(QUIET_KEY) ?? false;
40
+ }
32
41
  /** The enclosing figure's legend, or a private one for a legend drawn outside any. Call during component init. */
33
42
  static ensure() {
34
43
  return LegendState.current() ?? new LegendState();
@@ -149,19 +158,21 @@ export class LegendState {
149
158
  const { title, domain, range, color, filled, symbol } = entry;
150
159
  ramps.push({
151
160
  type: 'size',
161
+ channel: 'r',
152
162
  title: title && format(title),
153
163
  domain,
154
164
  range,
155
165
  color,
156
166
  filled,
157
167
  ...(symbol ? { symbol } : {}),
158
- ...adjust('size', title)
168
+ ...adjust('r', title)
159
169
  });
160
170
  }
161
171
  else if (entry.type === 'symbol') {
162
172
  const { title, items: shapes, color, filled } = entry;
163
173
  ramps.push({
164
174
  type: 'symbol',
175
+ channel: 'symbol',
165
176
  title: title && format(title),
166
177
  items: shapes,
167
178
  color,
@@ -173,6 +184,7 @@ export class LegendState {
173
184
  const { title, min, max, opacityMin, opacityMax, color } = entry;
174
185
  ramps.push({
175
186
  type: 'continuous',
187
+ channel: 'opacity',
176
188
  title: title && format(title),
177
189
  min,
178
190
  max,
@@ -185,6 +197,7 @@ export class LegendState {
185
197
  const { title, min, max, colorMin, colorMax, scheme, pivot } = entry;
186
198
  const section = {
187
199
  type: 'continuous',
200
+ channel: 'color',
188
201
  title: title && format(title),
189
202
  min,
190
203
  max,
@@ -268,11 +281,15 @@ export class LegendState {
268
281
  */
269
282
  static entriesOf(plot) {
270
283
  const color = (name) => name !== undefined && name !== 'default' ? plot.colorForSeries?.(name) : undefined;
284
+ // A marker that is `legend: false` is decoration - a connector - and does not give the series its symbol.
271
285
  const mark = plot.markers
272
- ?.map((marker) => MarkerKinds.of(marker.type)?.legendSymbol)
286
+ ?.filter((marker) => marker.legend !== false)
287
+ .map((marker) => MarkerKinds.of(marker.type)?.legendSymbol)
273
288
  .find((kind) => kind !== undefined);
274
289
  const dots = LegendChannels.look((plot.markers ?? []).filter((marker) => marker.type === 'dot' && !marker.legend));
275
- const series = (plot.resolvedSeries ?? []).map((s) => ({
290
+ // A series with no rows draws nothing, so it has nothing to show.
291
+ const drawn = (plot.resolvedSeries ?? []).filter((s) => !Array.isArray(s.data) || s.data.length > 0);
292
+ const series = drawn.map((s) => ({
276
293
  type: 'series',
277
294
  name: s.name,
278
295
  color: color(s.name),
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { ticks } from 'd3-array';
3
3
  import type { SizeLegendSection } from '../../types/layout/legend';
4
- import { SymbolPath } from '../../utils/symbol';
4
+ import { SymbolPath } from '../../utils/SymbolPath';
5
5
  import { AxisNumberFormat } from './AxisNumberFormat';
6
6
  import { getConfiguration } from '../../configuration/config.svelte';
7
7
 
@@ -29,6 +29,8 @@ export type PlotMarginsInputs = {
29
29
  scales: () => Partial<Record<AxisChannelName, Pick<AxisScale, 'tickRotate'>>> | undefined;
30
30
  /** The tick labels' font size. */
31
31
  tickFontSize: () => number;
32
+ /** How wide the widest tick label of an axis is, where the plot measured it: a rotated axis takes room for that, not for a guessed width. */
33
+ tickWidth?: () => Partial<Record<AxisChannelName, number | undefined>>;
32
34
  /** Receives the margins the labels settled on - the plot's bindable `margins`. */
33
35
  settle?: (margins: MarginConfig) => void;
34
36
  };
@@ -93,9 +95,4 @@ export declare class PlotMargins {
93
95
  x: number;
94
96
  y: number;
95
97
  }, anchor: BoxAnchors): Box;
96
- /**
97
- * Changes whenever the labels' margins move after mount, which svelteplot
98
- * only takes on a remount. The same margins read back from `settle` keep it.
99
- */
100
- readonly remountKey: string;
101
98
  }
@@ -161,18 +161,19 @@ export class PlotMargins {
161
161
  /**
162
162
  * How much more room (or less) each axis' rotated tick labels take across
163
163
  * it, on its side. An x label stands as tall as its text, a y label as wide;
164
- * rotated, it reaches across by its turned box. A label is taken as twice
165
- * as wide as its font size.
164
+ * rotated, it reaches across by its turned box.
166
165
  */
167
166
  #tickRoom = $derived.by(() => {
168
167
  const scales = this.#inputs.scales();
169
168
  const height = this.#inputs.tickFontSize();
170
- const width = 2 * height;
169
+ const measured = this.#inputs.tickWidth?.();
171
170
  const room = {};
172
171
  for (const axis of ['x', 'y']) {
173
172
  const degrees = scales?.[axis]?.tickRotate;
174
173
  if (!degrees)
175
174
  continue;
175
+ // A label is taken as twice as wide as its font size, unless the plot measured it.
176
+ const width = measured?.[axis] || 2 * height;
176
177
  const rad = (degrees * Math.PI) / 180;
177
178
  const [across, along] = axis === 'x' ? [height, width] : [width, height];
178
179
  const turned = Math.abs(Math.cos(rad)) * across + Math.abs(Math.sin(rad)) * along;
@@ -211,9 +212,4 @@ export class PlotMargins {
211
212
  place(size, point, anchor) {
212
213
  return size.placeNear(point, anchor, this.box);
213
214
  }
214
- /**
215
- * Changes whenever the labels' margins move after mount, which svelteplot
216
- * only takes on a remount. The same margins read back from `settle` keep it.
217
- */
218
- remountKey = $derived.by(() => JSON.stringify(this.#labels ?? null));
219
215
  }
@@ -39,6 +39,10 @@ export declare class Slice<TRow extends Record<string, unknown>> {
39
39
  * displays its axes.
40
40
  */
41
41
  facetScales<TScales extends object>(shared: Record<string, object> | undefined, place: FacetCellContext<TRow>): TScales | undefined;
42
- /** The scales a timeline alone keeps every step on - the domains all its rows span - unless it fits each step's own. */
42
+ /**
43
+ * The scales a timeline alone keeps every step on - the domains all its rows
44
+ * span - unless it fits each step's own: both under `'free'`, or the one axis
45
+ * `'free-x'`/`'free-y'` names, which leaves the other on its shared domain.
46
+ */
43
47
  timelineScales<TScales extends object>(shared: Record<string, object> | undefined): TScales | undefined;
44
48
  }
@@ -1,4 +1,4 @@
1
- import { resolveAccessor } from '../../plots/utils/accessors';
1
+ import { resolveAccessor } from '../../utils/accessors';
2
2
  import { merge } from '../../utils/merge';
3
3
  import { TimelineSteps } from '../timeline/TimelineSteps';
4
4
  import { TimelineTime } from '../timeline/TimelineTime';
@@ -90,11 +90,21 @@ export class Slice {
90
90
  return undefined;
91
91
  return merge(shared?.[key], this.#axes?.(place));
92
92
  }
93
- /** The scales a timeline alone keeps every step on - the domains all its rows span - unless it fits each step's own. */
93
+ /**
94
+ * The scales a timeline alone keeps every step on - the domains all its rows
95
+ * span - unless it fits each step's own: both under `'free'`, or the one axis
96
+ * `'free-x'`/`'free-y'` names, which leaves the other on its shared domain.
97
+ */
94
98
  timelineScales(shared) {
95
99
  const { timeline, facet } = this;
96
- if (!timeline || facet || timeline.scales === 'free')
100
+ const mode = timeline?.scales;
101
+ if (!timeline || facet || mode === 'free')
97
102
  return undefined;
98
- return shared?.[''];
103
+ const all = shared?.[''];
104
+ if (!all || (mode !== 'free-x' && mode !== 'free-y'))
105
+ return all;
106
+ const kept = { ...all };
107
+ delete kept[mode === 'free-x' ? 'x' : 'y'];
108
+ return kept;
99
109
  }
100
110
  }
@@ -1,4 +1,5 @@
1
1
  import type { AxisChannelName } from '../../types/layout/mapping';
2
+ import type { NiceOption } from '../../types/layout/scales';
2
3
  /**
3
4
  * "Nice" (1/2/5×10ⁿ) tick steps and the domains they round to, compatible with
4
5
  * d3-array's and reimplemented here to avoid depending on internals svelteplot
@@ -24,6 +25,8 @@ export declare class NiceTicks {
24
25
  static step(start: number, stop: number, count: number): number;
25
26
  /** Multiples of `step` covering `[start, stop]`, inclusive of either endpoint when it lands exactly on one. */
26
27
  static inRange(start: number, stop: number, step: number): number[];
28
+ /** The tolerance a scale's `nice` asks for, or `undefined` for the default. */
29
+ static toleranceOf(nice: NiceOption | undefined): number | undefined;
27
30
  /** How many ticks fit `span` pixels at one per `spacing`, and at least `min`. */
28
31
  static count(span: number, spacing: number, min: number): number;
29
32
  /**
@@ -44,6 +44,10 @@ export class NiceTicks {
44
44
  out.push(i * step);
45
45
  return out;
46
46
  }
47
+ /** The tolerance a scale's `nice` asks for, or `undefined` for the default. */
48
+ static toleranceOf(nice) {
49
+ return typeof nice === 'object' ? nice.tolerance : undefined;
50
+ }
47
51
  /** How many ticks fit `span` pixels at one per `spacing`, and at least `min`. */
48
52
  static count(span, spacing, min) {
49
53
  return Math.max(min, Math.round(span / spacing));
@@ -9,6 +9,7 @@
9
9
  import { DISCRETE_SCALE_TYPES } from '../../types/layout/scales';
10
10
  import type { AxisBasedScalesConfig } from '../../types/layout/scales';
11
11
  import type { AxisValue } from '../../types/layout/mapping';
12
+ import type { PlotLayoutState } from '../../types/layout/plot';
12
13
 
13
14
  /** Axis ticks, titles and grid lines for the plot kinds with an x/y axis pair. */
14
15
  let {
@@ -19,7 +20,9 @@
19
20
  height,
20
21
  numericMargins,
21
22
  scales,
22
- edgeDomains = undefined
23
+ edgeDomains = undefined,
24
+ tickValues = undefined,
25
+ state: plotState
23
26
  }: {
24
27
  data: TData[];
25
28
  getX: (d: TData) => AxisValue;
@@ -33,8 +36,18 @@
33
36
  * `'extend'` resolved a collision (see `EdgeTicks`), for the plot to give its scale.
34
37
  */
35
38
  edgeDomains?: Map<'x' | 'y', [number, number]>;
39
+ /** The labels a category axis writes, when it leaves some out for want of room. */
40
+ tickValues?: Partial<Record<'x' | 'y', string[]>>;
41
+ /** The plot's state: its fitted axes and the y channel's field, which titles a vertical y axis with no rows. */
42
+ state: Pick<PlotLayoutState, 'fittedAxes' | 'channels'>;
36
43
  } = $props();
37
44
 
45
+ const fittedAxes = $derived(plotState.fittedAxes);
46
+ const yField = $derived.by(() => {
47
+ const source = plotState.channels?.y?.source;
48
+ return typeof source === 'string' ? source : undefined;
49
+ });
50
+
38
51
  const cfg = $derived(getConfiguration());
39
52
  const plot = usePlot().svelteplot;
40
53
 
@@ -101,6 +114,8 @@
101
114
  if (!extent) return undefined;
102
115
  const [lo, hi] = extent;
103
116
  if (!Number.isInteger(lo) || !Number.isInteger(hi)) return undefined;
117
+ const numbers = values.filter((v): v is number => typeof v === 'number');
118
+ if (numbers.length === 0 || !numbers.every(Number.isInteger)) return undefined;
104
119
  return hi - lo < NiceTicks.count(span, spacing, min) ? 1 : undefined;
105
120
  }
106
121
 
@@ -139,7 +154,7 @@
139
154
  scale?.ticks != null ||
140
155
  scale?.tickSpacing != null ||
141
156
  scale?.interval != null ||
142
- scale?.domain != null
157
+ (scale?.domain != null && !fittedAxes?.includes(axis))
143
158
  )
144
159
  return undefined;
145
160
  if (type != null && isDiscreteType(type)) return undefined;
@@ -179,6 +194,12 @@
179
194
  });
180
195
  });
181
196
 
197
+ /** A turned label is written on one line: the axis does not wrap it. */
198
+ const turned = $derived(scales?.x?.tickRotate ? { wordwrap: false } : {}) as Record<
199
+ string,
200
+ unknown
201
+ >;
202
+
182
203
  const yTitleFontSize = $derived(scales?.y?.titleFontSize ?? cfg.axis.titleFontSize);
183
204
 
184
205
  /**
@@ -187,7 +208,8 @@
187
208
  */
188
209
  const verticalYLabel = $derived.by(() => {
189
210
  if (scales?.y?.labelOrientation !== 'vertical' || scales.y.label === false) return null;
190
- const text = scales.y.label || plot.scales.y.autoTitle;
211
+ const text =
212
+ scales.y.label || plot.scales.y.autoTitle || (data.length === 0 ? yField : undefined);
191
213
  if (!text) return null;
192
214
  const position = scales.y.labelPosition ?? 'middle';
193
215
  const x = yTitleFontSize;
@@ -220,11 +242,54 @@
220
242
  $effect(() => () => {
221
243
  $autoMarginLeft.delete(marginId);
222
244
  });
245
+
246
+ // An x label centred on the domain's end reaches past the plot's right side; an `'auto'` right margin takes that much room.
247
+ let xAxisEl: SVGGElement | undefined = $state();
248
+ const { autoMarginRight } = getContext<{ autoMarginRight: Writable<Map<string, number>> }>(
249
+ 'svelteplot/autoMargins'
250
+ );
251
+ const overhangId = `dct-x-tick-overhang-${Math.random().toString(36).slice(2)}`;
252
+ $effect(() => {
253
+ const el = xAxisEl;
254
+ // Read so a new axis, a new box or a new margin measures again.
255
+ void [scales?.x, xEdgeTicks, tickValues?.x, plot.options.marginLeft, plot.facetWidth];
256
+ if (!el) return;
257
+ let frame: number | undefined;
258
+ let cancelled = false;
259
+ const measure = () => {
260
+ if (cancelled) return;
261
+ const labels = el.querySelectorAll('g.tick text');
262
+ const last = labels.item(labels.length - 1);
263
+ const svg = el.ownerSVGElement;
264
+ const { marginLeft } = plot.options;
265
+ if (last && svg && Number.isFinite(marginLeft) && Number.isFinite(plot.facetWidth)) {
266
+ const edge = svg.getBoundingClientRect().left + Number(marginLeft) + plot.facetWidth;
267
+ const overhang = Math.max(0, Math.ceil(last.getBoundingClientRect().right - edge));
268
+ untrack(() => {
269
+ if (overhang === 0) $autoMarginRight.delete(overhangId);
270
+ else if ($autoMarginRight.get(overhangId) !== overhang)
271
+ $autoMarginRight.set(overhangId, overhang);
272
+ });
273
+ }
274
+ };
275
+ // Text measures right only once its fonts load.
276
+ (document.fonts?.ready ?? Promise.resolve()).then(() => {
277
+ if (!cancelled) frame = requestAnimationFrame(measure);
278
+ });
279
+ return () => {
280
+ cancelled = true;
281
+ if (frame !== undefined) cancelAnimationFrame(frame);
282
+ };
283
+ });
284
+ $effect(() => () => {
285
+ $autoMarginRight.delete(overhangId);
286
+ });
223
287
  </script>
224
288
 
225
289
  {#snippet axisX()}
226
290
  <AxisX
227
- ticks={xEdgeTicks?.ticks}
291
+ ticks={(xEdgeTicks?.ticks ?? tickValues?.x) as string[] | undefined}
292
+ {...turned}
228
293
  tickCount={xTickCount}
229
294
  interval={xTickInterval}
230
295
  tickSize={scales?.x?.tickSize ?? cfg.axis.xTickSize}
@@ -234,13 +299,13 @@
234
299
  />
235
300
  {/snippet}
236
301
  {#if scales?.x?.axisDisplay === 'hidden'}
237
- <g style:visibility="hidden">{@render axisX()}</g>
302
+ <g style:visibility="hidden" bind:this={xAxisEl}>{@render axisX()}</g>
238
303
  {:else if scales?.x?.axisDisplay !== 'none'}
239
- {@render axisX()}
304
+ <g bind:this={xAxisEl}>{@render axisX()}</g>
240
305
  {/if}
241
306
  {#snippet axisY()}
242
307
  <AxisY
243
- ticks={yEdgeTicks?.ticks}
308
+ ticks={(yEdgeTicks?.ticks ?? tickValues?.y) as string[] | undefined}
244
309
  tickCount={yTickCount}
245
310
  interval={yTickInterval}
246
311
  tickSize={scales?.y?.tickSize ?? cfg.axis.yTickSize}
@@ -1,5 +1,6 @@
1
1
  import type { AxisBasedScalesConfig } from '../../types/layout/scales';
2
2
  import type { AxisValue } from '../../types/layout/mapping';
3
+ import type { PlotLayoutState } from '../../types/layout/plot';
3
4
  declare function $$render<TData extends Record<string, unknown>>(): {
4
5
  props: {
5
6
  data: TData[];
@@ -19,6 +20,10 @@ declare function $$render<TData extends Record<string, unknown>>(): {
19
20
  * `'extend'` resolved a collision (see `EdgeTicks`), for the plot to give its scale.
20
21
  */
21
22
  edgeDomains?: Map<"x" | "y", [number, number]>;
23
+ /** The labels a category axis writes, when it leaves some out for want of room. */
24
+ tickValues?: Partial<Record<"x" | "y", string[]>>;
25
+ /** The plot's state: its fitted axes and the y channel's field, which titles a vertical y axis with no rows. */
26
+ state: Pick<PlotLayoutState, "fittedAxes" | "channels">;
22
27
  };
23
28
  exports: {};
24
29
  bindings: "";
@@ -7,8 +7,8 @@ export declare class SveltePlotScale {
7
7
  static readonly CONTINUOUS_NUMERIC_TYPES: ReadonlySet<string>;
8
8
  /**
9
9
  * The scale without what the package handles itself - `grid`, `axisDisplay`
10
- * and a vertical `label`, which `ScalesLayout` draws, and `niceTolerance`,
11
- * which the "scales" phase applies - with a custom `sort` resolved into a
10
+ * and a vertical `label`, which `ScalesLayout` draws, and a `nice` object's `tolerance`,
11
+ * which the "scales" phase applies (svelteplot is told plain `nice: true`) - with a custom `sort` resolved into a
12
12
  * `domain`, and `nice: true` on an unpinned numeric axis.
13
13
  */
14
14
  static build<TData>(scale: AxisScale<TData> | undefined, rows: TData[], getAxisValue: (d: TData) => AxisValue): AxisScale<TData> | undefined;
@@ -12,8 +12,8 @@ export class SveltePlotScale {
12
12
  ]);
13
13
  /**
14
14
  * The scale without what the package handles itself - `grid`, `axisDisplay`
15
- * and a vertical `label`, which `ScalesLayout` draws, and `niceTolerance`,
16
- * which the "scales" phase applies - with a custom `sort` resolved into a
15
+ * and a vertical `label`, which `ScalesLayout` draws, and a `nice` object's `tolerance`,
16
+ * which the "scales" phase applies (svelteplot is told plain `nice: true`) - with a custom `sort` resolved into a
17
17
  * `domain`, and `nice: true` on an unpinned numeric axis.
18
18
  */
19
19
  static build(scale, rows, getAxisValue) {
@@ -24,24 +24,27 @@ export class SveltePlotScale {
24
24
  (scale?.type == null || SveltePlotScale.CONTINUOUS_NUMERIC_TYPES.has(scale.type)) &&
25
25
  SveltePlotScale.#isNumeric(rows, getAxisValue);
26
26
  const removesAxis = scale?.axisDisplay === 'none';
27
- if (!sorted && !wantsNice && !removesAxis)
27
+ // svelteplot treats a categorical axis told to be `nice` as linear, and draws nothing.
28
+ const dropsNice = scale?.nice != null && SveltePlotScale.#isCategorical(rows, getAxisValue);
29
+ if (!sorted && !wantsNice && !removesAxis && !dropsNice)
28
30
  return sorted;
29
31
  const out = { ...sorted };
30
32
  delete out.grid;
31
33
  delete out.axisDisplay;
32
- delete out.niceTolerance;
33
34
  if (removesAxis)
34
35
  out.axis = false;
35
36
  if (scale?.labelOrientation === 'vertical')
36
37
  out.label = false;
37
- if (wantsNice)
38
+ if (dropsNice)
39
+ delete out.nice;
40
+ else if (wantsNice || typeof scale?.nice === 'object')
38
41
  out.nice = true;
39
42
  return out;
40
43
  }
41
44
  /** svelteplot's `sort` option only does a fixed ascending sort; a custom `scale.sort` comparator is resolved into an explicit `domain` instead, which svelteplot honors as-is. */
42
45
  static #sorted(scale, rows, getAxisValue) {
43
46
  const sort = scale?.sort;
44
- if (!sort || scale?.domain)
47
+ if (typeof sort !== 'function' || scale?.domain)
45
48
  return scale;
46
49
  const reps = SveltePlotScale.#uniqueRows(rows, getAxisValue);
47
50
  if (reps.length === 0 || !reps.every((r) => typeof getAxisValue(r) === 'string'))
@@ -62,6 +65,10 @@ export class SveltePlotScale {
62
65
  }
63
66
  return out;
64
67
  }
68
+ /** Whether the axis lays out text categories: any of its values is a string. */
69
+ static #isCategorical(rows, getAxisValue) {
70
+ return rows.some((row) => typeof getAxisValue(row) === 'string');
71
+ }
65
72
  /** Whether the axis' values are numeric; `nice` on a categorical axis would make svelteplot treat it as linear. */
66
73
  static #isNumeric(rows, getAxisValue) {
67
74
  let numericSeen = 0;
@@ -0,0 +1,32 @@
1
+ import type { PlotStylesConfig } from '../../types/configuration/styling';
2
+ /** How a category axis lays its tick labels out: the angle they stand at, and which of them are written. */
3
+ export type TickLayout = {
4
+ /** `0`, `-45` or `-90` degrees. */
5
+ rotate: 0 | -45 | -90;
6
+ /** Every how-manieth label is written: `1` writes them all. */
7
+ every: number;
8
+ /** The widest label, in px, as it is written - not wrapped, when it is rotated. */
9
+ width: number;
10
+ };
11
+ /**
12
+ * Where the tick labels of a category axis fit. Written flat they wrap at their
13
+ * spaces to the width of their band - a word is never split - and stand side by
14
+ * side as long as the widest line is narrower than the step between categories.
15
+ * Otherwise they turn: at 45 degrees a label needs a step of about one and a
16
+ * half lines of text, at 90 degrees of one; past that, only every few labels
17
+ * are written.
18
+ */
19
+ export declare class TickLabels {
20
+ /** The gap, in px, kept between neighbouring labels. */
21
+ static readonly GAP = 6;
22
+ /**
23
+ * The layout of `labels` along an axis `span` px long - the categories
24
+ * `bandPadding` (0-1) apart - written at `fontSize`.
25
+ */
26
+ static layout(labels: readonly string[], span: number, bandPadding: number, fontSize: number, cfg: Pick<PlotStylesConfig, 'font'>): TickLayout;
27
+ /**
28
+ * The layout of a category axis running down the plot, whose labels stand
29
+ * flat in a row each: only how many can be written.
30
+ */
31
+ static rows(count: number, span: number, fontSize: number): number;
32
+ }
@@ -0,0 +1,55 @@
1
+ import { Box } from '../margins/Box';
2
+ /**
3
+ * Where the tick labels of a category axis fit. Written flat they wrap at their
4
+ * spaces to the width of their band - a word is never split - and stand side by
5
+ * side as long as the widest line is narrower than the step between categories.
6
+ * Otherwise they turn: at 45 degrees a label needs a step of about one and a
7
+ * half lines of text, at 90 degrees of one; past that, only every few labels
8
+ * are written.
9
+ */
10
+ export class TickLabels {
11
+ /** The gap, in px, kept between neighbouring labels. */
12
+ static GAP = 6;
13
+ /**
14
+ * The layout of `labels` along an axis `span` px long - the categories
15
+ * `bandPadding` (0-1) apart - written at `fontSize`.
16
+ */
17
+ static layout(labels, span, bandPadding, fontSize, cfg) {
18
+ const count = labels.length;
19
+ const measure = (text) => Box.ofText(text, fontSize, cfg).width;
20
+ const lineHeight = fontSize * 1.2;
21
+ const whole = Math.max(0, ...labels.map(measure));
22
+ const flat = { rotate: 0, every: 1, width: whole };
23
+ if (count < 2 || span <= 0 || whole === 0)
24
+ return flat;
25
+ const step = span / count;
26
+ const room = step - TickLabels.GAP;
27
+ // What a flat label measures once wrapped to its band, as the axis does.
28
+ const maxLine = step * (1 - bandPadding) * 0.9;
29
+ const wrapped = Math.max(0, ...labels.map((label) => {
30
+ const text = measure(label);
31
+ if (text <= maxLine)
32
+ return text;
33
+ const words = Math.max(0, ...label.split(/\s+/).map(measure));
34
+ return Math.max(words, maxLine);
35
+ }));
36
+ if (wrapped <= room)
37
+ return { ...flat, width: wrapped };
38
+ // Turned, a label stands as wide as a line of text across its step.
39
+ if (room >= lineHeight / Math.sin(Math.PI / 4))
40
+ return { rotate: -45, every: 1, width: whole };
41
+ if (room >= lineHeight)
42
+ return { rotate: -90, every: 1, width: whole };
43
+ return { rotate: -90, every: Math.ceil(lineHeight / Math.max(1, room)), width: whole };
44
+ }
45
+ /**
46
+ * The layout of a category axis running down the plot, whose labels stand
47
+ * flat in a row each: only how many can be written.
48
+ */
49
+ static rows(count, span, fontSize) {
50
+ if (count < 2 || span <= 0)
51
+ return 1;
52
+ const row = span / count;
53
+ return Math.max(1, Math.ceil((fontSize * 1.2 + 2) / row));
54
+ }
55
+ }
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { Frame } from 'svelteplot';
3
3
  import TileLayer from './TileLayer.svelte';
4
- import { geometryLonLatBounds } from '../../plots/utils/geoAccessors';
4
+ import { GeoGeometry } from '../../plots/map/geo/GeoGeometry';
5
5
  import type { StylesLayoutConfig } from '../../types/layout/styles';
6
6
 
7
7
  /**
@@ -36,7 +36,7 @@
36
36
  let minLat = Infinity;
37
37
  let maxLat = -Infinity;
38
38
  for (const f of features) {
39
- const b = geometryLonLatBounds(f.geometry);
39
+ const b = GeoGeometry.lonLatBounds(f.geometry);
40
40
  if (!b) continue;
41
41
  if (b[0] < minLon) minLon = b[0];
42
42
  if (b[2] > maxLon) maxLon = b[2];
@@ -8,7 +8,7 @@ import type { FontStyle, StrokeStyle } from '../../types/plots/styling';
8
8
  import type { TextAnchor, ValueAnchor } from '../../types/plots/constants';
9
9
  import type { BoxAnchors, EdgeBox } from '../../types/layout/box';
10
10
  import type { MarginSide } from '../../types/plots/props';
11
- import type { AxisPlotCtx, AxisPlotState, ProcessedRow } from '../../types/phases';
11
+ import type { AxisPlotCtx, AxisPlotState, ProcessedData, ProcessedRow } from '../../types/phases';
12
12
  import type { TextMarkerConfig } from '../../types/markers/common';
13
13
  /**
14
14
  * A plot's value labels: the author's `styles.values` over the plot kind's
@@ -20,12 +20,14 @@ export declare class ValueLabels {
20
20
  #private;
21
21
  readonly show: boolean;
22
22
  readonly anchor: ValueAnchor;
23
- readonly format: (value: number, seriesName: string) => string;
23
+ readonly format: (value: number, seriesName: string, row?: Record<string, unknown>) => string;
24
24
  readonly hoverIsolate: boolean;
25
25
  readonly font: FontStyle | undefined;
26
26
  readonly fontSize: number;
27
27
  /** The connectors of labels that had to move apart. */
28
28
  readonly strokeStyle: StrokeStyle | undefined;
29
+ /** `'series'` writes each label in its series' color; any other CSS color writes them all in it. */
30
+ readonly color: 'series' | string | undefined;
29
31
  /** How labels that would overlap move apart - the configuration's `text.declutter`. */
30
32
  readonly declutter: PlotStylesConfig['text']['declutter'];
31
33
  /** Where the labels are expected to sit: boxes around their points, on the edges those can reach. */
@@ -33,6 +35,14 @@ export declare class ValueLabels {
33
35
  constructor(values: ValuesStyle | undefined, cfg: PlotStylesConfig, options?: Omit<ValueLabelsOptions<never>, 'reach'>, reach?: (labels: ValueLabels) => EdgeBox[]);
34
36
  /** A plot's value labels: `values` over `options`, the kind's own defaults, their reach read off `state`. */
35
37
  static build<TState>(values: ValuesStyle | undefined, cfg: PlotStylesConfig, options: ValueLabelsOptions<TState>, state: TState): ValueLabels;
38
+ /** The configuration the labels were built under, for a plot kind's own label defaults. */
39
+ get config(): PlotStylesConfig;
40
+ /**
41
+ * The fill every label takes whatever its series: the author's own
42
+ * `fontStyle.fill`, else a literal `color`. `undefined` leaves each label to
43
+ * its plot's default (its series' color, or the axis').
44
+ */
45
+ get fill(): string | undefined;
36
46
  /** One line of label text's height. */
37
47
  get lineHeight(): number;
38
48
  /** The box one label's `text` takes. */
@@ -82,9 +92,27 @@ export declare class ValueLabels {
82
92
  * (`filter` + `selectLast`, per series), at its top (a stacked row's
83
93
  * `y2`), labelled with its own value and placed by `anchor`. Labels that
84
94
  * would overlap fan out into a shared column (`declutter`), colored by the
85
- * segment the row falls in.
95
+ * segment the row falls in. A plot that labels each end of its series apart
96
+ * passes the `rows` and `anchor` of one end, and `lane` to route its labels
97
+ * out to a lane whether or not they overlap (`flip: false` keeps one on the
98
+ * left in the margin instead of flipping it over its points).
86
99
  */
87
- atSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object>): TextMarkerConfig[];
100
+ atSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object>, end?: {
101
+ rows?: ProcessedRow[];
102
+ anchor?: ValueAnchor;
103
+ lane?: boolean | {
104
+ elbowGap: number;
105
+ };
106
+ flip?: boolean;
107
+ }): TextMarkerConfig[];
108
+ /** How far (px) a lane takes the label of a series' first point from it - clear of the line that leaves it. */
109
+ static readonly FIRST_LANE_GAP = 28;
110
+ /** The rows of a series-over-`x` plot that cannot be labelled: a gap, or a stack with no top. For the "transforms" phase's `labels.skip`. */
111
+ static skipGaps<TData extends Record<string, unknown>>(state: {
112
+ processedData?: ProcessedData;
113
+ resolvedSeries?: Series<TData>[];
114
+ axes?: PlotAxes;
115
+ }): (row: ProcessedRow) => boolean;
88
116
  /**
89
117
  * Where {@link atSeriesEnds}' labels are expected to sit: past each
90
118
  * series' last point, at the right edge (or the left, for labels set
@@ -93,5 +121,5 @@ export declare class ValueLabels {
93
121
  * domain when the scales set one, so it holds across a timeline; else off
94
122
  * every value.
95
123
  */
96
- reachAtSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object>): EdgeBox[];
124
+ reachAtSeriesEnds<TData extends Record<string, unknown>>(state: AxisPlotState<TData, object>, anchor?: ValueAnchor): EdgeBox[];
97
125
  }