matterviz 0.4.1 → 0.4.3

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 (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  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 +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  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 +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  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 +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -29,12 +29,7 @@
29
29
  import TemperatureSlider from './TemperatureSlider.svelte'
30
30
  import type { Point4D } from './thermodynamics'
31
31
  import * as thermo from './thermodynamics'
32
- import type {
33
- ConvexHullEntry,
34
- HighlightStyle,
35
- HullFaceColorMode,
36
- PhaseData,
37
- } from './types'
32
+ import type { ConvexHullEntry, HighlightStyle, HullFaceColorMode, PhaseData } from './types'
38
33
  import { MAGNETIC_ORDERING_CATEGORY } from './types'
39
34
  import { compute_hull_stability } from './helpers'
40
35
 
@@ -61,9 +56,7 @@
61
56
  ),
62
57
  element_colors = vesta_hex,
63
58
  color_mode = $bindable(DEFAULTS.convex_hull.quaternary.color_mode),
64
- color_scale = $bindable(
65
- DEFAULTS.convex_hull.quaternary.color_scale as D3InterpolateName,
66
- ),
59
+ color_scale = $bindable(DEFAULTS.convex_hull.quaternary.color_scale as D3InterpolateName),
67
60
  info_pane_open = $bindable(DEFAULTS.convex_hull.quaternary.info_pane_open),
68
61
  controls_open = $bindable(DEFAULTS.convex_hull.quaternary.legend_pane_open),
69
62
  max_hull_dist_show_phases = $bindable(
@@ -72,12 +65,8 @@
72
65
  max_hull_dist_show_labels = $bindable(
73
66
  DEFAULTS.convex_hull.quaternary.max_hull_dist_show_labels,
74
67
  ),
75
- show_stable_labels = $bindable(
76
- DEFAULTS.convex_hull.quaternary.show_stable_labels,
77
- ),
78
- show_unstable_labels = $bindable(
79
- DEFAULTS.convex_hull.quaternary.show_unstable_labels,
80
- ),
68
+ show_stable_labels = $bindable(DEFAULTS.convex_hull.quaternary.show_stable_labels),
69
+ show_unstable_labels = $bindable(DEFAULTS.convex_hull.quaternary.show_unstable_labels),
81
70
  on_file_drop,
82
71
  enable_click_selection = true,
83
72
  enable_structure_preview = true,
@@ -96,9 +85,10 @@
96
85
  children,
97
86
  tooltip,
98
87
  ...rest
99
- }: BaseConvexHullProps<ConvexHullEntry> & Hull3DProps & {
100
- highlight_style?: HighlightStyle
101
- } = $props()
88
+ }: BaseConvexHullProps<ConvexHullEntry> &
89
+ Hull3DProps & {
90
+ highlight_style?: HighlightStyle
91
+ } = $props()
102
92
 
103
93
  const merged_controls = $derived({ ...default_controls, ...controls })
104
94
  const controls_config = $derived(normalize_show_controls(show_controls))
@@ -106,13 +96,24 @@
106
96
  ...default_hull_config,
107
97
  ...config,
108
98
  colors: { ...default_hull_config.colors, ...config.colors },
109
- margin: { t: 60, r: 60, b: 60, l: 60, ...config.margin },
110
99
  })
111
100
 
112
- // Reactive dark mode detection for canvas text color
113
- let dark_mode = $state(is_dark_mode())
114
- $effect(() => watch_dark_mode((dark) => dark_mode = dark))
115
- const text_color = $derived(helpers.get_canvas_text_color(dark_mode))
101
+ // Cache resolved canvas colors and refresh them only when the theme changes.
102
+ const initial_text_color = helpers.get_canvas_text_color(is_dark_mode())
103
+ let text_color = $state(initial_text_color)
104
+ let hull_edge_color = $state(initial_text_color)
105
+ function refresh_canvas_colors(dark_mode: boolean): void {
106
+ const next_text_color = helpers.get_canvas_text_color(dark_mode)
107
+ text_color = next_text_color
108
+ const resolved_edge_color = canvas
109
+ ? getComputedStyle(canvas).getPropertyValue(`--hull-edge-color`).trim()
110
+ : ``
111
+ hull_edge_color = resolved_edge_color || next_text_color
112
+ }
113
+ $effect(() => {
114
+ refresh_canvas_colors(is_dark_mode())
115
+ return watch_dark_mode(refresh_canvas_colors)
116
+ })
116
117
 
117
118
  // Shared reactive data pipeline (temperature → gas → energy mode → hull data → threshold)
