@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
@@ -2,7 +2,8 @@
2
2
  import { Dot } from 'svelteplot';
3
3
  import { MarkerChannels } from '../utils/MarkerChannels';
4
4
  import { getConfiguration } from '../../configuration/config.svelte';
5
- import { resolveAccessor } from '../../plots/utils/accessors';
5
+ import { resolveAccessor } from '../../utils/accessors';
6
+ import RowOffsetMarks from '../utils/RowOffsetMarks.svelte';
6
7
  import type { DotMarkerConfig } from '../../types/markers/common';
7
8
 
8
9
  /**
@@ -69,34 +70,30 @@
69
70
  const strokeDasharray = $derived(styles?.dotStrokeDasharray);
70
71
  </script>
71
72
 
73
+ {#snippet dots(rows: TData[], fillOpacity: number)}
74
+ <RowOffsetMarks {marker} {rows}>
75
+ {#snippet mark(own)}
76
+ <Dot
77
+ data={own}
78
+ x={x ?? 0}
79
+ y={y ?? 0}
80
+ {r}
81
+ {fill}
82
+ {fillOpacity}
83
+ {stroke}
84
+ {strokeWidth}
85
+ {strokeOpacity}
86
+ {strokeDasharray}
87
+ {symbol}
88
+ />
89
+ {/snippet}
90
+ </RowOffsetMarks>
91
+ {/snippet}
92
+
72
93
  {#if opacityBuckets}
73
94
  {#each opacityBuckets as bucket (bucket.value)}
74
- <Dot
75
- data={bucket.data}
76
- x={x ?? 0}
77
- y={y ?? 0}
78
- {r}
79
- {fill}
80
- fillOpacity={bucket.value}
81
- {stroke}
82
- {strokeWidth}
83
- {strokeOpacity}
84
- {strokeDasharray}
85
- {symbol}
86
- />
95
+ {@render dots(bucket.data, bucket.value)}
87
96
  {/each}
88
97
  {:else}
89
- <Dot
90
- data={displayData}
91
- x={x ?? 0}
92
- y={y ?? 0}
93
- {r}
94
- {fill}
95
- fillOpacity={flatFillOpacity}
96
- {stroke}
97
- {strokeWidth}
98
- {strokeOpacity}
99
- {strokeDasharray}
100
- {symbol}
101
- />
98
+ {@render dots(displayData, flatFillOpacity)}
102
99
  {/if}
@@ -1,5 +1,6 @@
1
1
  <script lang="ts">
2
2
  import { Image } from 'svelteplot';
3
+ import RowOffsetMarks from '../utils/RowOffsetMarks.svelte';
3
4
  import type { ImageMarkerConfig } from '../../types/markers/common';
4
5
 
5
6
  /** Renders one `'image'` marker as `<Image>` - an image centered on each row's `x`/`y`. */
@@ -8,15 +9,19 @@
8
9
  const data = $derived(marker.data ?? []);
9
10
  </script>
10
11
 
11
- <Image
12
- {data}
13
- x={marker.x}
14
- y={marker.y}
15
- src={marker.src}
16
- r={marker.r}
17
- width={marker.width}
18
- height={marker.height}
19
- title={marker.title}
20
- preserveAspectRatio={marker.preserveAspectRatio}
21
- opacity={marker.opacity}
22
- />
12
+ <RowOffsetMarks {marker} rows={data}>
13
+ {#snippet mark(rows)}
14
+ <Image
15
+ data={rows}
16
+ x={marker.x}
17
+ y={marker.y}
18
+ src={marker.src}
19
+ r={marker.r}
20
+ width={marker.width}
21
+ height={marker.height}
22
+ title={marker.title}
23
+ preserveAspectRatio={marker.preserveAspectRatio}
24
+ opacity={marker.opacity}
25
+ />
26
+ {/snippet}
27
+ </RowOffsetMarks>
@@ -2,7 +2,7 @@
2
2
  import { geoPath } from 'd3-geo';
3
3
  import { buildInsetProjection } from './insetProjection';
4
4
  import { insetBox } from './insetLayout';
5
- import { filterGeometryParts } from '../../plots/utils/geoAccessors';
5
+ import { GeoGeometry } from '../../plots/map/geo/GeoGeometry';
6
6
  import Tooltip from '../../layout/tooltip/Tooltip.svelte';
7
7
  import type { GeoInsetMarkerConfig } from '../../types/markers/geo';
8
8
  import type { GeoFeature } from '../../types/plots/data/geo';
@@ -65,7 +65,7 @@
65
65
  if (!marker.featurePartsFilter) return matched;
66
66
  const partsFilter = marker.featurePartsFilter;
67
67
  return matched.flatMap((f) => {
68
- const geometry = filterGeometryParts(f.geometry, (part) => partsFilter(part, f));
68
+ const geometry = GeoGeometry.filterParts(f.geometry, (part) => partsFilter(part, f));
69
69
  return geometry ? [{ ...f, geometry }] : [];
70
70
  });
71
71
  }
