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
@@ -1,26 +1,14 @@
1
- import type { ElementSymbol } from '../../element/types';
2
- import * as math from '../../math';
3
- import type { TrajectoryType } from '../index';
4
- export declare function parse_extxyz_columns(comment: string): {
5
- species_col: number;
6
- pos_col: number;
7
- forces_col: number;
8
- min_cols: number;
9
- };
10
- export declare function parse_extxyz_lattice(comment: string): math.Matrix3x3 | undefined;
1
+ import type { TrajectoryFrame, TrajectoryType } from '../index';
11
2
  export declare function parse_xyz_comment_metadata(comment: string): {
12
3
  step?: number;
13
4
  properties: Record<string, number>;
14
5
  };
15
- type ForceStats = {
16
- forces: number[][];
17
- force_max: number;
18
- force_norm: number;
19
- };
20
- export declare function parse_xyz_atom_lines(lines: string[], start: number, num_atoms: number, comment: string, frame_label: string): {
21
- elements: ElementSymbol[];
22
- positions: number[][];
23
- force_stats: ForceStats | null;
24
- };
6
+ export declare function build_xyz_frame(lines: string[], frame: {
7
+ start: number;
8
+ num_atoms: number;
9
+ comment: string;
10
+ }, opts: {
11
+ frame_label: string;
12
+ default_step: number;
13
+ }): TrajectoryFrame;
25
14
  export declare function parse_xyz_trajectory(content: string): TrajectoryType;
26
- export {};
@@ -1,15 +1,17 @@
1
1
  import * as math from '../../math';
2
- import { coerce_element_symbol, create_trajectory_frame } from '../helpers';
2
+ import { coerce_elem_symbol } from '../../element/helpers';
3
+ import { calc_force_stats, create_trajectory_frame, iter_xyz_frames, } from '../helpers';
4
+ import { traj_warn } from './diagnostics';
3
5
  // Resolve species/pos/forces column offsets from an extxyz Properties string of
4
6
  // name:type:ncols triples (e.g. "species:S:1:pos:R:3:forces:R:3"), falling back
5
7
  // to the conventional "symbol x y z" layout when absent or malformed
6
- export function parse_extxyz_columns(comment) {
7
- const fields = /Properties\s*=\s*"?([^"\s]+)"?/i.exec(comment)?.[1].split(`:`) ?? [];
8
+ function parse_extxyz_columns(comment) {
9
+ const fields = /Properties\s*=\s*"?(?<properties>[^"\s]+)"?/i.exec(comment)?.[1].split(`:`) ?? [];
8
10
  // Well-formed Properties is name:type:ncols triples; a non-multiple of 3 is malformed,
9
11
  // so bail to the conventional default rather than trusting a partial layout
10
12
  let layout = fields.length % 3 === 0 ? {} : null;
11
13
  for (let idx = 0, offset = 0; layout && idx + 3 <= fields.length; idx += 3) {
12
- const ncols = parseInt(fields[idx + 2], 10);
14
+ const ncols = Math.trunc(Number(fields[idx + 2]));
13
15
  if (Number.isInteger(ncols) && ncols > 0) {
14
16
  layout[fields[idx].toLowerCase()] = { offset, ncols };
15
17
  offset += ncols;
@@ -23,8 +25,12 @@ export function parse_extxyz_columns(comment) {
23
25
  return { species_col, pos_col, forces_col, min_cols: Math.max(pos_col + 3, species_col + 1) };
24
26
  }
25
27
  // Parse Lattice="ax ay az bx by bz cx cy cz" from an extxyz comment line
26
- export function parse_extxyz_lattice(comment) {
27
- const vals = /Lattice\s*=\s*"([^"]+)"/i.exec(comment)?.[1].trim().split(/\s+/).map(Number);
28
+ function parse_extxyz_lattice(comment) {
29
+ const vals = /Lattice\s*=\s*"(?<lattice>[^"]+)"/i
30
+ .exec(comment)?.[1]
31
+ .trim()
32
+ .split(/\s+/)
33
+ .map(Number);
28
34
  if (vals?.length !== 9 || !vals.every(Number.isFinite))
29
35
  return undefined;
30
36
  return [vals.slice(0, 3), vals.slice(3, 6), vals.slice(6, 9)];
