matterviz 0.3.7 → 0.4.1

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 (486) hide show
  1. package/dist/Icon.svelte +7 -4
  2. package/dist/MillerIndexInput.svelte +1 -1
  3. package/dist/api/optimade.js +32 -26
  4. package/dist/app.css +0 -3
  5. package/dist/brillouin/BrillouinZone.svelte +76 -148
  6. package/dist/brillouin/BrillouinZone.svelte.d.ts +6 -14
  7. package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
  8. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  11. package/dist/brillouin/BrillouinZoneScene.svelte +97 -205
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +4 -23
  13. package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
  14. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  15. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  16. package/dist/brillouin/compute.d.ts +2 -0
  17. package/dist/brillouin/compute.js +89 -90
  18. package/dist/brillouin/geometry.d.ts +8 -0
  19. package/dist/brillouin/geometry.js +57 -0
  20. package/dist/brillouin/index.d.ts +2 -0
  21. package/dist/brillouin/index.js +2 -0
  22. package/dist/brillouin/types.d.ts +2 -2
  23. package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  25. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +109 -203
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  27. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +180 -470
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  29. package/dist/chempot-diagram/async-compute.svelte.js +3 -1
  30. package/dist/chempot-diagram/chempot-worker.js +2 -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 +4 -4
  34. package/dist/chempot-diagram/compute.js +20 -20
  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.js +8 -7
  45. package/dist/composition/FormulaFilter.svelte +18 -11
  46. package/dist/composition/PieChart.svelte +11 -10
  47. package/dist/composition/chem-sys.d.ts +8 -0
  48. package/dist/composition/chem-sys.js +86 -0
  49. package/dist/composition/format.js +7 -4
  50. package/dist/composition/index.d.ts +1 -0
  51. package/dist/composition/index.js +1 -0
  52. package/dist/composition/parse.d.ts +0 -1
  53. package/dist/composition/parse.js +41 -31
  54. package/dist/controls.d.ts +1 -0
  55. package/dist/controls.js +0 -1
  56. package/dist/convex-hull/ConvexHull.svelte +8 -10
  57. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  58. package/dist/convex-hull/ConvexHull2D.svelte +106 -185
  59. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  60. package/dist/convex-hull/ConvexHull3D.svelte +179 -683
  61. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  62. package/dist/convex-hull/ConvexHull4D.svelte +183 -687
  63. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  64. package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
  65. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  66. package/dist/convex-hull/ConvexHullControls.svelte +88 -7
  67. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  68. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  69. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  70. package/dist/convex-hull/ConvexHullStats.svelte +36 -175
  71. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  72. package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
  73. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  74. package/dist/convex-hull/GasPressureControls.svelte +4 -4
  75. package/dist/convex-hull/TemperatureSlider.svelte +2 -2
  76. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  77. package/dist/convex-hull/barycentric-coords.js +6 -33
  78. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  79. package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
  80. package/dist/convex-hull/demo-temperature.d.ts +1 -1
  81. package/dist/convex-hull/demo-temperature.js +20 -22
  82. package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
  83. package/dist/convex-hull/gas-thermodynamics.js +22 -30
  84. package/dist/convex-hull/helpers.d.ts +42 -7
  85. package/dist/convex-hull/helpers.js +171 -78
  86. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  87. package/dist/convex-hull/hull-state.svelte.js +124 -0
  88. package/dist/convex-hull/index.d.ts +10 -8
  89. package/dist/convex-hull/index.js +7 -2
  90. package/dist/convex-hull/thermodynamics.js +136 -960
  91. package/dist/convex-hull/types.d.ts +13 -5
  92. package/dist/convex-hull/types.js +12 -0
  93. package/dist/coordination/CoordinationBarPlot.svelte +27 -34
  94. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  95. package/dist/element/BohrAtom.svelte +2 -1
  96. package/dist/element/index.d.ts +4 -0
  97. package/dist/element/index.js +18 -0
  98. package/dist/feedback/DragOverlay.svelte +3 -1
  99. package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
  100. package/dist/feedback/StatusMessage.svelte +13 -3
  101. package/dist/fermi-surface/FermiSlice.svelte +13 -5
  102. package/dist/fermi-surface/FermiSurface.svelte +78 -151
  103. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
  104. package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
  105. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  106. package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -221
  107. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  108. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
  109. package/dist/fermi-surface/compute.js +67 -66
  110. package/dist/fermi-surface/export.js +6 -16
  111. package/dist/fermi-surface/index.d.ts +0 -1
  112. package/dist/fermi-surface/index.js +0 -1
  113. package/dist/fermi-surface/parse.d.ts +1 -1
  114. package/dist/fermi-surface/parse.js +71 -79
  115. package/dist/fermi-surface/types.d.ts +3 -2
  116. package/dist/heatmap-matrix/HeatmapMatrix.svelte +69 -52
  117. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
  118. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
  119. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  120. package/dist/heatmap-matrix/index.d.ts +3 -2
  121. package/dist/heatmap-matrix/index.js +1 -1
  122. package/dist/index.d.ts +1 -0
  123. package/dist/index.js +1 -0
  124. package/dist/io/ExportPane.svelte +166 -0
  125. package/dist/io/ExportPane.svelte.d.ts +17 -0
  126. package/dist/io/decompress.js +5 -4
  127. package/dist/io/export.d.ts +9 -5
  128. package/dist/io/export.js +77 -51
  129. package/dist/io/fetch.d.ts +2 -1
  130. package/dist/io/fetch.js +5 -1
  131. package/dist/io/file-drop.d.ts +8 -1
  132. package/dist/io/file-drop.js +48 -36
  133. package/dist/io/index.d.ts +2 -0
  134. package/dist/io/index.js +10 -0
  135. package/dist/io/types.d.ts +13 -0
  136. package/dist/io/url-drop.js +64 -33
  137. package/dist/isosurface/parse.js +52 -51
  138. package/dist/isosurface/slice.js +5 -4
  139. package/dist/isosurface/types.js +1 -1
  140. package/dist/keyboard.d.ts +3 -0
  141. package/dist/keyboard.js +23 -0
  142. package/dist/labels.d.ts +1 -1
  143. package/dist/labels.js +9 -8
  144. package/dist/layout/FullscreenButton.svelte +33 -0
  145. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  146. package/dist/layout/FullscreenToggle.svelte +8 -14
  147. package/dist/layout/PropertyFilter.svelte +3 -2
  148. package/dist/layout/SettingsSection.svelte +1 -1
  149. package/dist/layout/ViewerChrome.svelte +116 -0
  150. package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
  151. package/dist/layout/fullscreen.d.ts +4 -0
  152. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  153. package/dist/layout/fullscreen.svelte.js +37 -0
  154. package/dist/layout/index.d.ts +3 -0
  155. package/dist/layout/index.js +3 -0
  156. package/dist/layout/json-tree/JsonNode.svelte +1 -1
  157. package/dist/layout/json-tree/JsonTree.svelte +2 -2
  158. package/dist/layout/json-tree/utils.js +5 -4
  159. package/dist/marching-cubes.js +8 -13
  160. package/dist/math.d.ts +12 -4
  161. package/dist/math.js +42 -30
  162. package/dist/overlays/DraggablePane.svelte +4 -4
  163. package/dist/overlays/index.d.ts +4 -0
  164. package/dist/periodic-table/PeriodicTable.svelte +27 -15
  165. package/dist/periodic-table/PropertySelect.svelte +1 -0
  166. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
  167. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  168. package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
  169. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  170. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  171. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  172. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
  173. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  174. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
  175. package/dist/phase-diagram/build-diagram.js +2 -2
  176. package/dist/phase-diagram/colors.js +1 -1
  177. package/dist/phase-diagram/parse.d.ts +2 -1
  178. package/dist/phase-diagram/parse.js +6 -5
  179. package/dist/phase-diagram/types.d.ts +1 -1
  180. package/dist/phase-diagram/utils.d.ts +3 -3
  181. package/dist/phase-diagram/utils.js +8 -12
  182. package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +246 -841
  183. package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +8 -16
  184. package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
  185. package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
  186. package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +8 -7
  187. package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
  188. package/dist/plot/bar/data.d.ts +40 -0
  189. package/dist/plot/bar/data.js +154 -0
  190. package/dist/plot/bar/geometry.d.ts +39 -0
  191. package/dist/plot/bar/geometry.js +60 -0
  192. package/dist/plot/bar/index.d.ts +3 -0
  193. package/dist/plot/bar/index.js +3 -0
  194. package/dist/plot/box/BoxPlot.svelte +1292 -0
  195. package/dist/plot/box/BoxPlot.svelte.d.ts +95 -0
  196. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  197. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  198. package/dist/plot/box/Violin.svelte +14 -0
  199. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  200. package/dist/plot/box/box-plot.d.ts +56 -0
  201. package/dist/plot/box/box-plot.js +129 -0
  202. package/dist/plot/box/index.d.ts +5 -0
  203. package/dist/plot/box/index.js +5 -0
  204. package/dist/plot/box/kde.d.ts +17 -0
  205. package/dist/plot/box/kde.js +160 -0
  206. package/dist/plot/box/quantile.d.ts +3 -0
  207. package/dist/plot/box/quantile.js +53 -0
  208. package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +1 -1
  209. package/dist/plot/{auto-place.js → core/auto-place.js} +6 -3
  210. package/dist/plot/core/axis-utils.d.ts +46 -0
  211. package/dist/plot/core/axis-utils.js +110 -0
  212. package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
  213. package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
  214. package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +41 -38
  215. package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +7 -6
  216. package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
  217. package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
  218. package/dist/plot/core/components/ControlPane.svelte +46 -0
  219. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  220. package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
  221. package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
  222. package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
  223. package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
  224. package/dist/plot/{Line.svelte → core/components/Line.svelte} +33 -15
  225. package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +3 -2
  226. package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +9 -6
  227. package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +5 -3
  228. package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
  229. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  230. package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
  231. package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
  232. package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
  233. package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
  234. package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
  235. package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
  236. package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
  237. package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +5 -5
  238. package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +5 -5
  239. package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +8 -8
  240. package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +5 -5
  241. package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
  242. package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
  243. package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
  244. package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
  245. package/dist/plot/core/components/index.d.ts +17 -0
  246. package/dist/plot/core/components/index.js +17 -0
  247. package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
  248. package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +21 -23
  249. package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
  250. package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
  251. package/dist/plot/core/fill-utils.d.ts +34 -0
  252. package/dist/plot/core/fill-utils.js +391 -0
  253. package/dist/plot/core/index.d.ts +10 -0
  254. package/dist/plot/core/index.js +11 -0
  255. package/dist/plot/core/interactions.d.ts +39 -0
  256. package/dist/plot/core/interactions.js +209 -0
  257. package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
  258. package/dist/plot/{layout.js → core/layout.js} +16 -8
  259. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  260. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  261. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  262. package/dist/plot/core/placed-tween.svelte.js +68 -0
  263. package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +11 -11
  264. package/dist/plot/{reference-line.js → core/reference-line.js} +29 -42
  265. package/dist/plot/core/scales.d.ts +40 -0
  266. package/dist/plot/{scales.js → core/scales.js} +94 -93
  267. package/dist/plot/core/svg.d.ts +3 -0
  268. package/dist/plot/core/svg.js +41 -0
  269. package/dist/plot/{types.d.ts → core/types.d.ts} +36 -85
  270. package/dist/plot/{types.js → core/types.js} +1 -1
  271. package/dist/plot/{utils → core/utils}/label-placement.d.ts +3 -3
  272. package/dist/plot/{utils → core/utils}/label-placement.js +3 -3
  273. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  274. package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
  275. package/dist/plot/core/utils.d.ts +12 -0
  276. package/dist/plot/core/utils.js +27 -0
  277. package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +174 -551
  278. package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
  279. package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
  280. package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
  281. package/dist/plot/histogram/index.d.ts +2 -0
  282. package/dist/plot/histogram/index.js +2 -0
  283. package/dist/plot/index.d.ts +8 -41
  284. package/dist/plot/index.js +10 -39
  285. package/dist/plot/sankey/Sankey.svelte +697 -0
  286. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  287. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  288. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  289. package/dist/plot/sankey/index.d.ts +4 -0
  290. package/dist/plot/sankey/index.js +3 -0
  291. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  292. package/dist/plot/sankey/sankey-types.js +4 -0
  293. package/dist/plot/sankey/sankey.d.ts +52 -0
  294. package/dist/plot/sankey/sankey.js +189 -0
  295. package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +64 -64
  296. package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +6 -6
  297. package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
  298. package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
  299. package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +297 -1008
  300. package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +10 -18
  301. package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
  302. package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +2 -2
  303. package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
  304. package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
  305. package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
  306. package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
  307. package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +5 -12
  308. package/dist/plot/scatter/index.d.ts +7 -0
  309. package/dist/plot/scatter/index.js +5 -0
  310. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  311. package/dist/plot/scatter/scatter-data.js +212 -0
  312. package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +25 -34
  313. package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +9 -17
  314. package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +14 -14
  315. package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +6 -6
  316. package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +129 -128
  317. package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +6 -15
  318. package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +7 -6
  319. package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +5 -4
  320. package/dist/plot/scatter-3d/index.d.ts +4 -0
  321. package/dist/plot/scatter-3d/index.js +4 -0
  322. package/dist/plot/sunburst/Sunburst.svelte +1041 -0
  323. package/dist/plot/sunburst/Sunburst.svelte.d.ts +97 -0
  324. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  325. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  326. package/dist/plot/sunburst/index.d.ts +4 -0
  327. package/dist/plot/sunburst/index.js +4 -0
  328. package/dist/plot/sunburst/render.d.ts +34 -0
  329. package/dist/plot/sunburst/render.js +122 -0
  330. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  331. package/dist/plot/sunburst/sunburst.js +269 -0
  332. package/dist/rdf/RdfPlot.svelte +2 -1
  333. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  334. package/dist/rdf/calc-rdf.js +11 -24
  335. package/dist/sanitize.js +14 -3
  336. package/dist/scene/SceneCamera.svelte +62 -0
  337. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  338. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  339. package/dist/scene/bind-renderer.svelte.js +14 -0
  340. package/dist/scene/index.d.ts +4 -0
  341. package/dist/scene/index.js +5 -0
  342. package/dist/scene/props.js +52 -0
  343. package/dist/scene/types.d.ts +26 -0
  344. package/dist/scene/types.js +1 -0
  345. package/dist/settings.d.ts +79 -3
  346. package/dist/settings.js +321 -1
  347. package/dist/spectral/Bands.svelte +47 -36
  348. package/dist/spectral/Bands.svelte.d.ts +6 -6
  349. package/dist/spectral/BandsAndDos.svelte +23 -25
  350. package/dist/spectral/BrillouinBandsDos.svelte +42 -30
  351. package/dist/spectral/Dos.svelte +15 -23
  352. package/dist/spectral/Dos.svelte.d.ts +4 -3
  353. package/dist/spectral/helpers.d.ts +8 -6
  354. package/dist/spectral/helpers.js +137 -65
  355. package/dist/state.svelte.d.ts +0 -7
  356. package/dist/state.svelte.js +0 -6
  357. package/dist/structure/Arrow.svelte +2 -4
  358. package/dist/structure/AtomLegend.svelte +8 -9
  359. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  360. package/dist/structure/CanvasTooltip.svelte +1 -0
  361. package/dist/structure/CellSelect.svelte +12 -5
  362. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  363. package/dist/structure/Cylinder.svelte +12 -8
  364. package/dist/structure/Cylinder.svelte.d.ts +4 -1
  365. package/dist/structure/Lattice.svelte +2 -2
  366. package/dist/structure/Structure.svelte +365 -423
  367. package/dist/structure/Structure.svelte.d.ts +5 -15
  368. package/dist/structure/StructureControls.svelte +217 -2
  369. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  370. package/dist/structure/StructureExportPane.svelte +54 -156
  371. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  372. package/dist/structure/StructureInfoPane.svelte +10 -9
  373. package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
  374. package/dist/structure/StructureScene.svelte +376 -208
  375. package/dist/structure/StructureScene.svelte.d.ts +22 -20
  376. package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
  377. package/dist/structure/{label-placement.js → atom-label-placement.js} +15 -5
  378. package/dist/structure/atom-properties.d.ts +1 -1
  379. package/dist/structure/atom-properties.js +17 -22
  380. package/dist/structure/bond-order-perception.js +3 -5
  381. package/dist/structure/bonding.d.ts +4 -0
  382. package/dist/structure/bonding.js +134 -63
  383. package/dist/structure/export.d.ts +24 -4
  384. package/dist/structure/export.js +89 -143
  385. package/dist/structure/index.d.ts +4 -4
  386. package/dist/structure/index.js +3 -3
  387. package/dist/structure/measure.d.ts +3 -2
  388. package/dist/structure/measure.js +6 -5
  389. package/dist/structure/parse.d.ts +3 -2
  390. package/dist/structure/parse.js +419 -438
  391. package/dist/structure/partial-occupancy.d.ts +0 -1
  392. package/dist/structure/partial-occupancy.js +1 -1
  393. package/dist/structure/pbc.d.ts +1 -1
  394. package/dist/structure/pbc.js +190 -13
  395. package/dist/structure/polyhedra.d.ts +41 -0
  396. package/dist/structure/polyhedra.js +602 -0
  397. package/dist/structure/site.d.ts +4 -0
  398. package/dist/structure/site.js +1 -0
  399. package/dist/structure/supercell.js +3 -2
  400. package/dist/structure/validation.js +5 -6
  401. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  402. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  403. package/dist/symmetry/SymmetryElements.svelte +354 -0
  404. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  405. package/dist/symmetry/SymmetryStats.svelte +113 -8
  406. package/dist/symmetry/WyckoffTable.svelte +68 -7
  407. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  408. package/dist/symmetry/cell-transform.js +7 -14
  409. package/dist/symmetry/index.d.ts +14 -4
  410. package/dist/symmetry/index.js +291 -72
  411. package/dist/symmetry/spacegroups.d.ts +12 -1
  412. package/dist/symmetry/spacegroups.js +63 -14
  413. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  414. package/dist/symmetry/symmetry-elements.js +521 -0
  415. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  416. package/dist/symmetry/wyckoff-db.js +87 -0
  417. package/dist/table/HeatmapTable.svelte +66 -25
  418. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  419. package/dist/table/index.d.ts +1 -3
  420. package/dist/table/index.js +1 -1
  421. package/dist/theme/index.js +8 -8
  422. package/dist/tooltip/KCoords.svelte +45 -0
  423. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  424. package/dist/tooltip/index.d.ts +1 -0
  425. package/dist/tooltip/index.js +1 -0
  426. package/dist/trajectory/Trajectory.svelte +123 -100
  427. package/dist/trajectory/Trajectory.svelte.d.ts +11 -22
  428. package/dist/trajectory/TrajectoryExportPane.svelte +17 -25
  429. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  430. package/dist/trajectory/TrajectoryInfoPane.svelte +5 -3
  431. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  432. package/dist/trajectory/constants.js +6 -2
  433. package/dist/trajectory/extract.js +17 -37
  434. package/dist/trajectory/format-detect.d.ts +1 -1
  435. package/dist/trajectory/format-detect.js +27 -19
  436. package/dist/trajectory/frame-reader.d.ts +0 -1
  437. package/dist/trajectory/frame-reader.js +63 -162
  438. package/dist/trajectory/helpers.d.ts +10 -2
  439. package/dist/trajectory/helpers.js +56 -36
  440. package/dist/trajectory/index.js +1 -1
  441. package/dist/trajectory/parse/ase.d.ts +9 -1
  442. package/dist/trajectory/parse/ase.js +47 -32
  443. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  444. package/dist/trajectory/parse/diagnostics.js +14 -0
  445. package/dist/trajectory/parse/hdf5.js +1 -1
  446. package/dist/trajectory/parse/index.d.ts +1 -1
  447. package/dist/trajectory/parse/index.js +65 -105
  448. package/dist/trajectory/parse/lammps.d.ts +0 -2
  449. package/dist/trajectory/parse/lammps.js +8 -6
  450. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  451. package/dist/trajectory/parse/pymatgen.js +74 -0
  452. package/dist/trajectory/parse/vasp.js +38 -18
  453. package/dist/trajectory/parse/xyz.d.ts +13 -1
  454. package/dist/trajectory/parse/xyz.js +102 -94
  455. package/dist/trajectory/plotting.d.ts +1 -2
  456. package/dist/trajectory/plotting.js +16 -113
  457. package/dist/utils.d.ts +2 -0
  458. package/dist/utils.js +7 -5
  459. package/dist/xrd/XrdPlot.svelte +16 -30
  460. package/dist/xrd/broadening.d.ts +2 -1
  461. package/dist/xrd/calc-xrd.js +18 -20
  462. package/dist/xrd/index.d.ts +2 -2
  463. package/dist/xrd/parse.js +2 -2
  464. package/package.json +43 -26
  465. package/dist/element/data.json +0 -11864
  466. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  467. package/dist/fermi-surface/marching-cubes.js +0 -2
  468. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  469. package/dist/plot/axis-utils.d.ts +0 -19
  470. package/dist/plot/axis-utils.js +0 -78
  471. package/dist/plot/defaults.d.ts +0 -19
  472. package/dist/plot/defaults.js +0 -9
  473. package/dist/plot/fill-utils.d.ts +0 -46
  474. package/dist/plot/fill-utils.js +0 -322
  475. package/dist/plot/hover-lock.svelte.d.ts +0 -14
  476. package/dist/plot/hover-lock.svelte.js +0 -46
  477. package/dist/plot/interactions.d.ts +0 -12
  478. package/dist/plot/interactions.js +0 -101
  479. package/dist/plot/scales.d.ts +0 -48
  480. package/dist/plot/svg.d.ts +0 -1
  481. package/dist/plot/svg.js +0 -11
  482. package/dist/plot/utils/series-visibility.d.ts +0 -15
  483. package/dist/plot/utils.d.ts +0 -1
  484. package/dist/plot/utils.js +0 -14
  485. /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
  486. /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