118
119
  // Explicit generic breaks the circular type inference through the all_enriched_entries thunk
@@ -131,44 +132,44 @@
131
132
  show_unstable: () => show_unstable,
132
133
  entry_category: () => entry_category,
133
134
  hidden_categories: () => hidden_categories,
134
- // Always include stable entries and elemental reference points
135
- keep_plot_entry: (entry, max_dist) =>
136
- helpers.entry_is_stable(entry) ||
137
- (typeof entry.e_above_hull === `number` && entry.e_above_hull <= max_dist),
138
- set_temperature: (next_temp) => temperature = next_temp,
139
- set_max_hull_dist_show_phases: (value) => max_hull_dist_show_phases = value,
140
- set_stable_entries: (value) => stable_entries = value,
141
- set_unstable_entries: (value) => unstable_entries = value,
135
+ keep_plot_entry: helpers.entry_within_hull_dist,
136
+ set_temperature: (next_temp) => (temperature = next_temp),
137
+ set_max_hull_dist_show_phases: (value) => (max_hull_dist_show_phases = value),
138
+ set_stable_entries: (value) => (stable_entries = value),
139
+ set_unstable_entries: (value) => (unstable_entries = value),
142
140
  })
143
141
  const merged_gas_config = $derived(hull_data.merged_gas_config)
144
142
  const pd_data = $derived(hull_data.pd_data)
145
143
  const elements = $derived(hull_data.elements)
146
144
  const plot_entries = $derived(hull_data.plot_entries)
147
145
 
146
+ // Entry → 4D hull point (3 barycentric composition fractions + e_form as w),
147
+ // or null when the entry lacks a finite formation energy or valid composition
148
+ function to_point_4d(entry: ConvexHullEntry): Point4D | null {
149
+ if (
150
+ !Number.isFinite(entry.e_form_per_atom) ||
151
+ ![entry.x, entry.y, entry.z].every(Number.isFinite)
152
+ )
153
+ return null
154
+ const amounts = elements.map((el) => entry.composition[el] || 0)
155
+ const total = amounts.reduce((sum, amt) => sum + amt, 0)
156
+ if (!(total > 0)) return null
157
+ const [x, y, z] = amounts.map((amt) => amt / total)
158
+ return [x, y, z].every(Number.isFinite)
159
+ ? { x, y, z, w: entry.e_form_per_atom ?? NaN }
160
+ : null
161
+ }
162
+
148
163
  // Compute 4D hull for visualization (always compute when we have formation energies)
149
164
  const hull_4d = $derived.by(() => {
150
165
  if (elements.length !== 4) return []
151
166
 
152
167
  try {
153
- // Get coords with formation energies, excluding entries that don't participate in hull
154
- const coords = compute_4d_coords(pd_data.entries, elements)
168
+ // Excluded entries don't participate in hull construction
169
+ const points_4d = compute_4d_coords(pd_data.entries, elements)
155
170
  .filter((ent) => !ent.exclude_from_hull)
156
-
157
- // Convert to 4D points for hull computation using barycentric coordinates (composition fractions)
158
- const points_4d: Point4D[] = coords
159
- .filter(
160
- (ent) =>
161
- Number.isFinite(ent.e_form_per_atom) &&
162
- [ent.x, ent.y, ent.z].every(Number.isFinite),
163
- )
164
- .map((ent) => {
165
- const amounts = elements.map((el) => ent.composition[el] || 0)
166
- const total = amounts.reduce((sum, amt) => sum + amt, 0)
167
- if (!(total > 0)) return { x: NaN, y: NaN, z: NaN, w: NaN }
168
- const [x, y, z] = amounts.map((amt) => amt / total)
169
- return { x, y, z, w: ent.e_form_per_atom ?? NaN }
170
- })
171
- .filter((point) => [point.x, point.y, point.z, point.w].every(Number.isFinite))
171
+ .map(to_point_4d)
172
+ .filter((point): point is Point4D => point !== null)
172
173
 
173
174
  if (points_4d.length < 5) return [] // Need at least 5 points for 4D hull
174
175
 
@@ -189,32 +190,26 @@
189
190
 
190
191
  // Build 4D points, tracking original indices for mapping hull distances back
191
192
  const valid = coords.flatMap((entry, idx) => {
192
- if (
193
- !Number.isFinite(entry.e_form_per_atom) ||
194
- ![entry.x, entry.y, entry.z].every(Number.isFinite)
195
- ) return []
196
- const amounts = elements.map((el) => entry.composition[el] || 0)
197
- const total = amounts.reduce((sum, amt) => sum + amt, 0)
198
- if (!(total > 0)) return []
199
- const [x, y, z] = amounts.map((amt) => amt / total)
200
- return [x, y, z].every(Number.isFinite)
201
- ? [{ idx, pt: { x, y, z, w: entry.e_form_per_atom ?? NaN } }]
202
- : []
193
+ const pt = to_point_4d(entry)
194
+ return pt ? [{ idx, pt }] : []
203
195
  })
204
- const raw_dists = thermo.compute_e_above_hull_4d(valid.map((item) => item.pt), hull_4d)
196
+ const raw_dists = thermo.compute_e_above_hull_4d(
197
+ valid.map((item) => item.pt),
198
+ hull_4d,
199
+ )
205
200
  const hull_map = new Map(valid.map((item, hull_idx) => [item.idx, raw_dists[hull_idx]]))
206
- return coords.map((entry, idx) => {
207
- const raw = hull_map.get(idx)
208
- if (raw === undefined) return { ...entry, e_above_hull: raw, is_stable: false }
209
- return { ...entry, ...compute_hull_stability(raw, entry.exclude_from_hull) }
210
- })
201
+ // missing/non-finite distance (no energy or point outside hull projection) -> unknown
202
+ return coords.map((entry, idx) => ({
203
+ ...entry,
204
+ ...compute_hull_stability(hull_map.get(idx), entry.exclude_from_hull),
205
+ }))
211
206
  } catch (err) {
212
207
  console.error(`Error computing quaternary coordinates:`, err)
213
208
  return []
214
209
  }
215
210
  })
