matterviz 0.3.7 → 0.4.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 (324) hide show
  1. package/dist/Icon.svelte +7 -4
  2. package/dist/MillerIndexInput.svelte +1 -1
  3. package/dist/api/optimade.js +32 -26
  4. package/dist/app.css +0 -3
  5. package/dist/brillouin/BrillouinZone.svelte +8 -3
  6. package/dist/brillouin/BrillouinZone.svelte.d.ts +2 -1
  7. package/dist/brillouin/BrillouinZoneScene.svelte +52 -6
  8. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -0
  9. package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
  10. package/dist/brillouin/compute.js +10 -14
  11. package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
  12. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +12 -15
  13. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +8 -10
  14. package/dist/chempot-diagram/async-compute.svelte.js +3 -1
  15. package/dist/chempot-diagram/chempot-worker.js +2 -1
  16. package/dist/chempot-diagram/compute.d.ts +1 -1
  17. package/dist/chempot-diagram/compute.js +17 -19
  18. package/dist/colors/index.js +6 -5
  19. package/dist/composition/FormulaFilter.svelte +12 -6
  20. package/dist/composition/PieChart.svelte +6 -5
  21. package/dist/composition/chem-sys.d.ts +8 -0
  22. package/dist/composition/chem-sys.js +85 -0
  23. package/dist/composition/format.js +4 -2
  24. package/dist/composition/index.d.ts +1 -0
  25. package/dist/composition/index.js +1 -0
  26. package/dist/composition/parse.js +25 -13
  27. package/dist/convex-hull/ConvexHull2D.svelte +12 -10
  28. package/dist/convex-hull/ConvexHull3D.svelte +5 -5
  29. package/dist/convex-hull/ConvexHull4D.svelte +5 -9
  30. package/dist/convex-hull/ConvexHullStats.svelte +12 -12
  31. package/dist/convex-hull/GasPressureControls.svelte +4 -4
  32. package/dist/convex-hull/TemperatureSlider.svelte +2 -2
  33. package/dist/convex-hull/demo-temperature.d.ts +1 -1
  34. package/dist/convex-hull/demo-temperature.js +20 -22
  35. package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
  36. package/dist/convex-hull/gas-thermodynamics.js +22 -30
  37. package/dist/convex-hull/helpers.d.ts +3 -0
  38. package/dist/convex-hull/helpers.js +17 -9
  39. package/dist/convex-hull/index.d.ts +1 -1
  40. package/dist/convex-hull/thermodynamics.js +83 -78
  41. package/dist/convex-hull/types.d.ts +1 -1
  42. package/dist/coordination/CoordinationBarPlot.svelte +23 -23
  43. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  44. package/dist/element/ElementTile.svelte.d.ts +1 -1
  45. package/dist/fermi-surface/FermiSlice.svelte +13 -5
  46. package/dist/fermi-surface/FermiSurface.svelte +11 -5
  47. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  48. package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
  49. package/dist/fermi-surface/FermiSurfaceScene.svelte +3 -0
  50. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
  51. package/dist/fermi-surface/compute.js +59 -59
  52. package/dist/fermi-surface/export.js +3 -2
  53. package/dist/fermi-surface/parse.js +7 -4
  54. package/dist/fermi-surface/types.d.ts +1 -0
  55. package/dist/heatmap-matrix/HeatmapMatrix.svelte +23 -21
  56. package/dist/heatmap-matrix/index.js +1 -1
  57. package/dist/io/decompress.js +4 -2
  58. package/dist/io/export.d.ts +4 -4
  59. package/dist/io/export.js +47 -25
  60. package/dist/io/fetch.js +5 -1
  61. package/dist/io/file-drop.d.ts +1 -1
  62. package/dist/io/file-drop.js +35 -36
  63. package/dist/io/url-drop.js +64 -33
  64. package/dist/isosurface/parse.js +6 -7
  65. package/dist/isosurface/slice.js +5 -4
  66. package/dist/isosurface/types.js +1 -1
  67. package/dist/keyboard.d.ts +3 -0
  68. package/dist/keyboard.js +23 -0
  69. package/dist/labels.d.ts +1 -1
  70. package/dist/labels.js +8 -7
  71. package/dist/layout/PropertyFilter.svelte +3 -2
  72. package/dist/layout/SettingsSection.svelte +1 -1
  73. package/dist/layout/json-tree/JsonNode.svelte +1 -1
  74. package/dist/layout/json-tree/JsonTree.svelte +2 -2
  75. package/dist/layout/json-tree/utils.js +5 -4
  76. package/dist/marching-cubes.js +8 -13
  77. package/dist/math.d.ts +5 -1
  78. package/dist/math.js +24 -9
  79. package/dist/overlays/DraggablePane.svelte +4 -4
  80. package/dist/periodic-table/PeriodicTable.svelte +20 -9
  81. package/dist/periodic-table/PropertySelect.svelte +1 -0
  82. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
  83. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  84. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  85. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  86. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
  87. package/dist/phase-diagram/build-diagram.js +2 -2
  88. package/dist/phase-diagram/parse.js +6 -5
  89. package/dist/phase-diagram/types.d.ts +1 -1
  90. package/dist/phase-diagram/utils.d.ts +3 -3
  91. package/dist/phase-diagram/utils.js +8 -12
  92. package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +229 -587
  93. package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +5 -5
  94. package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
  95. package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
  96. package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +6 -6
  97. package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
  98. package/dist/plot/bar/data.d.ts +40 -0
  99. package/dist/plot/bar/data.js +154 -0
  100. package/dist/plot/bar/geometry.d.ts +39 -0
  101. package/dist/plot/bar/geometry.js +60 -0
  102. package/dist/plot/bar/index.d.ts +3 -0
  103. package/dist/plot/bar/index.js +3 -0
  104. package/dist/plot/box/BoxPlot.svelte +1462 -0
  105. package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
  106. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  107. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  108. package/dist/plot/box/Violin.svelte +14 -0
  109. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  110. package/dist/plot/box/box-plot.d.ts +55 -0
  111. package/dist/plot/box/box-plot.js +126 -0
  112. package/dist/plot/box/index.d.ts +5 -0
  113. package/dist/plot/box/index.js +5 -0
  114. package/dist/plot/box/kde.d.ts +16 -0
  115. package/dist/plot/box/kde.js +160 -0
  116. package/dist/plot/box/quantile.d.ts +3 -0
  117. package/dist/plot/box/quantile.js +53 -0
  118. package/dist/plot/{auto-place.js → core/auto-place.js} +2 -2
  119. package/dist/plot/core/axis-utils.d.ts +46 -0
  120. package/dist/plot/core/axis-utils.js +110 -0
  121. package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
  122. package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
  123. package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +36 -33
  124. package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +2 -2
  125. package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
  126. package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
  127. package/dist/plot/core/components/ControlPane.svelte +46 -0
  128. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  129. package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
  130. package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
  131. package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
  132. package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
  133. package/dist/plot/{Line.svelte → core/components/Line.svelte} +30 -13
  134. package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +7 -5
  135. package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +3 -2
  136. package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
  137. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  138. package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
  139. package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
  140. package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
  141. package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
  142. package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
  143. package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
  144. package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
  145. package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +4 -4
  146. package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +2 -2
  147. package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +7 -7
  148. package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +2 -2
  149. package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
  150. package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
  151. package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
  152. package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
  153. package/dist/plot/core/components/index.d.ts +17 -0
  154. package/dist/plot/core/components/index.js +17 -0
  155. package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
  156. package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +3 -5
  157. package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
  158. package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
  159. package/dist/plot/core/fill-utils.d.ts +33 -0
  160. package/dist/plot/core/fill-utils.js +388 -0
  161. package/dist/plot/{hover-lock.svelte.js → core/hover-lock.svelte.js} +5 -6
  162. package/dist/plot/core/index.d.ts +10 -0
  163. package/dist/plot/core/index.js +11 -0
  164. package/dist/plot/core/interactions.d.ts +35 -0
  165. package/dist/plot/core/interactions.js +195 -0
  166. package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
  167. package/dist/plot/{layout.js → core/layout.js} +16 -8
  168. package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +1 -1
  169. package/dist/plot/{reference-line.js → core/reference-line.js} +23 -36
  170. package/dist/plot/{scales.d.ts → core/scales.d.ts} +2 -2
  171. package/dist/plot/{scales.js → core/scales.js} +84 -85
  172. package/dist/plot/core/svg.d.ts +2 -0
  173. package/dist/plot/core/svg.js +41 -0
  174. package/dist/plot/{types.d.ts → core/types.d.ts} +19 -79
  175. package/dist/plot/{types.js → core/types.js} +1 -1
  176. package/dist/plot/{utils → core/utils}/label-placement.d.ts +2 -2
  177. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  178. package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
  179. package/dist/plot/core/utils.d.ts +11 -0
  180. package/dist/plot/core/utils.js +27 -0
  181. package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +154 -294
  182. package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
  183. package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
  184. package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
  185. package/dist/plot/histogram/index.d.ts +2 -0
  186. package/dist/plot/histogram/index.js +2 -0
  187. package/dist/plot/index.d.ts +8 -41
  188. package/dist/plot/index.js +10 -39
  189. package/dist/plot/sankey/Sankey.svelte +700 -0
  190. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  191. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  192. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  193. package/dist/plot/sankey/index.d.ts +4 -0
  194. package/dist/plot/sankey/index.js +3 -0
  195. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  196. package/dist/plot/sankey/sankey-types.js +4 -0
  197. package/dist/plot/sankey/sankey.d.ts +52 -0
  198. package/dist/plot/sankey/sankey.js +187 -0
  199. package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +61 -59
  200. package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +4 -4
  201. package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
  202. package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
  203. package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +221 -642
  204. package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +7 -7
  205. package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
  206. package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +1 -1
  207. package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
  208. package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
  209. package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
  210. package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
  211. package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +3 -3
  212. package/dist/plot/scatter/index.d.ts +7 -0
  213. package/dist/plot/scatter/index.js +5 -0
  214. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  215. package/dist/plot/scatter/scatter-data.js +212 -0
  216. package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +12 -10
  217. package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +7 -7
  218. package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +5 -4
  219. package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +2 -2
  220. package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +11 -11
  221. package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +3 -3
  222. package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +1 -1
  223. package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +1 -1
  224. package/dist/plot/scatter-3d/index.d.ts +4 -0
  225. package/dist/plot/scatter-3d/index.js +4 -0
  226. package/dist/plot/sunburst/Sunburst.svelte +1045 -0
  227. package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
  228. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  229. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  230. package/dist/plot/sunburst/index.d.ts +4 -0
  231. package/dist/plot/sunburst/index.js +4 -0
  232. package/dist/plot/sunburst/render.d.ts +34 -0
  233. package/dist/plot/sunburst/render.js +122 -0
  234. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  235. package/dist/plot/sunburst/sunburst.js +266 -0
  236. package/dist/rdf/RdfPlot.svelte +2 -1
  237. package/dist/rdf/calc-rdf.js +11 -24
  238. package/dist/sanitize.js +1 -1
  239. package/dist/settings.d.ts +65 -1
  240. package/dist/settings.js +262 -0
  241. package/dist/spectral/Bands.svelte +39 -29
  242. package/dist/spectral/Bands.svelte.d.ts +3 -4
  243. package/dist/spectral/BandsAndDos.svelte +1 -1
  244. package/dist/spectral/BrillouinBandsDos.svelte +39 -27
  245. package/dist/spectral/Dos.svelte +10 -19
  246. package/dist/spectral/Dos.svelte.d.ts +2 -2
  247. package/dist/spectral/helpers.d.ts +3 -1
  248. package/dist/spectral/helpers.js +95 -29
  249. package/dist/structure/AtomLegend.svelte +8 -9
  250. package/dist/structure/CellSelect.svelte +1 -2
  251. package/dist/structure/Cylinder.svelte +12 -8
  252. package/dist/structure/Cylinder.svelte.d.ts +4 -1
  253. package/dist/structure/Structure.svelte +78 -72
  254. package/dist/structure/Structure.svelte.d.ts +1 -1
  255. package/dist/structure/StructureInfoPane.svelte +5 -6
  256. package/dist/structure/StructureScene.svelte +11 -10
  257. package/dist/structure/atom-properties.js +6 -6
  258. package/dist/structure/bond-order-perception.js +1 -1
  259. package/dist/structure/bonding.d.ts +1 -0
  260. package/dist/structure/bonding.js +43 -15
  261. package/dist/structure/export.js +27 -23
  262. package/dist/structure/index.d.ts +2 -4
  263. package/dist/structure/index.js +1 -3
  264. package/dist/structure/label-placement.js +4 -4
  265. package/dist/structure/measure.d.ts +3 -2
  266. package/dist/structure/measure.js +6 -5
  267. package/dist/structure/parse.js +121 -103
  268. package/dist/structure/pbc.js +4 -0
  269. package/dist/symmetry/SymmetryStats.svelte +2 -2
  270. package/dist/symmetry/index.d.ts +1 -1
  271. package/dist/symmetry/index.js +22 -24
  272. package/dist/symmetry/spacegroups.d.ts +7 -0
  273. package/dist/symmetry/spacegroups.js +48 -13
  274. package/dist/table/HeatmapTable.svelte +63 -11
  275. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  276. package/dist/table/index.d.ts +1 -3
  277. package/dist/table/index.js +1 -1
  278. package/dist/theme/index.js +8 -8
  279. package/dist/tooltip/KCoords.svelte +45 -0
  280. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  281. package/dist/tooltip/index.d.ts +1 -0
  282. package/dist/tooltip/index.js +1 -0
  283. package/dist/trajectory/Trajectory.svelte +66 -40
  284. package/dist/trajectory/Trajectory.svelte.d.ts +2 -1
  285. package/dist/trajectory/TrajectoryExportPane.svelte +2 -1
  286. package/dist/trajectory/TrajectoryInfoPane.svelte +2 -1
  287. package/dist/trajectory/format-detect.d.ts +1 -0
  288. package/dist/trajectory/format-detect.js +25 -11
  289. package/dist/trajectory/frame-reader.js +17 -50
  290. package/dist/trajectory/helpers.js +1 -1
  291. package/dist/trajectory/index.js +1 -1
  292. package/dist/trajectory/parse/hdf5.js +1 -1
  293. package/dist/trajectory/parse/index.js +14 -6
  294. package/dist/trajectory/parse/vasp.js +36 -17
  295. package/dist/trajectory/parse/xyz.d.ts +24 -0
  296. package/dist/trajectory/parse/xyz.js +102 -89
  297. package/dist/trajectory/plotting.d.ts +1 -1
  298. package/dist/trajectory/plotting.js +15 -15
  299. package/dist/utils.d.ts +1 -0
  300. package/dist/utils.js +6 -4
  301. package/dist/xrd/XrdPlot.svelte +2 -1
  302. package/dist/xrd/calc-xrd.js +15 -12
  303. package/dist/xrd/parse.js +2 -2
  304. package/package.json +22 -18
  305. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  306. package/dist/plot/axis-utils.d.ts +0 -19
  307. package/dist/plot/axis-utils.js +0 -78
  308. package/dist/plot/defaults.d.ts +0 -19
  309. package/dist/plot/defaults.js +0 -9
  310. package/dist/plot/fill-utils.d.ts +0 -46
  311. package/dist/plot/fill-utils.js +0 -322
  312. package/dist/plot/interactions.d.ts +0 -12
  313. package/dist/plot/interactions.js +0 -101
  314. package/dist/plot/svg.d.ts +0 -1
  315. package/dist/plot/svg.js +0 -11
  316. package/dist/plot/utils/series-visibility.d.ts +0 -15
  317. package/dist/plot/utils.d.ts +0 -1
  318. package/dist/plot/utils.js +0 -14
  319. /package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +0 -0
  320. /package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +0 -0
  321. /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
  322. /package/dist/plot/{hover-lock.svelte.d.ts → core/hover-lock.svelte.d.ts} +0 -0
  323. /package/dist/plot/{utils → core/utils}/label-placement.js +0 -0
  324. /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