@@ -45,15 +51,15 @@ export function parse_xyz_comment_metadata(comment) {
45
51
  for (const [key, pattern] of Object.entries(METADATA_PATTERNS)) {
46
52
  const match = pattern.exec(comment);
47
53
  if (match)
48
- properties[key] = parseFloat(match[1]);
54
+ properties[key] = Number(match[1]);
49
55
  }
50
- const step = /(?:^|\s)(?:step|frame|ionic_step)\s*[=:]?\s*(\d+)/i.exec(comment)?.[1];
51
- return { step: step ? parseInt(step, 10) : undefined, properties };
56
+ const step = /(?:^|\s)(?:step|frame|ionic_step)\s*[=:]?\s*(?<step>\d+)/i.exec(comment)?.[1];
57
+ return { step: step ? Math.trunc(Number(step)) : undefined, properties };
52
58
  }
53
59
  // Parse num_atoms atom lines starting at lines[start], reading species/pos/forces from
54
60
  // their Properties-declared column offsets; invalid atoms are skipped with a warning.
55
61
  // force_stats holds raw forces plus max and RMS force magnitudes when forces are present.
56
- export function parse_xyz_atom_lines(lines, start, num_atoms, comment, frame_label) {
62
+ function parse_xyz_atom_lines(lines, start, num_atoms, comment, frame_label) {
57
63
  const { species_col, pos_col, forces_col, min_cols } = parse_extxyz_columns(comment);
58
64
  const elements = [];
59
65
  const positions = [];
@@ -64,13 +70,13 @@ export function parse_xyz_atom_lines(lines, start, num_atoms, comment, frame_lab
64
70
  continue;
65
71
  const pos = parts.slice(pos_col, pos_col + 3).map(parseFloat);
66
72
  if (!pos.every(Number.isFinite)) {
67
- console.warn(`Skipping XYZ atom with invalid coordinates in ${frame_label} at line ${start + idx + 1}`);
73
+ traj_warn(`Skipping XYZ atom with invalid coordinates in ${frame_label} at line ${start + idx + 1}`);
68
74
  continue;
69
75
  }
70
76
  const symbol = parts[species_col];
71
- const element_symbol = coerce_element_symbol(symbol);
77
+ const element_symbol = coerce_elem_symbol(symbol);
72
78
  if (!element_symbol) {
73
- console.warn(`Skipping XYZ atom with unknown element symbol "${symbol}" in ${frame_label}`);
79
+ traj_warn(`Skipping XYZ atom with unknown element symbol "${symbol}" in ${frame_label}`);
74
80
  continue;
75
81
  }
76
82
  elements.push(element_symbol);
@@ -81,36 +87,29 @@ export function parse_xyz_atom_lines(lines, start, num_atoms, comment, frame_lab
81
87
  forces.push(force_vec);
82
88
  }
83
89
  }
84
- if (forces.length === 0)
85
- return { elements, positions, force_stats: null };
86
- const mags = forces.map((force) => Math.hypot(...force));
87
- const force_norm = Math.sqrt(mags.reduce((sum, mag) => sum + mag ** 2, 0) / mags.length);
88
- return {
89
- elements,
90
- positions,
91
- force_stats: { forces, force_max: Math.max(...mags), force_norm },
92
- };
90
+ const stats = calc_force_stats(forces);
91
+ return { elements, positions, force_stats: stats && { forces, ...stats } };
92
+ }
93
+ // Assemble a TrajectoryFrame from the XYZ frame starting at lines[start] (count line,
94
+ // comment line, atom lines). Shared by the eager parser and the indexed frame reader.
95
+ export function build_xyz_frame(lines, frame, opts) {
96
+ const { start, num_atoms, comment } = frame;
97
+ const { step, properties } = parse_xyz_comment_metadata(comment);
98
+ const lattice_matrix = parse_extxyz_lattice(comment);
99
+ const { elements, positions, force_stats } = parse_xyz_atom_lines(lines, start + 2, num_atoms, comment, opts.frame_label);
100
+ const metadata = { ...properties, ...force_stats };
101
+ if (lattice_matrix)
102
+ metadata.volume = math.calc_lattice_params(lattice_matrix).volume;
103
+ return create_trajectory_frame(positions, elements, lattice_matrix, lattice_matrix ? [true, true, true] : undefined, step ?? opts.default_step, metadata);
93
104
  }
94
105
  export function parse_xyz_trajectory(content) {
95
106
  const lines = content.trim().split(/\r?\n/);
96
107
  const frames = [];
97
- let line_idx = 0;
98
- while (line_idx < lines.length) {
99
- const num_atoms = parseInt(lines[line_idx].trim(), 10);
100
- if (isNaN(num_atoms) || num_atoms <= 0 || line_idx + num_atoms + 1 >= lines.length) {
101
- line_idx++; // skip blank/invalid lines until the next frame's atom-count line
102
- continue;
103
- }
104
- const comment = lines[line_idx + 1] || ``;
105
- const { step, properties } = parse_xyz_comment_metadata(comment);
106
- const metadata = { ...properties };
107
- const lattice_matrix = parse_extxyz_lattice(comment);
108
- if (lattice_matrix)
109
- metadata.volume = math.calc_lattice_params(lattice_matrix).volume;
110
- const { elements, positions, force_stats } = parse_xyz_atom_lines(lines, line_idx + 2, num_atoms, comment, `frame ${frames.length}`);
111
- Object.assign(metadata, force_stats);
112
- frames.push(create_trajectory_frame(positions, elements, lattice_matrix, lattice_matrix ? [true, true, true] : undefined, step ?? frames.length, metadata));
113
- line_idx += num_atoms + 2;
108
+ for (const frame of iter_xyz_frames(lines)) {
109
+ frames.push(build_xyz_frame(lines, frame, {
110
+ frame_label: `frame ${frames.length}`,
111
+ default_step: frames.length,
112
+ }));
114
113
  }
115
114
  return {
116
115
  frames,
@@ -1,25 +1,23 @@
1
- import type { DataSeries } from '../plot/core/types';
1
+ import { type TrajPropertyConfig } from '../labels';
2
+ import type { DataSeries, ScaleType } from '../plot/core/types';
2
3
  import type { TrajectoryDataExtractor, TrajectoryMetadata, TrajectoryType } from './index';
3
4
  export interface PlotSeriesOptions {
4
- property_config?: Record<string, {
5
- label: string;
6
- unit: string;
7
- }>;
5
+ property_config?: Record<string, TrajPropertyConfig>;
8
6
  colors?: readonly string[];
9
7
  default_visible_properties?: Set<string>;
10
8
  }
11
9
  export declare function generate_plot_series(trajectory: TrajectoryType, data_extractor: TrajectoryDataExtractor, options?: PlotSeriesOptions): DataSeries[];
12
- export declare function toggle_series_visibility(series: DataSeries[], target_series_idx: number): DataSeries[];
13
10
  export declare function should_hide_plot(trajectory: TrajectoryType | undefined, plot_series: DataSeries[], tolerance?: number): boolean;
14
11
  export declare function generate_axis_labels(plot_series: DataSeries[]): {
15
12
  y1: string;
16
13
  y2: string;
17
14
  };
15
+ export declare function generate_axis_scale_types(plot_series: DataSeries[]): {
16
+ y1: ScaleType;
17
+ y2: ScaleType;
18
+ };
18
19
  interface StreamingPlotOptions {
19
- property_config?: Record<string, {
20
- label: string;
21
- unit: string;
22
- }>;
20
+ property_config?: Record<string, TrajPropertyConfig>;
23
21
  colors?: readonly string[];
24
22
  default_visible_properties?: Set<string>;
25
23
  max_points?: number;
@@ -1,19 +1,51 @@
1
1
  // Plotting utilities for trajectory visualization
2
2
  import { PLOT_COLORS } from '../colors';
3
- import { trajectory_property_config } from '../labels';
3
+ import { SCF_AXIS_GROUP, trajectory_property_config, } from '../labels';
4
4
  import { get_coefficient_of_variation } from '../math';
5
5
  // Configuration constants
6
6
  const ENERGY_UNITS = [`eV`, `eV/atom`, `hartree`, `kcal/mol`, `kJ/mol`];
7
7
  const ENERGY_PROPERTIES = [`energy`, `total_energy`, `potential_energy`];
8
8
  const FORCE_PROPERTIES = [`force`, `fmax`, `f`];
9
- const DEFAULT_VISIBLE = new Set([`energy`, `force_max`, `stress_frobenius`]);
9
+ // scf_energy_delta lives in its own axis group (see trajectory_property_config), so
10
+ // listing it here only surfaces it when higher-priority groups (energy/force/stress)
11
+ // don't fill both axes — i.e. single-point SCF convergence views.
12
+ const DEFAULT_VISIBLE = new Set([
13
+ `energy`,
14
+ `force_max`,
15
+ `stress_frobenius`,
16
+ `scf_energy_delta`,
17
+ ]);
18
+ // Shared per-series line/point styling derived from a single color
19
+ const series_color_styles = (color) => ({
20
+ line_style: { stroke: color, stroke_width: 2 },
21
+ point_style: { fill: color, stroke: color, stroke_width: 1 },
22
+ });
23
+ // Cache the per-frame walk per trajectory so re-renders that only change visible_properties or
24
+ // labels/config reuse it (legend toggles mutate plot_series directly and skip regeneration, so they
25
+ // don't hit this). Keyed by trajectory identity (WeakMap auto-evicts) and invalidated on extractor
26
+ // or frame identity changes.
27
+ const same_frames = (cached_frames, current_frames) => cached_frames.length === current_frames.length &&
28
+ cached_frames.every((frame, frame_idx) => frame === current_frames[frame_idx]);
29
+ const stats_cache = new WeakMap();
10
30
  // Unified property extraction and series generation
11
31
  export function generate_plot_series(trajectory, data_extractor, options = {}) {
12
32
  if (!trajectory?.frames?.length)
13
33
  return [];
14
34
  const { property_config = trajectory_property_config, colors = PLOT_COLORS, default_visible_properties = DEFAULT_VISIBLE, } = options;
15
- // Single-pass data extraction with variance detection
16
- const property_stats = extract_property_statistics(trajectory, data_extractor);
35
+ // Single-pass extraction with variance detection, cached per trajectory (see stats_cache above)
36
+ const cached = stats_cache.get(trajectory);
37
+ let property_stats;
38
+ if (cached?.extractor === data_extractor && same_frames(cached.frames, trajectory.frames)) {
39
+ property_stats = cached.stats;
40
+ }
41
+ else {
42
+ property_stats = extract_property_statistics(trajectory, data_extractor);
43
+ stats_cache.set(trajectory, {
44
+ extractor: data_extractor,
45
+ frames: [...trajectory.frames],
46
+ stats: property_stats,
47
+ });
48
+ }
17
49
  // Create all series
18
50
  const all_series = create_series_from_stats(property_stats, property_config, colors);
19
51
  // Group by units and assign axes/visibility
@@ -32,18 +64,9 @@ function extract_property_statistics(trajectory, data_extractor) {
32
64
  if (typeof value !== `number` || key === `Step` || key.startsWith(`constant_`)) {
33
65
  return;
34
66
  }
35
- if (!property_stats.has(key)) {
36
- const stats = { values: [], sum: 0, sum_squares: 0, min: value, max: value };
37
- property_stats.set(key, stats);
38
- }
39
- const stat = property_stats.get(key);
40
- if (stat) {
41
- stat.values.push(value);
42
- stat.sum += value;
43
- stat.sum_squares += value * value;
44
- stat.min = Math.min(stat.min, value);
45
- stat.max = Math.max(stat.max, value);
46
- }
67
+ const stat = property_stats.get(key) ?? { values: [] };
68
+ property_stats.set(key, stat);
69
+ stat.values.push(value);
47
70
  });
48
71
  });
49
72
  // Convert to final format with variation detection
@@ -75,22 +98,24 @@ function create_series_from_stats(property_stats, property_config, colors) {
75
98
  if (!stat)
76
99
  continue;
77
100
  const n_values = stat.values.length;
78
- const { clean_label, unit } = extract_label_and_unit(key, property_config);
101
+ const { clean_label, unit, axis_group } = extract_label_and_unit(key, property_config);
79
102
  const color = colors[color_idx % colors.length];
103
+ // shared per-series metadata (consumers only read metadata[0]); one object, not n copies
104
+ const series_metadata = {
105
+ series_label: unit ? `${clean_label} (${unit})` : clean_label,
106
+ property_key: key, // Store original property key for robust lookups
107
+ };
80
108
  all_series.push({
81
109
  x: Array.from({ length: n_values }, (_, idx) => idx),
82
110
  y: stat.values,
83
111
  label: clean_label,
84
112
  unit,
113
+ ...(axis_group ? { axis_group } : {}),
85
114
  y_axis: `y1`, // Will be reassigned
86
115
  visible: false, // Will be assigned
87
116
  markers: n_values < 30 ? `line+points` : `line`,
88
- metadata: Array(n_values).fill({
89
- series_label: unit ? `${clean_label} (${unit})` : clean_label,
90
- property_key: key, // Store original property key for robust lookups
91
- }),
92
- line_style: { stroke: color, stroke_width: 2 },
93
- point_style: { fill: color, radius: 4, stroke: color, stroke_width: 1 },
117
+ metadata: Array.from({ length: n_values }, () => series_metadata),
118
+ ...series_color_styles(color),
94
119
  });
95
120
  color_idx++;
96
121
  }
@@ -98,10 +123,10 @@ function create_series_from_stats(property_stats, property_config, colors) {
98
123
  }
99
124
  // Group series and assign visibility/axes
100
125
  function group_and_assign_series(series, default_visible_properties) {
101
- // Group by unit
126
+ // Group by axis_group when set (forces a dedicated axis), else by unit
102
127
  const unit_map = new Map();
103
128
  for (const srs of series) {
104
- const unit = srs.unit ?? `dimensionless`;
129
+ const unit = srs.axis_group ?? srs.unit ?? `dimensionless`;
105
130
  const group = unit_map.get(unit) ?? [];
106
131
  group.push(srs);
107
132
  unit_map.set(unit, group);
@@ -110,12 +135,12 @@ function group_and_assign_series(series, default_visible_properties) {
110
135
  const groups = Array.from(unit_map.entries())
111
136
  .map(([unit, group_series]) => {
112
137
  const priority = calculate_priority(unit, group_series);
113
- const has_default_visible = group_series.some((srs) => {
138
+ const is_visible = group_series.some((srs) => {
114
139
  const metadata = Array.isArray(srs.metadata) ? srs.metadata[0] : srs.metadata;
115
140
  const property_key = (metadata?.property_key || srs.label) ?? ``;
116
141
  return is_default_visible(property_key, default_visible_properties);
117
142
  });
118
- return { unit, series: group_series, priority, is_visible: has_default_visible };
143
+ return { unit, series: group_series, priority, is_visible };
119
144
  })
120
145
  .sort((a, b) => a.priority - b.priority);
121
146
  // Apply 2-group visibility limit
@@ -155,8 +180,9 @@ function apply_group_assignments(series, unit_groups) {
155
180
  // Helper functions
156
181
  function extract_label_and_unit(key, property_config) {
157
182
  const config = property_config[key] || property_config[key.toLowerCase()];
158
- if (config)
159
- return { clean_label: config.label, unit: config.unit };
183
+ if (config) {
184
+ return { clean_label: config.label, unit: config.unit, axis_group: config.axis_group };
185
+ }
160
186
  return {
161
187
  clean_label: key.charAt(0).toUpperCase() + key.slice(1).replaceAll('_', ` `),
162
188
  unit: ``,
@@ -201,94 +227,6 @@ const is_default_visible = (property_key, default_properties) => {
201
227
  }
202
228
  return false;
203
229
  };
204
- // Optimized series visibility toggling
205
- export function toggle_series_visibility(series, target_series_idx) {
206
- if (target_series_idx < 0 || target_series_idx >= series.length)
207
- return series;
208
- const target_series = series[target_series_idx];
209
- const new_visibility = !target_series.visible;
210
- // Create unit groups from current state
211
- const unit_groups = create_unit_groups_from_series(series);
212
- const target_group = unit_groups.find((group) => group.series.includes(target_series));
213
- if (!target_group)
214
- return series;
215
- // Start with updating the target series visibility
216
- const updated_series = series.map((srs) => srs === target_series ? { ...srs, visible: new_visibility } : { ...srs });
217
- // Handle smart group replacement for new groups
218
- if (new_visibility && !target_group.is_visible) {
219
- const visible_groups = unit_groups.filter((group) => group.is_visible);
220
- if (visible_groups.length >= 2) {
221
- // Hide lowest priority group (highest priority number)
222
- const lowest_priority_group = visible_groups
223
- .sort((g1, g2) => g1.priority - g2.priority)
224
- .pop(); // Get the last (lowest priority) group
225
- if (lowest_priority_group) {
226
- lowest_priority_group.is_visible = false;
227
- // Also hide the actual series in this group
228
- lowest_priority_group.series.forEach((srs1) => {
229
- const series_idx = updated_series.findIndex((srs2) => srs2.label === srs1.label && srs2.unit === srs1.unit);
230
- if (series_idx !== -1) {
231
- updated_series[series_idx] = { ...updated_series[series_idx], visible: false };
232
- }
233
- });
234
- }
235
- }
236
- target_group.is_visible = true;
237
- }
238
- // Recalculate group visibility and reassign axes
239
- update_group_visibility_and_axes(updated_series, unit_groups);
240
- return updated_series;
241
- }
242
- function create_unit_groups_from_series(series) {
243
- const unit_map = new Map();
244
- for (const srs of series) {
245
- const unit = srs.unit ?? `dimensionless`;
246
- const group = unit_map.get(unit) ?? [];
247
- group.push(srs);
248
- unit_map.set(unit, group);
249
- }
250
- return Array.from(unit_map.entries())
251
- .map(([unit, group_series]) => ({
252
- unit,
253
- series: group_series,
254
- priority: calculate_priority(unit, group_series),
255
- is_visible: group_series.some((srs) => srs.visible),
256
- }))
257
- .sort((a, b) => a.priority - b.priority);
258
- }
259
- function update_group_visibility_and_axes(series, unit_groups) {
260
- // Update group visibility based on series
261
- for (const group of unit_groups) {
262
- group.is_visible = group.series.some((srs1) => series.find((srs2) => srs2.label === srs1.label && srs2.unit === srs1.unit)?.visible);
263
- }
264
- // Apply 2-group limit
265
- if (unit_groups.filter((unit_group) => unit_group.is_visible).length > 2) {
266
- for (const group of unit_groups.filter((unit_group) => unit_group.is_visible).slice(2)) {
267
- group.is_visible = false;
268
- for (const srs1 of group.series) {
269
- const idx = series.findIndex((srs2) => srs2.label === srs1.label && srs2.unit === srs1.unit);
270
- if (idx !== -1)
271
- series[idx] = { ...series[idx], visible: false };
272
- }
273
- }
274
- }
275
- // Assign axes
276
- const final_visible = unit_groups
277
- .filter((group) => group.is_visible)
278
- .sort((g1, g2) => g1.priority - g2.priority);
279
- const axis_map = new Map();
280
- if (final_visible.length > 0)
281
- axis_map.set(final_visible[0], `y1`);
282
- if (final_visible.length === 2)
283
- axis_map.set(final_visible[1], `y2`);
284
- // Apply to series
285
- for (const [idx, srs] of series.entries()) {
286
- const group = unit_groups.find((unit_group) => unit_group.series.some((member) => member.label === srs.label && member.unit === srs.unit));
287
- if (group && axis_map.has(group)) {
288
- series[idx] = { ...srs, y_axis: axis_map.get(group) };
289
- }
290
- }
291
- }
292
230
  // Utility functions
293
231
  export function should_hide_plot(trajectory, plot_series, tolerance = 1e-10) {
294
232
  if (!trajectory || trajectory.frames.length <= 1 || plot_series.length === 0) {
@@ -340,14 +278,47 @@ export function generate_axis_labels(plot_series) {
340
278
  y2: get_axis_label(plot_series.filter((srs) => srs.y_axis === `y2`)),
341
279
  };
342
280
  }
281
+ // Log-scale heuristic: a y-axis defaults to log scale when every visible series on
282
+ // it is strictly positive AND their combined values span at least this many decades.
283
+ // SCF convergence residuals (|ΔE|, density rms) span 6+ decades and degenerate into
284
+ // hockey sticks on linear axes; plain energies (large negative) stay linear.
285
+ const LOG_SCALE_MIN_DECADE_SPAN = 3;
286
+ const LOG_SCALE_AXIS_GROUPS = new Set([SCF_AXIS_GROUP]);
287
+ export function generate_axis_scale_types(plot_series) {
288
+ const scale_for_axis = (axis) => {
289
+ let min_val = Infinity;
290
+ let max_val = -Infinity;
291
+ for (const srs of plot_series) {
292
+ if (!srs.visible || (srs.y_axis ?? `y1`) !== axis)
293
+ continue;
294
+ if (!srs.axis_group || !LOG_SCALE_AXIS_GROUPS.has(srs.axis_group))
295
+ return `linear`;
296
+ for (const val of srs.y) {
297
+ if (!Number.isFinite(val))
298
+ continue;
299
+ if (val < min_val)
300
+ min_val = val;
301
+ if (val > max_val)
302
+ max_val = val;
303
+ }
304
+ }
305
+ if (!Number.isFinite(min_val) || min_val <= 0)
306
+ return `linear`;
307
+ return max_val / min_val >= 10 ** LOG_SCALE_MIN_DECADE_SPAN ? `log` : `linear`;
308
+ };
309
+ return { y1: scale_for_axis(`y1`), y2: scale_for_axis(`y2`) };
310
+ }
343
311
  export function generate_streaming_plot_series(metadata_list, options = {}) {
344
312
  if (metadata_list.length === 0)
345
313
  return [];
346
314
  const { property_config = trajectory_property_config, colors = PLOT_COLORS, default_visible_properties = DEFAULT_VISIBLE, max_points = 10_000, // 10,000 plot points provides good visual fidelity while maintaining browser performance
347
315
  } = options;
348
- const sampled_metadata = metadata_list.length > max_points
349
- ? downsample_metadata(metadata_list, max_points)
350
- : metadata_list;
316
+ const ordered_metadata = [...metadata_list]
317
+ .sort((metadata_a, metadata_b) => metadata_a.frame_number - metadata_b.frame_number)
318
+ .filter((metadata, idx, sorted_metadata) => idx === 0 || metadata.frame_number !== sorted_metadata[idx - 1].frame_number);
319
+ const sampled_metadata = ordered_metadata.length > max_points
320
+ ? downsample_metadata(ordered_metadata, max_points)
321
+ : ordered_metadata;
351
322
  const all_properties = new Set();
352
323
  sampled_metadata.forEach((metadata) => {
353
324
  Object.keys(metadata.properties).forEach((prop) => all_properties.add(prop));
@@ -358,22 +329,26 @@ export function generate_streaming_plot_series(metadata_list, options = {}) {
358
329
  for (const property_key of all_properties) {
359
330
  const data_points = sampled_metadata
360
331
  .filter((metadata) => property_key in metadata.properties)
361
- .map((metadata) => ({ x: metadata.step, y: metadata.properties[property_key] }));
332
+ .map((metadata) => ({
333
+ x: metadata.frame_number,
334
+ y: metadata.properties[property_key],
335
+ }));
362
336
  if (data_points.length < 2)
363
337
  continue;
364
338
  const is_energy = property_key.toLowerCase() === `energy`;
365
339
  if (!is_energy && !has_significant_variation(data_points.map((point) => point.y)))
366
340
  continue;
367
- const { clean_label, unit } = extract_label_and_unit(property_key, property_config);
341
+ const { clean_label, unit, axis_group } = extract_label_and_unit(property_key, property_config);
368
342
  const is_visible = is_default_visible(property_key, default_visible_properties) || color_idx < 2;
369
343
  const color = colors[color_idx % colors.length];
370
344
  if (is_visible)
371
- visible_props.push({ property: property_key, unit });
345
+ visible_props.push({ property: property_key, unit, axis_group });
372
346
  all_series.push({
373
347
  x: data_points.map((point) => point.x),
374
348
  y: data_points.map((point) => point.y),
375
349
  label: clean_label,
376
350
  unit,
351
+ ...(axis_group ? { axis_group } : {}),
377
352
  y_axis: determine_axis_from_groups(property_key, unit, visible_props),
378
353
  visible: is_visible,
379
354
  markers: data_points.length < 1000 ? `line+points` : `line`,
@@ -381,8 +356,7 @@ export function generate_streaming_plot_series(metadata_list, options = {}) {
381
356
  series_label: unit ? `${clean_label} (${unit})` : clean_label,
382
357
  property_key, // Store original property key for robust lookups
383
358
  })),
384
- line_style: { stroke: color, stroke_width: 2 },
385
- point_style: { fill: color, radius: 4, stroke: color, stroke_width: 1 },
359
+ ...series_color_styles(color),
386
360
  });
387
361
  color_idx++;
388
362
  }
@@ -411,9 +385,10 @@ function has_significant_variation(values, tolerance = 1e-6) {
411
385
  return coefficient_of_variation >= tolerance;
412
386
  }
413
387
  function determine_axis_from_groups(property, unit, visible_properties) {
414
- const mock_series = visible_properties.map(({ property: prop, unit: u }) => ({
388
+ const mock_series = visible_properties.map(({ property: prop, unit: prop_unit, axis_group }) => ({
415
389
  label: prop,
416
- unit: u,
390
+ unit: prop_unit,
391
+ ...(axis_group ? { axis_group } : {}),
417
392
  }));
418
393
  const groups = group_and_assign_series(mock_series, new Set([property]));
419
394
  const target_group = groups.find((group) => group.series.some((srs) => srs.label === property && srs.unit === unit));
package/dist/utils.d.ts CHANGED
@@ -1,7 +1,11 @@
1
+ export declare const is_plain_object: (val: unknown) => val is Record<string, unknown>;
2
+ export declare const clamp01: (value: number) => number;
1
3
  export declare function merge_nested<T extends Record<string, unknown>>(obj1: T, obj2?: Partial<T>): T;
2
4
  export declare const escape_html: (unsafe_string: string) => string;
3
5
  export declare const normalize_unicode_minus: (value: string) => string;
4
6
  export declare const normalize_scientific_notation: (value: string) => string;
7
+ export declare const parse_num_token: (token: string) => number;
8
+ export declare const parse_leading_num: (line: string) => number;
5
9
  export declare const to_error: (value: unknown) => Error;
6
10
  export declare function make_change_detector(): (value: unknown) => boolean;
7
11
  export declare function decode_url_safe_base64(encoded: string): string | undefined;
package/dist/utils.js CHANGED
@@ -1,5 +1,7 @@
1
1
  // Check if value is a plain object (not array, null, or other types)
2
- const is_plain_object = (val) => typeof val === `object` && val !== null && !Array.isArray(val);
2
+ export const is_plain_object = (val) => typeof val === `object` && val !== null && !Array.isArray(val);
3
+ // Clamp a number to the [0, 1] range.
4
+ export const clamp01 = (value) => Math.max(0, Math.min(1, value));
3
5
  // Merge nested objects (1 level deep).
4
6
  export function merge_nested(obj1, obj2) {
5
7
  const result = { ...obj1, ...obj2 };
@@ -21,6 +23,11 @@ export const escape_html = (unsafe_string) => unsafe_string
21
23
  export const normalize_unicode_minus = (value) => value.replaceAll('−', `-`);
22
24
  // Normalize scientific notation variants (d/D exponent, Mathematica *^).
23
25
  export const normalize_scientific_notation = (value) => normalize_unicode_minus(value).toLowerCase().replaceAll('d', `e`).replaceAll('*^', `e`);
26
+ // Number(token) that treats blank strings as NaN, not 0 like Number(``) does
27
+ export const parse_num_token = (token) => token.trim() === `` ? NaN : Number(token);
28
+ // Parse a line's first whitespace-separated token: tolerates trailing
29
+ // tokens/comments (`1.0 ! scale` -> 1.0) like parseFloat, blank lines are NaN
30
+ export const parse_leading_num = (line) => parse_num_token(line.trim().split(/\s+/)[0]);
24
31
  // Coerce an unknown thrown value into an Error (for typed Promise rejections / error callbacks).
25
32
  export const to_error = (value) => value instanceof Error ? value : new Error(String(value));
26
33
  export function make_change_detector() {