216
211
 
217
- let canvas: HTMLCanvasElement | undefined = undefined
212
+ let canvas = $state<HTMLCanvasElement>()
218
213
  let ctx: CanvasRenderingContext2D | null = null
219
214
 
220
215
  // Camera state - following Materials Project's 3D camera setup
@@ -234,12 +229,12 @@
234
229
  canvas: () => canvas,
235
230
  wrapper: () => wrapper,
236
231
  ctx: () => ctx,
237
- set_ctx: (context) => ctx = context,
238
- set_canvas_dims: (dims) => canvas_dims = dims,
232
+ set_ctx: (context) => (ctx = context),
233
+ set_canvas_dims: (dims) => (canvas_dims = dims),
239
234
  visible_entries: () => hull_data.visible_entries,
240
235
  plot_entries: () => plot_entries,
241
236
  selected_entry: () => selected_entry,
242
- set_selected_entry: (entry) => selected_entry = entry,
237
+ set_selected_entry: (entry) => (selected_entry = entry),
243
238
  fullscreen: () => fullscreen,
244
239
  enable_click_selection: () => enable_click_selection,
245
240
  enable_structure_preview: () => enable_structure_preview,
@@ -248,7 +243,7 @@
248
243
  on_file_drop: () => on_file_drop,
249
244
  entry_category: () => entry_category,
250
245
  zoom: () => camera.zoom,
251
- set_zoom: (zoom) => camera.zoom = zoom,
246
+ set_zoom: (zoom) => (camera.zoom = zoom),
252
247
  project_point: project_3d_point,
253
248
  extract_structure: extract_structure_from_entry,
254
249
  render_frame,
@@ -271,11 +266,11 @@
271
266
  },
272
267
  actions: () => ({
273
268
  r: reset_camera,
274
- b: () => color_mode = color_mode === `stability` ? `energy` : `stability`,
275
- s: () => show_stable = !show_stable,
276
- u: () => show_unstable = !show_unstable,
277
- h: () => show_hull_faces = !show_hull_faces,
278
- l: () => show_stable_labels = !show_stable_labels,
269
+ b: () => (color_mode = color_mode === `stability` ? `energy` : `stability`),
270
+ s: () => (show_stable = !show_stable),
271
+ u: () => (show_unstable = !show_unstable),
272
+ h: () => (show_hull_faces = !show_hull_faces),
273
+ l: () => (show_stable_labels = !show_stable_labels),
279
274
  }),
280
275
  })
281
276
  const { render_once } = interactions
@@ -292,9 +287,7 @@
292
287
  let pulse_opacity = $derived(0.3 + 0.4 * pulse.unit)
293
288
 
294
289
  // Merge highlight style with defaults
295
- const merged_highlight_style = $derived(
296
- helpers.merge_highlight_style(highlight_style),
297
- )
290
+ const merged_highlight_style = $derived(helpers.merge_highlight_style(highlight_style))
298
291
 
299
292
  // Helper to check if entry is highlighted
300
293
  const is_highlighted = (entry: ConvexHullEntry): boolean =>