@@ -21,6 +21,7 @@
21
21
  x={marker.x}
22
22
  y={marker.y}
23
23
  z={marker.grouping}
24
+ curve={marker.curve ?? cfg.line.curve}
24
25
  stroke={channelStroke ?? marker.styles?.stroke}
25
26
  strokeWidth={marker.styles?.strokeWidth}
26
27
  strokeOpacity={marker.styles?.strokeOpacity}
@@ -1,47 +1,192 @@
1
1
  <script lang="ts">
2
2
  import { Geo } from 'svelteplot';
3
- import { resolveAccessor } from '../../plots/utils/accessors';
4
- import { greatCircleInterpolate } from '../../plots/utils/geoAccessors';
3
+ import { geoPath } from 'd3-geo';
4
+ import { resolveAccessor } from '../../utils/accessors';
5
+ import { usePlot } from '../../layout/plot/usePlot';
6
+ import { GeoGeometry } from '../../plots/map/geo/GeoGeometry';
7
+ import { toProjectionLike, type StreamingProjection } from '../../plots/utils/tiles';
5
8
  import type { GeoLinkMarkerConfig } from '../../types/markers/geo';
6
9
 
7
- /** Renders one `'link'` marker - geodesic-aware lines between point pairs, as a synthetic `LineString` fed through `<Geo>`. */
10
+ /**
11
+ * Renders one `'link'` marker - lines between point pairs. A plain `'auto'`
12
+ * link follows the great circle, as a `LineString` fed through `<Geo>`; a
13
+ * `'linear'` one, or any with an `altitude`, is a path drawn from the
14
+ * projected positions.
15
+ */
8
16
  let { marker }: { marker: GeoLinkMarkerConfig } = $props();
9
17
 
18
+ type Point = [number, number];
19
+ const STEPS = 64;
20
+
21
+ const plot = usePlot().svelteplot;
22
+
10
23
  const getX1 = $derived(resolveAccessor(marker.x1));
11
24
  const getY1 = $derived(resolveAccessor(marker.y1));
12
25
  const getX2 = $derived(resolveAccessor(marker.x2));
13
26
  const getY2 = $derived(resolveAccessor(marker.y2));
27
+ const altitude = $derived(marker.altitude ?? 0);
28
+ const drawn = $derived(marker.curve === 'linear' || altitude > 0);
14
29
 
