@fundar/data-chart-telling 1.0.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 (560) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/README.md +58 -19
  3. package/dist/configuration/config.svelte.d.ts +1 -1
  4. package/dist/configuration/config.svelte.js +172 -95
  5. package/dist/configuration/themes/index.d.ts +5 -1304
  6. package/dist/index.d.ts +24 -14
  7. package/dist/index.js +20 -10
  8. package/dist/layout/base/BasePlotLayout.svelte +129 -51
  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/hover/HoverSettings.d.ts +20 -6
  31. package/dist/layout/hover/HoverSettings.js +29 -4
  32. package/dist/layout/legend/ContinuousSection.svelte +44 -9
  33. package/dist/layout/legend/DiscreteBadgeItem.svelte +2 -2
  34. package/dist/layout/legend/DiscreteSection.svelte +2 -2
  35. package/dist/layout/legend/DiscreteSymbolIcon.svelte +1 -1
  36. package/dist/layout/legend/LegendChannels.js +36 -12
  37. package/dist/layout/legend/LegendLayout.svelte +9 -1
  38. package/dist/layout/legend/LegendState.svelte.d.ts +9 -0
  39. package/dist/layout/legend/LegendState.svelte.js +24 -3
  40. package/dist/layout/legend/SizeSection.svelte +1 -1
  41. package/dist/layout/margins/PlotMargins.svelte.d.ts +2 -5
  42. package/dist/layout/margins/PlotMargins.svelte.js +4 -8
  43. package/dist/layout/plot/Plot.svelte +6 -3
  44. package/dist/layout/plot/PublicPlotContext.d.ts +5 -4
  45. package/dist/layout/plot/PublicPlotContext.js +7 -3
  46. package/dist/layout/plot/Slice.d.ts +5 -1
  47. package/dist/layout/plot/Slice.js +18 -6
  48. package/dist/layout/scales/EdgeTicks.d.ts +39 -0
  49. package/dist/layout/scales/EdgeTicks.js +82 -0
  50. package/dist/layout/scales/NiceTicks.d.ts +43 -0
  51. package/dist/layout/scales/NiceTicks.js +76 -0
  52. package/dist/layout/scales/ScalesLayout.svelte +133 -34
  53. package/dist/layout/scales/ScalesLayout.svelte.d.ts +10 -0
  54. package/dist/layout/scales/SveltePlotScale.d.ts +15 -0
  55. package/dist/layout/scales/SveltePlotScale.js +86 -0
  56. package/dist/layout/scales/TickLabels.d.ts +32 -0
  57. package/dist/layout/scales/TickLabels.js +55 -0
  58. package/dist/layout/styles/StylesLayout.svelte +2 -2
  59. package/dist/layout/styles/ValueLabels.d.ts +33 -5
  60. package/dist/layout/styles/ValueLabels.js +83 -23
  61. package/dist/layout/timeline/Timeline.svelte +5 -2
  62. package/dist/layout/timeline/Timeline.svelte.d.ts +2 -0
  63. package/dist/layout/timeline/TimelineLayout.svelte +39 -13
  64. package/dist/layout/timeline/TimelineLayout.svelte.d.ts +7 -5
  65. package/dist/layout/timeline/TimelineRule.svelte +1 -0
  66. package/dist/layout/timeline/TimelineState.svelte.d.ts +13 -5
  67. package/dist/layout/timeline/TimelineState.svelte.js +42 -8
  68. package/dist/layout/timeline/TimelineTime.d.ts +18 -0
  69. package/dist/layout/timeline/TimelineTime.js +117 -0
  70. package/dist/layout/tooltip/Tooltip.svelte +10 -7
  71. package/dist/layout/tooltip/Tooltip.svelte.d.ts +6 -4
  72. package/dist/layout/tooltip/TooltipState.svelte.d.ts +8 -2
  73. package/dist/layout/tooltip/TooltipState.svelte.js +23 -4
  74. package/dist/markers/MarkerKinds.d.ts +5 -0
  75. package/dist/markers/MarkerKinds.js +1 -0
  76. package/dist/markers/area/AreaMarker.svelte +15 -63
  77. package/dist/markers/arrow/ArrowMarker.svelte +51 -9
  78. package/dist/markers/bar/BarMarker.svelte +8 -4
  79. package/dist/markers/bollinger/BollingerMarker.svelte +33 -18
  80. package/dist/markers/box/BoxMarker.svelte +40 -9
  81. package/dist/markers/delta/Delta.js +1 -1
  82. package/dist/markers/delta/DeltaMarker.svelte +9 -7
  83. package/dist/markers/dot/DotMarker.svelte +24 -27
  84. package/dist/markers/image/ImageMarker.svelte +17 -12
  85. package/dist/markers/inset/InsetMarker.svelte +2 -2
  86. package/dist/markers/line/LineMarker.svelte +1 -0
  87. package/dist/markers/link/LinkMarker.svelte +174 -29
  88. package/dist/markers/regression/RegressionMarker.svelte +16 -33
  89. package/dist/markers/rule/RuleMarker.svelte +9 -3
  90. package/dist/markers/text/Declutter.d.ts +4 -0
  91. package/dist/markers/text/Declutter.js +26 -11
  92. package/dist/markers/text/TextMarker.svelte +91 -48
  93. package/dist/markers/tick/TickMarker.svelte +27 -25
  94. package/dist/markers/utils/MarkerChannels.d.ts +24 -0
  95. package/dist/markers/utils/MarkerChannels.js +42 -7
  96. package/dist/markers/utils/RowOffset.d.ts +23 -0
  97. package/dist/markers/utils/RowOffset.js +23 -0
  98. package/dist/markers/utils/RowOffsetMarks.svelte +30 -0
  99. package/dist/markers/utils/RowOffsetMarks.svelte.d.ts +33 -0
  100. package/dist/markers/utils/RowStroke.d.ts +31 -0
  101. package/dist/markers/utils/RowStroke.js +28 -0
  102. package/dist/markers/violin/ViolinMarker.svelte +75 -0
  103. package/dist/markers/violin/ViolinMarker.svelte.d.ts +7 -0
  104. package/dist/markers/violin/ViolinProfiles.d.ts +29 -0
  105. package/dist/markers/violin/ViolinProfiles.js +55 -0
  106. package/dist/markers/waffle/WaffleMarker.svelte +17 -37
  107. package/dist/phases/Pipeline.d.ts +5 -0
  108. package/dist/phases/Pipeline.js +8 -2
  109. package/dist/phases/data/DataPhase.d.ts +5 -11
  110. package/dist/phases/data/DataPhase.js +14 -11
  111. package/dist/phases/data/PlotAxes.d.ts +10 -0
  112. package/dist/phases/data/PlotAxes.js +14 -1
  113. package/dist/phases/facet/FacetPanels.d.ts +55 -0
  114. package/dist/phases/facet/FacetPanels.js +96 -0
  115. package/dist/phases/facet/FacetPhase.d.ts +1 -42
  116. package/dist/phases/facet/FacetPhase.js +1 -87
  117. package/dist/phases/hover/HoverPhase.d.ts +6 -43
  118. package/dist/phases/hover/HoverPhase.js +19 -54
  119. package/dist/phases/mapping/MappingPhase.d.ts +1 -1
  120. package/dist/phases/mapping/MappingPhase.js +3 -5
  121. package/dist/phases/markers/MarkersPhase.js +2 -1
  122. package/dist/phases/scales/CategoryOrder.d.ts +23 -0
  123. package/dist/phases/scales/CategoryOrder.js +73 -0
  124. package/dist/phases/scales/ScalesPhase.d.ts +1 -3
  125. package/dist/phases/scales/ScalesPhase.js +37 -27
  126. package/dist/phases/sharedScales/SharedScalesPhase.d.ts +6 -2
  127. package/dist/phases/sharedScales/SharedScalesPhase.js +14 -8
  128. package/dist/phases/statistics/Statistics.d.ts +10 -6
  129. package/dist/phases/statistics/Statistics.js +20 -10
  130. package/dist/phases/statistics/StatisticsPhase.js +10 -6
  131. package/dist/phases/statistics/methods/BollingerStatistic.d.ts +1 -1
  132. package/dist/phases/statistics/methods/BollingerStatistic.js +13 -11
  133. package/dist/phases/statistics/methods/BoxStatistic.d.ts +1 -1
  134. package/dist/phases/statistics/methods/BoxStatistic.js +14 -12
  135. package/dist/phases/statistics/methods/Density2dStatistic.d.ts +1 -1
  136. package/dist/phases/statistics/methods/Density2dStatistic.js +13 -11
  137. package/dist/phases/statistics/methods/DensityStatistic.d.ts +1 -1
  138. package/dist/phases/statistics/methods/DensityStatistic.js +11 -9
  139. package/dist/phases/statistics/methods/DeviationStatistic.d.ts +8 -0
  140. package/dist/phases/statistics/methods/DeviationStatistic.js +111 -0
  141. package/dist/phases/statistics/methods/MovingAverageStatistic.d.ts +1 -1
  142. package/dist/phases/statistics/methods/MovingAverageStatistic.js +11 -9
  143. package/dist/phases/statistics/methods/RegressionStatistic.d.ts +1 -1
  144. package/dist/phases/statistics/methods/RegressionStatistic.js +16 -14
  145. package/dist/phases/tooltip/TooltipPhase.d.ts +4 -2
  146. package/dist/phases/tooltip/TooltipPhase.js +10 -3
  147. package/dist/phases/transforms/ProcessedPositions.d.ts +30 -0
  148. package/dist/phases/transforms/ProcessedPositions.js +74 -0
  149. package/dist/phases/transforms/TransformsPhase.d.ts +5 -42
  150. package/dist/phases/transforms/TransformsPhase.js +67 -58
  151. package/dist/phases/transforms/ValueSelection.d.ts +30 -0
  152. package/dist/phases/transforms/ValueSelection.js +53 -0
  153. package/dist/plots/{heatmap → correlation/heatmap}/Plot.svelte +5 -2
  154. package/dist/plots/{heatmap → correlation/heatmap}/Plot.svelte.d.ts +2 -2
  155. package/dist/plots/{heatmap → correlation/heatmap}/defaults.d.ts +2 -2
  156. package/dist/plots/{heatmap → correlation/heatmap}/defaults.js +5 -5
  157. package/dist/plots/{heatmap → correlation/heatmap}/markers.d.ts +4 -4
  158. package/dist/plots/{heatmap → correlation/heatmap}/markers.js +4 -3
  159. package/dist/plots/{scatter → correlation/scatter}/Plot.svelte +5 -2
  160. package/dist/plots/{scatter → correlation/scatter}/Plot.svelte.d.ts +2 -2
  161. package/dist/plots/{scatter → correlation/scatter}/defaults.d.ts +2 -2
  162. package/dist/plots/{scatter → correlation/scatter}/defaults.js +6 -5
  163. package/dist/plots/{scatter → correlation/scatter}/markers.d.ts +4 -4
  164. package/dist/plots/{scatter → correlation/scatter}/markers.js +5 -4
  165. package/dist/plots/distribution/box/BoxSummaries.d.ts +19 -0
  166. package/dist/plots/distribution/box/BoxSummaries.js +101 -0
  167. package/dist/plots/distribution/box/Plot.svelte +42 -0
  168. package/dist/plots/distribution/box/Plot.svelte.d.ts +26 -0
  169. package/dist/plots/distribution/box/defaults.d.ts +12 -0
  170. package/dist/plots/distribution/box/defaults.js +34 -0
  171. package/dist/plots/distribution/box/markers.d.ts +12 -0
  172. package/dist/plots/distribution/box/markers.js +34 -0
  173. package/dist/plots/distribution/density/Plot.svelte +45 -0
  174. package/dist/plots/distribution/density/Plot.svelte.d.ts +26 -0
  175. package/dist/plots/distribution/density/defaults.d.ts +9 -0
  176. package/dist/plots/distribution/density/defaults.js +29 -0
  177. package/dist/plots/distribution/density/markers.d.ts +9 -0
  178. package/dist/plots/distribution/density/markers.js +42 -0
  179. package/dist/plots/{histogram → distribution/histogram}/Plot.svelte +2 -2
  180. package/dist/plots/{histogram → distribution/histogram}/Plot.svelte.d.ts +2 -2
  181. package/dist/plots/{histogram → distribution/histogram}/defaults.d.ts +2 -2
  182. package/dist/plots/{histogram → distribution/histogram}/defaults.js +4 -4
  183. package/dist/plots/{histogram → distribution/histogram}/markers.d.ts +3 -3
  184. package/dist/plots/{histogram → distribution/histogram}/markers.js +7 -7
  185. package/dist/plots/{pyramid → distribution/pyramid}/Plot.svelte +5 -2
  186. package/dist/plots/{pyramid → distribution/pyramid}/Plot.svelte.d.ts +2 -2
  187. package/dist/plots/{pyramid → distribution/pyramid}/defaults.d.ts +2 -2
  188. package/dist/plots/{pyramid → distribution/pyramid}/defaults.js +7 -6
  189. package/dist/plots/{pyramid → distribution/pyramid}/markers.d.ts +4 -4
  190. package/dist/plots/{pyramid → distribution/pyramid}/markers.js +8 -11
  191. package/dist/plots/distribution/violin/Plot.svelte +45 -0
  192. package/dist/plots/distribution/violin/Plot.svelte.d.ts +26 -0
  193. package/dist/plots/distribution/violin/defaults.d.ts +10 -0
  194. package/dist/plots/distribution/violin/defaults.js +58 -0
  195. package/dist/plots/distribution/violin/markers.d.ts +10 -0
  196. package/dist/plots/distribution/violin/markers.js +71 -0
  197. package/dist/plots/{area → evolution/area}/Plot.svelte +2 -2
  198. package/dist/plots/{area → evolution/area}/Plot.svelte.d.ts +2 -2
  199. package/dist/plots/{area → evolution/area}/defaults.d.ts +2 -2
  200. package/dist/plots/{area → evolution/area}/defaults.js +2 -0
  201. package/dist/plots/{area → evolution/area}/markers.d.ts +2 -2
  202. package/dist/plots/{area → evolution/area}/markers.js +2 -3
  203. package/dist/plots/{line → evolution/line}/Plot.svelte +2 -2
  204. package/dist/plots/{line → evolution/line}/Plot.svelte.d.ts +2 -2
  205. package/dist/plots/{line → evolution/line}/defaults.d.ts +2 -2
  206. package/dist/plots/{line → evolution/line}/defaults.js +2 -0
  207. package/dist/plots/{line → evolution/line}/markers.d.ts +11 -8
  208. package/dist/plots/{line → evolution/line}/markers.js +7 -6
  209. package/dist/plots/evolution/slope/Plot.svelte +42 -0
  210. package/dist/plots/evolution/slope/Plot.svelte.d.ts +26 -0
  211. package/dist/plots/evolution/slope/defaults.d.ts +8 -0
  212. package/dist/plots/evolution/slope/defaults.js +31 -0
  213. package/dist/plots/evolution/slope/markers.d.ts +16 -0
  214. package/dist/plots/evolution/slope/markers.js +79 -0
  215. package/dist/plots/evolution/sparkline/Plot.svelte +45 -0
  216. package/dist/plots/evolution/sparkline/Plot.svelte.d.ts +26 -0
  217. package/dist/plots/evolution/sparkline/defaults.d.ts +7 -0
  218. package/dist/plots/evolution/sparkline/defaults.js +23 -0
  219. package/dist/plots/evolution/sparkline/markers.d.ts +7 -0
  220. package/dist/plots/evolution/sparkline/markers.js +56 -0
  221. package/dist/plots/{geo → map/geo}/Core.svelte +11 -10
  222. package/dist/plots/{geo → map/geo}/Core.svelte.d.ts +1 -1
  223. package/dist/plots/map/geo/GeoFeatures.svelte.d.ts +9 -0
  224. package/dist/plots/map/geo/GeoFeatures.svelte.js +55 -0
  225. package/dist/plots/map/geo/GeoGeometry.d.ts +27 -0
  226. package/dist/plots/map/geo/GeoGeometry.js +142 -0
  227. package/dist/plots/map/geo/GeoSegments.d.ts +16 -0
  228. package/dist/plots/map/geo/GeoSegments.js +23 -0
  229. package/dist/plots/{geo → map/geo}/Plot.svelte +10 -10
  230. package/dist/plots/{geo → map/geo}/Plot.svelte.d.ts +2 -2
  231. package/dist/plots/{geo → map/geo}/defaults.d.ts +2 -2
  232. package/dist/plots/{geo → map/geo}/defaults.js +1 -1
  233. package/dist/plots/{geo → map/geo}/phases/data.d.ts +1 -1
  234. package/dist/plots/{geo → map/geo}/phases/data.js +7 -6
  235. package/dist/plots/{geo → map/geo}/phases/hover.d.ts +1 -1
  236. package/dist/plots/{geo → map/geo}/phases/hover.js +5 -5
  237. package/dist/plots/{geo → map/geo}/phases/markers.d.ts +1 -1
  238. package/dist/plots/{geo → map/geo}/phases/markers.js +8 -13
  239. package/dist/plots/{geo → map/geo}/phases/scales.d.ts +2 -2
  240. package/dist/plots/{geo → map/geo}/phases/scales.js +28 -12
  241. package/dist/plots/{geo → map/geo}/phases/tooltip.d.ts +1 -1
  242. package/dist/plots/map/geo/phases/tooltip.js +5 -0
  243. package/dist/plots/{geo → map/geo}/slices.d.ts +2 -2
  244. package/dist/plots/{geo → map/geo}/slices.js +7 -4
  245. package/dist/plots/{bar → ranking/bar}/Plot.svelte +2 -2
  246. package/dist/plots/{bar → ranking/bar}/Plot.svelte.d.ts +2 -2
  247. package/dist/plots/ranking/bar/defaults.d.ts +16 -0
  248. package/dist/plots/{bar → ranking/bar}/defaults.js +17 -15
  249. package/dist/plots/{bar → ranking/bar}/markers.d.ts +8 -8
  250. package/dist/plots/{bar → ranking/bar}/markers.js +11 -19
  251. package/dist/plots/ranking/bullet/Plot.svelte +42 -0
  252. package/dist/plots/ranking/bullet/Plot.svelte.d.ts +26 -0
  253. package/dist/plots/ranking/bullet/defaults.d.ts +8 -0
  254. package/dist/plots/ranking/bullet/defaults.js +24 -0
  255. package/dist/plots/ranking/bullet/markers.d.ts +10 -0
  256. package/dist/plots/ranking/bullet/markers.js +90 -0
  257. package/dist/plots/ranking/cleveland/ClevelandConnector.d.ts +48 -0
  258. package/dist/plots/ranking/cleveland/ClevelandConnector.js +140 -0
  259. package/dist/plots/ranking/cleveland/ClevelandMarkers.d.ts +33 -0
  260. package/dist/plots/ranking/cleveland/ClevelandMarkers.js +375 -0
  261. package/dist/plots/ranking/cleveland/ClevelandRanges.d.ts +31 -0
  262. package/dist/plots/ranking/cleveland/ClevelandRanges.js +116 -0
  263. package/dist/plots/ranking/cleveland/Plot.svelte +45 -0
  264. package/dist/plots/ranking/cleveland/Plot.svelte.d.ts +26 -0
  265. package/dist/plots/ranking/cleveland/defaults.d.ts +13 -0
  266. package/dist/plots/ranking/cleveland/defaults.js +66 -0
  267. package/dist/plots/ranking/dumbbell/Plot.svelte +45 -0
  268. package/dist/plots/ranking/dumbbell/Plot.svelte.d.ts +26 -0
  269. package/dist/plots/ranking/dumbbell/defaults.d.ts +9 -0
  270. package/dist/plots/ranking/dumbbell/defaults.js +19 -0
  271. package/dist/plots/ranking/forest/Plot.svelte +42 -0
  272. package/dist/plots/ranking/forest/Plot.svelte.d.ts +26 -0
  273. package/dist/plots/ranking/forest/defaults.d.ts +11 -0
  274. package/dist/plots/ranking/forest/defaults.js +20 -0
  275. package/dist/plots/ranking/lollipop/Plot.svelte +45 -0
  276. package/dist/plots/ranking/lollipop/Plot.svelte.d.ts +26 -0
  277. package/dist/plots/ranking/lollipop/defaults.d.ts +9 -0
  278. package/dist/plots/ranking/lollipop/defaults.js +18 -0
  279. package/dist/plots/utils/RowNumbers.d.ts +16 -0
  280. package/dist/plots/utils/RowNumbers.js +24 -0
  281. package/dist/plots/utils/gaps.js +1 -1
  282. package/dist/plots/utils/segments.js +1 -1
  283. package/dist/types/configuration/styling.d.ts +287 -132
  284. package/dist/types/layout/composer.d.ts +5 -2
  285. package/dist/types/layout/coordinates.d.ts +5 -4
  286. package/dist/types/layout/legend.d.ts +21 -5
  287. package/dist/types/layout/plot.d.ts +44 -1
  288. package/dist/types/layout/scales.d.ts +51 -3
  289. package/dist/types/layout/statistics/deviation.d.ts +40 -0
  290. package/dist/types/layout/statistics/index.d.ts +7 -2
  291. package/dist/types/layout/styles/base.d.ts +18 -0
  292. package/dist/types/layout/styles/bullet.d.ts +25 -0
  293. package/dist/types/layout/styles/connector.d.ts +98 -0
  294. package/dist/types/layout/styles/curve.d.ts +11 -0
  295. package/dist/types/layout/styles/frame.d.ts +17 -0
  296. package/dist/types/layout/styles/gaps.d.ts +12 -0
  297. package/dist/types/layout/styles/geo.d.ts +55 -0
  298. package/dist/types/layout/styles/index.d.ts +8 -0
  299. package/dist/types/layout/styles/index.js +8 -0
  300. package/dist/types/layout/styles/values.d.ts +47 -0
  301. package/dist/types/layout/timeline.d.ts +19 -7
  302. package/dist/types/layout/tooltip.d.ts +6 -2
  303. package/dist/types/markers/axis/area.d.ts +2 -2
  304. package/dist/types/markers/axis/arrow.d.ts +3 -0
  305. package/dist/types/markers/axis/axisBasedMarkersConfig.d.ts +2 -1
  306. package/dist/types/markers/axis/bar.d.ts +1 -1
  307. package/dist/types/markers/axis/box.d.ts +5 -0
  308. package/dist/types/markers/axis/difference.d.ts +2 -2
  309. package/dist/types/markers/axis/image.d.ts +3 -2
  310. package/dist/types/markers/axis/line.d.ts +2 -0
  311. package/dist/types/markers/axis/rule.d.ts +9 -0
  312. package/dist/types/markers/axis/trail.d.ts +2 -3
  313. package/dist/types/markers/axis/violin.d.ts +25 -0
  314. package/dist/types/markers/basic/dot.d.ts +3 -2
  315. package/dist/types/markers/basic/text.d.ts +13 -3
  316. package/dist/types/markers/channels/commonMarkerConfig.d.ts +7 -3
  317. package/dist/types/markers/channels/commonMarkerConfigWithRowOffset.d.ts +13 -0
  318. package/dist/types/markers/common.d.ts +1 -1
  319. package/dist/types/markers/common.js +1 -0
  320. package/dist/types/markers/geo/link.d.ts +5 -1
  321. package/dist/types/phases/hover/phase.d.ts +6 -0
  322. package/dist/types/phases/index.d.ts +1 -1
  323. package/dist/types/phases/scales/phase.d.ts +5 -1
  324. package/dist/types/phases/state.d.ts +20 -4
  325. package/dist/types/phases/statistics/phase.d.ts +3 -1
  326. package/dist/types/phases/statistics/source.d.ts +3 -1
  327. package/dist/types/phases/transforms/phase.d.ts +32 -0
  328. package/dist/types/plots/{heatmap → correlation/heatmap}/props.d.ts +6 -6
  329. package/dist/types/plots/{heatmap → correlation/heatmap}/state.d.ts +4 -4
  330. package/dist/types/plots/{scatter → correlation/scatter}/props.d.ts +6 -6
  331. package/dist/types/plots/{scatter → correlation/scatter}/state.d.ts +2 -2
  332. package/dist/types/plots/distribution/box/props.d.ts +10 -0
  333. package/dist/types/plots/distribution/box/state.d.ts +23 -0
  334. package/dist/types/plots/distribution/density/props.d.ts +23 -0
  335. package/dist/types/plots/distribution/density/state.d.ts +6 -0
  336. package/dist/types/plots/distribution/density/state.js +1 -0
  337. package/dist/types/plots/{histogram → distribution/histogram}/props.d.ts +7 -7
  338. package/dist/types/plots/distribution/histogram/props.js +1 -0
  339. package/dist/types/plots/{histogram → distribution/histogram}/state.d.ts +2 -2
  340. package/dist/types/plots/distribution/histogram/state.js +1 -0
  341. package/dist/types/plots/{pyramid → distribution/pyramid}/props.d.ts +6 -6
  342. package/dist/types/plots/distribution/pyramid/props.js +1 -0
  343. package/dist/types/plots/{pyramid → distribution/pyramid}/state.d.ts +3 -3
  344. package/dist/types/plots/distribution/pyramid/state.js +1 -0
  345. package/dist/types/plots/distribution/violin/props.d.ts +23 -0
  346. package/dist/types/plots/distribution/violin/props.js +1 -0
  347. package/dist/types/plots/distribution/violin/state.d.ts +6 -0
  348. package/dist/types/plots/distribution/violin/state.js +1 -0
  349. package/dist/types/plots/{area → evolution/area}/props.d.ts +6 -6
  350. package/dist/types/plots/evolution/area/props.js +1 -0
  351. package/dist/types/plots/{area → evolution/area}/state.d.ts +2 -2
  352. package/dist/types/plots/evolution/area/state.js +1 -0
  353. package/dist/types/plots/evolution/line/props.d.ts +10 -0
  354. package/dist/types/plots/evolution/line/props.js +1 -0
  355. package/dist/types/plots/{line → evolution/line}/state.d.ts +3 -3
  356. package/dist/types/plots/evolution/line/state.js +1 -0
  357. package/dist/types/plots/evolution/slope/props.d.ts +5 -0
  358. package/dist/types/plots/evolution/slope/props.js +1 -0
  359. package/dist/types/plots/evolution/slope/state.d.ts +5 -0
  360. package/dist/types/plots/evolution/slope/state.js +1 -0
  361. package/dist/types/plots/evolution/sparkline/props.d.ts +5 -0
  362. package/dist/types/plots/evolution/sparkline/props.js +1 -0
  363. package/dist/types/plots/evolution/sparkline/state.d.ts +5 -0
  364. package/dist/types/plots/evolution/sparkline/state.js +1 -0
  365. package/dist/types/plots/{geo → map/geo}/props.d.ts +8 -8
  366. package/dist/types/plots/map/geo/props.js +1 -0
  367. package/dist/types/plots/{geo → map/geo}/state.d.ts +18 -11
  368. package/dist/types/plots/map/geo/state.js +1 -0
  369. package/dist/types/plots/props.d.ts +3 -1
  370. package/dist/types/plots/{bar → ranking/bar}/props.d.ts +6 -6
  371. package/dist/types/plots/ranking/bar/props.js +1 -0
  372. package/dist/types/plots/{bar → ranking/bar}/state.d.ts +2 -2
  373. package/dist/types/plots/ranking/bar/state.js +1 -0
  374. package/dist/types/plots/ranking/bullet/props.d.ts +22 -0
  375. package/dist/types/plots/ranking/bullet/props.js +1 -0
  376. package/dist/types/plots/ranking/bullet/state.d.ts +5 -0
  377. package/dist/types/plots/ranking/bullet/state.js +1 -0
  378. package/dist/types/plots/ranking/cleveland/props.d.ts +10 -0
  379. package/dist/types/plots/ranking/cleveland/props.js +1 -0
  380. package/dist/types/plots/ranking/cleveland/state.d.ts +49 -0
  381. package/dist/types/plots/ranking/cleveland/state.js +1 -0
  382. package/dist/types/plots/ranking/dumbbell/props.d.ts +10 -0
  383. package/dist/types/plots/ranking/dumbbell/props.js +1 -0
  384. package/dist/types/plots/ranking/dumbbell/state.d.ts +5 -0
  385. package/dist/types/plots/ranking/dumbbell/state.js +1 -0
  386. package/dist/types/plots/ranking/forest/props.d.ts +23 -0
  387. package/dist/types/plots/ranking/forest/props.js +1 -0
  388. package/dist/types/plots/ranking/forest/state.d.ts +5 -0
  389. package/dist/types/plots/ranking/forest/state.js +1 -0
  390. package/dist/types/plots/ranking/lollipop/props.d.ts +10 -0
  391. package/dist/types/plots/ranking/lollipop/props.js +1 -0
  392. package/dist/types/plots/ranking/lollipop/state.d.ts +5 -0
  393. package/dist/types/plots/ranking/lollipop/state.js +1 -0
  394. package/dist/types/plots/segments/common.d.ts +4 -1
  395. package/dist/utils/OpacityScale.d.ts +14 -0
  396. package/dist/utils/OpacityScale.js +43 -0
  397. package/dist/utils/{symbol.d.ts → SymbolPath.d.ts} +0 -12
  398. package/dist/utils/{symbol.js → SymbolPath.js} +0 -24
  399. package/dist/utils/SymbolScale.d.ts +18 -0
  400. package/dist/utils/SymbolScale.js +29 -0
  401. package/dist/utils/color/ColorRamp.d.ts +27 -0
  402. package/dist/utils/color/ColorRamp.js +120 -0
  403. package/dist/utils/color/CssColor.d.ts +19 -0
  404. package/dist/utils/color/CssColor.js +114 -0
  405. package/dist/utils/color/Palette.d.ts +21 -0
  406. package/dist/utils/color/Palette.js +52 -0
  407. package/dist/utils/color/index.d.ts +11 -3
  408. package/dist/utils/color/index.js +14 -3
  409. package/dist/utils/grouping.js +1 -1
  410. package/docs/architecture.md +1 -1
  411. package/docs/chrome.md +39 -8
  412. package/docs/composer.md +19 -3
  413. package/docs/concepts.md +1 -1
  414. package/docs/development.md +14 -5
  415. package/docs/facets.md +62 -8
  416. package/docs/getting-started.md +8 -9
  417. package/docs/legend.md +73 -24
  418. package/docs/markers.md +45 -32
  419. package/docs/plots/correlation/heatmap.md +26 -0
  420. package/docs/plots/correlation/scatter.md +35 -0
  421. package/docs/plots/distribution/box.md +28 -0
  422. package/docs/plots/distribution/density.md +26 -0
  423. package/docs/plots/distribution/histogram.md +33 -0
  424. package/docs/plots/distribution/pyramid.md +31 -0
  425. package/docs/plots/distribution/violin.md +35 -0
  426. package/docs/plots/evolution/area.md +32 -0
  427. package/docs/plots/evolution/line.md +93 -0
  428. package/docs/plots/evolution/slope.md +39 -0
  429. package/docs/plots/evolution/sparkline.md +34 -0
  430. package/docs/plots/ranking/bar.md +59 -0
  431. package/docs/plots/ranking/bullet.md +37 -0
  432. package/docs/plots/ranking/cleveland.md +54 -0
  433. package/docs/plots/ranking/dumbbell.md +39 -0
  434. package/docs/plots/ranking/forest.md +40 -0
  435. package/docs/plots/ranking/lollipop.md +39 -0
  436. package/docs/plots.md +22 -154
  437. package/docs/scales.md +50 -27
  438. package/docs/state.md +1 -1
  439. package/docs/styles-and-segments.md +96 -39
  440. package/docs/theming.md +33 -19
  441. package/docs/timeline.md +62 -28
  442. package/docs/tooltip-and-hover.md +72 -24
  443. package/docs/transforms-and-statistics.md +56 -25
  444. package/examples/BarValues.svelte +2 -2
  445. package/examples/Box.svelte +7 -0
  446. package/examples/Bullet.svelte +17 -0
  447. package/examples/Chrome.svelte +17 -0
  448. package/examples/ChromeOrder.svelte +18 -0
  449. package/examples/Cleveland.svelte +15 -0
  450. package/examples/Composer.svelte +23 -0
  451. package/examples/CustomTooltip.svelte +21 -14
  452. package/examples/Density.svelte +7 -0
  453. package/examples/Dumbbell.svelte +16 -0
  454. package/examples/Facets.svelte +3 -3
  455. package/examples/FacetsCarousel.svelte +14 -0
  456. package/examples/FacetsRowsCols.svelte +23 -0
  457. package/examples/FirstPlot.svelte +7 -0
  458. package/examples/Forest.svelte +17 -0
  459. package/examples/Gaps.svelte +21 -0
  460. package/examples/GroupedBars.svelte +15 -0
  461. package/examples/Heatmap.svelte +7 -0
  462. package/examples/HeatmapSegments.svelte +26 -0
  463. package/examples/Histogram.svelte +14 -0
  464. package/examples/HorizontalBars.svelte +15 -0
  465. package/examples/LegendSections.svelte +27 -0
  466. package/examples/LegendToggle.svelte +3 -3
  467. package/examples/LineByRegion.svelte +18 -0
  468. package/examples/LineDates.svelte +15 -0
  469. package/examples/LineStep.svelte +16 -0
  470. package/examples/LineStepSegment.svelte +18 -0
  471. package/examples/Lollipop.svelte +17 -0
  472. package/examples/Markers.svelte +27 -0
  473. package/examples/MovingAverage.svelte +15 -0
  474. package/examples/Pyramid.svelte +14 -0
  475. package/examples/Regression.svelte +14 -0
  476. package/examples/ResponsiveLine.svelte +7 -7
  477. package/examples/Scales.svelte +26 -0
  478. package/examples/Scatter.svelte +16 -0
  479. package/examples/SegmentHighlight.svelte +22 -0
  480. package/examples/Segments.svelte +11 -3
  481. package/examples/SegmentsBySeries.svelte +25 -0
  482. package/examples/Slope.svelte +17 -0
  483. package/examples/Sparkline.svelte +14 -0
  484. package/examples/StackedArea.svelte +16 -0
  485. package/examples/StackedBars.svelte +15 -0
  486. package/examples/TimelinePlayer.svelte +8 -7
  487. package/examples/TimelineRule.svelte +19 -0
  488. package/examples/Tooltip.svelte +3 -3
  489. package/examples/ValueLabels.svelte +21 -0
  490. package/examples/Violin.svelte +14 -0
  491. package/examples/datasets/argentina-chile-trends.ts +34 -0
  492. package/examples/datasets/commodity-prices.ts +48 -0
  493. package/examples/datasets/countries-over-time.ts +368 -0
  494. package/examples/datasets/daily-temperature.ts +121 -0
  495. package/examples/datasets/earthquakes.ts +977 -0
  496. package/examples/datasets/flight-routes.ts +29 -0
  497. package/examples/datasets/height-density.ts +37 -0
  498. package/examples/datasets/heights.ts +370 -0
  499. package/examples/datasets/index.ts +24 -0
  500. package/examples/datasets/inflation-by-region.ts +44 -0
  501. package/examples/datasets/inflation-ranges.ts +34 -0
  502. package/examples/datasets/iris-flower.ts +207 -0
  503. package/examples/datasets/life-expectancy.ts +95 -0
  504. package/examples/datasets/napoleons-march.ts +182 -0
  505. package/examples/datasets/penguins.ts +54 -0
  506. package/examples/datasets/population-by-age-with-gaps.ts +23 -0
  507. package/examples/datasets/population-by-age.ts +890 -0
  508. package/examples/datasets/province-population.ts +521 -0
  509. package/examples/datasets/stock-prices.ts +63 -0
  510. package/examples/datasets/weather-stations-over-time.ts +31 -0
  511. package/examples/datasets/weather-stations.ts +22 -0
  512. package/examples/datasets/wind-vectors.ts +30 -0
  513. package/examples/datasets/world-temperature.ts +400 -0
  514. package/llms-full.txt +51 -12
  515. package/llms.txt +60 -4
  516. package/package.json +12 -2
  517. package/dist/layout/scales/buildScale.d.ts +0 -8
  518. package/dist/layout/scales/buildScale.js +0 -67
  519. package/dist/layout/scales/niceDomain.d.ts +0 -23
  520. package/dist/layout/scales/niceDomain.js +0 -59
  521. package/dist/plots/bar/defaults.d.ts +0 -9
  522. package/dist/plots/geo/features.svelte.d.ts +0 -5
  523. package/dist/plots/geo/features.svelte.js +0 -44
  524. package/dist/plots/geo/phases/tooltip.js +0 -5
  525. package/dist/plots/utils/geoAccessors.d.ts +0 -72
  526. package/dist/plots/utils/geoAccessors.js +0 -220
  527. package/dist/plots/utils/geoSegments.d.ts +0 -29
  528. package/dist/plots/utils/geoSegments.js +0 -37
  529. package/dist/types/layout/styles.d.ts +0 -122
  530. package/dist/types/markers/axis/curveName.d.ts +0 -2
  531. package/dist/types/plots/line/props.d.ts +0 -10
  532. package/dist/utils/color/contrast.d.ts +0 -9
  533. package/dist/utils/color/contrast.js +0 -40
  534. package/dist/utils/color/cssColor.d.ts +0 -4
  535. package/dist/utils/color/cssColor.js +0 -77
  536. package/dist/utils/color/ramp.d.ts +0 -17
  537. package/dist/utils/color/ramp.js +0 -110
  538. package/dist/utils/opacity.d.ts +0 -9
  539. package/dist/utils/opacity.js +0 -38
  540. package/examples/data.ts +0 -12
  541. /package/dist/types/layout/{styles.js → statistics/deviation.js} +0 -0
  542. /package/dist/types/{markers/axis/curveName.js → layout/styles/base.js} +0 -0
  543. /package/dist/types/{plots/area/props.js → layout/styles/bullet.js} +0 -0
  544. /package/dist/types/{plots/area/state.js → layout/styles/connector.js} +0 -0
  545. /package/dist/types/{plots/bar/props.js → layout/styles/curve.js} +0 -0
  546. /package/dist/types/{plots/bar/state.js → layout/styles/frame.js} +0 -0
  547. /package/dist/types/{plots/geo/props.js → layout/styles/gaps.js} +0 -0
  548. /package/dist/types/{plots/geo/state.js → layout/styles/geo.js} +0 -0
  549. /package/dist/types/{plots/heatmap/props.js → layout/styles/values.js} +0 -0
  550. /package/dist/types/{plots/heatmap/state.js → markers/axis/violin.js} +0 -0
  551. /package/dist/types/{plots/histogram/props.js → markers/channels/commonMarkerConfigWithRowOffset.js} +0 -0
  552. /package/dist/types/plots/{line → correlation/heatmap}/props.js +0 -0
  553. /package/dist/types/plots/{histogram → correlation/heatmap}/state.js +0 -0
  554. /package/dist/types/plots/{pyramid → correlation/scatter}/props.js +0 -0
  555. /package/dist/types/plots/{line → correlation/scatter}/state.js +0 -0
  556. /package/dist/types/plots/{scatter → distribution/box}/props.js +0 -0
  557. /package/dist/types/plots/{pyramid → distribution/box}/state.js +0 -0
  558. /package/dist/types/plots/{scatter/state.js → distribution/density/props.js} +0 -0
  559. /package/dist/{plots/utils → utils}/accessors.d.ts +0 -0
  560. /package/dist/{plots/utils → utils}/accessors.js +0 -0
