matterviz 0.4.1 → 0.4.2

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 (395) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +75 -85
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  11. package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  13. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
  15. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
  17. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  18. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  19. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  20. package/dist/colors/index.d.ts +0 -4
  21. package/dist/colors/index.js +19 -20
  22. package/dist/composition/BarChart.svelte +37 -31
  23. package/dist/composition/BubbleChart.svelte +17 -17
  24. package/dist/composition/Composition.svelte +7 -11
  25. package/dist/composition/Formula.svelte +18 -25
  26. package/dist/composition/FormulaFilter.svelte +92 -95
  27. package/dist/composition/PieChart.svelte +55 -41
  28. package/dist/composition/format.js +1 -1
  29. package/dist/composition/index.d.ts +2 -0
  30. package/dist/composition/index.js +14 -0
  31. package/dist/composition/parse.d.ts +2 -2
  32. package/dist/composition/parse.js +11 -10
  33. package/dist/constants.js +11 -9
  34. package/dist/convex-hull/ConvexHull.svelte +12 -15
  35. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  36. package/dist/convex-hull/ConvexHull2D.svelte +93 -92
  37. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  38. package/dist/convex-hull/ConvexHull3D.svelte +109 -140
  39. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  40. package/dist/convex-hull/ConvexHull4D.svelte +75 -94
  41. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  42. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  43. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  44. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  45. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  46. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  47. package/dist/convex-hull/StructurePopup.svelte +17 -21
  48. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  49. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  50. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  51. package/dist/convex-hull/helpers.d.ts +8 -10
  52. package/dist/convex-hull/helpers.js +36 -36
  53. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  54. package/dist/convex-hull/thermodynamics.js +18 -17
  55. package/dist/coordination/CoordinationBarPlot.svelte +38 -33
  56. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  57. package/dist/coordination/calc-coordination.d.ts +1 -1
  58. package/dist/coordination/calc-coordination.js +28 -25
  59. package/dist/element/BohrAtom.svelte +5 -8
  60. package/dist/element/ElementHeading.svelte +4 -1
  61. package/dist/element/ElementPhoto.svelte +11 -9
  62. package/dist/element/ElementStats.svelte +12 -10
  63. package/dist/element/ElementTile.svelte +24 -29
  64. package/dist/element/Nucleus.svelte +4 -2
  65. package/dist/element/data.d.ts +1 -2
  66. package/dist/element/helpers.d.ts +4 -0
  67. package/dist/element/helpers.js +18 -0
  68. package/dist/element/index.d.ts +1 -4
  69. package/dist/element/index.js +3 -18
  70. package/dist/feedback/DragOverlay.svelte +5 -5
  71. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  72. package/dist/feedback/StatusMessage.svelte +7 -4
  73. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  74. package/dist/fermi-surface/FermiSurface.svelte +14 -22
  75. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
  76. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  77. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  80. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  81. package/dist/fermi-surface/compute.js +3 -3
  82. package/dist/fermi-surface/parse.js +22 -24
  83. package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
  84. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  85. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  86. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  87. package/dist/heatmap-matrix/index.d.ts +5 -0
  88. package/dist/icons.d.ts +4 -0
  89. package/dist/icons.js +4 -0
  90. package/dist/io/ExportPane.svelte +10 -6
  91. package/dist/io/decompress.d.ts +2 -1
  92. package/dist/io/decompress.js +22 -35
  93. package/dist/io/export.d.ts +4 -0
  94. package/dist/io/export.js +5 -1
  95. package/dist/io/fetch.d.ts +0 -3
  96. package/dist/io/fetch.js +0 -11
  97. package/dist/io/index.d.ts +0 -1
  98. package/dist/io/index.js +2 -9
  99. package/dist/io/is-binary.d.ts +9 -0
  100. package/dist/io/is-binary.js +45 -1
  101. package/dist/io/url-drop.js +13 -25
  102. package/dist/isosurface/Isosurface.svelte +17 -23
  103. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  104. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  105. package/dist/isosurface/parse-vaspwave.js +138 -0
  106. package/dist/isosurface/parse.js +6 -6
  107. package/dist/labels.d.ts +6 -2
  108. package/dist/labels.js +43 -13
  109. package/dist/layout/FullscreenButton.svelte +2 -1
  110. package/dist/layout/FullscreenToggle.svelte +10 -4
  111. package/dist/layout/InfoCard.svelte +7 -18
  112. package/dist/layout/InfoTag.svelte +1 -3
  113. package/dist/layout/NumberRangeInput.svelte +46 -0
  114. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  115. package/dist/layout/PropertyFilter.svelte +2 -6
  116. package/dist/layout/SettingsSection.svelte +21 -17
  117. package/dist/layout/SubpageGrid.svelte +3 -1
  118. package/dist/layout/ViewerChrome.svelte +9 -10
  119. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  120. package/dist/layout/fullscreen.js +3 -5
  121. package/dist/layout/fullscreen.svelte.js +1 -2
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  125. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  126. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  127. package/dist/layout/json-tree/utils.js +14 -23
  128. package/dist/math.d.ts +2 -0
  129. package/dist/math.js +19 -0
  130. package/dist/overlays/ContextMenu.svelte +4 -2
  131. package/dist/overlays/CopyButton.svelte +11 -5
  132. package/dist/overlays/DragControlTab.svelte +6 -1
  133. package/dist/overlays/DraggablePane.svelte +81 -26
  134. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  135. package/dist/overlays/GlassChip.svelte +30 -0
  136. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  137. package/dist/overlays/InfoPaneCards.svelte +11 -23
  138. package/dist/overlays/index.d.ts +7 -0
  139. package/dist/overlays/index.js +26 -0
  140. package/dist/overlays/portal.d.ts +2 -0
  141. package/dist/overlays/portal.js +14 -0
  142. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  143. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  144. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  145. package/dist/periodic-table/TableInset.svelte +9 -4
  146. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  147. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  148. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  149. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  150. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  151. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  152. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  153. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  154. package/dist/phase-diagram/build-diagram.js +3 -3
  155. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  156. package/dist/phase-diagram/parse.js +15 -15
  157. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  158. package/dist/phase-diagram/utils.js +2 -3
  159. package/dist/plot/bar/BarPlot.svelte +430 -391
  160. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  161. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  162. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  163. package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
  164. package/dist/plot/bar/data.d.ts +5 -4
  165. package/dist/plot/bar/data.js +2 -1
  166. package/dist/plot/box/BoxPlot.svelte +301 -209
  167. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  168. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  169. package/dist/plot/box/box-plot.js +1 -1
  170. package/dist/plot/core/auto-place.js +1 -1
  171. package/dist/plot/core/axis-utils.d.ts +12 -7
  172. package/dist/plot/core/axis-utils.js +48 -48
  173. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  174. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  175. package/dist/plot/core/components/ColorBar.svelte +101 -106
  176. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  177. package/dist/plot/core/components/FillArea.svelte +10 -17
  178. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  179. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  180. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  181. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  182. package/dist/plot/core/components/Line.svelte +18 -9
  183. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  184. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  185. package/dist/plot/core/components/PlotControls.svelte +65 -41
  186. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  187. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  188. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  189. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  190. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  191. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  192. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  193. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  194. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  195. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  196. package/dist/plot/core/components/index.d.ts +1 -0
  197. package/dist/plot/core/components/index.js +1 -0
  198. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  199. package/dist/plot/core/data-cleaning-signal.js +467 -0
  200. package/dist/plot/core/data-cleaning.d.ts +2 -42
  201. package/dist/plot/core/data-cleaning.js +27 -474
  202. package/dist/plot/core/data-transform.js +9 -5
  203. package/dist/plot/core/fill-utils.d.ts +3 -1
  204. package/dist/plot/core/fill-utils.js +28 -6
  205. package/dist/plot/core/index.d.ts +1 -0
  206. package/dist/plot/core/index.js +1 -0
  207. package/dist/plot/core/interactions.js +0 -2
  208. package/dist/plot/core/layout.d.ts +3 -1
  209. package/dist/plot/core/layout.js +22 -13
  210. package/dist/plot/core/marginals.d.ts +170 -0
  211. package/dist/plot/core/marginals.js +436 -0
  212. package/dist/plot/core/reference-line.js +1 -1
  213. package/dist/plot/core/scales.d.ts +23 -0
  214. package/dist/plot/core/scales.js +39 -13
  215. package/dist/plot/core/types/fills.d.ts +101 -0
  216. package/dist/plot/core/types/fills.js +15 -0
  217. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  218. package/dist/plot/core/types/plot-3d.js +4 -0
  219. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  220. package/dist/plot/core/types/reference-lines.js +9 -0
  221. package/dist/plot/core/types.d.ts +29 -324
  222. package/dist/plot/core/types.js +23 -20
  223. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  224. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  225. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  226. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  227. package/dist/plot/core/utils/label-placement.js +2 -2
  228. package/dist/plot/histogram/Histogram.svelte +304 -325
  229. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  230. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  231. package/dist/plot/histogram/histogram.d.ts +31 -0
  232. package/dist/plot/histogram/histogram.js +70 -0
  233. package/dist/plot/histogram/index.d.ts +1 -0
  234. package/dist/plot/histogram/index.js +1 -0
  235. package/dist/plot/index.d.ts +1 -0
  236. package/dist/plot/index.js +1 -0
  237. package/dist/plot/sankey/Sankey.svelte +78 -69
  238. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  239. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  240. package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
  241. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  242. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  243. package/dist/plot/scatter/ScatterPlot.svelte +477 -385
  244. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  245. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  246. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  247. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  248. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  249. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  250. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  251. package/dist/plot/scatter/scatter-data.js +8 -7
  252. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  253. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  254. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  255. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  256. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  257. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  258. package/dist/plot/sunburst/Sunburst.svelte +251 -329
  259. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  260. package/dist/plot/sunburst/index.d.ts +1 -1
  261. package/dist/plot/sunburst/index.js +2 -1
  262. package/dist/plot/sunburst/render.d.ts +2 -2
  263. package/dist/plot/sunburst/render.js +47 -22
  264. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  265. package/dist/plot/sunburst/sunburst.js +10 -3
  266. package/dist/plot/treemap/Treemap.svelte +907 -0
  267. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  268. package/dist/plot/treemap/index.d.ts +3 -0
  269. package/dist/plot/treemap/index.js +4 -0
  270. package/dist/plot/treemap/treemap.d.ts +26 -0
  271. package/dist/plot/treemap/treemap.js +99 -0
  272. package/dist/rdf/RdfPlot.svelte +22 -26
  273. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  274. package/dist/rdf/calc-rdf.js +4 -8
  275. package/dist/sanitize.js +1 -1
  276. package/dist/scene/bind-renderer.svelte.js +14 -6
  277. package/dist/settings.d.ts +19 -9
  278. package/dist/settings.js +77 -50
  279. package/dist/spectral/Bands.svelte +223 -230
  280. package/dist/spectral/BandsAndDos.svelte +11 -9
  281. package/dist/spectral/BrillouinBandsDos.svelte +19 -27
  282. package/dist/spectral/Dos.svelte +70 -73
  283. package/dist/spectral/helpers.d.ts +3 -3
  284. package/dist/spectral/helpers.js +25 -35
  285. package/dist/state.svelte.js +5 -18
  286. package/dist/structure/Arrow.svelte +5 -18
  287. package/dist/structure/ArrowInstances.svelte +160 -0
  288. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  289. package/dist/structure/AtomLegend.svelte +115 -75
  290. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  291. package/dist/structure/Bond.svelte +31 -23
  292. package/dist/structure/CanvasTooltip.svelte +15 -3
  293. package/dist/structure/CellSelect.svelte +11 -26
  294. package/dist/structure/Cylinder.svelte +24 -40
  295. package/dist/structure/InstancedAtoms.svelte +114 -0
  296. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  297. package/dist/structure/Lattice.svelte +85 -149
  298. package/dist/structure/SiteLabels.svelte +122 -0
  299. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  300. package/dist/structure/Structure.svelte +473 -419
  301. package/dist/structure/Structure.svelte.d.ts +4 -2
  302. package/dist/structure/StructureCarousel.svelte +630 -0
  303. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  304. package/dist/structure/StructureControls.svelte +157 -399
  305. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  306. package/dist/structure/StructureExportPane.svelte +17 -21
  307. package/dist/structure/StructureInfoPane.svelte +72 -66
  308. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  309. package/dist/structure/StructureScene.svelte +467 -476
  310. package/dist/structure/StructureScene.svelte.d.ts +3 -1
  311. package/dist/structure/StructureViewport.svelte +386 -0
  312. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  313. package/dist/structure/atom-label-placement.d.ts +16 -12
  314. package/dist/structure/atom-label-placement.js +70 -37
  315. package/dist/structure/atom-properties.d.ts +2 -0
  316. package/dist/structure/atom-properties.js +104 -38
  317. package/dist/structure/bonding.d.ts +10 -3
  318. package/dist/structure/bonding.js +84 -28
  319. package/dist/structure/edit-history.d.ts +6 -0
  320. package/dist/structure/edit-history.js +27 -0
  321. package/dist/structure/export.d.ts +1 -0
  322. package/dist/structure/export.js +39 -31
  323. package/dist/structure/format-detect.d.ts +1 -0
  324. package/dist/structure/format-detect.js +22 -0
  325. package/dist/structure/geometry.d.ts +9 -0
  326. package/dist/structure/geometry.js +27 -0
  327. package/dist/structure/index.d.ts +16 -1
  328. package/dist/structure/index.js +13 -2
  329. package/dist/structure/measure.d.ts +1 -1
  330. package/dist/structure/measure.js +6 -12
  331. package/dist/structure/parse.d.ts +2 -1
  332. package/dist/structure/parse.js +243 -222
  333. package/dist/structure/partial-occupancy.js +4 -2
  334. package/dist/structure/pbc.js +78 -98
  335. package/dist/structure/polyhedra.d.ts +0 -1
  336. package/dist/structure/polyhedra.js +3 -18
  337. package/dist/structure/supercell.d.ts +1 -2
  338. package/dist/structure/supercell.js +7 -13
  339. package/dist/symmetry/SymmetryElements.svelte +11 -15
  340. package/dist/symmetry/SymmetryStats.svelte +56 -68
  341. package/dist/symmetry/WyckoffTable.svelte +5 -24
  342. package/dist/symmetry/cell-transform.js +1 -0
  343. package/dist/symmetry/index.d.ts +1 -0
  344. package/dist/symmetry/index.js +8 -2
  345. package/dist/symmetry/spacegroups.js +3 -2
  346. package/dist/table/HeatmapTable.svelte +1102 -365
  347. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  348. package/dist/table/ToggleMenu.svelte +5 -12
  349. package/dist/table/index.d.ts +21 -6
  350. package/dist/table/index.js +34 -21
  351. package/dist/theme/ThemeControl.svelte +16 -8
  352. package/dist/theme/index.d.ts +1 -5
  353. package/dist/theme/index.js +4 -10
  354. package/dist/theme/themes.mjs +14 -7
  355. package/dist/tooltip/KCoords.svelte +4 -1
  356. package/dist/tooltip/TooltipContent.svelte +2 -5
  357. package/dist/trajectory/Trajectory.svelte +515 -308
  358. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  359. package/dist/trajectory/TrajectoryError.svelte +11 -8
  360. package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
  361. package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
  362. package/dist/trajectory/extract.js +56 -34
  363. package/dist/trajectory/format-detect.js +11 -9
  364. package/dist/trajectory/frame-reader.d.ts +2 -0
  365. package/dist/trajectory/frame-reader.js +33 -29
  366. package/dist/trajectory/helpers.d.ts +2 -0
  367. package/dist/trajectory/helpers.js +18 -7
  368. package/dist/trajectory/index.d.ts +1 -0
  369. package/dist/trajectory/index.js +3 -0
  370. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  371. package/dist/trajectory/parse/h5-utils.js +109 -0
  372. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  373. package/dist/trajectory/parse/hdf5.js +116 -106
  374. package/dist/trajectory/parse/index.d.ts +2 -3
  375. package/dist/trajectory/parse/index.js +17 -20
  376. package/dist/trajectory/parse/lammps.js +8 -12
  377. package/dist/trajectory/parse/vasp.js +10 -7
  378. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  379. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  380. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  381. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  382. package/dist/trajectory/parse/xyz.js +11 -7
  383. package/dist/trajectory/plotting.d.ts +8 -9
  384. package/dist/trajectory/plotting.js +99 -27
  385. package/dist/utils.d.ts +3 -0
  386. package/dist/utils.js +7 -0
  387. package/dist/xrd/XrdPlot.svelte +47 -61
  388. package/dist/xrd/broadening.js +2 -1
  389. package/dist/xrd/calc-xrd.js +2 -4
  390. package/dist/xrd/parse.d.ts +0 -1
  391. package/dist/xrd/parse.js +56 -73
  392. package/package.json +61 -33
  393. package/dist/api/mp.d.ts +0 -6
  394. package/dist/api/mp.js +0 -22
  395. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