@@ -1,11 +1,11 @@
1
1
  <script lang="ts">
2
2
  import type { D3InterpolateName } from '../colors'
3
- import { is_color, pick_contrast_color } from '../colors'
3
+ import { get_d3_interpolator, is_color, pick_contrast_color } from '../colors'
4
4
  import { format_num } from '../labels'
5
+ import type { Vec2 } from '../math'
5
6
  import type { AxisConfig } from '../plot'
6
- import ColorBar from '../plot/ColorBar.svelte'
7
- import { make_change_detector } from '../utils'
8
- import * as d3_sc from 'd3-scale-chromatic'
7
+ import ColorBar from '../plot/core/components/ColorBar.svelte'
8
+ import { quickselect } from '../plot/box/quantile'
9
9
  import { type ComponentProps, onDestroy, onMount, type Snippet } from 'svelte'
10
10
  import type { HTMLAttributes } from 'svelte/elements'
11
11
  import { SvelteMap, SvelteSet } from 'svelte/reactivity'
@@ -127,7 +127,7 @@
127
127
  ) => number | null
128
128
  normalize?: NormalizeMode
129
129
  domain_mode?: DomainMode
130
- quantile_clip?: [number, number]
130
+ quantile_clip?: Vec2
131
131
  show_legend?: boolean