@@ -1,8 +1,8 @@
1
+ import { ProcessedPositions } from '../../phases/transforms/ProcessedPositions';
1
2
  import { Box } from '../margins/Box';
2
- import { resolveAccessor } from '../../plots/utils/accessors';
3
- import { SERIES_ID_KEY, SERIES_KEY, TransformsPhase } from '../../phases/transforms/TransformsPhase';
3
+ import { resolveAccessor } from '../../utils/accessors';
4
+ import { SERIES_ID_KEY, SERIES_KEY } from '../../phases/transforms/TransformsPhase';
4
5
  import { seriesIdOf } from '../../utils/grouping';
5
- import { Transforms } from '../../phases/transforms/Transforms';
6
6
  import { isGapValue } from '../../plots/utils/gaps';
7
7
  import { PlotAxes } from '../../phases/data/PlotAxes';
8
8
  /**
@@ -20,6 +20,8 @@ export class ValueLabels {
20
20
  fontSize;
21
21
  /** The connectors of labels that had to move apart. */
22
22
  strokeStyle;
23
+ /** `'series'` writes each label in its series' color; any other CSS color writes them all in it. */
24
+ color;
23
25
  /** How labels that would overlap move apart - the configuration's `text.declutter`. */
24
26
  declutter;
25
27
  /** Where the labels are expected to sit: boxes around their points, on the edges those can reach. */