@@ -303,13 +296,11 @@
303
296
  // Re-render when important state changes
304
297
  $effect(() => {
305
298
  // oxfmt-ignore
306
- void [show_hull_faces, color_mode, color_scale, camera.rotation_x, camera.rotation_y, camera.zoom, camera.center_x, camera.center_y, plot_entries, hull_data.visible_entries, hull_face_color, hull_face_opacity, hull_face_color_mode, element_colors, text_color, elements] // track reactively
299
+ void [show_hull_faces, color_mode, color_scale, camera.rotation_x, camera.rotation_y, camera.zoom, camera.center_x, camera.center_y, plot_entries, hull_data.visible_entries, hull_face_color, hull_face_opacity, hull_face_color_mode, element_colors, text_color, hull_edge_color, elements] // track reactively
307
300
 
308
301
  render_once()
309
302
  })
310
303
 
311
- // Visibility toggles are now bindable props
312
-
313
304
  // Smart label defaults: hide labels for large datasets. Applied once per dataset
314
305
  // (keyed on the entries prop) so later entry-count changes from temperature/gas
315
306
  // filtering don't clobber the user's label toggles.
@@ -347,8 +338,7 @@
347
338
  show_unstable_labels = DEFAULTS.convex_hull.quaternary.show_unstable_labels
348
339
  // Use auto-computed threshold based on entry count instead of static default
349
340
  max_hull_dist_show_phases = hull_data.auto_default_threshold
350
- max_hull_dist_show_labels =
351
- DEFAULTS.convex_hull.quaternary.max_hull_dist_show_labels
341
+ max_hull_dist_show_labels = DEFAULTS.convex_hull.quaternary.max_hull_dist_show_labels
352
342
  show_hull_faces = DEFAULTS.convex_hull.quaternary.show_hull_faces
353
343
  hull_face_color = DEFAULTS.convex_hull.quaternary.hull_face_color
354
344
  hull_face_opacity = DEFAULTS.convex_hull.quaternary.hull_face_opacity
@@ -365,8 +355,8 @@
365
355
  )
366
356
 
367
357
  // Cache energy color scale per frame/setting
368
- const energy_color_scale = $derived.by(() =>
369
- helpers.get_energy_color_scale(color_mode, color_scale, plot_entries)
358
+ const energy_color_scale = $derived(
359
+ helpers.get_energy_color_scale(color_mode, color_scale, plot_entries),
370
360
  )
371
361
 
372
362
  // Convex hull statistics - compute internally and expose via bindable prop
@@ -382,16 +372,11 @@
382
372
  ): { x: number; y: number; depth: number } {
383
373
  if (!canvas) return { x: 0, y: 0, depth: 0 }
384
374
 
385
- // Center coordinates around tetrahedron/triangle centroid
386
- let [centered_x, centered_y, centered_z] = [x, y, z]
387
-
388
- // Tetrahedron centroid: average of vertices (1,0,0), (0.5,√3/2,0), (0.5,√3/6,√6/3), (0,0,0)
389
- const centroid_x = (1 + 0.5 + 0.5 + 0) / 4 // = 0.5
390
- const centroid_y = (0 + Math.sqrt(3) / 2 + Math.sqrt(3) / 6 + 0) / 4 // = √3/6
391
- const centroid_z = (0 + 0 + Math.sqrt(6) / 3 + 0) / 4 // = √6/12
392
- centered_x = x - centroid_x
393
- centered_y = y - centroid_y
394
- centered_z = z - centroid_z
375
+ // Center coordinates around the tetrahedron centroid: average of vertices
376
+ // (1,0,0), (0.5,√3/2,0), (0.5,√3/6,√6/3), (0,0,0)
377
+ const centered_x = x - (1 + 0.5 + 0.5 + 0) / 4 // centroid_x = 0.5
378
+ const centered_y = y - (0 + Math.sqrt(3) / 2 + Math.sqrt(3) / 6 + 0) / 4 // = √3/6
379
+ const centered_z = z - (0 + 0 + Math.sqrt(6) / 3 + 0) / 4 // = √6/12
395
380
 
396
381
  // Apply 3D transformations around the centered coordinates
397
382
  const cos_x = Math.cos(camera.rotation_x)
@@ -419,56 +404,33 @@
419
404
  }
420
405
  }
421
406
 