15
- const linkFeatures = $derived(
30
+ const ends = (d: Record<string, unknown>): [Point, Point] => [
31
+ [Number(getX1(d)), Number(getY1(d))],
32
+ [Number(getX2(d)), Number(getY2(d))]
33
+ ];
34
+
35
+ const arcFeatures = $derived(
16
36
  marker.data.map((d) => ({
17
37
  type: 'Feature' as const,
18
38
  properties: {},
19
- geometry: {
20
- type: 'LineString' as const,
21
- coordinates:
22
- marker.curve === 'linear'
23
- ? [
24
- [Number(getX1(d)), Number(getY1(d))],
25
- [Number(getX2(d)), Number(getY2(d))]
26
- ]
27
- : greatCircleInterpolate(
28
- Number(getX1(d)),
29
- Number(getY1(d)),
30
- Number(getX2(d)),
31
- Number(getY2(d))
32
- )
33
- }
39
+ geometry: { type: 'LineString' as const, coordinates: GeoGeometry.greatCircle(...ends(d)) }
34
40
  }))
35
41
  );
42
+
43
+ // The same shared, already-fitted projection every other map mark draws through.
44
+ const projection = $derived(
45
+ toProjectionLike(plot.scales.projection as unknown as StreamingProjection)
46
+ );
47
+
48
+ /** The projected globe's center and width; a projection that clips (a globe) is lifted radially, a flat one upward. */
49
+ const frame = $derived.by(() => {
50
+ const sphere = geoPath(plot.scales.projection as unknown as Parameters<typeof geoPath>[0]);
51
+ const [[x0, y0], [x1, y1]] = sphere.bounds({ type: 'Sphere' });
52
+ const probes: Point[] = [
53
+ [-170, 0],
54
+ [-90, 0],
55
+ [0, 0],
56
+ [90, 0],
57
+ [170, 0]
58
+ ];
59
+ return {
60
+ center: [(x0 + x1) / 2, (y0 + y1) / 2] as Point,
61
+ width: x1 - x0,
62
+ globe: probes.some((probe) => projection(probe) === null)
63
+ };
64
+ });
65
+
66
+ /** Unit vector of a lon/lat on the sphere. */
67
+ const toVector = ([lon, lat]: Point): [number, number, number] => {
68
+ const [lambda, phi] = [(lon * Math.PI) / 180, (lat * Math.PI) / 180];
69
+ return [Math.cos(phi) * Math.cos(lambda), Math.cos(phi) * Math.sin(lambda), Math.sin(phi)];
70
+ };
71
+ const toLonLat = ([x, y, z]: [number, number, number]): Point => [
72
+ (Math.atan2(y, x) * 180) / Math.PI,
73
+ (Math.atan2(z, Math.hypot(x, y)) * 180) / Math.PI
74
+ ];
75
+
76
+ /** The point of the sphere facing the viewer, on a globe. */
77
+ const facing = $derived.by(() => {
78
+ if (!frame.globe) return undefined;
79
+ const lonLat = projection.invert?.(frame.center);
80
+ return lonLat ? toVector(lonLat) : undefined;
81
+ });
82
+
83
+ /**
84
+ * Where a point sits on screen, and whether it faces the viewer. On a
85
+ * globe, a point on the far side shows where its mirror image across the
86
+ * view plane does - that is where a lifted arc over the horizon is drawn.
87
+ */
88
+ function place(point: Point): { xy: Point; front: boolean } | null {
89
+ const xy = projection(point);
90
+ if (xy) return { xy, front: true };
91
+ if (marker.occlusion !== 'globe' || !facing) return null;
92
+ const vector = toVector(point);
93
+ const depth = vector.reduce((sum, value, index) => sum + value * facing[index], 0);
94
+ const mirrored = vector.map((value, index) => value - 2 * depth * facing[index]);
95
+ const shown = projection(toLonLat(mirrored as [number, number, number]));
96
+ return shown ? { xy: shown, front: false } : null;
97
+ }
98
+
99
+ /** A point lifted off a globe's surface; one from the far side counts only once it clears the globe's outline. */
100
+ function lifted([x, y]: Point, rise: number, front: boolean): Point | null {
101
+ const [cx, cy] = frame.center;
102
+ const out: Point = [cx + (x - cx) * (1 + rise), cy + (y - cy) * (1 + rise)];
103
+ return front || Math.hypot(out[0] - cx, out[1] - cy) > frame.width / 2 ? out : null;
104
+ }
105
+
106
+ /** One route as projected runs of points; a run ends where the projection clips or the line wraps around a flat map. */
107
+ function runsOf(d: Record<string, unknown>): Point[][] {
108
+ const [from, to] = ends(d);
109
+ const start = projection(from);
110
+ const end = projection(to);
111
+ // A straight line needs both ends on screen; an arc keeps whatever part of it shows.
112
+ if (marker.curve === 'linear' && (!start || !end)) return [];
113
+ const steps = altitude > 0 ? STEPS : 1;
114
+ const projected: ({ xy: Point; front: boolean } | null)[] =
115
+ marker.curve === 'linear'
116
+ ? Array.from({ length: steps + 1 }, (_, index) => ({
117
+ xy: [
118
+ start![0] + ((end![0] - start![0]) * index) / steps,
119
+ start![1] + ((end![1] - start![1]) * index) / steps
120
+ ] as Point,
121
+ front: true
122
+ }))
123
+ : (altitude > 0 ? GeoGeometry.parallelPath : GeoGeometry.greatCircle)(from, to, steps).map(
124
+ (point) => place(point)
125
+ );
126
+ const chord = start && end ? Math.hypot(end[0] - start[0], end[1] - start[1]) : 0;
127
+
128
+ const runs: Point[][] = [];
129
+ let run: Point[] = [];
130
+ projected.forEach((point, index) => {
131
+ const rise = altitude * Math.sin((Math.PI * index) / steps);
132
+ const next: Point | null = !point
133
+ ? null
134
+ : frame.globe
135
+ ? lifted(point.xy, rise, point.front)
136
+ : [point.xy[0], point.xy[1] - chord * rise];
137
+ const previous = run[run.length - 1];
138
+ const wrapped =
139
+ next &&
140
+ previous &&
141
+ marker.curve !== 'linear' &&
142
+ !frame.globe &&
143
+ Math.abs(next[0] - previous[0]) > frame.width / 2;
144
+ if (!next || wrapped) {
145
+ if (run.length > 1) runs.push(run);
146
+ run = next ? [next] : [];
147
+ } else {
148
+ run.push(next);
149
+ }
150
+ });
151
+ if (run.length > 1) runs.push(run);
152
+ return runs;
153
+ }
154
+
155
+ const paths = $derived(
156
+ drawn
157
+ ? marker.data.flatMap((d) => {
158
+ const runs = runsOf(d);
159
+ return runs.length
160
+ ? [runs.map((run) => 'M' + run.map(([x, y]) => `${x},${y}`).join('L')).join('')]
161
+ : [];
162
+ })
163
+ : []
164
+ );
36
165
  </script>
37
166
 
38
- <!-- No `fill` prop: svelteplot treats any string as scale-worthy unless it's a real CSS color, so a literal `'none'` would run through the color scale instead of staying unfilled. Omitting it leaves svelteplot's own unfilled default in place. -->
39
- <Geo
40
- class="link"
41
- data={linkFeatures}
42
- stroke={marker.styles?.stroke ?? 'currentColor'}
43
- strokeWidth={marker.styles?.strokeWidth ?? 1}
44
- strokeOpacity={marker.styles?.strokeOpacity}
45
- strokeDasharray={marker.styles?.strokeDasharray}
46
- style="vector-effect: non-scaling-stroke"
47
- />
167
+ {#if drawn}
168
+ <g class="link">
169
+ {#each paths as d, index (index)}
170
+ <path
171
+ {d}
172
+ fill="none"
173
+ stroke={marker.styles?.stroke ?? 'currentColor'}
174
+ stroke-width={marker.styles?.strokeWidth ?? 1}
175
+ stroke-opacity={marker.styles?.strokeOpacity}
176
+ stroke-dasharray={marker.styles?.strokeDasharray}
177
+ style="vector-effect: non-scaling-stroke"
178
+ />
179
+ {/each}
180
+ </g>
181
+ {:else}
182
+ <!-- No `fill` prop: svelteplot treats any string as scale-worthy unless it's a real CSS color, so a literal `'none'` would run through the color scale instead of staying unfilled. Omitting it leaves svelteplot's own unfilled default in place. -->
183
+ <Geo
184
+ class="link"
185
+ data={arcFeatures}
186
+ stroke={marker.styles?.stroke ?? 'currentColor'}
187
+ strokeWidth={marker.styles?.strokeWidth ?? 1}
188
+ strokeOpacity={marker.styles?.strokeOpacity}
189
+ strokeDasharray={marker.styles?.strokeDasharray}
190
+ style="vector-effect: non-scaling-stroke"
191
+ />
192
+ {/if}
@@ -21,40 +21,23 @@
21
21
 
22
22
  const plot = usePlot();
23
23
  const isHorizontal = $derived(plot.axes?.isHorizontal ?? false);
24
+ const RegressionMark = $derived(isHorizontal ? RegressionX : RegressionY);
24
25
 
25
26
  const data = $derived(marker.data ?? []);
26
27
  </script>
27
28
 
28
- {#if isHorizontal}
29
- <RegressionX
30
- {data}
31
- x={marker.x}
32
- y={marker.y}
33
- type={marker.regressionType}
34
- order={marker.order}
35
- base={marker.base}
36
- span={marker.span}
37
- confidence={marker.confidence}
38
- stroke={marker.styles?.stroke ?? 'currentColor'}
39
- strokeWidth={marker.styles?.strokeWidth}
40
- strokeOpacity={marker.styles?.strokeOpacity}
41
- strokeDasharray={marker.styles?.strokeDasharray}
42
- fill={marker.confidence !== false ? 'currentColor' : undefined}
43
- />
44
- {:else}
45
- <RegressionY
46
- {data}
47
- x={marker.x}
48
- y={marker.y}
49
- type={marker.regressionType}
50
- order={marker.order}
51
- base={marker.base}
52
- span={marker.span}
53
- confidence={marker.confidence}
54
- stroke={marker.styles?.stroke ?? 'currentColor'}
55
- strokeWidth={marker.styles?.strokeWidth}
56
- strokeOpacity={marker.styles?.strokeOpacity}
57
- strokeDasharray={marker.styles?.strokeDasharray}
58
- fill={marker.confidence !== false ? 'currentColor' : undefined}
59
- />
60
- {/if}
29
+ <RegressionMark
30
+ {data}
31
+ x={marker.x}
32
+ y={marker.y}
33
+ type={marker.regressionType}
34
+ order={marker.order}
35
+ base={marker.base}
36
+ span={marker.span}
37
+ confidence={marker.confidence}
38
+ stroke={marker.styles?.stroke ?? 'currentColor'}
39
+ strokeWidth={marker.styles?.strokeWidth}
40
+ strokeOpacity={marker.styles?.strokeOpacity}
41
+ strokeDasharray={marker.styles?.strokeDasharray}
42
+ fill={marker.confidence !== false ? 'currentColor' : undefined}
43
+ />
@@ -1,6 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { RuleX, RuleY } from 'svelteplot';
3
3
  import type { AxisValue } from '../../types/layout/mapping';
4
+ import { RowStroke } from '../utils/RowStroke';
4
5
  import type { RuleMarkerConfig } from '../../types/markers/common';
5
6
 
6
7
  /**
@@ -29,6 +30,11 @@
29
30
  * single synthetic `{v: value}` row.
30
31
  */
31
32
  const position = $derived(data ? value : (d: { v: AxisValue }) => d.v);
33
+
34
+ /** Each row's own stroke, over the marker's `styles`. */
35
+ const row = $derived(
36
+ RowStroke.of(marker, styles, { stroke: 'currentColor', strokeWidth: 1, strokeOpacity: 1 })
37
+ );
32
38
  </script>
33
39
 
34
40
  <RuleMark
@@ -40,8 +46,8 @@
40
46
  {...axis === 'x'
41
47
  ? { insetTop: marker.insetTop, insetBottom: marker.insetBottom }
42
48
  : { insetLeft: marker.insetLeft, insetRight: marker.insetRight }}
43
- stroke={styles?.stroke ?? 'currentColor'}
44
- strokeWidth={styles?.strokeWidth ?? 1}
45
- strokeOpacity={styles?.strokeOpacity ?? 1}
49
+ stroke={row.stroke}
50
+ strokeWidth={row.strokeWidth}
51
+ strokeOpacity={row.strokeOpacity}
46
52
  strokeDasharray={styles?.strokeDasharray}
47
53
  />
@@ -31,5 +31,9 @@ export declare class Declutter {
31
31
  top: number;
32
32
  bottom: number;
33
33
  };
34
+ /** Aligns the labels on the shared column even when none of them overlaps. */
35
+ forceAligned?: boolean;
36
+ /** Lets a leftward fan with no room flip right. Defaults to `true`. */
37
+ flip?: boolean;
34
38
  }): Map<K, LabelLane>;
35
39
  }
@@ -11,20 +11,22 @@ export class Declutter {
11
11
  * axis's tick labels sit there) flips right instead.
12
12
  */
13
13
  static buildLanes(args) {
14
- const { items, dx, fontSize, geometry, bounds } = args;
14
+ const { items, dx, fontSize, geometry, bounds, forceAligned, flip = true } = args;
15
15
  const lanes = new Map();
16
- if (items.length < 2)
16
+ if (items.length < 2 && !forceAligned)
17
17
  return lanes;
18
18
  const sorted = [...items].sort((a, b) => a.py - b.py);
19
19
  const originals = sorted.map((item) => item.py);
20
20
  const minGap = Math.max(16, fontSize * 1.4);
21
- const { finals, connected } = Declutter.#spread(originals, minGap, [bounds.top, bounds.bottom]);
21
+ const { finals, connected } = sorted.length > 1
22
+ ? Declutter.#spread(originals, minGap, [bounds.top, bounds.bottom])
23
+ : { finals: originals, connected: [] };
22
24
  const ranks = Declutter.#assignLanes(originals, finals, connected);
23
- const aligned = ranks.some((r) => r.runSize > 1);
25
+ const aligned = !!forceAligned || ranks.some((r) => r.runSize > 1);
24
26
  const lanesUsed = aligned ? Math.max(...ranks.map((r) => r.runSize)) : 1;
25
27
  const reach = geometry.elbowGap + (lanesUsed - 1) * geometry.laneStep + geometry.labelGap;
26
28
  let dir = Math.sign(dx) || 1;
27
- if (aligned && dir === -1) {
29
+ if (aligned && dir === -1 && flip) {
28
30
  // Unknown room (no x position yet) counts as none: flipping right is never wrong.
29
31
  const rooms = sorted.flatMap((item) => (item.px == null ? [] : [item.px - bounds.left]));
30
32
  if ((rooms.length > 0 ? Math.min(...rooms) : -Infinity) < reach)
@@ -142,12 +144,25 @@ export class Declutter {
142
144
  const runSize = end - start + 1;
143
145
  if (runSize < 2)
144
146
  continue;
145
- const order = Array.from({ length: runSize }, (_, k) => start + k).sort((a, b) => {
146
- const aNearer = saferNearer(a, b);
147
- if (aNearer !== saferNearer(b, a))
148
- return aNearer ? -1 : 1;
149
- return distance(b) - distance(a);
150
- });
147
+ const members = Array.from({ length: runSize }, (_, k) => start + k);
148
+ // The pairs the geometry decides: `before` holds the members that must take a nearer lane than each key.
149
+ const before = new Map(members.map((k) => [k, new Set()]));
150
+ for (const i of members) {
151
+ for (const j of members) {
152
+ if (i !== j && saferNearer(i, j) && !saferNearer(j, i))
153
+ before.get(j).add(i);
154
+ }
155
+ }
156
+ // Nearest lane first, each member only once everything that must precede it has a lane; the one that traveled furthest goes first among the free ones.
157
+ const order = [];
158
+ const placed = new Set();
159
+ while (order.length < runSize) {
160
+ const left = members.filter((k) => !placed.has(k));
161
+ const free = left.filter((k) => [...before.get(k)].every((i) => placed.has(i)));
162
+ const next = (free.length ? free : left).reduce((best, k) => distance(k) > distance(best) ? k : best);
163
+ order.push(next);
164
+ placed.add(next);
165
+ }
151
166
  order.forEach((k, rank) => {
152
167
  out[k] = { rank, runSize };
153
168
  });