@@ -33,6 +35,7 @@ export class ValueLabels {
33
35
  this.font = values?.fontStyle;
34
36
  this.fontSize = typeof this.font?.fontSize === 'number' ? this.font.fontSize : 12;
35
37
  this.strokeStyle = values?.strokeStyle;
38
+ this.color = values?.color;
36
39
  this.declutter = cfg.text.declutter;
37
40
  this.#cfg = cfg;
38
41
  this.reach = (this.show && reach?.(this)) || [];
@@ -42,6 +45,18 @@ export class ValueLabels {
42
45
  const { reach } = options;
43
46
  return new ValueLabels(values, cfg, options, reach && ((labels) => reach(labels, state)));
44
47
  }
48
+ /** The configuration the labels were built under, for a plot kind's own label defaults. */
49
+ get config() {
50
+ return this.#cfg;
51
+ }
52
+ /**
53
+ * The fill every label takes whatever its series: the author's own
54
+ * `fontStyle.fill`, else a literal `color`. `undefined` leaves each label to
55
+ * its plot's default (its series' color, or the axis').
56
+ */
57
+ get fill() {
58
+ return this.font?.fill ?? (this.color === 'series' ? undefined : this.color);
59
+ }
45
60
  /** One line of label text's height. */
46
61
  get lineHeight() {
47
62
  return this.fontSize * 1.2;
@@ -132,14 +147,46 @@ export class ValueLabels {
132
147
  * (`filter` + `selectLast`, per series), at its top (a stacked row's
133
148
  * `y2`), labelled with its own value and placed by `anchor`. Labels that
134
149
  * would overlap fan out into a shared column (`declutter`), colored by the
135
- * segment the row falls in.
150
+ * segment the row falls in. A plot that labels each end of its series apart
151
+ * passes the `rows` and `anchor` of one end, and `lane` to route its labels
152
+ * out to a lane whether or not they overlap (`flip: false` keeps one on the
153
+ * left in the margin instead of flipping it over its points).
136
154
  */
137
- atSeriesEnds(state) {
155
+ atSeriesEnds(state, end = {}) {
156
+ if (end.rows)
157
+ return this.#seriesEnds(state, end);
158
+ // A label on a series' first point would sit on its own line: it goes out to a lane instead.
159
+ const firsts = ValueLabels.#firstRows(state);
160
+ const labelled = state.labelled ?? [];
161
+ return [
162
+ ...this.#seriesEnds(state, { rows: labelled.filter((row) => !firsts.has(row)) }),
163
+ ...this.#seriesEnds(state, {
164
+ rows: labelled.filter((row) => firsts.has(row)),
165
+ lane: { elbowGap: ValueLabels.FIRST_LANE_GAP }
166
+ })
167
+ ];
168
+ }
169
+ /** How far (px) a lane takes the label of a series' first point from it - clear of the line that leaves it. */
170
+ static FIRST_LANE_GAP = 28;
171
+ /** The first row of every series that has more than one. */
172
+ static #firstRows(state) {
173
+ const first = new Map();
174
+ const counts = new Map();
175
+ for (const row of state.processedData?.data ?? []) {
176
+ const id = String(row[SERIES_ID_KEY]);
177
+ if (!first.has(id))
178
+ first.set(id, row);
179
+ counts.set(id, (counts.get(id) ?? 0) + 1);
180
+ }
181
+ return new Set([...first].filter(([id]) => (counts.get(id) ?? 0) > 1).map(([, row]) => row));
182
+ }
183
+ #seriesEnds(state, end) {
138
184
  const processed = state.processedData;
139
185
  if (!processed)
140
186
  return [];
141
- const { font, anchor, format } = this;
142
- const position = TransformsPhase.processedPosition(processed);
187
+ const { font, format } = this;
188
+ const anchor = end.anchor ?? this.anchor;
189
+ const position = ProcessedPositions.of(processed);
143
190
  const topOf = (d) => position.y(d);
144
191
  const nameOf = (d) => String(d[SERIES_KEY]);
145
192
  const valueOf = ValueLabels.valueOf(state);
@@ -152,33 +199,39 @@ export class ValueLabels {
152
199
  group?.color ??
153
200
  state.colorForSeries?.(nameOf(d)));
154
201
  };