@@ -13,10 +13,27 @@
13
13
  import { create_pulse_animation } from '../../effects.svelte'
14
14
  import ColorBar from '../core/components/ColorBar.svelte'
15
15
  import PlotAxis from '../core/components/PlotAxis.svelte'
16
+ import PlotMarginals from '../core/components/PlotMarginals.svelte'
16
17
  import PlotTooltip from '../core/components/PlotTooltip.svelte'
17
18
  import ZoomRect from '../core/components/ZoomRect.svelte'
18
- import { compute_element_placement, filter_padding } from '../core/layout'
19
+ import {
20
+ AXIS_TITLE_OFFSET,
21
+ compute_element_placement,
22
+ DEFAULT_PLOT_PADDING,
23
+ filter_padding,
24
+ LABEL_GAP_DEFAULT,
25
+ measure_full_footprint,
26
+ } from '../core/layout'
19
27
  import type { Sides } from '../core/layout'
28
+ import { get_series_color } from '../core/data-transform'
29
+ import type { MarginalSeriesInput, MarginalsProp } from '../core/marginals'
30
+ import {
31
+ add_sides,
32
+ marginal_axis,
33
+ marginal_axis_presence,
34
+ normalize_marginals,
35
+ reserve_marginal_pad,
36
+ } from '../core/marginals'
20
37
  import {
21
38
  build_pick_index,
22
39
  bin_points,
@@ -29,9 +46,29 @@
29
46
  series_extents,
30
47
  should_render_points,
31
48
  } from './adaptive-density'