132
132
  legend_position?: LegendPosition
133
133
  legend_label?: string
@@ -146,8 +146,8 @@
146
146
  oncontextmenu?: (cell: CellContext, event: MouseEvent) => void
147
147
  enable_brush?: boolean
148
148
  onbrush?: (payload: {
149
- x_range: [number, number]
150
- y_range: [number, number]
149
+ x_range: Vec2
150
+ y_range: Vec2
151
151
  cells: CellContext[]
152
152
  }) => void
153
153
  tile_size?: string
@@ -213,7 +213,6 @@
213
213
  // === Value resolution ===
214
214
  let x_keys = $derived(x_items.map((item) => item.key ?? item.label))
215
215
  let y_keys = $derived(y_items.map((item) => item.key ?? item.label))
216
- let interaction_axis_signature = $derived(JSON.stringify([x_keys, y_keys]))
217
216
  let highlight_x_key_set = $derived(new SvelteSet(highlight_x_keys))
218
217
  let highlight_y_key_set = $derived(new SvelteSet(highlight_y_keys))
219
218
  let search_query_norm = $derived(search_query.trim().toLowerCase())
@@ -290,11 +289,23 @@
290
289
 
291
290
  const col_has_data = Array(x_items.length).fill(false)
292
291
  const row_has_data = Array(y_items.length).fill(false)