155
- const marker = Transforms.resolve({
202
+ const marker = {
156
203
  type: 'text',
157
- data: processed.data,
204
+ // The rows the "transforms" phase picked for the labels: by default each series' last.
205
+ data: end.rows ?? state.labelled ?? [],
158
206
  x: (processed.channels.x ?? position.x),
159
207
  y: (processed.channels.y2 ?? processed.channels.y ?? topOf),
160
208
  grouping: SERIES_ID_KEY,
161
- transforms: [
162
- {
163
- type: 'filter',
164
- filter: (d) => !isGapValue(valueOf(d)) && !isGapValue(topOf(d))
165
- },
166
- { type: 'selectLast' }
167
- ],
168
209
  text: (d) => format(Number(valueOf(d)), nameOf(d)),
169
210
  styles: {
170
211
  ...font,
212
+ ...(this.fill ? { fill: this.fill } : {}),
171
213
  fontSize: font?.fontSize ?? 12,
172
214
  dx: font?.dx ?? (anchor === 'start' ? 6 : anchor === 'end' ? -6 : 0),
173
215
  dy: font?.dy ?? (anchor === 'outside' ? -8 : 0),
174
216
  textAnchor: this.textAnchor ?? (anchor === 'start' || anchor === 'end' ? anchor : 'middle'),
175
217
  lineAnchor: font?.lineAnchor ?? (anchor === 'outside' ? 'bottom' : 'middle')
176
218
  },
177
- fill: font?.fill ? undefined : colorOf,
178
- declutter: { connector: this.strokeStyle }
179
- }, processed.data);
219
+ fill: this.fill ? undefined : colorOf,
220
+ declutter: {
221
+ connector: this.strokeStyle,
222
+ aligned: !!end.lane && (anchor === 'start' || anchor === 'end'),
223
+ elbowGap: typeof end.lane === 'object' ? end.lane.elbowGap : undefined,
224
+ flip: end.flip
225
+ }
226
+ };
180
227
  return marker.data?.length ? [marker] : [];
