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