@@ -1,11 +1,11 @@
1
- import type { D3ColorSchemeName, D3InterpolateName } from '../colors';
2
- import type { Point2D } from '../math';
3
- import type { AxisLoadError, BasePlotProps, ControlsConfig, DataLoaderFn, DataSeries, ErrorBand, FillHandlerEvent, FillRegion, HoverConfig, InternalPoint, LabelPlacementConfig, LegendConfig, PanConfig, PlotConfig, Point, RefLine, RefLineEvent, ScaleType, ScatterHandlerEvent, ScatterHandlerProps, StyleOverrides, UserContentProps } from './';
4
- import { ColorBar } from './';
1
+ import type { D3ColorSchemeName, D3InterpolateName } from '../../colors';
2
+ import type { Point2D } from '../../math';
3
+ import type { AxisLoadError, BasePlotProps, ControlsConfig, DataLoaderFn, DataSeries, ErrorBand, FillHandlerEvent, FillRegion, HoverConfig, InternalPoint, LabelPlacementConfig, LegendConfig, PanConfig, PlotConfig, Point, RefLine, RefLineEvent, ScaleType, ScatterHandlerEvent, ScatterHandlerProps, StyleOverrides, UserContentProps } from '..';
4
+ import { ColorBar } from '..';
5
5
  import type { ComponentProps, Snippet } from 'svelte';