32
- import type { DensityBin, DenseInternalPoint, DensePointSeries } from './adaptive-density'
33
- import { create_color_scale, create_scale, create_size_scale, generate_ticks } from '../core/scales'
34
- import type { AxisConfig, DataSeries, InternalPoint, ScatterHandlerProps } from '../core/types'
49
+ import type {
50
+ DensityBin,
51
+ DenseInternalPoint,
52
+ DensePointSeries,
53
+ } from './adaptive-density'
54
+ import {
55
+ create_color_scale,
56
+ create_scale,
57
+ create_size_scale,
58
+ generate_ticks,
59
+ } from '../core/scales'
60
+ import type {
61
+ AxisConfig,
62
+ DataSeries,
63
+ InternalPoint,
64
+ ScatterHandlerProps,
65
+ } from '../core/types'
66
+ import {
67
+ COLOR_BAR_DEFAULTS,
68
+ REF_LINE_STYLE_DEFAULTS,
69
+ SCALE_DEFAULTS,
70
+ } from '../core/types'
71
+ import { resolve_line_endpoints } from '../core/reference-line'
35
72
  import {
36
73
  compute_label_positions,
37
74
  estimate_label_size,
@@ -43,7 +80,6 @@
43
80
  import type { HTMLAttributes } from 'svelte/elements'
44
81
  import { SvelteMap, SvelteSet } from 'svelte/reactivity'
45
82
  import type {
46
- BinnedColorScaleConfig,
47
83
  BinnedDensityConfig,
48
84
  BinnedOverlaysConfig,
49
85
  BinnedPointDataFn,
@@ -52,6 +88,7 @@
52
88
  BinnedPointTooltipPayload,
53
89
  BinnedSizeScaleConfig,
54
90
  } from './binned-scatter-types'
91
+ import { DEFAULT_BINNED_SIZE_SCALE } from './binned-scatter-types'
55
92
 
56
93
  type RenderMode = `density` | `points`
57
94
  type DensePointEvent = {
@@ -65,29 +102,15 @@
65
102
  event: MouseEvent
66
103
  }
67
104
  type OverlayContext = { height: number; width: number; fullscreen: boolean }
68
- const default_color_bar_size = { width: 220, height: 10 }
69
105
  const default_density_auto_point_mode = { max_points: 25_000, max_points_per_px: 0.12 }
70
106
  const default_density_color_bar: ComponentProps<typeof ColorBar> = { title: `Density` }
71
- const default_density_color_scale = {
72
- type: `linear`,
73
- scheme: `interpolateViridis`,
74
- } satisfies Exclude<BinnedColorScaleConfig, string>
75
- const default_pad = { l: 64, r: 24, t: 24, b: 56 }
76
- const default_point_radius_range: Vec2 = [4, 12]
77
- const default_pick_radius = default_point_radius_range[1]
78
- const default_size_scale = {
79
- type: `linear`,
80
- radius_range: default_point_radius_range,
81
- pick_radius: default_pick_radius,
82
- } satisfies BinnedSizeScaleConfig
83
107
  const max_placement_bins = 500
84
- const default_point_color = `#4dabf7`
85
108
 
86
109
  let {
87
110
  series,
88
111
  x_axis = {},
89
112
  y_axis = {},
90
- size_scale = default_size_scale,
113
+ size_scale = DEFAULT_BINNED_SIZE_SCALE,
91
114
  density: density_config = {},
92
115
  overlays: overlays_config = {},
93
116
  padding: padding_config = {},
@@ -103,6 +126,8 @@
103
126
  fullscreen_toggle = true,
104
127
  children,
105
128
  header_controls,
129
+ annotation,
130
+ marginals = false,
106
131
  ...rest
107
132
  }: Omit<HTMLAttributes<HTMLDivElement>, `children`> & {
108
133
  series: DensePointSeries<Metadata>[]
@@ -124,6 +149,10 @@
124
149
  fullscreen_toggle?: boolean
125
150
  children?: Snippet<[OverlayContext]>
126
151
  header_controls?: Snippet<[OverlayContext]>
152
+ // auto-placed badge (e.g. MAE/R² stats): rendered inside the plot area wherever it
153
+ // overlaps the least data, while also avoiding the auto-placed colorbar
154
+ annotation?: Snippet<[OverlayContext]>
155
+ marginals?: MarginalsProp
127
156
  } = $props()
128
157
 
129
158
  let canvas = $state<HTMLCanvasElement>()
@@ -139,21 +168,77 @@
139
168
  let hovered_point = $state<DenseInternalPoint<Metadata> | null>(null)
140
169
  let tooltip_pos = $state<Point2D>({ x: 0, y: 0 })
141
170
  let colorbar_element = $state<HTMLDivElement>()
171
+ let annotation_element = $state<HTMLDivElement>()
142
172
  let label_measure_root = $state<HTMLDivElement>()
143
173
  let label_sizes = new SvelteMap<string, LabelSize>()
144
174
  const clip_path_id = `binned-scatter-plot-area-${next_clip_id++}`
145
175
 
146
- let pad = $derived(filter_padding(padding_config, default_pad))
176
+ const resolved_marginals = $derived(
177
+ normalize_marginals(marginals, { top: true, right: true }),
178
+ )
179
+ // Unlike the other 2D plots this one doesn't auto-grow padding for tick labels, so this
180
+ // shared default is its final pad (merged with any user `padding`), not just a floor.
181
+ let pad = $derived(
182
+ add_sides(
183
+ filter_padding(padding_config, DEFAULT_PLOT_PADDING),
184
+ reserve_marginal_pad(resolved_marginals),
185
+ ),
186
+ )
187
+ const marginal_series = $derived<MarginalSeriesInput[]>(
188
+ series.map((srs, idx) => ({
189
+ x: srs.x,
190
+ y: srs.y,
191
+ color: srs.color ?? get_series_color(idx),
192
+ label: srs.label,
193
+ visible: true,
194
+ })),
195
+ )
196
+ const marginal_has_axis = marginal_axis_presence(false, false)
147
197
  let density_settings = $derived({
148
198
  bin_px: density_config.bin_px ?? 2.8,
149
- color_scale: density_config.color_scale ?? default_density_color_scale,
150
- color_bar: density_config.color_bar === undefined ? default_density_color_bar : density_config.color_bar,
151
- auto_point_mode: density_config.auto_point_mode === undefined
152
- ? default_density_auto_point_mode
153
- : density_config.auto_point_mode,
199
+ color_scale: density_config.color_scale ?? SCALE_DEFAULTS.color,
200
+ color_bar:
201
+ density_config.color_bar === undefined
202
+ ? default_density_color_bar
203
+ : density_config.color_bar,
204
+ auto_point_mode:
205
+ density_config.auto_point_mode === undefined
206
+ ? default_density_auto_point_mode
207
+ : density_config.auto_point_mode,
154
208
  bin_click: density_config.bin_click ?? `zoom`,
155
209
  })
156
- let ref_lines = $derived(overlays_config.ref_lines ?? [])
210
+ // pixel-space endpoints + style per ref line. Declarative RefLine entries (with a
211
+ // `type` field) are resolved against the current axis ranges via the shared core
212
+ // resolver, so e.g. a parity diagonal spans the full plot area and stays correct
213
+ // under zoom; legacy explicit-endpoint entries are scaled as-is (clip path crops
214
+ // out-of-range parts). Annotation/legend/interaction RefLine fields are ignored.
215
+ let resolved_ref_lines = $derived.by(() => {
216
+ const [x_min, x_max] = range_bounds(x_range)
217
+ const [y_min, y_max] = range_bounds(y_range)
218
+ return (overlays_config.ref_lines ?? []).flatMap((line) => {
219
+ if (!(`type` in line)) {
220
+ return {
221
+ x1: x_scale_fn(line.x1),
222
+ y1: y_scale_fn(line.y1),
223
+ x2: x_scale_fn(line.x2),
224
+ y2: y_scale_fn(line.y2),
225
+ color: line.color ?? `currentColor`,
226
+ width: line.width ?? 1.5,
227
+ dash: line.dash ?? `5 4`,
228
+ opacity: 1,
229
+ }
230
+ }
231
+ if (line.visible === false) return []
232
+ const endpoints = resolve_line_endpoints(
233
+ line,
234
+ { x_min, x_max, y_min, y_max },
235
+ { x_scale: x_scale_fn, y_scale: y_scale_fn },
236
+ )
237
+ if (!endpoints) return []
238
+ const [x1, y1, x2, y2] = endpoints
239
+ return { x1, y1, x2, y2, ...REF_LINE_STYLE_DEFAULTS, ...line.style }
240
+ })
241
+ })
157
242
  let point_labels_settings = $derived({
158
243
  font_size: point_labels.font_size ?? `11px`,
159
244
  max_count: point_labels.max_count ?? 50,
@@ -217,14 +302,8 @@
217
302
  width: plot_width,
218
303
  height: plot_height,
219
304
  })
220
- let x_scale_fn = $derived(create_scale(x_scale_type, x_range, [
221
- pad.l,
222
- width - pad.r,
223
- ]))
224
- let y_scale_fn = $derived(create_scale(y_scale_type, y_range, [
225
- height - pad.b,
226
- pad.t,
227
- ]))
305
+ let x_scale_fn = $derived(create_scale(x_scale_type, x_range, [pad.l, width - pad.r]))
306
+ let y_scale_fn = $derived(create_scale(y_scale_type, y_range, [height - pad.b, pad.t]))
228
307
  let x_ticks = $derived(
229
308
  generate_ticks(x_range, x_scale_type, x_axis.ticks, x_scale_fn, {
230
309
  default_count: 7,
@@ -251,10 +330,14 @@
251
330
  const bin_at = (coords: Point2D) =>
252
331
  density_bin_at_point(density_result, coords, plot_rect, x_range, y_range, bin_transforms)
253
332
  let auto_color_range = $derived<Vec2>([1, Math.max(1, density_result.max_count)])
254
- let color_scale_fn = $derived(create_color_scale(density_settings.color_scale, auto_color_range))
333
+ let color_scale_fn = $derived(
334
+ create_color_scale(density_settings.color_scale, auto_color_range),
335
+ )
255
336
  let hovered_bin_color = $derived(hovered_bin ? color_scale_fn(hovered_bin.count) : undefined)
256
337
  let color_scale_type = $derived(
257
- typeof density_settings.color_scale === `string` ? undefined : density_settings.color_scale.type,
338
+ typeof density_settings.color_scale === `string`
339
+ ? undefined
340
+ : density_settings.color_scale.type,
258
341
  )
259
342
  let color_bar_props = $derived.by((): ComponentProps<typeof ColorBar> | null => {
260
343
  const color_bar = density_settings.color_bar
@@ -266,8 +349,9 @@
266
349
  tick_format: color_bar.tick_format ?? `.2~s`,
267
350
  tick_labels: color_bar.tick_labels ?? 4,
268
351
  tick_side: color_bar.tick_side ?? `primary`,
269
- bar_style: color_bar.bar_style ??
270
- `width: ${default_color_bar_size.width}px; height: ${default_color_bar_size.height}px; ${color_bar.style ?? ``}`,
352
+ bar_style:
353
+ color_bar.bar_style ??
354
+ `width: ${COLOR_BAR_DEFAULTS.width}px; height: ${COLOR_BAR_DEFAULTS.binned_bar_height}px; ${color_bar.style ?? ``}`,
271
355
  }
272
356
  })
273
357
  let density_placement_points = $derived.by(() => {
@@ -275,8 +359,8 @@
275
359
  const bin_w = plot_width / density_result.x_bins
276
360
  const bin_h = plot_height / density_result.y_bins
277
361
  let occupied_count = 0
278
- for (let idx = 0; idx < density_result.counts.length; idx++) {
279
- if (density_result.counts[idx]) occupied_count++
362
+ for (const count of density_result.counts) {
363
+ if (count) occupied_count++
280
364
  }
281
365
  const stride = Math.max(1, Math.ceil(occupied_count / max_placement_bins))
282
366
  let occupied_idx = 0
@@ -292,6 +376,13 @@
292
376
  }
293
377
  return points
294
378
  })
379
+ // Fallback sizes (incl. room for tick labels) used before the colorbar first
380
+ // renders; compute_element_placement measures the real footprint once laid out
381
+ let colorbar_fallback_size = $derived(
382
+ color_bar_props?.orientation === `vertical`
383
+ ? COLOR_BAR_DEFAULTS.vertical_footprint
384
+ : COLOR_BAR_DEFAULTS.horizontal_footprint,
385
+ )
295
386
  let color_bar_placement = $derived.by(() => {
296
387
  if (
297
388
  !color_bar_props ||
@@ -303,17 +394,10 @@
303
394
  return null
304
395
  }
305
396
 
306
- const is_vertical = color_bar_props?.orientation === `vertical`
307
- // Fallback sizes (incl. room for tick labels) used before the colorbar first
308
- // renders; compute_element_placement measures the real footprint once laid out
309
- const fallback_size = is_vertical
310
- ? { width: 56, height: 120 }
311
- : { width: default_color_bar_size.width, height: 50 }
312
-
313
397
  return compute_element_placement({
314
398
  plot_bounds: plot_rect,
315
399
  element: colorbar_element,
316
- element_size: fallback_size,
400
+ element_size: colorbar_fallback_size,
317
401
  // Small gap from the corner; the full-footprint measurement reserves the tick
318
402
  // labels, so this alone keeps the colorbar off the axes
319
403
  axis_clearance: 12,
@@ -321,16 +405,41 @@
321
405
  grid_resolution: 12,
322
406
  })
323
407
  })
408
+ // Fallback footprint before the annotation snippet first renders; the real
409
+ // footprint is measured once laid out (mirrors colorbar_fallback_size above)
410
+ const annotation_fallback_size = { width: 120, height: 50 }
411
+ // Auto-place the annotation snippet like the colorbar, but with the already-placed
412
+ // colorbar's footprint as an exclusion zone so the two never overlap.
413
+ let annotation_placement = $derived.by(() => {
414
+ if (!annotation || !width || !height) return null
415
+
416
+ const colorbar_rect = color_bar_placement && {
417
+ ...(colorbar_element?.offsetWidth && colorbar_element?.offsetHeight
418
+ ? measure_full_footprint(colorbar_element)
419
+ : colorbar_fallback_size),
420
+ x: color_bar_placement.x,
421
+ y: color_bar_placement.y,
422
+ }
423
+ return compute_element_placement({
424
+ plot_bounds: plot_rect,
425
+ element: annotation_element,
426
+ element_size: annotation_fallback_size,
427
+ axis_clearance: 12,
428
+ exclude_rects: colorbar_rect ? [colorbar_rect] : [],
429
+ points: density_placement_points,
430
+ grid_resolution: 12,
431
+ })
432
+ })
324
433
 
325
434
  let auto_render_mode = $derived.by((): RenderMode => {
326
435
  const auto_point_mode = density_settings.auto_point_mode
327
436
  if (auto_point_mode === false) return render_mode
328
437
  return should_render_points(
329
- density_result.visible_count,
330
- plot_width * plot_height,
331
- auto_point_mode.max_points ?? default_density_auto_point_mode.max_points,
332
- auto_point_mode.max_points_per_px ?? default_density_auto_point_mode.max_points_per_px,
333
- )
438
+ density_result.visible_count,
439
+ plot_width * plot_height,
440
+ auto_point_mode.max_points ?? default_density_auto_point_mode.max_points,
441
+ auto_point_mode.max_points_per_px ?? default_density_auto_point_mode.max_points_per_px,
442
+ )
334
443
  ? `points`
335
444
  : `density`
336
445
  })
@@ -338,8 +447,7 @@
338
447
  const values: number[] = []
339
448
  for (const srs of series) {
340
449
  if (!srs.size_values) continue
341
- for (let idx = 0; idx < srs.size_values.length; idx++) {
342
- const size_value = srs.size_values[idx]
450
+ for (const size_value of Array.from(srs.size_values)) {
343
451
  if (size_value == null || !Number.isFinite(size_value)) continue
344
452
  values.push(size_value)
345
453
  }
@@ -347,12 +455,16 @@
347
455
  return values
348
456
  })
349
457
  let size_scale_fn = $derived(create_size_scale(size_scale, all_size_values))
350
- let min_point_radius = $derived(size_scale.radius_range?.[0] ?? default_point_radius_range[0])
351
- let max_point_radius = $derived(size_scale.radius_range?.[1] ?? default_point_radius_range[1])
458
+ let min_point_radius = $derived(
459
+ size_scale.radius_range?.[0] ?? SCALE_DEFAULTS.binned_radius[0],
460
+ )
461
+ let max_point_radius = $derived(
462
+ size_scale.radius_range?.[1] ?? SCALE_DEFAULTS.binned_radius[1],
463
+ )
352
464
  let pick_radius_px = $derived(
353
465
  size_scale.pick_radius === `auto`
354
466
  ? max_point_radius
355
- : size_scale.pick_radius ?? default_pick_radius,
467
+ : (size_scale.pick_radius ?? SCALE_DEFAULTS.binned_radius[1]),
356
468
  )
357
469
 
358
470
  $effect(() => {
@@ -411,7 +523,10 @@
411
523
  if (!style) {
412
524
  style = {
413
525
  fill: color_scale_fn(count),
414
- alpha: Math.min(0.95, 0.2 + Math.log1p(count) / Math.log1p(density_result.max_count)),
526
+ alpha: Math.min(
527
+ 0.95,
528
+ 0.2 + Math.log1p(count) / Math.log1p(density_result.max_count),
529
+ ),
415
530
  }
416
531
  style_cache.set(count, style)
417
532
  }
@@ -433,7 +548,7 @@
433
548
  const [y_min, y_max] = range_bounds(y_range)
434
549
  const pulse = selected_pulse.unit
435
550
  for (const [series_idx, srs] of series.entries()) {
436
- ctx.fillStyle = srs.color ?? default_point_color
551
+ ctx.fillStyle = srs.color ?? get_series_color(series_idx)
437
552
  const n_points = Math.min(srs.x.length, srs.y.length)
438
553
  for (let point_idx = 0; point_idx < n_points; point_idx++) {
439
554
  const x = srs.x[point_idx]
@@ -453,7 +568,7 @@
453
568
  ctx.fill()
454
569
  if (is_selected) {
455
570
  ctx.globalAlpha = 0.35 + 0.25 * pulse
456
- ctx.strokeStyle = srs.color ?? default_point_color
571
+ ctx.strokeStyle = srs.color ?? get_series_color(series_idx)
457
572
  ctx.lineWidth = 1.5 + pulse
458
573
  ctx.beginPath()
459
574
  ctx.arc(cx, cy, radius * (1.45 + 0.25 * pulse), 0, 2 * Math.PI)
@@ -514,7 +629,7 @@
514
629
  })
515
630
 
516
631
  const point_color = (point: DenseInternalPoint<Metadata>): string =>
517
- series[point.series_idx]?.color ?? default_point_color
632
+ series[point.series_idx]?.color ?? get_series_color(point.series_idx)
518
633
 
519
634
  const point_label_key = (point: DenseInternalPoint<Metadata>): string =>
520
635
  `${point.series_idx}-${point.point_idx}`
@@ -554,7 +669,7 @@
554
669
  payload: BinnedPointPayload<Metadata, PointData>,
555
670
  ): LabelSize =>
556
671
  label_sizes.get(point_label_key(payload.point)) ??
557
- estimate_label_size(label_measure_text(payload), point_labels_settings.font_size)
672
+ estimate_label_size(label_measure_text(payload), point_labels_settings.font_size)
558
673
 
559
674
  let point_label_payloads = $derived.by(() => {
560
675
  if (!point_labels_settings.render || render_mode !== `points`) return []
@@ -575,7 +690,8 @@
575
690
  x > x_max ||
576
691
  y < y_min ||
577
692
  y > y_max
578
- ) continue
693
+ )
694
+ continue
579
695
  payloads.push(point_payload(make_point(series_idx, point_idx)))
580
696
  if (payloads.length > point_labels_settings.max_count) return []
581
697
  }
@@ -586,20 +702,19 @@
586
702
  let point_label_positions = $derived.by(() => {
587
703
  if (point_label_payloads.length === 0) return {}
588
704
 
589
- const filtered_data: InternalPoint<Metadata>[] = point_label_payloads.map(
590
- (payload) => ({
591
- ...payload.point,
592
- point_label: {
593
- text: label_measure_text(payload),
594
- auto_placement: true,
595
- font_size: point_labels_settings.font_size,
596
- size: label_sizes.get(point_label_key(payload.point)),
597
- },
598
- point_style: {
599
- radius: point_radius_for_value(payload.point.size_value) + point_labels_settings.gap_px,
600
- },
601
- }),
602
- )
705
+ const filtered_data: InternalPoint<Metadata>[] = point_label_payloads.map((payload) => ({
706
+ ...payload.point,
707
+ point_label: {
708
+ text: label_measure_text(payload),
709
+ auto_placement: true,
710
+ font_size: point_labels_settings.font_size,
711
+ size: label_sizes.get(point_label_key(payload.point)),
712
+ },
713
+ point_style: {
714
+ radius:
715
+ point_radius_for_value(payload.point.size_value) + point_labels_settings.gap_px,
716
+ },
717
+ }))
603
718
  const label_series: DataSeries<Metadata>[] = [{ x: [], y: [], filtered_data }]
604
719
 
605
720
  return compute_label_positions(
@@ -615,7 +730,8 @@
615
730
  if (!label_measure_root) return
616
731
 
617
732
  const active_keys = new SvelteSet<string>()
618
- const measured_elements = label_measure_root.querySelectorAll<HTMLElement>(`[data-label-key]`)
733
+ const measured_elements =
734
+ label_measure_root.querySelectorAll<HTMLElement>(`[data-label-key]`)
619
735
  for (const element of measured_elements) {
620
736
  const label_key = element.dataset.labelKey
621
737
  if (!label_key) continue
@@ -641,7 +757,10 @@
641
757
  payload: BinnedPointPayload<Metadata, PointData>,
642
758
  label_position: Point2D,
643
759
  ): { x1: number; y1: number; x2: number; y2: number } | null {
644
- const displacement = Math.hypot(label_position.x - payload.cx, label_position.y - payload.cy)
760
+ const displacement = Math.hypot(
761
+ label_position.x - payload.cx,
762
+ label_position.y - payload.cy,
763
+ )
645
764
  if (displacement <= (actual_label_placement_config.leader_line_threshold ?? 15)) {
646
765
  return null
647
766
  }
@@ -670,7 +789,8 @@
670
789
  hovered_bin?.x_bin !== bin?.x_bin ||
671
790
  hovered_bin?.y_bin !== bin?.y_bin ||
672
791
  hovered_bin?.count !== bin?.count
673
- ) hovered_bin = bin
792
+ )
793
+ hovered_bin = bin
674
794
  return
675
795
  }
676
796
 
@@ -679,7 +799,8 @@
679
799
  if (
680
800
  hovered_point?.series_idx !== point?.series_idx ||
681
801
  hovered_point?.point_idx !== point?.point_idx
682
- ) hovered_point = point
802
+ )
803
+ hovered_point = point
683
804
  }
684
805
 
685
806
  function emit_point_click(
@@ -720,13 +841,7 @@
720
841
  }
721
842
  if (bin.count > 1 && density_settings.bin_click !== `point`) return
722
843
 
723
- const point = first_point_in_bin(
724
- series,
725
- density_result,
726
- bin,
727
- x_scale_fn,
728
- y_scale_fn,
729
- )
844
+ const point = first_point_in_bin(series, density_result, bin, x_scale_fn, y_scale_fn)
730
845
  if (point) emit_point_click(point, event, color_scale_fn(bin.count))
731
846
  return
732
847
  }
@@ -801,7 +916,7 @@
801
916
  <div
802
917
  {...rest}
803
918
  bind:this={wrapper}
804
- class="binned-scatter {rest.class ?? ``}"
919
+ class={[`binned-scatter`, rest.class]}
805
920
  class:fullscreen
806
921
  data-render-mode={render_mode}
807
922
  style:--binned-scatter-label-font-size={point_labels_settings.font_size}
@@ -841,7 +956,7 @@
841
956
 
842
957
  <canvas bind:this={canvas}></canvas>
843
958
 
844
- <svg width={width} height={height} aria-hidden="true">
959
+ <svg {width} {height} aria-hidden="true">
845
960
  <defs>
846
961
  <clipPath id={clip_path_id}>
847
962
  <rect x={pad.l} y={pad.t} width={plot_width} height={plot_height} />
@@ -849,15 +964,16 @@
849
964
  </defs>
850
965
 
851
966
  <g class="reference-lines" clip-path="url(#{clip_path_id})">
852
- {#each ref_lines as line}
967
+ {#each resolved_ref_lines as line}
853
968
  <line
854
- x1={x_scale_fn(line.x1)}
855
- x2={x_scale_fn(line.x2)}
856
- y1={y_scale_fn(line.y1)}
857
- y2={y_scale_fn(line.y2)}
858
- stroke={line.color ?? `currentColor`}
859
- stroke-width={line.width ?? 1.5}
860
- stroke-dasharray={line.dash ?? `5 4`}
969
+ x1={line.x1}
970
+ x2={line.x2}
971
+ y1={line.y1}
972
+ y2={line.y2}
973
+ stroke={line.color}
974
+ stroke-width={line.width}
975
+ stroke-dasharray={line.dash || null}
976
+ stroke-opacity={line.opacity}
861
977
  />
862
978
  {/each}
863
979
  </g>
@@ -872,7 +988,7 @@
872
988
  show_grid
873
989
  tick_label={(tick) => format_value(tick, x_axis.format ?? `.2~g`)}
874
990
  label_x={pad.l + plot_width / 2}
875
- label_y={height - 12}
991
+ label_y={height - pad.b + AXIS_TITLE_OFFSET}
876
992
  />
877
993
  <PlotAxis
878
994
  side="y"
@@ -884,7 +1000,7 @@
884
1000
  {height}
885
1001
  show_grid
886
1002
  tick_label={(tick) => format_value(tick, y_axis.format ?? `.2~g`)}
887
- label_x={22}
1003
+ label_x={Math.max(12, pad.l - LABEL_GAP_DEFAULT)}
888
1004
  label_y={pad.t + plot_height / 2}
889
1005
  />
890
1006
 
@@ -894,7 +1010,9 @@
894
1010
  <g class="point-label-leaders" clip-path="url(#{clip_path_id})">
895
1011
  {#each point_label_payloads as payload (point_label_key(payload.point))}
896
1012
  {@const label_position = point_label_positions[point_label_key(payload.point)]}
897
- {@const leader_line = label_position ? label_leader_line(payload, label_position) : null}
1013
+ {@const leader_line = label_position
1014
+ ? label_leader_line(payload, label_position)
1015
+ : null}
898
1016
  {#if leader_line}
899
1017
  <line
900
1018
  x1={leader_line.x1}
@@ -906,6 +1024,21 @@
906
1024
  {/each}
907
1025
  </g>
908
1026
  {/if}
1027
+
1028
+ <!-- Marginal distribution strips -->
1029
+ <PlotMarginals
1030
+ marginals={resolved_marginals}
1031
+ series={marginal_series}
1032
+ {width}
1033
+ {height}
1034
+ {pad}
1035
+ has_axis={marginal_has_axis}
1036
+ axes={{
1037
+ x1: marginal_axis(x_scale_fn, x_range, x_axis),
1038
+ y1: marginal_axis(y_scale_fn, y_range, y_axis),
1039
+ }}
1040
+ id={clip_path_id}
1041
+ />
909
1042
  </svg>
910
1043
 
911
1044
  {#if point_labels_settings.render && point_label_payloads.length}
@@ -947,13 +1080,24 @@
947
1080
  >
948
1081
  <ColorBar
949
1082
  {...color_bar_props}
950
- color_scale_fn={color_scale_fn}
1083
+ {color_scale_fn}
951
1084
  color_scale_domain={auto_color_range}
952
1085
  range={auto_color_range}
953
1086
  />
954
1087
  </div>
955
1088
  {/if}
956
1089
 
1090
+ {#if annotation && annotation_placement}
1091
+ <div
1092
+ bind:this={annotation_element}
1093
+ class="annotation"
1094
+ style:left={`${annotation_placement.x}px`}
1095
+ style:top={`${annotation_placement.y}px`}
1096
+ >
1097
+ {@render annotation({ height, width, fullscreen })}
1098
+ </div>
1099
+ {/if}
1100
+
957
1101
  {#if hovered_bin}
958
1102
  <PlotTooltip
959
1103
  x={tooltip_pos.x}
@@ -961,9 +1105,9 @@
961
1105
  offset={{ x: 0, y: 0 }}
962
1106
  bg_color={hovered_bin_color}
963
1107
  >
964
- {hovered_bin.count.toLocaleString()} samples<br>
1108
+ {hovered_bin.count.toLocaleString()} samples<br />
965
1109
  x: {format_value(hovered_bin.x_range[0], x_axis.format ?? `.3~g`)}
966
- - {format_value(hovered_bin.x_range[1], x_axis.format ?? `.3~g`)}<br>
1110
+ - {format_value(hovered_bin.x_range[1], x_axis.format ?? `.3~g`)}<br />
967
1111
  y: {format_value(hovered_bin.y_range[0], y_axis.format ?? `.3~g`)}
968
1112
  - {format_value(hovered_bin.y_range[1], y_axis.format ?? `.3~g`)}
969
1113
  </PlotTooltip>
@@ -973,7 +1117,7 @@
973
1117
  {#if tooltip}
974
1118
  {@render tooltip(props)}
975
1119
  {:else}
976
- {x_axis.label ?? `x`}: {props.x_formatted}<br>
1120
+ {x_axis.label ?? `x`}: {props.x_formatted}<br />
977
1121
  {y_axis.label ?? `y`}: {props.y_formatted}
978
1122
  {/if}
979
1123
  </PlotTooltip>
@@ -1029,7 +1173,9 @@
1029
1173
  position: absolute;
1030
1174
  right: var(--fullscreen-btn-right, 4px);
1031
1175
  top: var(--ctrl-btn-top, 5pt);
1032
- transition: opacity 0.2s, background-color 0.2s;
1176
+ transition:
1177
+ opacity 0.2s,
1178
+ background-color 0.2s;
1033
1179
  z-index: var(--fullscreen-btn-z-index, 10);
1034
1180
  }
1035
1181
  .header-controls :global(.fullscreen-toggle) {
@@ -1069,7 +1215,10 @@
1069
1215
  opacity: 0.75;
1070
1216
  }
1071
1217
  .point-label-leaders line {
1072
- stroke: var(--binned-scatter-label-leader-color, color-mix(in srgb, currentColor 60%, transparent));
1218
+ stroke: var(
1219
+ --binned-scatter-label-leader-color,
1220
+ color-mix(in srgb, currentColor 60%, transparent)
1221
+ );
1073
1222
  stroke-dasharray: var(--binned-scatter-label-leader-dash, 2 2);
1074
1223
  stroke-width: var(--binned-scatter-label-leader-width, 0.8);
1075
1224
  }
@@ -1111,4 +1260,9 @@
1111
1260
  pointer-events: auto;
1112
1261
  position: absolute;
1113
1262
  }
1263
+ .annotation {
1264
+ pointer-events: none;
1265
+ position: absolute;
1266
+ width: max-content;
1267
+ }
1114
1268
  </style>