181
228
  }
229
+ /** 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`. */
230
+ static skipGaps(state) {
231
+ const valueOf = ValueLabels.valueOf(state);
232
+ const top = ProcessedPositions.of(state.processedData).y;
233
+ return (row) => isGapValue(valueOf(row)) || isGapValue(top(row));
234
+ }
182
235
  /**
183
236
  * Where {@link atSeriesEnds}' labels are expected to sit: past each
184
237
  * series' last point, at the right edge (or the left, for labels set
@@ -187,9 +240,9 @@ export class ValueLabels {
187
240
  * domain when the scales set one, so it holds across a timeline; else off
188
241
  * every value.
189
242
  */
190
- reachAtSeriesEnds(state) {
243
+ reachAtSeriesEnds(state, anchor = this.anchor) {
191
244
  const series = state.resolvedSeries ?? [];
192
- const { anchor, font, format } = this;
245
+ const { font, format } = this;
193
246
  const dx = typeof font?.dx === 'number' ? font.dx : anchor === 'start' ? 6 : anchor === 'end' ? -6 : 0;
194
247
  const dy = typeof font?.dy === 'number' ? font.dy : anchor === 'outside' ? -8 : 0;
195
248
  const textAnchor = this.textAnchor ?? (anchor === 'start' ? 'start' : anchor === 'end' ? 'end' : 'middle');
@@ -202,11 +255,18 @@ export class ValueLabels {
202
255
  const { elbowGap, laneStep, labelGap } = this.declutter;
203
256
  const lanes = elbowGap + (series.length - 1) * laneStep + labelGap;
204
257
  const at = { x: series.length > 1 ? (Math.sign(dx) || 1) * lanes : dx, y: dy };
258
+ // Only a label that can sit at the plot's right end - any but a first point's - reaches that edge.
259
+ const selects = state.labelSelects ?? [];
260
+ const atRight = selects.length === 0 || selects.some((select) => select !== 'first');
261
+ // Likewise a label set before its point reaches the left edge only from a point that can sit there: any but a last one - or a last one that is also the first, of a series with a single point.
262
+ const atLeft = selects.length === 0 ||
263
+ selects.some((select) => select !== 'last') ||
264
+ series.some((s) => s.data.length < 2);
205
265
  const edges = [
206
266
  'top',
207
267
  'bottom',
208
- ...(dx < 0 ? ['left'] : []),
209
- ...(dx >= 0 || series.length > 1 ? ['right'] : [])
268
+ ...(dx < 0 && atLeft ? ['left'] : []),
269
+ ...((dx >= 0 || series.length > 1) && atRight ? ['right'] : [])
210
270
  ];
211
271
  const texts = [];
212
272
  const domain = state.scales.y?.domain;
@@ -15,12 +15,15 @@
15
15
  currentValue,
16
16
  values,
17
17
  orientation = 'vertical',
18
+ format = (value: TimeValue) => String(value),
18
19
  width,
19
20
  height
20
21
  }: {
21
22
  currentValue: TimeValue;
22
23
  values: TimeValue[];
23
24
  orientation?: Orientation;
25
+ /** How a step's label reads. */
26
+ format?: (value: TimeValue) => string;
24
27
  width: number;
25
28
  height: number;
26
29
  } = $props();
@@ -72,7 +75,7 @@
72
75
  <Text
73
76
  data={baseValues}
74
77
  {...isHorizontal ? { x: identity, y: 0 } : { x: 0, y: identity }}
75
- text={(d: TimeValue) => `${d}`}
78
+ text={(d: TimeValue) => format(d)}
76
79
  {...textOffset}
77
80
  fontSize={rule.fontSize}
78
81
  fill="var(--dct-timeline-axis, currentColor)"
@@ -82,7 +85,7 @@
82
85
  <Text
83
86
  data={[currentValue]}
84
87
  {...isHorizontal ? { x: identity, y: 0 } : { x: 0, y: identity }}
85
- text={(d: TimeValue) => `${d}`}
88
+ text={(d: TimeValue) => format(d)}
86
89
  {...textOffset}
87
90
  fontSize={rule.activeFontSize}
88
91
  fontWeight={rule.activeFontWeight}
@@ -3,6 +3,8 @@ type $$ComponentProps = {
3
3
  currentValue: TimeValue;
4
4
  values: TimeValue[];
5
5
  orientation?: Orientation;
6
+ /** How a step's label reads. */
7
+ format?: (value: TimeValue) => string;
6
8
  width: number;
7
9
  height: number;
8
10
  };
@@ -1,11 +1,13 @@
1
1
  <script lang="ts" generics="TRow extends Record<string, unknown>">
2
2
  import { untrack } from 'svelte';
3
- import { resolveAccessor } from '../../plots/utils/accessors';
3
+ import { resolveAccessor } from '../../utils/accessors';
4
4
  import TimelineFrame from './TimelineFrame.svelte';
5
5
  import { TimelineSteps } from './TimelineSteps';
6
+ import { TimelineTime } from './TimelineTime';
6
7
  import { Interpolation } from '../../utils/Interpolation';
7
8
  import type {
8
9
  Orientation,
10
+ TimeInput,
9
11
  TimeValue,
10
12
  TimelineChildSnippet,
11
13
  TimelineInterpolation
@@ -22,6 +24,7 @@
22
24
  let {
23
25
  data,
24
26
  accessor,
27
+ dateFormat,
25
28
  progress,
26
29
  values,
27
30
  orientation = 'vertical',
@@ -35,28 +38,44 @@
35
38
  child
36
39
  }: {
37
40
  data: TRow[];
38
- accessor: Accessor<TRow, TimeValue>;
41
+ accessor: Accessor<TRow, TimeInput>;
42
+ /** How a non-ISO date string reads. */
43
+ dateFormat?: string;
39
44
  progress: number;
40
- values?: TimeValue[];
45
+ values?: TimeInput[];
41
46
  orientation?: Orientation;
42
47
  show?: boolean;
43
48
  thickness?: number;
44
49
  filterMode?: 'exact' | 'upTo';
45
50
  interpolate?: TimelineInterpolation<TRow>;
46
- /** Told the steps, whenever they change - for whoever else draws or drives the timeline. */
47
- onsteps?: (values: TimeValue[]) => void;
51
+ /** Told the steps, and whether they are dates, when they change. */
52
+ onsteps?: (values: TimeValue[], temporal: boolean) => void;
48
53
  width: number;
49
54
  height: number;
50
55
  child: TimelineChildSnippet<TRow>;
51
56
  } = $props();
52
57
 
53
- const getTime = $derived(resolveAccessor<TRow>(accessor));
58
+ const time = $derived(new TimelineTime(dateFormat));
59
+ const getRaw = $derived(resolveAccessor<TRow>(accessor) as (row: TRow) => unknown);
60
+ /** A row's step, or `undefined` when its value reads as none. */
61
+ const getTime = $derived((row: TRow) => time.toTime(getRaw(row)));
62
+ /** The rows with a step; one without shows at every step. */
63
+ const timed = $derived(data.filter((row) => getTime(row) !== undefined));
64
+ const untimed = $derived(data.filter((row) => getTime(row) === undefined));
54
65
 
55
- const steps = $derived(TimelineSteps.of(values, data, getTime));
66
+ const steps = $derived(
67
+ TimelineSteps.of(
68
+ values?.map((value) => time.toTime(value)).filter((v): v is TimeValue => v !== undefined),
69
+ timed,
70
+ getTime as (row: TRow) => TimeValue
71
+ )
72
+ );
73
+ const temporal = $derived(time.isTemporal(values?.length ? values : timed.map(getRaw)));
56
74
 
57
75
  $effect(() => {
58
76
  const found = steps.values;
59
- untrack(() => onsteps?.(found));
77
+ const dates = temporal;
78
+ untrack(() => onsteps?.(found, dates));
60
79
  });
61
80
 
62
81
  const progressEasingFn = $derived(Interpolation.buildEasing(interpolate?.progressEasing));
@@ -77,12 +96,19 @@
77
96
  );
78
97
  return upper;
79
98
  }
80
- return { ...upper, [accessor]: x, [valueField]: value } as TRow;
99
+ return {
100
+ ...upper,
101
+ [accessor]: time.toValueLike(x, upper[accessor]),
102
+ [valueField]: value
103
+ } as TRow;
81
104
  }