292
+ // Early-exit: skip cells whose row+col are already non-empty, stop once all resolved (dense matrices touch ~n+m cells, not n*m)
293
+ let unknown_cols = x_items.length
294
+ let unknown_rows = y_items.length
293
295
  for (let y_idx = 0; y_idx < y_items.length; y_idx++) {
296
+ if (unknown_cols === 0 && unknown_rows === 0) break
294
297
  for (let x_idx = 0; x_idx < x_items.length; x_idx++) {
295
- if (get_value(x_idx, y_idx) !== null) {
298
+ if (row_has_data[y_idx] && col_has_data[x_idx]) continue
299
+ // ignore cells hidden by symmetric rendering so emptiness reflects only visible cells
300
+ if (is_hidden_cell(x_idx, y_idx)) continue
301
+ if (get_value(x_idx, y_idx) === null) continue
302
+ if (!col_has_data[x_idx]) {
296
303
  col_has_data[x_idx] = true
304
+ unknown_cols--
305
+ }
306
+ if (!row_has_data[y_idx]) {
297
307
  row_has_data[y_idx] = true
308
+ unknown_rows--
298
309
  }
299
310
  }
300
311
  }
@@ -313,11 +324,9 @@
313
324
  })
314
325
 
315
326
  // === Color computation ===