407
+ // Dashed tetrahedron outline (matching the gray structure lines used in 3D)
408
+ // plus corner element labels
422
409
  function draw_structure_outline(): void {
423
410
  if (!ctx || !canvas) return
424
411
 
425
- const styles = getComputedStyle(canvas)
426
- // Match gray dashed structure lines used in 3D
427
412
  ctx.strokeStyle = CONVEX_HULL_STYLE.structure_line.color
428
413
  ctx.lineWidth = CONVEX_HULL_STYLE.structure_line.line_width
429
414
  ctx.setLineDash(CONVEX_HULL_STYLE.structure_line.dash)
430
415
 
431
- // Draw tetrahedron edges
432
- draw_tetrahedron()
433
-
434
- // Reset dash and stroke for subsequent drawings
435
- ctx.setLineDash([])
436
- ctx.strokeStyle = styles.getPropertyValue(`--hull-edge-color`) || `#212121`
437
- }
438
-
439
- function draw_tetrahedron(): void {
440
- if (!ctx) return
441
-
442
- // Convert vertices to Point3D objects
443
416
  const vertices = TETRAHEDRON_VERTICES.map(([x, y, z]) => ({ x, y, z }))
444
-
445
- // Tetrahedron edges (connecting vertices)
446
- const edges = [
447
- [0, 1],
448
- [0, 2],
449
- [0, 3], // From vertex 0
450
- [1, 2],
451
- [1, 3], // From vertex 1
452
- [2, 3], // From vertex 2
453
- ]
454
-
455
- // Draw edges
417
+ // oxfmt-ignore
418
+ const edges = [[0, 1], [0, 2], [0, 3], [1, 2], [1, 3], [2, 3]]
456
419
  ctx.beginPath()
457
420
  for (const [start, end] of edges) {
458
- const v1 = vertices[start]
459
- const v2 = vertices[end]
460
-
461
- const proj1 = project_3d_point(v1.x, v1.y, v1.z)
462
- const proj2 = project_3d_point(v2.x, v2.y, v2.z)
463
-
421
+ const proj1 = project_3d_point(vertices[start].x, vertices[start].y, vertices[start].z)
422
+ const proj2 = project_3d_point(vertices[end].x, vertices[end].y, vertices[end].z)
464
423
  ctx.moveTo(proj1.x, proj1.y)
465
424
  ctx.lineTo(proj2.x, proj2.y)
466
425
  }
467
426
  ctx.stroke()
468
427
 
469
- // Corner element labels: place just outside along line towards tetrahedron centroid
428
+ // Reset dash and stroke for subsequent drawings
429
+ ctx.setLineDash([])
430
+ ctx.strokeStyle = hull_edge_color
431
+
432
+ // Corner element labels: place just outside each vertex, along the centroid→vertex line
470
433
  if (elements.length === 4) {
471
- // Tetrahedron centroid in barycentric space maps to average of vertices
472
434
  const centroid = {
473
435
  x: (vertices[0].x + vertices[1].x + vertices[2].x + vertices[3].x) / 4,
474
436
  y: (vertices[0].y + vertices[1].y + vertices[2].y + vertices[3].y) / 4,
@@ -483,16 +445,13 @@
483
445
  const distance = 0.06
484
446
  for (let idx = 0; idx < 4; idx++) {
485
447
  const vx = vertices[idx]
486
- // Direction from centroid to vertex
487
- const { x: cx, y: cy, z: cz } = centroid
488
- const dir = { x: vx.x - cx, y: vx.y - cy, z: vx.z - cz }
448
+ const dir = { x: vx.x - centroid.x, y: vx.y - centroid.y, z: vx.z - centroid.z }
489
449
  const len = Math.hypot(dir.x, dir.y, dir.z) || 1
490
- const label_pos = {
491
- x: vx.x + (dir.x / len) * distance,
492
- y: vx.y + (dir.y / len) * distance,
493
- z: vx.z + (dir.z / len) * distance,
494
- }
495
- const proj = project_3d_point(label_pos.x, label_pos.y, label_pos.z)
450
+ const proj = project_3d_point(
451
+ vx.x + (dir.x / len) * distance,
452
+ vx.y + (dir.y / len) * distance,
453
+ vx.z + (dir.z / len) * distance,
454
+ )
496
455
  ctx.fillText(elements[idx], proj.x, proj.y)
497
456
  }
498
457
  }
@@ -527,30 +486,10 @@
527
486
  const [p0, p1, p2, p3] = tet.vertices
528
487
 
529
488
  // Convert barycentric coordinates to tetrahedral 3D coordinates
530
- const tet0 = barycentric_to_tetrahedral([
531
- p0.x,
532
- p0.y,
533
- p0.z,
534
- 1 - p0.x - p0.y - p0.z,
535
- ])
536
- const tet1 = barycentric_to_tetrahedral([
537
- p1.x,
538
- p1.y,
539
- p1.z,
540
- 1 - p1.x - p1.y - p1.z,
541
- ])
542
- const tet2 = barycentric_to_tetrahedral([
543
- p2.x,
544
- p2.y,
545
- p2.z,
546
- 1 - p2.x - p2.y - p2.z,
547
- ])
548
- const tet3 = barycentric_to_tetrahedral([
549
- p3.x,
550
- p3.y,
551
- p3.z,
552
- 1 - p3.x - p3.y - p3.z,
553
- ])
489
+ const tet0 = barycentric_to_tetrahedral([p0.x, p0.y, p0.z, 1 - p0.x - p0.y - p0.z])
490
+ const tet1 = barycentric_to_tetrahedral([p1.x, p1.y, p1.z, 1 - p1.x - p1.y - p1.z])
491
+ const tet2 = barycentric_to_tetrahedral([p2.x, p2.y, p2.z, 1 - p2.x - p2.y - p2.z])
492
+ const tet3 = barycentric_to_tetrahedral([p3.x, p3.y, p3.z, 1 - p3.x - p3.y - p3.z])
554
493
 
555
494
  // Project to 2D screen space
556
495
  const proj0 = project_3d_point(tet0.x, tet0.y, tet0.z)
@@ -564,8 +503,14 @@
564
503
  (p0.x + p1.x + p2.x + p3.x) / 4,
565
504
  (p0.y + p1.y + p2.y + p3.y) / 4,
566
505
  (p0.z + p1.z + p2.z + p3.z) / 4,
567
- ((1 - p0.x - p0.y - p0.z) + (1 - p1.x - p1.y - p1.z) +
568
- (1 - p2.x - p2.y - p2.z) + (1 - p3.x - p3.y - p3.z)) / 4,
506
+ (1 -
507
+ p0.x -
508
+ p0.y -
509
+ p0.z +
510
+ (1 - p1.x - p1.y - p1.z) +
511
+ (1 - p2.x - p2.y - p2.z) +
512
+ (1 - p3.x - p3.y - p3.z)) /
513
+ 4,
569
514
  ]
570
515
 
571
516
  // Each tetrahedron has 4 triangular faces
@@ -607,7 +552,7 @@
607
552
  let min_w = 0
608
553
  if (hull_face_color_mode === `formation_energy`) {
609
554
  const all_avg_w = triangles.map((tri) => tri.avg_w)
610
- min_w = Math.min(...all_avg_w)
555
+ min_w = helpers.array_min(all_avg_w)
611
556
  energy_face_scale = helpers.get_energy_color_scale(
612
557
  `energy`,
613
558
  color_scale,
@@ -625,7 +570,7 @@
625
570
  }
626
571
  if (hull_face_color_mode === `dominant_element`) {
627
572
  // Find element with highest fraction
628
- const max_idx = tri.centroid_bary.indexOf(Math.max(...tri.centroid_bary))
573
+ const max_idx = tri.centroid_bary.indexOf(helpers.array_max(tri.centroid_bary))
629
574
  const el = elements[max_idx]
630
575
  return element_colors[el] ?? `#888888`
631
576
  }
@@ -639,9 +584,10 @@
639
584
  for (const tri of triangles) {
640
585
  const [v0, v1, v2] = tri.vertices
641
586
  // Uniform mode uses variable opacity; other modes use fixed opacity
642
- const alpha = hull_face_color_mode === `uniform`
643
- ? (norm_alpha?.(tri.avg_w) ?? hull_face_opacity)
644
- : hull_face_opacity
587
+ const alpha =
588
+ hull_face_color_mode === `uniform`
589
+ ? (norm_alpha?.(tri.avg_w) ?? hull_face_opacity)
590
+ : hull_face_opacity
645
591
  const face_color = get_face_color(tri)
646
592
 
647
593
  ctx.save()
@@ -683,9 +629,12 @@
683
629
  .filter((entry) => {
684
630
  if (entry.is_element) return false
685
631
  const is_stable = helpers.entry_is_stable(entry)
686
- return (is_stable && show_stable_labels) ||
687
- (!is_stable && show_unstable_labels &&
632
+ return (
633
+ (is_stable && show_stable_labels) ||
634
+ (!is_stable &&
635
+ show_unstable_labels &&
688
636
  (entry.e_above_hull ?? 0) <= max_hull_dist_show_labels)
637
+ )
689
638
  }),
690
639
  )
691
640
 
@@ -761,7 +710,7 @@
761
710
 
762
711
  <div
763
712
  {...rest}
764
- class="convex-hull-4d {rest.class ?? ``}"
713
+ class={[`convex-hull-4d`, rest.class]}
765
714
  class:dragover={interactions.drag_over}
766
715
  style={`${style}; ${rest.style ?? ``}`}
767
716
  data-has-selection={selected_entry !== null}
@@ -776,11 +725,11 @@
776
725
  aria-label="Convex hull visualization"
777
726
  >
778
727
  {@render children?.({
779
- stable_entries,
780
- unstable_entries,
781
- highlighted_entries,
782
- selected_entry,
783
- })}
728
+ stable_entries,
729
+ unstable_entries,
730
+ highlighted_entries,
731
+ selected_entry,
732
+ })}
784
733
  <h3 style="position: absolute; left: 1em; top: 1ex; margin: 0">