6
6
  import type { HTMLAttributes } from 'svelte/elements';
7
7
  import { type TweenOptions } from 'svelte/motion';
8
- import type { Sides } from './layout';
8
+ import type { Sides } from '../core/layout';
9
9
  declare function $$render<Metadata extends Record<string, unknown> = Record<string, unknown>>(): {
10
10
  props: HTMLAttributes<HTMLDivElement> & Omit<BasePlotProps, "change"> & PlotConfig & {
11
11
  series?: DataSeries<Metadata>[];
@@ -73,7 +73,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
73
73
  pan?: PanConfig;
74
74
  };
75
75
  exports: {};
76
- bindings: "display" | "x_axis" | "y_axis" | "fullscreen" | "series" | "hovered" | "ref_lines" | "wrapper" | "x2_axis" | "y2_axis" | "tooltip_point" | "fill_regions" | "selected_series_idx";
76
+ bindings: "display" | "fullscreen" | "series" | "hovered" | "ref_lines" | "x_axis" | "y_axis" | "x2_axis" | "y2_axis" | "wrapper" | "tooltip_point" | "fill_regions" | "selected_series_idx";
77
77
  slots: {};
78
78
  events: {};
79
79
  };
@@ -81,7 +81,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
81
81
  props(): ReturnType<typeof $$render<Metadata>>['props'];
82
82
  events(): ReturnType<typeof $$render<Metadata>>['events'];
83
83
  slots(): ReturnType<typeof $$render<Metadata>>['slots'];
84
- bindings(): "display" | "x_axis" | "y_axis" | "fullscreen" | "series" | "hovered" | "ref_lines" | "wrapper" | "x2_axis" | "y2_axis" | "tooltip_point" | "fill_regions" | "selected_series_idx";
84
+ bindings(): "display" | "fullscreen" | "series" | "hovered" | "ref_lines" | "x_axis" | "y_axis" | "x2_axis" | "y2_axis" | "wrapper" | "tooltip_point" | "fill_regions" | "selected_series_idx";
85
85
  exports(): {};
86
86
  }
87
87
  interface $$IsomorphicComponent {
@@ -1,18 +1,19 @@
1
1
  <script lang="ts">
2
- import { SettingsSection } from '../layout'
3
- import { PlotControls } from './'
2
+ import { SettingsSection } from '../../layout'
3
+ import { PlotControls } from '..'
4
4
  import type {
5
5
  DataSeries,
6
6
  PlotConfig,
7
7
  PlotControlsProps,
8
8
  StyleOverrides,
9
- } from './types'
10
- import { DEFAULTS } from '../settings'
9
+ } from '../core/types'
10
+ import { unique_id } from '../core/utils'
11
+ import { DEFAULTS } from '../../settings'
11
12
  import type { Snippet } from 'svelte'
12
13
  import { tooltip } from 'svelte-multiselect/attachments'
13
14
 
14
15
  // Unique ID prefix to avoid conflicts when multiple instances on same page