316
- let color_scale_fn = $derived.by(() => {
317
- if (typeof color_scale === `function`) return color_scale
318
- const named_scale = d3_sc[color_scale]
319
- return typeof named_scale === `function` ? named_scale : d3_sc.interpolateViridis
320
- })
327
+ let color_scale_fn = $derived(
328
+ typeof color_scale === `function` ? color_scale : get_d3_interpolator(color_scale),
329
+ )
321
330
 
322
331
  function get_transformed_value(x_idx: number, y_idx: number): number | null {
323
332
  const raw_value = get_value(x_idx, y_idx)
@@ -333,49 +342,53 @@
333
342
  return transformed_value
334
343
  }
335
344
 
336
- function get_quantile(sorted_values: number[], quantile: number): number {
337
- if (!sorted_values.length) return 0
345
+ // Interpolated quantile via quickselect (O(n) avg vs full sort); reorders `scratch_values` in place so callers must pass a copy they own
346
+ function get_quantile(scratch_values: number[], quantile: number): number {
347
+ if (scratch_values.length === 0) return 0
338
348
  const clipped_quantile = Math.max(0, Math.min(1, quantile))
339
- const float_idx = (sorted_values.length - 1) * clipped_quantile
349
+ const float_idx = (scratch_values.length - 1) * clipped_quantile
340
350
  const low_idx = Math.floor(float_idx)
341
351
  const high_idx = Math.ceil(float_idx)
342
- if (low_idx === high_idx) return sorted_values[low_idx]
352
+ const low_val = quickselect(scratch_values, low_idx)
353
+ if (low_idx === high_idx) return low_val
354
+ const high_val = quickselect(scratch_values, high_idx)
343
355
  const low_weight = high_idx - float_idx
344
356
  const high_weight = float_idx - low_idx
345
- return sorted_values[low_idx] * low_weight + sorted_values[high_idx] * high_weight
357
+ return low_val * low_weight + high_val * high_weight
346
358
  }
347
359
 
348
- let valid_numeric_values = $derived.by(() => {
360
+ // Single pass collecting transformed values + min/max (avoids spreading large arrays into
361
+ // Math.min/max). min_pos is the log-mode lower bound when domain min <= 0 (the old
362
+ // Number.MIN_VALUE floor gave log_min ~ -744, squashing all colors to the top)
363
+ let { valid_numeric_values, auto_min, auto_max, min_pos } = $derived.by(() => {
349
364
  const numeric_values: number[] = []
365
+ let [min, max, pos] = [Infinity, -Infinity, Infinity]
350
366
  for (let y_idx = 0; y_idx < y_items.length; y_idx++) {
351
367
  for (let x_idx = 0; x_idx < x_items.length; x_idx++) {
352
368
  if (is_hidden_cell(x_idx, y_idx)) continue
353
369
  const value = get_transformed_value(x_idx, y_idx)
354
370
  if (value === null) continue
355
371
  numeric_values.push(value)
372
+ if (value < min) min = value
373
+ if (value > max) max = value
374
+ if (value > 0 && value < pos) pos = value
356
375
  }
357
376
  }
358
- return numeric_values
359
- })
360
-
361
- // Single-pass min/max to avoid spreading large arrays into Math.min/max
362
- let [auto_min, auto_max] = $derived.by(() => {
363
- let [min, max] = [Infinity, -Infinity]
364
- for (const value of valid_numeric_values) {
365
- if (value < min) min = value
366
- if (value > max) max = value
377
+ return {
378
+ valid_numeric_values: numeric_values,
379
+ auto_min: min <= max ? min : 0,
380
+ auto_max: min <= max ? max : 1,
381
+ min_pos: Number.isFinite(pos) ? pos : null,
367
382
  }
368
- return min <= max ? [min, max] as const : [0, 1] as const
369
383
  })
370
384
 
385
+ // Lazy derived: only evaluated while domain_mode === 'robust' reads it
371
386
  let [robust_min, robust_max] = $derived.by(() => {
372
- if (!valid_numeric_values.length) return [0, 1] as const
373
- const sorted_values = valid_numeric_values.toSorted((value_a, value_b) =>
374
- value_a - value_b
375
- )
387
+ if (valid_numeric_values.length === 0) return [0, 1] as const
388
+ const scratch = [...valid_numeric_values]
376
389
  const [q_low, q_high] = quantile_clip
377
- const clipped_min = get_quantile(sorted_values, q_low)
378
- const clipped_max = get_quantile(sorted_values, q_high)
390
+ const clipped_min = get_quantile(scratch, q_low)
391
+ const clipped_max = get_quantile(scratch, q_high)
379
392
  return clipped_min <= clipped_max
380
393
  ? [clipped_min, clipped_max] as const
381
394
  : [clipped_max, clipped_min] as const
@@ -418,7 +431,7 @@
418
431
  const lower_bound = Math.min(cs_min, cs_max)
419
432
  const upper_bound = Math.max(cs_min, cs_max)
420
433
  if (upper_bound <= 0) return missing_color || null
421
- const safe_lower_bound = Math.max(lower_bound, Number.MIN_VALUE)
434
+ const safe_lower_bound = lower_bound > 0 ? lower_bound : (min_pos ?? upper_bound)
422
435
  const safe_value = Math.max(val, safe_lower_bound)
423
436
  const log_min = Math.log(safe_lower_bound)
424
437
  const log_max = Math.log(upper_bound)
@@ -460,7 +473,7 @@
460
473
  return colors
461
474
  })
462
475
 
463
- const to_contrast_colors = (bg_values: Array<string | null>): Array<string | null> =>
476
+ const to_contrast_colors = (bg_values: (string | null)[]): (string | null)[] =>
464
477
  bg_values.map((bg_color) =>
465
478
  bg_color ? pick_contrast_color({ bg_color }) : null
466
479
  )
@@ -481,16 +494,14 @@
481
494
  bg_flat[get_flat_idx(x_idx, y_idx)]
482
495
 
483
496
  // === Cell context builder (only called for clicks, not per-hover) ===
484
- function build_cell_context(x_idx: number, y_idx: number): CellContext {
485
- return {
486
- x_item: x_items[x_idx],
487
- y_item: y_items[y_idx],
488
- x_idx,
489
- y_idx,
490
- value: get_value(x_idx, y_idx),
491
- bg_color: get_bg(x_idx, y_idx),
492
- }
493
- }
497
+ const build_cell_context = (x_idx: number, y_idx: number): CellContext => ({
498
+ x_item: x_items[x_idx],
499
+ y_item: y_items[y_idx],
500
+ x_idx,
501
+ y_idx,
502
+ value: get_value(x_idx, y_idx),
503
+ bg_color: get_bg(x_idx, y_idx),
504
+ })
494
505
 
495
506
  // === Fully imperative hover management ===
496
507
  // ZERO $state writes during mouseover — all DOM updates are direct.
@@ -777,7 +788,7 @@
777
788
  cell_pos_key(pos.x_idx, pos.y_idx) === clicked_key
778
789
  )
779
790
  const toggle_mode = selection_mode === `multi` && (event.metaKey || event.ctrlKey)
780
- if (existing_idx >= 0 && toggle_mode) next_cells.splice(existing_idx, 1)
791
+ if (existing_idx !== -1 && toggle_mode) next_cells.splice(existing_idx, 1)
781
792
  else if (selection_mode === `multi` && toggle_mode) next_cells.push(clicked_cell)
782
793
  else next_cells.splice(0, next_cells.length, clicked_cell)
783
794
  selected_cells = next_cells
@@ -1012,7 +1023,7 @@
1012
1023
  }
1013
1024
 
1014
1025
  function compute_summary(summary_values: number[]): number | null {
1015
- if (!summary_values.length) return null
1026
+ if (summary_values.length === 0) return null
1016
1027
  if (summary_fn) return summary_fn(summary_values)
1017
1028
  const total = summary_values.reduce((sum, value) => sum + value, 0)
1018
1029
  return total / summary_values.length
@@ -1087,9 +1098,15 @@
1087
1098
 
1088
1099
  // Tooltip state: only used for custom tooltip snippets (function tooltips)
1089
1100
  let tooltip_cell: CellContext | null = $state(null)
1090
- const axis_changed = make_change_detector()
1101
+ // Reset interactions when axis keys change; element-wise compare beats JSON.stringify-ing every key on each x_items/y_items update
1102
+ const keys_equal = (keys_a: string[], keys_b: string[]): boolean =>
1103
+ keys_a.length === keys_b.length && keys_a.every((key, idx) => key === keys_b[idx])
1104
+ let prev_axis_keys: { x: string[]; y: string[] } | null = null
1091
1105
  $effect(() => {
1092
- if (!axis_changed(interaction_axis_signature)) return
1106
+ const changed = prev_axis_keys !== null &&
1107
+ !(keys_equal(x_keys, prev_axis_keys.x) && keys_equal(y_keys, prev_axis_keys.y))
1108
+ prev_axis_keys = { x: x_keys, y: y_keys }
1109
+ if (!changed) return
1093
1110
  cancel_raf(active_cell_raf)
1094
1111
  // Cancel delayed clicks before old cell coordinates can fire on new axes.
1095
1112
  clear_pending_click()
@@ -1,4 +1,5 @@
1
1
  import type { D3InterpolateName } from '../colors';
2
+ import type { Vec2 } from '../math';
2
3
  import type { AxisConfig } from '../plot';
3
4
  import { type ComponentProps, type Snippet } from 'svelte';
4
5
  import type { HTMLAttributes } from 'svelte/elements';
@@ -29,7 +30,7 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclick` | `ondblc
29
30
  }) => number | null;
30
31
  normalize?: NormalizeMode;
31
32
  domain_mode?: DomainMode;
32
- quantile_clip?: [number, number];
33
+ quantile_clip?: Vec2;
33
34
  show_legend?: boolean;
34
35
  legend_position?: LegendPosition;
35
36
  legend_label?: string;
@@ -51,8 +52,8 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclick` | `ondblc
51
52
  oncontextmenu?: (cell: CellContext, event: MouseEvent) => void;
52
53
  enable_brush?: boolean;
53
54
  onbrush?: (payload: {
54
- x_range: [number, number];
55
- y_range: [number, number];
55
+ x_range: Vec2;
56
+ y_range: Vec2;
56
57
  cells: CellContext[];
57
58
  }) => void;
58
59
  tile_size?: string;
@@ -1,4 +1,5 @@
1
1
  <script lang="ts">
2
+ import type { PaneProps, PaneToggleProps } from '../overlays'
2
3
  import DraggablePane from '../overlays/DraggablePane.svelte'
3
4
  import type { ComponentProps, Snippet } from 'svelte'
4
5
  import {
@@ -46,8 +47,8 @@
46
47
  export_formats?: HeatmapExportFormat[]
47
48
  onexport?: (format: HeatmapExportFormat) => void
48
49
  show_pane?: boolean
49
- pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`]
50
- toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`]
50
+ pane_props?: PaneProps
51
+ toggle_props?: PaneToggleProps
51
52
  children?: Snippet<[{ controls_open: boolean }]>
52
53
  } = $props()
53
54
 
@@ -1,5 +1,5 @@
1
- import DraggablePane from '../overlays/DraggablePane.svelte';
2
- import type { ComponentProps, Snippet } from 'svelte';
1
+ import type { PaneProps, PaneToggleProps } from '../overlays';
2
+ import type { Snippet } from 'svelte';
3
3
  import type { ElementAxisOrderingKey, DomainMode, HeatmapExportFormat, LegendPosition, NormalizeMode, SymmetricMode } from './index';
4
4
  type $$ComponentProps = {
5
5
  ordering?: ElementAxisOrderingKey;
@@ -19,12 +19,12 @@ type $$ComponentProps = {
19
19
  export_formats?: HeatmapExportFormat[];
20
20
  onexport?: (format: HeatmapExportFormat) => void;
21
21
  show_pane?: boolean;
22
- pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`];
23
- toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`];
22
+ pane_props?: PaneProps;
23
+ toggle_props?: PaneToggleProps;
24
24
  children?: Snippet<[{
25
25
  controls_open: boolean;
26
26
  }]>;
27
27
  };
28
- declare const HeatmapMatrixControls: import("svelte").Component<$$ComponentProps, {}, "normalize" | "theme" | "show_legend" | "controls_open" | "show_values" | "ordering" | "toggle_visible" | "domain_mode" | "legend_position" | "search_query" | "symmetric" | "show_row_summaries" | "show_col_summaries">;
28
+ declare const HeatmapMatrixControls: import("svelte").Component<$$ComponentProps, {}, "normalize" | "show_values" | "show_legend" | "controls_open" | "ordering" | "theme" | "toggle_visible" | "domain_mode" | "legend_position" | "search_query" | "symmetric" | "show_row_summaries" | "show_col_summaries">;
29
29
  type HeatmapMatrixControls = ReturnType<typeof HeatmapMatrixControls>;
30
30
  export default HeatmapMatrixControls;
@@ -1,4 +1,5 @@
1
1
  import type { ChemicalElement, ElementSymbol } from '../element';
2
+ import type { Vec2 } from '../math';
2
3
  import type { Snippet } from 'svelte';
3
4
  export { COLOR_OVERRIDE_KEY_SEPARATOR, make_color_override_key } from './shared';
4
5
  export type AxisItem<T = Record<string, unknown>> = {
@@ -41,8 +42,8 @@ export type HeatmapSelection = {
41
42
  };
42
43
  export type HeatmapExportFormat = `csv` | `json`;
43
44
  export type HeatmapBrushPayload = {
44
- x_range: [number, number];
45
- y_range: [number, number];
45
+ x_range: Vec2;
46
+ y_range: Vec2;
46
47
  cells: CellContext[];
47
48
  };
48
49
  export declare const ELEMENT_ORDERINGS: ElementAxisOrderingKey[];
@@ -40,7 +40,7 @@ function escape_csv_field(value) {
40
40
  return `"${field.replaceAll(`"`, `""`)}"`;
41
41
  }
42
42
  export function rows_to_csv(rows) {
43
- if (!rows.length)
43
+ if (rows.length === 0)
44
44
  return ``;
45
45
  const headers = Object.keys(rows[0]);
46
46
  const lines = [
package/dist/index.d.ts CHANGED
@@ -27,6 +27,7 @@ export * from './phase-diagram';
27
27
  export * from './plot';
28
28
  export * from './rdf';
29
29
  export * from './sanitize';
30
+ export * from './scene';
30
31
  export * from './settings';
31
32
  export * from './spectral';
32
33
  export * from './structure';
package/dist/index.js CHANGED
@@ -27,6 +27,7 @@ export * from './phase-diagram';
27
27
  export * from './plot';
28
28
  export * from './rdf';
29
29
  export * from './sanitize';
30
+ export * from './scene';
30
31
  export * from './settings';
31
32
  export * from './spectral';
32
33
  export * from './structure';
@@ -0,0 +1,166 @@
1
+ <script lang="ts">
2
+ import type { PaneProps, PaneToggleProps } from '../overlays'
3
+ import type { ExportItem, ExportSection } from './types'
4
+ import DraggablePane from '../overlays/DraggablePane.svelte'
5
+ import { sanitize_html } from '../sanitize'
6
+ import { type ComponentProps, onDestroy, type Snippet } from 'svelte'
7
+ import { tooltip } from 'svelte-multiselect/attachments'
8
+ import type { HTMLAttributes } from 'svelte/elements'
9
+
10
+ let {
11
+ export_pane_open = $bindable(false),
12
+ sections = [],
13
+ png_dpi = $bindable(150),
14
+ dpi_range = [50, 600],
15
+ icon_style = ``,
16
+ toggle_props = {},
17
+ pane_props = {},
18
+ children = undefined,
19
+ ...rest
20
+ }: HTMLAttributes<HTMLDivElement> & {
21
+ export_pane_open?: boolean
22
+ sections?: ExportSection[]
23
+ png_dpi?: number
24
+ dpi_range?: readonly [number, number]
25
+ icon_style?: string
26
+ toggle_props?: PaneToggleProps
27
+ pane_props?: PaneProps
28
+ // Pane-specific extras rendered below the sections (e.g. video export controls)
29
+ children?: Snippet
30
+ } = $props()
31
+
32
+ // Clamp DPI into dpi_range on input change (fires on blur, before any download click)
33
+ function clamp_dpi(): void {
34
+ const [min_dpi, max_dpi] = dpi_range
35
+ if (typeof png_dpi !== `number` || !Number.isFinite(png_dpi)) png_dpi = 150
36
+ else png_dpi = Math.round(Math.min(max_dpi, Math.max(min_dpi, png_dpi)))
37
+ }
38
+
39
+ // Copy-to-clipboard with temporary ✅ feedback; copy_text runs only on click
40
+ let copied_key = $state<string | null>(null)
41
+ let copied_timeout: ReturnType<typeof setTimeout> | undefined
42
+ async function handle_copy(item: ExportItem, key: string): Promise<void> {
43
+ if (item.disabled) return
44
+ const text = item.copy_text?.()
45
+ if (!text) return
46
+ try {
47
+ await navigator.clipboard.writeText(text)
48
+ copied_key = key
49
+ clearTimeout(copied_timeout)
50
+ copied_timeout = setTimeout(() => (copied_key = null), 1000)
51
+ } catch (error) {
52
+ console.error(`Failed to copy ${item.label} to clipboard`, error)
53
+ }
54
+ }
55
+ onDestroy(() => clearTimeout(copied_timeout))
56
+ </script>
57
+
58
+ <DraggablePane
59
+ bind:show={export_pane_open}
60
+ open_icon="Cross"
61
+ closed_icon="Export"
62
+ {icon_style}
63
+ pane_props={{
64
+ ...rest,
65
+ ...pane_props,
66
+ class: `export-pane ${rest.class ?? ``} ${pane_props?.class ?? ``}`.trim(),
67
+ }}
68
+ {toggle_props}
69
+ >
70
+ {#each sections as section, sec_idx (section.title ?? sec_idx)}
71
+ {#if section.title}
72
+ <h4
73
+ {@attach section.tooltip
74
+ ? tooltip({ allow_html: true, content: sanitize_html(section.tooltip) })
75
+ : () => {}}
76
+ >{section.title}</h4>
77
+ {/if}
78
+ <div class="export-grid">
79
+ {#each section.items as item, item_idx (item.label)}
80
+ {@const copy_key = `${sec_idx}-${item_idx}`}
81
+ <!-- not a <label>: it would forward label-text clicks to the first (download) button -->
82
+ <span class="export-item">
83
+ {#if item.hint}
84
+ <span
85
+ {@attach tooltip({ allow_html: true, content: sanitize_html(item.hint) })}
86
+ >{item.label}</span>
87
+ {:else}
88
+ {item.label}
89
+ {/if}
90
+ {#if item.on_download}
91
+ <button
92
+ type="button"
93
+ onclick={item.on_download}
94
+ disabled={item.disabled ?? false}
95
+ aria-label={`Download ${item.label}`}
96
+ title={`Download ${item.label}${item.show_dpi ? ` (${png_dpi} DPI)` : ``}`}
97
+ >
98
+
99
+ </button>
100
+ {/if}
101
+ {#if item.copy_text}
102
+ <button
103
+ type="button"
104
+ onclick={() => handle_copy(item, copy_key)}
105
+ disabled={item.disabled ?? false}
106
+ aria-label="Copy {item.label} to clipboard"
107
+ title="Copy {item.label} to clipboard"
108
+ >
109
+ {copied_key === copy_key ? `✅` : `📋`}
110
+ </button>
111
+ {/if}
112
+ {#if item.show_dpi}
113
+ <span class="dpi-input">(DPI: <input
114
+ type="number"
115
+ min={dpi_range[0]}
116
+ max={dpi_range[1]}
117
+ bind:value={png_dpi}
118
+ onchange={clamp_dpi}
119
+ title="Export resolution in dots per inch"
120
+ />)</span>
121
+ {/if}
122
+ </span>
123
+ {/each}
124
+ </div>
125
+ {/each}
126
+ {@render children?.()}
127
+ </DraggablePane>
128
+
129
+ <style>
130
+ h4 {
131
+ display: flex;
132
+ align-items: center;
133
+ margin: 0;
134
+ }
135
+ .export-grid {
136
+ display: flex;
137
+ flex-wrap: wrap;
138
+ align-items: center;
139
+ gap: 4pt 10pt;
140
+ font-size: 0.95em;
141
+ }
142
+ .export-item {
143
+ display: flex;
144
+ align-items: center;
145
+ gap: 4pt;
146
+ white-space: nowrap;
147
+ }
148
+ .export-grid button {
149
+ min-width: 1.9em;
150
+ height: 1.6em;
151
+ padding: 0 4pt;
152
+ box-sizing: border-box;
153
+ display: inline-flex;
154
+ align-items: center;
155
+ justify-content: center;
156
+ }
157
+ .export-grid input[type='number'] {
158
+ width: 3.5em;
159
+ }
160
+ .dpi-input {
161
+ display: inline-flex;
162
+ align-items: center;
163
+ gap: 2pt;
164
+ white-space: nowrap;
165
+ }
166
+ </style>
@@ -0,0 +1,17 @@
1
+ import type { PaneProps, PaneToggleProps } from '../overlays';
2
+ import type { ExportSection } from './types';
3
+ import { type Snippet } from 'svelte';
4
+ import type { HTMLAttributes } from 'svelte/elements';
5
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
6
+ export_pane_open?: boolean;
7
+ sections?: ExportSection[];
8
+ png_dpi?: number;
9
+ dpi_range?: readonly [number, number];
10
+ icon_style?: string;
11
+ toggle_props?: PaneToggleProps;
12
+ pane_props?: PaneProps;
13
+ children?: Snippet;
14
+ };
15
+ declare const ExportPane: import("svelte").Component<$$ComponentProps, {}, "export_pane_open" | "png_dpi">;
16
+ type ExportPane = ReturnType<typeof ExportPane>;
17
+ export default ExportPane;
@@ -1,4 +1,5 @@
1
1
  import { COMPRESSION_EXTENSIONS_REGEX, COMPRESSION_FORMATS } from '../constants';
2
+ import { to_error } from '../utils';
2
3
  export function detect_compression_format(filename) {
3
4
  const lower = filename.toLowerCase();
4
5
  for (const [format, extensions] of Object.entries(COMPRESSION_FORMATS)) {
@@ -15,7 +16,6 @@ export async function decompress_data(data, format) {
15
16
  // Decompress data and return as ArrayBuffer (for binary files like .brml.gz)
16
17
  export async function decompress_data_binary(data, format) {
17
18
  try {
18
- // Handle unsupported formats
19
19
  if (format === `zip` || format === `xz` || format === `bz2`) {
20
20
  throw new Error(`${format.toUpperCase()} decompression is not supported in the browser. ` +
21
21
  `Please extract the ${format.toUpperCase()} file first.`);
@@ -39,13 +39,14 @@ export async function decompress_data_binary(data, format) {
39
39
  }
40
40
  export function decompress_file(file) {
41
41
  const format = detect_compression_format(file.name);
42
- const is_supported = Boolean(format && ![`zip`, `xz`, `bz2`].includes(format));
42
+ const is_supported = format !== null && format !== `zip` && format !== `xz` && format !== `bz2`;
43
43
  return new Promise((resolve, reject) => {
44
44
  const reader = new FileReader();
45
45
  reader.addEventListener(`load`, () => {
46
46
  try {
47
47
  const result = reader.result;
48
- if (!result)
48
+ // strict null check: empty files legitimately read as '' (falsy)
49
+ if (result === null)
49
50
  throw new Error(`Failed to read file`);
50
51
  if (is_supported && format) {
51
52
  if (!(result instanceof ArrayBuffer))
@@ -62,7 +63,7 @@ export function decompress_file(file) {
62
63
  }
63
64
  }
64
65
  catch (error) {
65
- reject(error);
66
+ reject(to_error(error));
66
67
  }
67
68
  }, { once: true });
68
69
  reader.addEventListener(`error`, () => reject(new Error(`Failed to read file ${file.name}`)));
@@ -1,11 +1,15 @@
1
1
  import type { AnyStructure } from '../structure';
2
- import { type Camera, type Scene } from 'three';
2
+ import { type Camera, type Scene, type WebGLRenderer } from 'three';
3
+ export declare const renderer_registry: WeakMap<HTMLCanvasElement, WebGLRenderer>;
4
+ export declare const dpi_to_scale: (png_dpi: number) => number;
3
5
  export declare function canvas_to_png_blob(canvas: HTMLCanvasElement, png_dpi?: number, scene?: Scene | null, camera?: Camera | null): Promise<Blob>;
4
6
  export declare function export_canvas_as_png(canvas: HTMLCanvasElement | null, structure_or_filename: AnyStructure | string | undefined, png_dpi?: number, scene?: Scene | null, camera?: Camera | null): void;
5
- export declare function svg_to_svg_string(svg_element: SVGElement): string;
6
- export declare function export_svg_as_svg(svg_element: SVGElement | null, filename: string): void;
7
- export declare function svg_to_png_blob(svg_element: SVGElement, png_dpi?: number): Promise<Blob>;
8
- export declare function export_svg_as_png(svg_element: SVGElement | null, filename: string, png_dpi?: number): void;
7
+ export declare function svg_to_svg_string(svg_element: SVGElement, inline_styles?: readonly string[]): string;
8
+ export declare function export_svg_as_svg(svg_element: SVGElement | null, filename: string, inline_styles?: readonly string[]): void;
9
+ export declare function svg_to_png_blob(svg_element: SVGElement, png_dpi?: number, inline_styles?: readonly string[]): Promise<Blob>;
10
+ export declare function export_svg_as_png(svg_element: SVGElement | null, filename: string, png_dpi?: number, inline_styles?: readonly string[]): void;
11
+ export declare function observe_canvas_presence(wrapper: HTMLElement | undefined, set: (has_canvas: boolean) => void): (() => void) | undefined;
12
+ export declare const estimate_video_bitrate: (pixel_count: number, fps: number) => number;
9
13
  export declare function get_ffmpeg_conversion_command(input_filename: string): string;
10
14
  export declare function export_trajectory_video(canvas: HTMLCanvasElement | null, filename: string, options?: {
11
15
  fps?: number;