785
734
  {@html sanitize_html(merged_controls.title || phase_stats?.chemical_system || ``)}
786
735
  </h3>
@@ -853,7 +802,10 @@
853
802
  />
854
803
 
855
804
  {#if hull_data.has_temp_data && temperature !== undefined}
856
- <TemperatureSlider available_temperatures={hull_data.available_temperatures} bind:temperature />
805
+ <TemperatureSlider
806
+ available_temperatures={hull_data.available_temperatures}
807
+ bind:temperature
808
+ />
857
809
  {/if}
858
810
 
859
811
  {#if hull_data.gas_analysis.has_gas_dependent_elements && merged_gas_config}
@@ -863,7 +815,6 @@
863
815
  temperature={temperature ?? 300}
864
816
  />
865
817
  {/if}
866
-
867
818
  </div>
868
819
 
869
820
  <style>
@@ -3,6 +3,6 @@ import type { ConvexHullEntry, HighlightStyle } from './types';
3
3
  type $$ComponentProps = BaseConvexHullProps<ConvexHullEntry> & Hull3DProps & {
4
4
  highlight_style?: HighlightStyle;
5
5
  };
6
- declare const ConvexHull4D: import("svelte").Component<$$ComponentProps, {}, "temperature" | "fullscreen" | "wrapper" | "controls_open" | "color_scale" | "info_pane_open" | "show_hull_faces" | "hull_face_opacity" | "hull_face_color_mode" | "color_mode" | "show_stable" | "show_unstable" | "show_stable_labels" | "show_unstable_labels" | "max_hull_dist_show_phases" | "max_hull_dist_show_labels" | "hidden_categories" | "energy_source_mode" | "stable_entries" | "unstable_entries" | "phase_stats" | "highlighted_entries" | "selected_entry" | "gas_pressures">;
6
+ declare const ConvexHull4D: import("svelte").Component<$$ComponentProps, {}, "fullscreen" | "wrapper" | "controls_open" | "color_scale" | "info_pane_open" | "temperature" | "show_hull_faces" | "hull_face_opacity" | "hull_face_color_mode" | "color_mode" | "show_stable" | "show_unstable" | "show_stable_labels" | "show_unstable_labels" | "max_hull_dist_show_phases" | "max_hull_dist_show_labels" | "hidden_categories" | "energy_source_mode" | "stable_entries" | "unstable_entries" | "phase_stats" | "highlighted_entries" | "selected_entry" | "gas_pressures">;
7
7
  type ConvexHull4D = ReturnType<typeof ConvexHull4D>;
8
8
  export default ConvexHull4D;
@@ -59,32 +59,30 @@
59
59
  max_hull_dist_show_phases = $bindable(0),
60
60
  max_hull_dist_show_labels = $bindable(0.1),
61
61
  energy_source_mode = $bindable(`precomputed`),
62
- }:
63
- & Pick<
64
- ControlsProps,
65
- | `camera`
66
- | `merged_controls`
67
- | `stable_entries`
68
- | `unstable_entries`
69
- | `color_mode`
70
- | `color_scale`
71
- | `show_stable`
72
- | `show_unstable`
73
- | `entry_category`
74
- | `hidden_categories`
75
- | `show_stable_labels`
76
- | `show_unstable_labels`
77
- | `max_hull_dist_show_phases`
78
- | `max_hull_dist_show_labels`
79
- | `energy_source_mode`
80
- | `controls_open`
81
- | `show_hull_faces`
82
- | `hull_face_color`
83
- | `hull_face_opacity`
84
- | `hull_face_color_mode`
85
- >
86
- & Pick<ComponentProps<typeof ConvexHullInfoPane>, `phase_stats` | `label_threshold`>
87
- & {
62
+ }: Pick<
63
+ ControlsProps,
64
+ | `camera`
65
+ | `merged_controls`
66
+ | `stable_entries`
67
+ | `unstable_entries`
68
+ | `color_mode`
69
+ | `color_scale`
70
+ | `show_stable`
71
+ | `show_unstable`
72
+ | `entry_category`
73
+ | `hidden_categories`
74
+ | `show_stable_labels`
75
+ | `show_unstable_labels`
76
+ | `max_hull_dist_show_phases`
77
+ | `max_hull_dist_show_labels`
78
+ | `energy_source_mode`
79
+ | `controls_open`
80
+ | `show_hull_faces`
81
+ | `hull_face_color`
82
+ | `hull_face_opacity`
83
+ | `hull_face_color_mode`
84
+ > &
85
+ Pick<ComponentProps<typeof ConvexHullInfoPane>, `phase_stats` | `label_threshold`> & {
88
86
  interactions: ReturnType<typeof create_canvas_interactions>
89
87
  hull_data: ReturnType<typeof create_hull_data_pipeline<ConvexHullEntry>>
90
88
  controls_config: ShowControlsState
@@ -107,12 +105,7 @@
107
105
  {#if controls_config.mode !== `never`}
108
106
  <section class="control-buttons {controls_config.class}">
109
107
  {#if controls_config.visible(`reset`)}
110
- <button
111
- type="button"
112
- onclick={reset_all}
113
- title={reset_title}
114
- class="reset-camera-btn"
115
- >
108
+ <button type="button" onclick={reset_all} title={reset_title} class="reset-camera-btn">
116
109
  <Icon icon="Reset" />
117
110
  </button>
118
111
  {/if}
@@ -159,14 +152,14 @@
159
152
  {merged_controls}
160
153
  toggle_props={{ class: `legend-controls-btn` }}
161
154
  {show_hull_faces}
162
- on_hull_faces_change={(value: boolean) => show_hull_faces = value}
155
+ on_hull_faces_change={(value: boolean) => (show_hull_faces = value)}
163
156
  {hull_face_color}
164
- on_hull_face_color_change={(value: string) => hull_face_color = value}
157
+ on_hull_face_color_change={(value: string) => (hull_face_color = value)}
165
158
  {hull_face_opacity}
166
- on_hull_face_opacity_change={(value: number) => hull_face_opacity = value}
159
+ on_hull_face_opacity_change={(value: number) => (hull_face_opacity = value)}
167
160
  {hull_face_color_mode}
168
161
  on_hull_face_color_mode_change={(value: HullFaceColorMode) =>
169
- hull_face_color_mode = value}
162
+ (hull_face_color_mode = value)}
170
163
  bind:energy_source_mode
171
164
  has_precomputed_e_form={hull_data.has_precomputed_e_form}
172
165
  can_compute_e_form={hull_data.can_compute_e_form}
@@ -181,8 +174,7 @@
181
174
  {#if interactions.hover_data}
182
175
  {@const { entry, position } = interactions.hover_data}
183
176
  {@const entry_highlight = is_highlighted(entry) ? merged_highlight_style : undefined}
184
- {@const tooltip_style =
185
- `z-index: ${CONVEX_HULL_STYLE.z_index.tooltip}; backdrop-filter: blur(4px);
177
+ {@const tooltip_style = `z-index: ${CONVEX_HULL_STYLE.z_index.tooltip}; backdrop-filter: blur(4px);
186
178
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);`}
187
179
  <PlotTooltip
188
180
  x={position.x}
@@ -209,7 +201,11 @@
209
201
  />
210
202
 
211
203
  <!-- z-index 1: above auto-stacked siblings after the chrome (3D gizmo, gas controls), below z-2 sliders -->
212
- <DragOverlay visible={interactions.drag_over} style="z-index: 1" />
204
+ <DragOverlay
205
+ visible={interactions.drag_over}
206
+ message="Drop JSON file to load phase diagram data"
207
+ style="z-index: 1"
208
+ />
213
209
 
214
210
  {#if interactions.modal_open && interactions.selected_structure}
215
211
  <StructurePopup
@@ -260,7 +256,7 @@
260
256
  color: var(--text-color, currentColor);
261
257
  transition: background-color 0.2s;
262
258
  display: flex;
263
- font-size: clamp(0.85em, 2cqmin, 1.3em);
259
+ font-size: var(--ctrl-btn-icon-size, clamp(0.7rem, 2cqmin, 0.85rem));
264
260
  }
265
261
  .control-buttons :global(button):hover {
266
262
  background-color: color-mix(in srgb, currentColor 8%, transparent);