82
105
 
83
106
  const filtered = $derived.by(() => {
84
107
  const discrete = () =>
85
- data.filter((d) => TimelineSteps.matches(getTime(d), selectedValue, filterMode));
108
+ data.filter((d) => {
109
+ const at = getTime(d);
110
+ return at === undefined || TimelineSteps.matches(at, selectedValue, filterMode);
111
+ });
86
112
 
87
113
  if (!interpolate) return discrete();
88
114
  if (!interpolate.value) {
@@ -96,14 +122,14 @@
96
122
  const getValue = resolveAccessor<TRow>(interpolate.value) as (d: TRow) => number;
97
123
  const create = interpolate.create ?? defaultCreate;
98
124
 
99
- const groups = Map.groupBy(data, (row) => String(getKey(row)));
125
+ const groups = Map.groupBy(timed, (row) => String(getKey(row)));
100
126
 
101
- const result: TRow[] = [];
127
+ const result: TRow[] = [...untimed];
102
128
  for (const rows of groups.values()) {
103
129
  const tweened = Interpolation.tweenSeries({
104
130
  rows,
105
131
  x: currentTime,
106
- getTime,
132
+ getTime: getTime as (row: TRow) => TimeValue,
107
133
  getValue,
108
134
  create,
109
135
  segmentEasing: segmentEasingFn
@@ -1,18 +1,20 @@
1
- import type { Orientation, TimeValue, TimelineChildSnippet, TimelineInterpolation } from '../../types/layout/timeline';
1
+ import type { Orientation, TimeInput, TimeValue, TimelineChildSnippet, TimelineInterpolation } from '../../types/layout/timeline';
2
2
  import type { Accessor } from '../../types/plots/data/common';
3
3
  declare function $$render<TRow extends Record<string, unknown>>(): {
4
4
  props: {
5
5
  data: TRow[];
6
- accessor: Accessor<TRow, TimeValue>;
6
+ accessor: Accessor<TRow, TimeInput>;
7
+ /** How a non-ISO date string reads. */
8
+ dateFormat?: string;
7
9
  progress: number;
8
- values?: TimeValue[];
10
+ values?: TimeInput[];
9
11
  orientation?: Orientation;
10
12
  show?: boolean;
11
13
  thickness?: number;
12
14
  filterMode?: "exact" | "upTo";
13
15
  interpolate?: TimelineInterpolation<TRow>;
14
- /** Told the steps, whenever they change - for whoever else draws or drives the timeline. */
15
- onsteps?: (values: TimeValue[]) => void;
16
+ /** Told the steps, and whether they are dates, when they change. */
17
+ onsteps?: (values: TimeValue[], temporal: boolean) => void;
16
18
  width: number;
17
19
  height: number;
18
20
  child: TimelineChildSnippet<TRow>;
@@ -28,6 +28,7 @@
28
28
  <Timeline
29
29
  currentValue={timeline.value}
30
30
  values={timeline.steps}
31
+ format={timeline.format}
31
32
  orientation={timeline.orientation}
32
33
  width={measuredWidth}
33
34
  height={measuredHeight}
@@ -1,10 +1,12 @@
1
- import type { PlayerConfig, PlayerControl, Orientation, TimeValue, TimelineCallbacks, TimelineType } from '../../types/layout/timeline';
1
+ import type { PlayerConfig, PlayerControl, Orientation, TimeInput, TimeValue, TimelineStep, TimelineCallbacks, TimelineType } from '../../types/layout/timeline';
2
2
  /** What a {@link TimelineState} reads from the timeline's owner, each time it needs it. */
3
3
  export type TimelineSettings = TimelineCallbacks & {
4
4
  type?: TimelineType;
5
5
  player?: PlayerConfig;
6
6
  progress?: number;
7
- values?: TimeValue[];
7
+ values?: TimeInput[];
8
+ /** How a non-ISO date string in `values` reads. */
9
+ dateFormat?: string;
8
10
  show?: boolean;
9
11
  orientation?: Orientation;
10
12
  thickness?: number;
@@ -37,8 +39,10 @@ export declare class TimelineState {
37
39
  get shown(): boolean;
38
40
  /** The steps it moves across, ascending: the owner's `values`, else those its plots report. */
39
41
  get steps(): TimeValue[];
40
- /** Reports the steps the plots found in their rows. */
41
- setSteps(values: TimeValue[]): void;
42
+ /** Whether the steps are dates. */
43
+ get temporal(): boolean;
44
+ /** Reports the steps the plots found in their rows, and whether they are dates. */
45
+ setSteps(values: TimeValue[], temporal?: boolean): void;
42
46
  /** The position across the steps, `0`-`1`. */
43
47
  get progress(): number;
44
48
  /** The step the position lands on, as an index; `-1` without steps. */
@@ -55,8 +59,12 @@ export declare class TimelineState {
55
59
  get speeds(): number[];
56
60
  /** Milliseconds each step lasts at speed `1`. */
57
61
  get stepDuration(): number;
58
- /** How the current step reads. */
62
+ /** How a step reads: the player's `format`, else a date label or the number. */
59
63
  get format(): (value: TimeValue) => string;
64
+ /** A step as authors see it. */
65
+ step(value: TimeValue): TimelineStep;
66
+ /** An author's step as the timeline's own, or `undefined` when it reads as none. */
67
+ timeOf(value: TimeInput): TimeValue | undefined;
60
68
  /** Moves to `progress` (`0`-`1`), and tells the owner. */
61
69
  seek(progress: number): void;
62
70
  /** Moves to the step at `index`. */
@@ -1,6 +1,7 @@
1
1
  import { getContext, setContext, untrack } from 'svelte';
2
2
  import { getConfiguration } from '../../configuration/config.svelte';
3
3
  import { TimelineSteps } from './TimelineSteps';
4
+ import { TimelineTime } from './TimelineTime';
4
5
  const TIMELINE_KEY = Symbol('dct-timeline');
5
6
  /** The longest a frame counts for while playing, so a hidden tab doesn't jump ahead when it comes back. */
6
7
  const MAX_FRAME_MS = 250;
@@ -17,6 +18,7 @@ const MAX_FRAME_MS = 250;
17
18
  export class TimelineState {
18
19
  #settings;
19
20
  #steps = $state([]);
21
+ #temporal = $state(false);
20
22
  #own = $state(null);
21
23
  #playing = $state(false);
22
24
  #loop = $state(false);
@@ -58,14 +60,33 @@ export class TimelineState {
58
60
  }
59
61
  /** The steps it moves across, ascending: the owner's `values`, else those its plots report. */
60
62
  get steps() {
61
- const values = this.#settings()?.values;
62
- return values?.length ? new TimelineSteps(values).values : this.#steps;
63
- }
64
- /** Reports the steps the plots found in their rows. */
65
- setSteps(values) {
63
+ const values = this.#ownerValues;
64
+ return values ? new TimelineSteps(values).values : this.#steps;
65
+ }
66
+ /** Whether the steps are dates. */
67
+ get temporal() {
68
+ const settings = this.#settings();
69
+ if (!settings?.values?.length)
70
+ return this.#temporal;
71
+ return new TimelineTime(settings.dateFormat).isTemporal(settings.values);
72
+ }
73
+ /** Reports the steps the plots found in their rows, and whether they are dates. */
74
+ setSteps(values, temporal = false) {
66
75
  const same = values.length === this.#steps.length && values.every((v, i) => v === this.#steps[i]);
67
76
  if (!same)
68
77
  this.#steps = values;
78
+ if (temporal !== this.#temporal)
79
+ this.#temporal = temporal;
80
+ }
81
+ /** The owner's `values` as steps, or `undefined` without any. */
82
+ get #ownerValues() {
83
+ const settings = this.#settings();
84
+ if (!settings?.values?.length)
85
+ return undefined;
86
+ const time = new TimelineTime(settings.dateFormat);
87
+ return settings.values
88
+ .map((value) => time.toTime(value))
89
+ .filter((value) => value !== undefined);
69
90
  }
70
91
  /** The position across the steps, `0`-`1`. */
71
92
  get progress() {
@@ -103,9 +124,22 @@ export class TimelineState {
103
124
  get stepDuration() {
104
125
  return (this.#settings()?.player?.stepDuration ?? getConfiguration().timeline.player.stepDuration);
105
126
  }
106
- /** How the current step reads. */
127
+ /** How a step reads: the player's `format`, else a date label or the number. */
107
128
  get format() {
108
- return this.#settings()?.player?.format ?? ((value) => String(value));
129
+ const own = this.#settings()?.player?.format;
130
+ if (own)
131
+ return (value) => own(this.step(value));
132
+ if (this.temporal)
133
+ return TimelineTime.dateLabel(this.steps, getConfiguration().axis.locale);
134
+ return (value) => String(value);
135
+ }
136
+ /** A step as authors see it. */
137
+ step(value) {
138
+ return TimelineTime.toStep(value, this.temporal);
139
+ }
140
+ /** An author's step as the timeline's own, or `undefined` when it reads as none. */
141
+ timeOf(value) {
142
+ return new TimelineTime(this.#settings()?.dateFormat).toTime(value);
109
143
  }
110
144
  /** Moves to `progress` (`0`-`1`), and tells the owner. */
111
145
  seek(progress) {
@@ -196,7 +230,7 @@ export class TimelineState {
196
230
  const value = this.value;
197
231
  untrack(() => {
198
232
  if (last !== undefined && value !== undefined && value !== last) {
199
- this.#settings()?.onvalue?.(value);
233
+ this.#settings()?.onvalue?.(this.step(value));
200
234
  }
201
235
  last = value;
202
236
  });
@@ -0,0 +1,18 @@
1
+ import type { TimeValue, TimelineStep } from '../../types/layout/timeline';
2
+ /** Reads a timeline's values (numbers, `Date`s, ISO or `dateFormat` strings) as numeric steps, and back. */
3
+ export declare class TimelineTime {
4
+ #private;
5
+ readonly dateFormat?: string | undefined;
6
+ /** @param dateFormat How a non-ISO date string reads, e.g. `'DD/MM/YYYY'`. */
7
+ constructor(dateFormat?: string | undefined);
8
+ /** A value as its step, or `undefined` when it reads as none. */
9
+ toTime(value: unknown): TimeValue | undefined;
10
+ /** A step as authors see it: a `Date` when `temporal`, else the number. */
11
+ static toStep(value: TimeValue, temporal: boolean): TimelineStep;
12
+ /** Whether `values` hold dates rather than plain numbers. */
13
+ isTemporal(values: unknown[]): boolean;
14
+ /** A step written back in the same form as `like`, for interpolated rows. */
15
+ toValueLike(time: TimeValue, like: unknown): unknown;
16
+ /** A date label as precise as the steps need: year, month, day or time. */
17
+ static dateLabel(steps: TimeValue[], locale?: string): (time: TimeValue) => string;
18
+ }
@@ -0,0 +1,117 @@
1
+ /** The `dateFormat` tokens and the UTC date part each reads or writes. */
2
+ const TOKENS = {
3
+ YYYY: { group: '(\\d{4})', get: (date) => date.getUTCFullYear(), width: 4 },
4
+ MM: { group: '(\\d{1,2})', get: (date) => date.getUTCMonth() + 1, width: 2 },
5
+ DD: { group: '(\\d{1,2})', get: (date) => date.getUTCDate(), width: 2 },
6
+ HH: { group: '(\\d{1,2})', get: (date) => date.getUTCHours(), width: 2 },
7
+ mm: { group: '(\\d{1,2})', get: (date) => date.getUTCMinutes(), width: 2 },
8
+ ss: { group: '(\\d{1,2})', get: (date) => date.getUTCSeconds(), width: 2 }
9
+ };
10
+ const TOKEN_PATTERN = /YYYY|MM|DD|HH|mm|ss/g;
11
+ /** An ISO 8601 date, from a bare year to a full date-time. */
12
+ const ISO_DATE = /^\d{4}(-\d{2}(-\d{2}([T ]\d{2}:\d{2}(:\d{2}(\.\d+)?)?(Z|[+-]\d{2}:?\d{2})?)?)?)?$/;
13
+ const DAY = 24 * 60 * 60 * 1000;
14
+ /** Reads a timeline's values (numbers, `Date`s, ISO or `dateFormat` strings) as numeric steps, and back. */
15
+ export class TimelineTime {
16
+ dateFormat;
17
+ /** @param dateFormat How a non-ISO date string reads, e.g. `'DD/MM/YYYY'`. */
18
+ constructor(dateFormat) {
19
+ this.dateFormat = dateFormat;
20
+ }
21
+ /** A value as its step, or `undefined` when it reads as none. */
22
+ toTime(value) {
23
+ if (typeof value === 'number')
24
+ return Number.isFinite(value) ? value : undefined;
25
+ if (value instanceof Date) {
26
+ const time = value.getTime();
27
+ return Number.isFinite(time) ? time : undefined;
28
+ }
29
+ if (typeof value !== 'string')
30
+ return undefined;
31
+ const text = value.trim();
32
+ if (this.dateFormat) {
33
+ const parsed = TimelineTime.#parse(text, this.dateFormat);
34
+ if (parsed !== undefined)
35
+ return parsed;
36
+ }
37
+ if (text !== '' && Number.isFinite(Number(text)) && !ISO_DATE.test(text))
38
+ return Number(text);
39
+ if (ISO_DATE.test(text)) {
40
+ // A bare year stays a year, like a number.
41
+ if (/^\d{4}$/.test(text))
42
+ return Number(text);
43
+ const time = Date.parse(/^\d{4}-\d{2}$/.test(text) ? `${text}-01` : text);
44
+ return Number.isFinite(time) ? time : undefined;
45
+ }
46
+ return undefined;
47
+ }
48
+ /** A step as authors see it: a `Date` when `temporal`, else the number. */
49
+ static toStep(value, temporal) {
50
+ return temporal ? new Date(value) : value;
51
+ }
52
+ /** Whether `values` hold dates rather than plain numbers. */
53
+ isTemporal(values) {
54
+ return values.some((value) => {
55
+ if (value instanceof Date)
56
+ return true;
57
+ if (typeof value !== 'string')
58
+ return false;
59
+ const text = value.trim();
60
+ return !/^-?\d+(\.\d+)?$/.test(text) && this.toTime(text) !== undefined;
61
+ });
62
+ }
63
+ /** A step written back in the same form as `like`, for interpolated rows. */
64
+ toValueLike(time, like) {
65
+ if (like instanceof Date)
66
+ return new Date(time);
67
+ if (typeof like !== 'string')
68
+ return time;
69
+ const text = like.trim();
70
+ if (this.dateFormat && TimelineTime.#parse(text, this.dateFormat) !== undefined) {
71
+ return TimelineTime.#write(new Date(time), this.dateFormat);
72
+ }
73
+ if (ISO_DATE.test(text) && !/^\d{4}$/.test(text)) {
74
+ return new Date(time).toISOString().slice(0, text.length);
75
+ }
76
+ return String(time);
77
+ }
78
+ /** A date label as precise as the steps need: year, month, day or time. */
79
+ static dateLabel(steps, locale) {
80
+ const dates = steps.map((time) => new Date(time));
81
+ const options = dates.every((d) => d.getUTCMonth() === 0 && d.getUTCDate() === 1 && d.getTime() % DAY === 0)
82
+ ? { year: 'numeric' }
83
+ : dates.every((d) => d.getUTCDate() === 1 && d.getTime() % DAY === 0)
84
+ ? { month: 'short', year: 'numeric' }
85
+ : dates.every((d) => d.getTime() % DAY === 0)
86
+ ? { day: 'numeric', month: 'short', year: 'numeric' }
87
+ : { dateStyle: 'medium', timeStyle: 'short' };
88
+ const format = new Intl.DateTimeFormat(locale, { ...options, timeZone: 'UTC' });
89
+ return (time) => format.format(new Date(time));
90
+ }
91
+ /** `text` read through `format`, or `undefined` when it does not match. */
92
+ static #parse(text, format) {
93
+ const order = [];
94
+ const pattern = format
95
+ .split(TOKEN_PATTERN)
96
+ .map((literal) => literal.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'));
97
+ const tokens = format.match(TOKEN_PATTERN) ?? [];
98
+ let source = pattern[0];
99
+ tokens.forEach((token, index) => {
100
+ order.push(token);
101
+ source += TOKENS[token].group + pattern[index + 1];
102
+ });
103
+ const match = new RegExp(`^${source}$`).exec(text);
104
+ if (!match || !order.length)
105
+ return undefined;
106
+ const parts = { YYYY: 1970, MM: 1, DD: 1, HH: 0, mm: 0, ss: 0 };
107
+ order.forEach((token, index) => (parts[token] = Number(match[index + 1])));
108
+ return Date.UTC(parts.YYYY, parts.MM - 1, parts.DD, parts.HH, parts.mm, parts.ss);
109
+ }
110
+ /** `date` written through `format`. */
111
+ static #write(date, format) {
112
+ return format.replace(TOKEN_PATTERN, (token) => {
113
+ const { get, width } = TOKENS[token];
114
+ return String(get(date)).padStart(width, '0');
115
+ });
116
+ }
117
+ }