15
- const uid = crypto.randomUUID().slice(0, 8)
16
+ const uid = unique_id(`scatter-ctrl`)
16
17
 
17
18
  let {
18
19
  series = [],
@@ -1,4 +1,4 @@
1
- import type { DataSeries, PlotConfig, PlotControlsProps, StyleOverrides } from './types';
1
+ import type { DataSeries, PlotConfig, PlotControlsProps, StyleOverrides } from '../core/types';
2
2
  import type { Snippet } from 'svelte';
3
3
  type $$ComponentProps = Omit<PlotControlsProps, `children` | `post_children`> & {
4
4
  series?: readonly DataSeries[];
@@ -1,10 +1,10 @@
1
1
  <script lang="ts">
2
- import { type D3SymbolName, symbol_map } from '../labels'
3
- import type { HoverStyle, LabelStyle, Point } from './'
4
- import type { Point2D } from '../math'
5
- import type { PointStyle } from './types'
6
- import { estimate_label_size, label_leader_segment } from './utils/label-placement'
7
- import { DEFAULTS } from '../settings'
2
+ import { type D3SymbolName, symbol_map } from '../../labels'
3
+ import type { HoverStyle, LabelStyle, Point } from '..'
4
+ import type { Point2D } from '../../math'
5
+ import type { PointStyle } from '../core/types'
6
+ import { estimate_label_size, label_leader_segment } from '../core/utils/label-placement'
7
+ import { DEFAULTS } from '../../settings'
8
8
  import * as d3_symbols from 'd3-shape'
9
9
  import { symbol } from 'd3-shape'
10
10
  import { cubicOut } from 'svelte/easing'
@@ -44,7 +44,7 @@
44
44
  function get_symbol_path(): string {
45
45
  const symbol_key: D3SymbolName = style.symbol_type ?? DEFAULTS.scatter.symbol_type
46
46
  const symbol_type = symbol_map[symbol_key] ?? d3_symbols.symbolCircle
47
- const size = style.symbol_size ?? Math.PI * Math.pow(style.radius ?? 2, 2)
47
+ const size = style.symbol_size ?? Math.PI * (style.radius ?? 2) ** 2
48
48
  return symbol().type(symbol_type).size(size)() || ``
49
49
  }
50
50
 
@@ -1,6 +1,6 @@
1
- import type { HoverStyle, LabelStyle, Point } from './';
2
- import type { Point2D } from '../math';
3
- import type { PointStyle } from './types';
1
+ import type { HoverStyle, LabelStyle, Point } from '..';
2
+ import type { Point2D } from '../../math';
3
+ import type { PointStyle } from '../core/types';
4
4
  import type { SVGAttributes } from 'svelte/elements';
5
5
  import { type TweenOptions } from 'svelte/motion';
6
6
  type $$ComponentProps = Omit<SVGAttributes<SVGGElement>, `style` | `offset` | `origin` | `transform`> & {
@@ -1,4 +1,5 @@
1
- import type { Point2D, Vec2 } from '../math';
1
+ import { type Point2D, type Vec2 } from '../../math';
2
+ import type { ScaleType } from '../core/types';
2
3
  export type NumericArray = ArrayLike<number>;
3
4
  export interface DensePointSeries<Metadata = Record<string, unknown>> {
4
5
  id?: string | number;
@@ -55,15 +56,24 @@ export interface PlotRect {
55
56
  width: number;
56
57
  height: number;
57
58
  }
59
+ export interface BinTransform {
60
+ forward: (value: number) => number;
61
+ inverse: (value: number) => number;
62
+ }
63
+ export type BinTransforms = {
64
+ x?: BinTransform;
65
+ y?: BinTransform;
66
+ };
67
+ export declare function scale_bin_transform(scale_type?: ScaleType): BinTransform;
58
68
  export declare const get_metadata_at: <Metadata>(metadata: DensePointSeries<Metadata>[`metadata`], point_idx: number) => Metadata | undefined;
59
69
  export declare const range_bounds: (range: Vec2) => Vec2;
60
70
  export declare function series_extents(series: readonly DensePointSeries[]): {
61
71
  x: Vec2;
62
72
  y: Vec2;
63
73
  };
64
- export declare function bin_points(series: readonly DensePointSeries[], x_range: Vec2, y_range: Vec2, x_bins: number, y_bins: number): DensityBinResult;
65
- export declare function density_bin_at_point(density: DensityBinResult, pointer: Point2D, plot_rect: PlotRect, x_range: Vec2, y_range: Vec2): DensityBin | null;
66
- export declare function should_render_points(visible_count: number, plot_area_px: number, max_points: number, max_points_per_px: number): boolean;
74
+ export declare function bin_points(series: readonly DensePointSeries[], x_range: Vec2, y_range: Vec2, x_bins: number, y_bins: number, transforms?: BinTransforms): DensityBinResult;
75
+ export declare function density_bin_at_point(density: DensityBinResult, pointer: Point2D, plot_rect: PlotRect, x_range: Vec2, y_range: Vec2, transforms?: BinTransforms): DensityBin | null;
76
+ export declare const should_render_points: (visible_count: number, plot_area_px: number, max_points: number, max_points_per_px: number) => boolean;
67
77
  export declare function build_pick_index<Metadata>(series: readonly DensePointSeries<Metadata>[], options: PickNearestOptions): PickIndex<Metadata>;
68
78
  export declare function pick_from_index<Metadata>(index: PickIndex<Metadata>, pointer: Point2D): DenseInternalPoint<Metadata> | null;
69
79
  export declare function first_point_in_bin<Metadata>(series: readonly DensePointSeries<Metadata>[], density: DensityBinResult, bin: Pick<DensityBin, `x_bin` | `y_bin`>, x_scale: (value: number) => number, y_scale: (value: number) => number): DenseInternalPoint<Metadata> | null;
@@ -1,3 +1,32 @@
1
+ import { LOG_EPS } from '../../math';
2
+ import { get_arcsinh_threshold, get_scale_type_name } from '../core/types';
3
+ const identity = { forward: (val) => val, inverse: (val) => val };
4
+ // Map an axis scale_type to the transform density binning should happen in
5
+ export function scale_bin_transform(scale_type) {
6
+ const type_name = get_scale_type_name(scale_type);
7
+ if (type_name === `log`) {
8
+ // Clamp to LOG_EPS (same floor as the rendered log scale) so bin edges align with the
9
+ // axis; non-positive samples are already dropped by the range filter in bin_points
10
+ return { forward: (val) => Math.log(Math.max(val, LOG_EPS)), inverse: Math.exp };
11
+ }
12
+ if (type_name !== `arcsinh`)
13
+ return identity;
14
+ const threshold = get_arcsinh_threshold(scale_type);
15
+ return {
16
+ forward: (val) => Math.asinh(val / threshold),
17
+ inverse: (val) => Math.sinh(val) * threshold,
18
+ };
19
+ }
20
+ // Data range of one bin: edges are uniform in transformed space, mapped back via inverse
21
+ const bin_range = (txf, range, bin, n_bins) => {
22
+ const transform = txf ?? identity;
23
+ const [t_min, t_max] = range_bounds(range).map(transform.forward);
24
+ const step = (t_max - t_min || 1) / n_bins;
25
+ return [
26
+ transform.inverse(t_min + bin * step),
27
+ transform.inverse(t_min + (bin + 1) * step),
28
+ ];
29
+ };
1
30
  export const get_metadata_at = (metadata, point_idx) => (Array.isArray(metadata) ? metadata[point_idx] : metadata);
2
31
  const cell_key = (x_bin, y_bin) => `${x_bin},${y_bin}`;
3
32
  export const range_bounds = (range) => range[0] <= range[1] ? range : [range[1], range[0]];
@@ -38,16 +67,19 @@ export function series_extents(series) {
38
67
  }
39
68
  return { x: padded_extent(x_min, x_max), y: padded_extent(y_min, y_max) };
40
69
  }
41
- export function bin_points(series, x_range, y_range, x_bins, y_bins) {
70
+ export function bin_points(series, x_range, y_range, x_bins, y_bins, transforms) {
42
71
  const counts = new Uint32Array(x_bins * y_bins);
43
72
  const first_point_idxs = new Int32Array(counts.length);
44
73
  const first_series_idxs = new Int32Array(counts.length);
45
74
  const [x_min, x_max] = range_bounds(x_range);
46
75
  const [y_min, y_max] = range_bounds(y_range);
47
- const x_span = x_max - x_min || 1;
48
- const y_span = y_max - y_min || 1;
49
- const x_bin_scale = x_bins / x_span;
50
- const y_bin_scale = y_bins / y_span;
76
+ // Bin in transformed (scale) space so bins align with the axis pixel grid
77
+ const x_fwd = transforms?.x?.forward ?? identity.forward;
78
+ const y_fwd = transforms?.y?.forward ?? identity.forward;
79
+ const t_x_min = x_fwd(x_min);
80
+ const t_y_min = y_fwd(y_min);
81
+ const x_bin_scale = x_bins / (x_fwd(x_max) - t_x_min || 1);
82
+ const y_bin_scale = y_bins / (y_fwd(y_max) - t_y_min || 1);
51
83
  const last_x_bin = x_bins - 1;
52
84
  const last_y_bin = y_bins - 1;
53
85
  let visible_count = 0;
@@ -65,10 +97,10 @@ export function bin_points(series, x_range, y_range, x_bins, y_bins) {
65
97
  y < y_min ||
66
98
  y > y_max)
67
99
  continue;
68
- const raw_x_bin = Math.floor((x - x_min) * x_bin_scale);
69
- const raw_y_bin = Math.floor((y - y_min) * y_bin_scale);
70
- const x_bin = raw_x_bin > last_x_bin ? last_x_bin : raw_x_bin;
71
- const y_bin = raw_y_bin > last_y_bin ? last_y_bin : raw_y_bin;
100
+ const raw_x_bin = Math.floor((x_fwd(x) - t_x_min) * x_bin_scale);
101
+ const raw_y_bin = Math.floor((y_fwd(y) - t_y_min) * y_bin_scale);
102
+ const x_bin = raw_x_bin < 0 ? 0 : raw_x_bin > last_x_bin ? last_x_bin : raw_x_bin;
103
+ const y_bin = raw_y_bin < 0 ? 0 : raw_y_bin > last_y_bin ? last_y_bin : raw_y_bin;
72
104
  const idx = y_bin * x_bins + x_bin;
73
105
  const count = ++counts[idx];
74
106
  if (count === 1) {
@@ -90,7 +122,7 @@ export function bin_points(series, x_range, y_range, x_bins, y_bins) {
90
122
  y_bins,
91
123
  };
92
124
  }
93
- export function density_bin_at_point(density, pointer, plot_rect, x_range, y_range) {
125
+ export function density_bin_at_point(density, pointer, plot_rect, x_range, y_range, transforms) {
94
126
  const rel_x = pointer.x - plot_rect.x;
95
127
  const rel_y = pointer.y - plot_rect.y;
96
128
  if (rel_x < 0 || rel_y < 0 || rel_x >= plot_rect.width || rel_y >= plot_rect.height) {
@@ -102,22 +134,16 @@ export function density_bin_at_point(density, pointer, plot_rect, x_range, y_ran
102
134
  const count = density.counts[y_bin * density.x_bins + x_bin];
103
135
  if (!count)
104
136
  return null;
105
- const [x_min, x_max] = range_bounds(x_range);
106
- const [y_min, y_max] = range_bounds(y_range);
107
- const x_step = (x_max - x_min || 1) / density.x_bins;
108
- const y_step = (y_max - y_min || 1) / density.y_bins;
109
137
  return {
110
138
  x_bin,
111
139
  y_bin,
112
140
  count,
113
- x_range: [x_min + x_bin * x_step, x_min + (x_bin + 1) * x_step],
114
- y_range: [y_min + y_bin * y_step, y_min + (y_bin + 1) * y_step],
141
+ x_range: bin_range(transforms?.x, x_range, x_bin, density.x_bins),
142
+ y_range: bin_range(transforms?.y, y_range, y_bin, density.y_bins),
115
143
  };
116
144
  }
117
- export function should_render_points(visible_count, plot_area_px, max_points, max_points_per_px) {
118
- return (visible_count <= max_points ||
119
- (plot_area_px > 0 && visible_count / plot_area_px <= max_points_per_px));
120
- }
145
+ export const should_render_points = (visible_count, plot_area_px, max_points, max_points_per_px) => visible_count <= max_points ||
146
+ (plot_area_px > 0 && visible_count / plot_area_px <= max_points_per_px);
121
147
  const internal_point = (srs, series_idx, point_idx, x_scale, y_scale) => {
122
148
  const x = srs.x[point_idx];
123
149
  const y = srs.y[point_idx];
@@ -1,7 +1,7 @@
1
- import type { D3ColorSchemeName, D3InterpolateName } from '../colors';
1
+ import type { D3ColorSchemeName, D3InterpolateName } from '../../colors';
2
2
  import type { DenseInternalPoint } from './adaptive-density';
3
- import type ColorBar from './ColorBar.svelte';
4
- import type { LabelPlacementConfig, ScaleType, ScatterHandlerProps } from './types';
3
+ import type ColorBar from '../core/components/ColorBar.svelte';
4
+ import type { LabelPlacementConfig, ScaleType, ScatterHandlerProps } from '../core/types';
5
5
  import type { ComponentProps, Snippet } from 'svelte';
6
6
  export type BinnedColorScaleConfig = {
7
7
  type?: ScaleType;
@@ -0,0 +1,7 @@
1
+ export type { DensePointSeries } from './adaptive-density';
2
+ export { default as BinnedScatterPlot } from './BinnedScatterPlot.svelte';
3
+ export type { BinnedColorScaleConfig, BinnedDensityConfig, BinnedOverlaysConfig, BinnedPointBasePayload, BinnedPointDataFn, BinnedPointLabelPlacementConfig, BinnedPointLabelsConfig, BinnedPointPayload, BinnedPointTooltipPayload, BinnedRefLine, BinnedSizeScaleConfig, } from './binned-scatter-types';
4
+ export { default as ElementScatter } from './ElementScatter.svelte';
5
+ export { default as ScatterPlot } from './ScatterPlot.svelte';
6
+ export { default as ScatterPlotControls } from './ScatterPlotControls.svelte';
7
+ export { default as ScatterPoint } from './ScatterPoint.svelte';
@@ -0,0 +1,5 @@
1
+ export { default as BinnedScatterPlot } from './BinnedScatterPlot.svelte';
2
+ export { default as ElementScatter } from './ElementScatter.svelte';
3
+ export { default as ScatterPlot } from './ScatterPlot.svelte';
4
+ export { default as ScatterPlotControls } from './ScatterPlotControls.svelte';
5
+ export { default as ScatterPoint } from './ScatterPoint.svelte';
@@ -0,0 +1,19 @@
1
+ import type { DataSeries, FillRegion, InternalPoint, LegendItem, PointStyle } from '..';
2
+ import { type AxisRanges } from '../core/types';
3
+ export type { AxisRanges };
4
+ export declare function filter_series_to_ranges<Metadata = Record<string, unknown>>(series: readonly DataSeries<Metadata>[], ranges: AxisRanges): (DataSeries<Metadata> & {
5
+ filtered_data: InternalPoint<Metadata>[];
6
+ })[];
7
+ export type LegendFill = FillRegion & {
8
+ idx: number;
9
+ source_type: `fill_region` | `error_band`;
10
+ source_idx: number;
11
+ };
12
+ export type ScatterLegendItem = LegendItem & {
13
+ has_explicit_label?: boolean;
14
+ };
15
+ export declare function build_legend_data<Metadata = Record<string, unknown>>(series: readonly DataSeries<Metadata>[], computed_fills: readonly LegendFill[], color_scale_fn: (value: number) => string): ScatterLegendItem[];
16
+ export declare function pick_tooltip_bg<Metadata = Record<string, unknown>>(point: {
17
+ color_value?: number | null;
18
+ point_style?: PointStyle;
19
+ }, series: DataSeries<Metadata> | undefined, color_scale_fn: (value: number) => string): string;
@@ -0,0 +1,212 @@
1
+ import { symbol_names } from '../../labels';
2
+ import { get_series_color, get_series_symbol, process_prop, } from '../core/data-transform';
3
+ import { is_fill_gradient } from '../core/fill-utils';
4
+ import { DEFAULT_MARKERS } from '../core/types';
5
+ const in_range = (val, lo, hi) => val != null && !isNaN(val) && val >= Math.min(lo, hi) && val <= Math.max(lo, hi);
6
+ // Filter series data to only include points within bounds and augment with internal data.
7
+ // Full x/y arrays are kept on each returned series (via spread) so connecting lines can
8
+ // continue through off-range points; only filtered_data (rendered markers) is range-limited.
9
+ export function filter_series_to_ranges(series, ranges) {
10
+ const [x_min, x_max] = ranges.x;
11
+ const [x2_min, x2_max] = ranges.x2;
12
+ const [y_min, y_max] = ranges.y;
13
+ const [y2_min, y2_max] = ranges.y2;
14
+ return (series
15
+ .map((data_series, series_idx) => {
16
+ if (!data_series) {
17
+ return {
18
+ x: [],
19
+ y: [],
20
+ visible: true,
21
+ filtered_data: [],
22
+ _id: series_idx,
23
+ orig_series_idx: series_idx,
24
+ };
25
+ }
26
+ if (!(data_series.visible ?? true)) {
27
+ return {
28
+ ...data_series,
29
+ visible: false,
30
+ filtered_data: [],
31
+ orig_series_idx: series_idx,
32
+ };
33
+ }
34
+ const { x: xs, y: ys, color_values, size_values, ...series_rest } = data_series;
35
+ const processed_points = xs.map((x_val, point_idx) => ({
36
+ x: x_val,
37
+ y: ys[point_idx],
38
+ color_value: color_values?.[point_idx],
39
+ metadata: process_prop(series_rest.metadata, point_idx),
40
+ point_style: process_prop(series_rest.point_style, point_idx),
41
+ point_hover: process_prop(series_rest.point_hover, point_idx),
42
+ point_label: process_prop(series_rest.point_label, point_idx),
43
+ point_offset: process_prop(series_rest.point_offset, point_idx),
44
+ series_idx,
45
+ point_idx,
46
+ size_value: size_values?.[point_idx],
47
+ }));
48
+ // Filter to plot bounds using the series' assigned axes (in_range handles
49
+ // inverted ranges like [3.5, 1.4])
50
+ const [series_x_min, series_x_max] = (data_series.x_axis ?? `x1`) === `x2` ? [x2_min, x2_max] : [x_min, x_max];
51
+ const [series_y_min, series_y_max] = (data_series.y_axis ?? `y1`) === `y2` ? [y2_min, y2_max] : [y_min, y_max];
52
+ const filtered_data = processed_points.filter(({ x, y }) => in_range(x, series_x_min, series_x_max) && in_range(y, series_y_min, series_y_max));
53
+ // orig_series_idx keeps auto-cycled colors/symbols stable across filtering
54
+ return { ...data_series, visible: true, filtered_data, orig_series_idx: series_idx };
55
+ })
56
+ // Drop series left completely empty after point filtering
57
+ .filter((srs) => (srs.filtered_data?.length ?? 0) > 0));
58
+ }
59
+ // Prepare legend items from series + computed fill regions, deduplicated by
60
+ // legend_group::label (first occurrence wins across both series and fills)
61
+ export function build_legend_data(series, computed_fills, color_scale_fn) {
62
+ const items = series.map((data_series, series_idx) => {
63
+ // Prefer top-level label, fall back to metadata label, then a generated default
64
+ const explicit_label = data_series?.label ??
65
+ (typeof data_series?.metadata === `object` &&
66
+ data_series.metadata !== null &&
67
+ `label` in data_series.metadata &&
68
+ typeof data_series.metadata.label === `string`
69
+ ? data_series.metadata.label
70
+ : null);
71
+ // Series-index defaults give auto-cycled colors/symbols
72
+ const series_default_color = get_series_color(series_idx);
73
+ const display_style = {
74
+ symbol_type: get_series_symbol(series_idx),
75
+ symbol_color: series_default_color,
76
+ line_color: series_default_color,
77
+ };
78
+ const series_markers = data_series?.markers ?? DEFAULT_MARKERS;
79
+ const first_point_style = Array.isArray(data_series?.point_style)
80
+ ? data_series.point_style[0]
81
+ : data_series?.point_style;
82
+ if (series_markers?.includes(`points`)) {
83
+ if (first_point_style) {
84
+ if (typeof first_point_style.symbol_type === `string` &&
85
+ symbol_names.includes(first_point_style.symbol_type)) {
86
+ display_style.symbol_type = first_point_style.symbol_type;
87
+ }
88
+ if (first_point_style.fill)
89
+ display_style.symbol_color = first_point_style.fill;
90
+ // Fall back to stroke when the fill is missing/none/transparent
91
+ if (first_point_style.stroke &&
92
+ (!display_style.symbol_color ||
93
+ display_style.symbol_color === `none` ||
94
+ display_style.symbol_color.startsWith(`rgba(`, 0))) {
95
+ display_style.symbol_color = first_point_style.stroke;
96
+ }
97
+ }
98
+ }
99
+ else {
100
+ // No points marker: no symbol swatch in the legend
101
+ display_style.symbol_type = undefined;
102
+ display_style.symbol_color = undefined;
103
+ }
104
+ if (series_markers?.includes(`line`)) {
105
+ // Explicit line stroke, then color scale, then point colors, then series default
106
+ let line_color = data_series?.line_style?.stroke;
107
+ if (!line_color) {
108
+ const first_cv = Array.isArray(data_series?.color_values)
109
+ ? data_series?.color_values?.find((color_val) => color_val != null)
110
+ : undefined;
111
+ /* oxlint-disable @typescript-eslint/prefer-nullish-coalescing -- empty-string colors should fall through */
112
+ line_color =
113
+ (first_cv != null ? color_scale_fn(first_cv) : undefined) ||
114
+ first_point_style?.fill ||
115
+ first_point_style?.stroke ||
116
+ series_default_color;
117
+ /* oxlint-enable @typescript-eslint/prefer-nullish-coalescing */
118
+ }
119
+ display_style.line_color = line_color;
120
+ display_style.line_dash = data_series?.line_style?.line_dash;
121
+ }
122
+ else {
123
+ // No line marker: no line swatch in the legend
124
+ display_style.line_dash = undefined;
125
+ display_style.line_color = undefined;
126
+ }
127
+ return {
128
+ series_idx,
129
+ label: explicit_label ?? `Series ${series_idx + 1}`,
130
+ visible: data_series?.visible ?? true,
131
+ display_style,
132
+ has_explicit_label: explicit_label != null,
133
+ legend_group: data_series?.legend_group,
134
+ };
135
+ });
136
+ // Deduplicate by legend_group::label (first occurrence wins, across series + fills)
137
+ const seen_labels = new Set();
138
+ const first_seen = (group, label) => {
139
+ const key = `${group ?? ``}::${label ?? ``}`;
140
+ if (seen_labels.has(key))
141
+ return false;
142
+ seen_labels.add(key);
143
+ return true;
144
+ };
145
+ const series_items = items.filter((item) => first_seen(item.legend_group, item.label));
146
+ const fill_items = computed_fills
147
+ .filter((fill) => fill.show_in_legend !== false && fill.label)
148
+ .filter((fill) => first_seen(fill.legend_group, fill.label))
149
+ .map((fill) => {
150
+ // Pass gradient for swatch rendering, or solid color as fallback
151
+ const fill_gradient = is_fill_gradient(fill.fill) ? fill.fill : undefined;
152
+ const fill_color = typeof fill.fill === `string` ? fill.fill : undefined;
153
+ return {
154
+ series_idx: -1, // Not a series
155
+ fill_idx: fill.idx,
156
+ fill_source_type: fill.source_type,
157
+ fill_source_idx: fill.source_idx,
158
+ item_type: `fill`,
159
+ label: fill.label ?? ``,
160
+ visible: fill.visible !== false,
161
+ legend_group: fill.legend_group,
162
+ display_style: {
163
+ fill_color,
164
+ fill_opacity: fill.fill_opacity ?? 0.3,
165
+ edge_color: fill.edge_upper?.color,
166
+ fill_gradient,
167
+ },
168
+ };
169
+ });
170
+ return [...series_items, ...fill_items];
171
+ }
172
+ const is_transparent_or_none = (color) => !color ||
173
+ color === `none` ||
174
+ color === `transparent` ||
175
+ /rgba\([^)]+[,/]\s*0(\.0*)?\s*\)$/.test(color);
176
+ // Type-guard negation of is_transparent_or_none so usable colors narrow to string
177
+ const is_opaque_color = (color) => !is_transparent_or_none(color);
178
+ // Resolve tooltip background color: point color-scale value, then point fill, then point
179
+ // stroke (points marker), then line color cascade (line marker), then dark fallback
180
+ export function pick_tooltip_bg(point, series, color_scale_fn) {
181
+ const { color_value, point_style } = point;
182
+ const series_markers = series?.markers ?? DEFAULT_MARKERS;
183
+ const scale_color = color_value != null ? color_scale_fn(color_value) : undefined;
184
+ if (is_opaque_color(scale_color))
185
+ return scale_color;
186
+ const fill_color = point_style?.fill;
187
+ if (is_opaque_color(fill_color))
188
+ return fill_color;
189
+ if (series_markers?.includes(`points`)) {
190
+ const stroke_color = point_style?.stroke;
191
+ if (is_opaque_color(stroke_color))
192
+ return stroke_color;
193
+ }
194
+ if (series_markers?.includes(`line`)) {
195
+ const line_style = series?.line_style ?? {};
196
+ const first_point_style = Array.isArray(series?.point_style)
197
+ ? series?.point_style[0]
198
+ : series?.point_style;
199
+ const first_color_value = series?.color_values?.[0];
200
+ let line_color_candidate = line_style.stroke;
201
+ if (is_transparent_or_none(line_color_candidate)) {
202
+ line_color_candidate = first_point_style?.fill;
203
+ }
204
+ if (is_transparent_or_none(line_color_candidate) && first_color_value != null)
205
+ line_color_candidate = color_scale_fn(first_color_value);
206
+ if (is_transparent_or_none(line_color_candidate) && series_markers?.includes(`points`))
207
+ line_color_candidate = first_point_style?.stroke;
208
+ if (is_opaque_color(line_color_candidate))
209
+ return line_color_candidate;
210
+ }
211
+ return `rgba(0, 0, 0, 0.7)`;
212
+ }
@@ -2,12 +2,12 @@
2
2
  lang="ts"
3
3
  generics="Metadata extends Record<string, unknown> = Record<string, unknown>"
4
4
  >
5
- import type { D3ColorSchemeName, D3InterpolateName } from '../colors'
6
- import { FullscreenToggle } from '../layout'
7
- import type { Vec2, Vec3 } from '../math'
8
- import { ColorBar, PlotLegend } from './'
9
- import { get_series_color } from './data-transform'
10
- import type { Sides } from './layout'
5
+ import type { D3ColorSchemeName, D3InterpolateName } from '../../colors'
6
+ import { FullscreenToggle } from '../../layout'
7
+ import type { Vec2, Vec3 } from '../../math'
8
+ import { ColorBar, PlotLegend } from '..'
9
+ import { get_series_color } from '../core/data-transform'
10
+ import type { Sides } from '../core/layout'
11
11
  import type {
12
12
  AxisConfig3D,
13
13
  CameraProjection3D,
@@ -22,7 +22,7 @@
22
22
  Scatter3DHandlerEvent,
23
23
  StyleOverrides3D,
24
24
  Surface3DConfig,
25
- } from './types'
25
+ } from '../core/types'
26
26
  import { Canvas } from '@threlte/core'
27
27
  import * as extras from '@threlte/extras'
28
28
  import { onMount } from 'svelte'
@@ -30,7 +30,7 @@
30
30
  import type { HTMLAttributes } from 'svelte/elements'
31
31
  import { SvelteMap, SvelteSet } from 'svelte/reactivity'
32
32
  import type { Camera, Scene } from 'three'
33
- import { create_color_scale } from './scales'
33
+ import { create_color_scale } from '../core/scales'
34
34
  import ScatterPlot3DControls from './ScatterPlot3DControls.svelte'
35
35
  import ScatterPlot3DScene from './ScatterPlot3DScene.svelte'
36
36
 
@@ -462,8 +462,10 @@
462
462
  border-radius: 0;
463
463
  max-height: none !important;
464
464
  overflow: hidden;
465
- /* Add padding to prevent titles from being cropped at top */
466
- padding-top: var(--plot-fullscreen-padding-top, 2em);
465
+ /* border-top (not padding-top): bind:clientHeight includes padding but excludes
466
+ borders - padding made the chart overflow + clip its bottom 2em (x-axis title) */
467
+ border-top: var(--plot-fullscreen-padding-top, 2em) solid
468
+ var(--scatter3d-bg, var(--plot-bg, transparent));
467
469
  box-sizing: border-box;
468
470
  }
469
471
  /* Threlte Canvas container needs flex: 1 to fill available space in flex layout
@@ -1,8 +1,8 @@
1
- import type { D3ColorSchemeName, D3InterpolateName } from '../colors';
2
- import type { Vec3 } from '../math';
3
- import { ColorBar } from './';
4
- import type { Sides } from './layout';
5
- import type { AxisConfig3D, CameraProjection3D, ControlsConfig3D, DataSeries3D, DisplayConfig3D, InternalPoint3D, LegendConfig, RefLine3D, RefPlane, ScaleType, Scatter3DHandlerEvent, StyleOverrides3D, Surface3DConfig } from './types';
1
+ import type { D3ColorSchemeName, D3InterpolateName } from '../../colors';
2
+ import type { Vec3 } from '../../math';
3
+ import { ColorBar } from '..';
4
+ import type { Sides } from '../core/layout';
5
+ import type { AxisConfig3D, CameraProjection3D, ControlsConfig3D, DataSeries3D, DisplayConfig3D, InternalPoint3D, LegendConfig, RefLine3D, RefPlane, ScaleType, Scatter3DHandlerEvent, StyleOverrides3D, Surface3DConfig } from '../core/types';
6
6
  import * as extras from '@threlte/extras';
7
7
  import type { ComponentProps, Snippet } from 'svelte';
8
8
  import type { HTMLAttributes } from 'svelte/elements';
@@ -72,7 +72,7 @@ declare function $$render<Metadata extends Record<string, unknown> = Record<stri
72
72
  controls_extra?: Snippet;
73
73
  };
74
74
  exports: {};
75
- bindings: "fullscreen" | "hovered" | "camera_position" | "wrapper" | "tooltip_point" | "camera" | "scene" | "orbit_controls";
75
+ bindings: "fullscreen" | "hovered" | "camera_position" | "wrapper" | "camera" | "tooltip_point" | "scene" | "orbit_controls";
76
76
  slots: {};
77
77
  events: {};
78
78
  };
@@ -80,7 +80,7 @@ declare class __sveltets_Render<Metadata extends Record<string, unknown> = Recor
80
80
  props(): ReturnType<typeof $$render<Metadata>>['props'];
81
81
  events(): ReturnType<typeof $$render<Metadata>>['events'];
82
82
  slots(): ReturnType<typeof $$render<Metadata>>['slots'];
83
- bindings(): "fullscreen" | "hovered" | "camera_position" | "wrapper" | "tooltip_point" | "camera" | "scene" | "orbit_controls";
83
+ bindings(): "fullscreen" | "hovered" | "camera_position" | "wrapper" | "camera" | "tooltip_point" | "scene" | "orbit_controls";
84
84
  exports(): {};
85
85
  }
86
86
  interface $$IsomorphicComponent {
@@ -1,19 +1,20 @@
1
1
  <script lang="ts">
2
2
  // NOTE: Axis config objects must be reassigned (not mutated) to trigger $bindable reactivity.
3
3
  // Pattern: `x_axis = { ...x_axis, prop: value }` instead of `x_axis.prop = value`
4
- import { SettingsSection } from '../layout'
5
- import DraggablePane from '../overlays/DraggablePane.svelte'
4
+ import { SettingsSection } from '../../layout'
5
+ import DraggablePane from '../../overlays/DraggablePane.svelte'
6
6
  import type {
7
7
  AxisConfig3D,
8
8
  CameraProjection3D,
9
9
  DataSeries3D,
10
10
  DisplayConfig3D,
11
11
  Surface3DConfig,
12
- } from './types'
12
+ } from '../core/types'
13
+ import { unique_id } from '../core/utils'
13
14
  import type { ComponentProps, Snippet } from 'svelte'
14
15
 
15
16
  // Unique ID prefix to avoid conflicts when multiple instances on same page
16
- const uid = crypto.randomUUID().slice(0, 8)
17
+ const uid = unique_id(`scatter3d-ctrl`)
17
18
 
18
19
  let {
19
20
  show = $bindable(false),
@@ -1,5 +1,5 @@
1
- import DraggablePane from '../overlays/DraggablePane.svelte';
2
- import type { AxisConfig3D, CameraProjection3D, DataSeries3D, DisplayConfig3D, Surface3DConfig } from './types';
1
+ import DraggablePane from '../../overlays/DraggablePane.svelte';
2
+ import type { AxisConfig3D, CameraProjection3D, DataSeries3D, DisplayConfig3D, Surface3DConfig } from '../core/types';
3
3
  import type { ComponentProps, Snippet } from 'svelte';
4
4
  type $$ComponentProps = {
5
5
  show?: boolean;