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
@@ -8,7 +8,8 @@
8
8
  import Icon from '../Icon.svelte'
9
9
  import type { D3SymbolName } from '../labels'
10
10
  import { symbol_map } from '../labels'
11
- import { set_fullscreen_bg, setup_fullscreen_effect } from '../layout'
11
+ import { FullscreenButton, set_fullscreen_bg, setup_fullscreen_effect } from '../layout'
12
+ import type { Point2D, Vec2 } from '../math'
12
13
  import type {
13
14
  AxisConfig,
14
15
  PointStyle,
@@ -25,38 +26,36 @@
25
26
  import ConvexHullTooltip from './ConvexHullTooltip.svelte'
26
27
  import GasPressureControls from './GasPressureControls.svelte'
27
28
  import * as helpers from './helpers'
29
+ import { create_hull_data_pipeline } from './hull-state.svelte'
28
30
  import type { BaseConvexHullProps } from './index'
29
31
  import { CONVEX_HULL_STYLE, default_controls, default_hull_config } from './index'
30
32
  import StructurePopup from './StructurePopup.svelte'
31
33
  import TemperatureSlider from './TemperatureSlider.svelte'
32
34
  import * as thermo from './thermodynamics'
33
- import type {
34
- ConvexHullEntry,
35
- HighlightStyle,
36
- HoverData3D,
37
- PhaseData,
38
- } from './types'
39
- import { compute_hull_stability, is_unary_entry } from './helpers'
35
+ import type { ConvexHullEntry, HighlightStyle, HoverData3D, PhaseData } from './types'
36
+ import { MAGNETIC_ORDERING_CATEGORY } from './types'
40
37
 
41
38
  // Binary convex hull rendered as energy vs composition (x in [0, 1])
42
39
  let {
43
40
  entries = [],
44
41
  controls = {},
45
42
  config = {},
43
+ show_controls,
46
44
  on_point_click,
47
45
  on_point_hover,
48
46
  fullscreen = $bindable(DEFAULTS.convex_hull.binary.fullscreen),
47
+ fullscreen_toggle = true,
49
48
  enable_info_pane = true,
50
49
  wrapper = $bindable(),
51
50
  label_threshold = 50,
52
51
  show_stable = $bindable(DEFAULTS.convex_hull.binary.show_stable),
53
52
  show_unstable = $bindable(DEFAULTS.convex_hull.binary.show_unstable),
53
+ entry_category = MAGNETIC_ORDERING_CATEGORY,
54
+ hidden_categories = $bindable([]),
54
55
  color_mode = $bindable(DEFAULTS.convex_hull.binary.color_mode),
55
- color_scale = $bindable(
56
- DEFAULTS.convex_hull.binary.color_scale as D3InterpolateName,
57
- ),
56
+ color_scale = $bindable(DEFAULTS.convex_hull.binary.color_scale as D3InterpolateName),
58
57
  info_pane_open = $bindable(DEFAULTS.convex_hull.binary.info_pane_open),
59
- legend_pane_open = $bindable(DEFAULTS.convex_hull.binary.legend_pane_open),
58
+ controls_open = $bindable(DEFAULTS.convex_hull.binary.legend_pane_open),
60
59
  max_hull_dist_show_phases = $bindable(
61
60
  DEFAULTS.convex_hull.binary.max_hull_dist_show_phases,
62
61
  ),
@@ -64,9 +63,7 @@
64
63
  DEFAULTS.convex_hull.binary.max_hull_dist_show_labels,
65
64
  ),
66
65
  show_stable_labels = $bindable(DEFAULTS.convex_hull.binary.show_stable_labels),
67
- show_unstable_labels = $bindable(
68
- DEFAULTS.convex_hull.binary.show_unstable_labels,
69
- ),
66
+ show_unstable_labels = $bindable(DEFAULTS.convex_hull.binary.show_unstable_labels),
70
67
  on_file_drop,
71
68
  enable_click_selection = true,
72
69
  enable_structure_preview = true,
@@ -95,7 +92,7 @@
95
92
  } = $props()
96
93
 
97
94
  const merged_controls = $derived({ ...default_controls, ...controls })
98
- const controls_config = $derived(normalize_show_controls(merged_controls.show))
95
+ const controls_config = $derived(normalize_show_controls(show_controls))
99
96
  const merged_config = $derived({
100
97
  ...default_hull_config,
101
98
  point_size: 6, // Binary diagrams use slightly smaller points
@@ -104,95 +101,47 @@
104
101
  margin: { t: 40, r: 40, b: 60, l: 60, ...config.margin },
105
102
  })
106
103
 
104
+ // Narrow deriveds to primitive fields so heavy downstream deriveds (scatter series,
105
+ // hull segments) don't recompute whenever the broad merged_config object is recreated.
106
+ const stable_color = $derived(merged_config.colors?.stable)
107
+ const unstable_color = $derived(merged_config.colors?.unstable)
108
+ const show_hull_line = $derived(merged_config.show_hull)
109
+
107
110
  // Merge highlight style with defaults (consistent with 3D/4D)
108
- const merged_highlight_style = $derived(
109
- helpers.merge_highlight_style(highlight_style),
110
- )
111
+ const merged_highlight_style = $derived(helpers.merge_highlight_style(highlight_style))
111
112
 
112
113
  // Helper to check if entry is highlighted
113
114
  const is_highlighted = (entry: ConvexHullEntry): boolean =>
114
115
  helpers.is_entry_highlighted(entry, highlighted_entries)
115
116
 
116
- // Temperature-dependent free energy support
117
- const { has_temp_data, available_temperatures } = $derived(
118
- helpers.analyze_temperature_data(entries),
119
- )
120
-
121
- // Initialize or reset temperature when it's undefined or no longer valid
122
- $effect(() => {
123
- if (
124
- has_temp_data &&
125
- available_temperatures.length > 0 &&
126
- (temperature === undefined || !available_temperatures.includes(temperature))
127
- ) temperature = available_temperatures[0]
128
- })
129
-
130
- // Filter entries by temperature when in temperature mode
131
- const temp_filtered_entries = $derived(
132
- has_temp_data && temperature !== undefined
133
- ? helpers.filter_entries_at_temperature(entries, temperature, {
134
- interpolate: interpolate_temperature,
135
- max_interpolation_gap,
136
- })
137
- : entries,
138
- )
139
-
140
- // Gas-dependent chemical potential support (corrections based on T, P)
141
- const {
142
- entries: gas_corrected_entries,
143
- analysis: gas_analysis,
144
- merged_config: merged_gas_config,
145
- } = $derived(
146
- helpers.get_gas_corrected_entries(
147
- temp_filtered_entries,
148
- gas_config,
149
- gas_pressures,
150
- temperature ?? helpers.DEFAULT_GAS_TEMP,
151
- ),
152
- )
153
-
154
- let { // Compute energy mode information
155
- has_precomputed_e_form,
156
- has_precomputed_hull,
157
- can_compute_e_form,
158
- can_compute_hull,
159
- energy_mode,
160
- unary_refs,
161
- } = $derived(
162
- helpers.compute_energy_mode_info(
163
- gas_corrected_entries,
164
- thermo.find_lowest_energy_unary_refs,
165
- energy_source_mode,
166
- ),
167
- )
168
-
169
- const effective_entries = $derived(
170
- helpers.get_effective_entries(
171
- gas_corrected_entries,
172
- energy_mode,
173
- unary_refs,
174
- thermo.compute_e_form_per_atom,
175
- ),
176
- )
177
-
178
- // Process data and element set
179
- const pd_data = $derived(thermo.process_hull_entries(effective_entries))
180
-
181
- const polymorph_stats_map = $derived(
182
- helpers.compute_all_polymorph_stats(effective_entries),
183
- ) // Pre-compute polymorph stats once for O(1) tooltip lookups
184
-
185
- const elements = $derived.by(() => {
186
- if (pd_data.elements.length > 2) {
187
- console.error(
188
- `ConvexHull2D: Dataset contains ${pd_data.elements.length} elements, but binary diagrams require exactly 2. Found: [${
189
- pd_data.elements.join(`, `)
190
- }]`,
191
- )
192
- return []
193
- }
194
- return pd_data.elements
117
+ // Shared reactive data pipeline (temperature → gas → energy mode → hull data → threshold)
118
+ // Explicit generic breaks the circular type inference through the all_enriched_entries thunk
119
+ const hull_data = create_hull_data_pipeline<ConvexHullEntry>({
120
+ dim: 2,
121
+ entries: () => entries,
122
+ temperature: () => temperature,
123
+ interpolate_temperature: () => interpolate_temperature,
124
+ max_interpolation_gap: () => max_interpolation_gap,
125
+ gas_config: () => gas_config,
126
+ gas_pressures: () => gas_pressures,
127
+ energy_source_mode: () => energy_source_mode,
128
+ all_enriched_entries: () => all_enriched_entries,
129
+ max_hull_dist_show_phases: () => max_hull_dist_show_phases,
130
+ show_stable: () => show_stable,
131
+ show_unstable: () => show_unstable,
132
+ entry_category: () => entry_category,
133
+ hidden_categories: () => hidden_categories,
134
+ keep_plot_entry: helpers.entry_within_hull_dist,
135
+ set_temperature: (next_temp) => (temperature = next_temp),
136
+ set_max_hull_dist_show_phases: (value) => (max_hull_dist_show_phases = value),
137
+ set_stable_entries: (value) => (stable_entries = value),
138
+ set_unstable_entries: (value) => (unstable_entries = value),
195
139
  })
140
+ const merged_gas_config = $derived(hull_data.merged_gas_config)
141
+ const elements = $derived(hull_data.elements)
142
+ const auto_default_threshold = $derived(hull_data.auto_default_threshold)
143
+ const plot_entries = $derived(hull_data.plot_entries)
144
+ const visible_entries = $derived(hull_data.visible_entries)
196
145
 
197
146
  // Coordinate computation ----------------------------------------------------
198
147
  function compute_binary_coordinates(
@@ -209,7 +158,7 @@
209
158
  const total = Object.values(entry.composition).reduce((sum, amount) => sum + amount, 0)
210
159
  if (total <= 0) continue
211
160
  const frac_b = (entry.composition[el2] || 0) / total
212
- const is_element = is_unary_entry(entry)
161
+ const is_element = helpers.is_unary_entry(entry)
213
162
  coords.push({ ...entry, x: frac_b, y: e_form, z: 0, is_element })
214
163
  }
215
164
  // Ensure elemental references at x=0 and x=1 with y=0 to close the hull
@@ -234,7 +183,7 @@
234
183
  const coords_entries = $derived.by(() => {
235
184
  if (elements.length !== 2) return []
236
185
  try {
237
- return compute_binary_coordinates(pd_data.entries, elements)
186
+ return compute_binary_coordinates(hull_data.pd_data.entries, elements)
238
187
  } catch (error) {
239
188
  console.error(`Error computing binary coordinates:`, error)
240
189
  return []
@@ -242,77 +191,43 @@
242
191
  })
243
192
 
244
193
  // Compute hull and enrich entries with e_above_hull (before filtering)
245
- const { all_enriched_entries, hull_points } = $derived.by(() => {
246
- if (coords_entries.length === 0) {
247
- return { all_enriched_entries: [], hull_points: [] }
248
- }
249
-
250
- // Build lower hull input: one minimum-energy point per composition x.
251
- // Excluded entries don't participate in hull construction.
252
- const min_y_by_x = new SvelteMap<number, number>()
253
- for (const entry of coords_entries) {
254
- if (entry.exclude_from_hull) continue
255
- const current_min_y = min_y_by_x.get(entry.x)
256
- if (current_min_y === undefined || entry.y < current_min_y) {
257
- min_y_by_x.set(entry.x, entry.y)
194
+ // Explicit return type breaks circular type inference with the hull_data pipeline
195
+ const { all_enriched_entries, hull_points } = $derived.by(
196
+ (): { all_enriched_entries: ConvexHullEntry[]; hull_points: Point2D[] } => {
197
+ if (coords_entries.length === 0) {
198
+ return { all_enriched_entries: [], hull_points: [] }
258
199
  }
259
- }
260
-
261
- const hull_input = [...min_y_by_x].map(([x_coord, min_y]) => ({
262
- x: x_coord,
263
- y: min_y,
264
- }))
265
- const computed_hull_points = thermo.compute_lower_hull_2d(hull_input)
266
-
267
- const enriched_entries = coords_entries.map((entry) => {
268
- const y_hull = thermo.interpolate_hull_2d(computed_hull_points, entry.x)
269
- const raw_dist = y_hull == null ? 0 : entry.y - y_hull
270
- return { ...entry, ...compute_hull_stability(raw_dist, entry.exclude_from_hull) }
271
- })
272
- return { all_enriched_entries: enriched_entries, hull_points: computed_hull_points }
273
- })
274
200
 
275
- // Auto threshold: show all for few entries, use default for many, interpolate between
276
- const max_hull_dist_in_data = $derived(
277
- helpers.calc_max_hull_dist_in_data(all_enriched_entries),
278
- )
279
- const auto_default_threshold = $derived(helpers.compute_auto_hull_dist_threshold(
280
- all_enriched_entries.length,
281
- max_hull_dist_in_data,
282
- DEFAULTS.convex_hull.binary.max_hull_dist_show_phases,
283
- ))
284
-
285
- const next_auto_threshold = helpers.auto_threshold_reset(
286
- DEFAULTS.convex_hull.binary.max_hull_dist_show_phases,
287
- )
288
- $effect(() => {
289
- max_hull_dist_show_phases = next_auto_threshold(
290
- entries,
291
- max_hull_dist_show_phases,
292
- auto_default_threshold,
293
- ) ?? max_hull_dist_show_phases
294
- })
201
+ // Build lower hull input: one minimum-energy point per composition x.
202
+ // Excluded entries don't participate in hull construction.
203
+ const min_y_by_x = new SvelteMap<number, number>()
204
+ for (const entry of coords_entries) {
205
+ if (entry.exclude_from_hull) continue
206
+ const current_min_y = min_y_by_x.get(entry.x)
207
+ if (current_min_y === undefined || entry.y < current_min_y) {
208
+ min_y_by_x.set(entry.x, entry.y)
209
+ }
210
+ }
295
211
 
296
- // Filter by threshold; visibility is a view predicate, not entry state.
297
- const plot_entries = $derived(
298
- all_enriched_entries.filter((entry) =>
299
- helpers.entry_is_stable(entry) ||
300
- (entry.e_above_hull ?? 0) <= max_hull_dist_show_phases
301
- ),
212
+ const hull_input = [...min_y_by_x].map(([x_coord, min_y]) => ({
213
+ x: x_coord,
214
+ y: min_y,
215
+ }))
216
+ const computed_hull_points = thermo.compute_lower_hull_2d(hull_input)
217
+
218
+ const enriched_entries = coords_entries.map((entry) => {
219
+ const y_hull = thermo.interpolate_hull_2d(computed_hull_points, entry.x)
220
+ // degenerate hull (<2 points): y_hull null -> unknown distance (not 0/stable)
221
+ const raw_dist = y_hull == null ? undefined : entry.y - y_hull
222
+ return {
223
+ ...entry,
224
+ ...helpers.compute_hull_stability(raw_dist, entry.exclude_from_hull),
225
+ }
226
+ })
227
+ return { all_enriched_entries: enriched_entries, hull_points: computed_hull_points }
228
+ },
302
229
  )
303
230
 
304
- // Update bindable entries arrays when plot_entries change (single pass)
305
- $effect(() => {
306
- const stable: ConvexHullEntry[] = []
307
- const unstable: ConvexHullEntry[] = []
308
- for (const entry of plot_entries) {
309
- if (helpers.entry_is_stable(entry)) stable.push(entry)
310
- else unstable.push(entry)
311
- }
312
- stable_entries = stable
313
- unstable_entries = unstable
314
- })
315
-
316
231
  let reset_counter = $state(0)
317
232
  // Drag and drop state (to match 3D/4D components)
318
233
  let drag_over = $state(false)
@@ -333,17 +248,16 @@
333
248
  })
334
249
 
335
250
  // Axis mapping helpers ------------------------------------------------------
336
- const x_domain = $derived<[number, number]>([0, 1])
337
- const y_domain = $derived.by((): [number, number] => {
251
+ const x_domain = $derived<Vec2>([0, 1])
252
+ const y_domain = $derived.by((): Vec2 => {
338
253
  const ys = plot_entries.map((entry) => entry.y)
339
254
  if (ys.length === 0) return [-1, 0]
340
- const min_y_data = Math.min(...ys)
341
- const max_y_data = Math.max(...ys)
255
+ const min_y_data = helpers.array_min(ys)
256
+ const max_y_data = helpers.array_max(ys)
342
257
  const span = Math.max(1e-9, max_y_data - min_y_data)
343
258
  const pad = 0.05 * span
344
259
  return [min_y_data - pad, max_y_data + pad]
345
260
  })
346
-
347
261
  // Build ScatterPlot series --------------------------------------------------
348
262
 
349
263
  // Map MarkerSymbol to D3SymbolName (type-safe via symbol_map lookup)
@@ -353,13 +267,6 @@
353
267
  return name in symbol_map ? (name as D3SymbolName) : undefined
354
268
  }
355
269
 
356
- // Pre-compute visible entries to avoid redundant filtering
357
- const visible_entries = $derived(helpers.visible_entries(
358
- plot_entries,
359
- show_stable,
360
- show_unstable,
361
- ))
362
-
363
270
  const scatter_points_series = $derived.by(() => {
364
271
  const is_energy_mode = color_mode === `energy`
365
272
  const count = visible_entries.length
@@ -381,15 +288,19 @@
381
288
  const hl = is_highlighted(entry) ? merged_highlight_style : null
382
289
 
383
290
  point_style[idx] = {
384
- fill: hl?.effect === `color` || hl?.effect === `both`
385
- ? hl?.color
386
- : is_energy_mode
387
- ? undefined
388
- : merged_config.colors?.[is_stable ? `stable` : `unstable`],
291
+ fill:
292
+ hl?.effect === `color` || hl?.effect === `both`
293
+ ? hl?.color
294
+ : is_energy_mode
295
+ ? undefined
296
+ : is_stable
297
+ ? stable_color
298
+ : unstable_color,
389
299
  stroke: is_stable ? `#ffffff` : `#000000`,
390
- radius: hl?.effect === `size` || hl?.effect === `both`
391
- ? base_radius * (hl?.size_multiplier ?? 1)
392
- : base_radius,
300
+ radius:
301
+ hl?.effect === `size` || hl?.effect === `both`
302
+ ? base_radius * (hl?.size_multiplier ?? 1)
303
+ : base_radius,
393
304
  symbol_type: marker_to_d3_symbol(entry.marker),
394
305
  is_highlighted: Boolean(hl),
395
306
  highlight_effect: hl?.effect,
@@ -400,7 +311,9 @@
400
311
  return {
401
312
  x: x_vals,
402
313
  y: y_vals,
403
- metadata: visible_entries,
314
+ // ConvexHullEntry is an interface (no implicit index signature), so cast for
315
+ // ScatterPlot's Metadata extends Record<string, unknown> constraint
316
+ metadata: visible_entries as (ConvexHullEntry & Record<string, unknown>)[],
404
317
  markers: `points` as const,
405
318
  point_style,
406
319
  ...(is_energy_mode ? { color_values } : {}),
@@ -408,7 +321,7 @@
408
321
  })
409
322
 
410
323
  const hull_segments_series = $derived.by(() => {
411
- if (!merged_config.show_hull || hull_points.length < 2) return []
324
+ if (!show_hull_line || hull_points.length < 2) return []
412
325
  const segments = []
413
326
  for (let idx = 0; idx < hull_points.length - 1; idx++) {
414
327
  const p1 = hull_points[idx]
@@ -447,22 +360,18 @@
447
360
  phase_stats = thermo.get_convex_hull_stats(plot_entries, elements, 3)
448
361
  })
449
362
 
450
- function extract_structure_from_entry(
451
- entry: ConvexHullEntry,
452
- ): AnyStructure | null {
453
- if (!entry.entry_id) return null
454
- const orig_entry = entries.find((ent) => ent.entry_id === entry.entry_id)
455
- return orig_entry?.structure as AnyStructure || null
456
- }
363
+ const extract_structure_from_entry = (entry: ConvexHullEntry): AnyStructure | null =>
364
+ helpers.extract_structure_from_entry(entries, entry)
457
365
 
458
366
  function reset_all() {
459
367
  fullscreen = DEFAULTS.convex_hull.binary.fullscreen
460
368
  info_pane_open = DEFAULTS.convex_hull.binary.info_pane_open
461
- legend_pane_open = DEFAULTS.convex_hull.binary.legend_pane_open
369
+ controls_open = DEFAULTS.convex_hull.binary.legend_pane_open
462
370
  color_mode = DEFAULTS.convex_hull.binary.color_mode
463
371
  color_scale = DEFAULTS.convex_hull.binary.color_scale as D3InterpolateName
464
372
  show_stable = DEFAULTS.convex_hull.binary.show_stable
465
373
  show_unstable = DEFAULTS.convex_hull.binary.show_unstable
374
+ hidden_categories = []
466
375
  show_stable_labels = DEFAULTS.convex_hull.binary.show_stable_labels
467
376
  show_unstable_labels = DEFAULTS.convex_hull.binary.show_unstable_labels
468
377
  // Use auto-computed threshold based on entry count instead of static default
@@ -477,17 +386,17 @@
477
386
  const has_changes_to_reset = $derived(
478
387
  fullscreen !== DEFAULTS.convex_hull.binary.fullscreen ||
479
388
  info_pane_open !== DEFAULTS.convex_hull.binary.info_pane_open ||
480
- legend_pane_open !== DEFAULTS.convex_hull.binary.legend_pane_open ||
389
+ controls_open !== DEFAULTS.convex_hull.binary.legend_pane_open ||
481
390
  color_mode !== DEFAULTS.convex_hull.binary.color_mode ||
482
391
  color_scale !== DEFAULTS.convex_hull.binary.color_scale ||
483
392
  show_stable !== DEFAULTS.convex_hull.binary.show_stable ||
484
393
  show_unstable !== DEFAULTS.convex_hull.binary.show_unstable ||
394
+ hidden_categories.length > 0 ||
485
395
  show_stable_labels !== DEFAULTS.convex_hull.binary.show_stable_labels ||
486
396
  show_unstable_labels !== DEFAULTS.convex_hull.binary.show_unstable_labels ||
487
397
  // Compare with auto-computed threshold, with small tolerance for floating point
488
398
  Math.abs(max_hull_dist_show_phases - auto_default_threshold) > 0.001 ||
489
- max_hull_dist_show_labels !==
490
- DEFAULTS.convex_hull.binary.max_hull_dist_show_labels,
399
+ max_hull_dist_show_labels !== DEFAULTS.convex_hull.binary.max_hull_dist_show_labels,
491
400
  )
492
401
 
493
402
  // Custom hover tooltip state used with ScatterPlot events
@@ -508,11 +417,13 @@
508
417
  const current_popup = helpers.current_entry(structure_popup.entry, plot_entries)
509
418
  if (structure_popup.open) {
510
419
  const structure = current_popup && extract_structure_from_entry(current_popup)
511
- if (!structure) structure_popup = { open: false, structure: null, entry: null, place_right: true }
420
+ if (!structure)
421
+ structure_popup = { open: false, structure: null, entry: null, place_right: true }
512
422
  else if (
513
423
  current_popup !== structure_popup.entry ||
514
424
  structure !== structure_popup.structure
515
- ) structure_popup = { ...structure_popup, entry: current_popup, structure }
425
+ )
426
+ structure_popup = { ...structure_popup, entry: current_popup, structure }
516
427
  }
517
428
  })
518
429
 
@@ -520,10 +431,10 @@
520
431
  const target = event.target
521
432
  if (target instanceof HTMLElement && target.tagName.match(/INPUT|TEXTAREA/)) return
522
433
  const actions: Record<string, () => void> = {
523
- b: () => color_mode = color_mode === `stability` ? `energy` : `stability`,
524
- s: () => show_stable = !show_stable,
525
- u: () => show_unstable = !show_unstable,
526
- l: () => show_stable_labels = !show_stable_labels,
434
+ b: () => (color_mode = color_mode === `stability` ? `energy` : `stability`),
435
+ s: () => (show_stable = !show_stable),
436
+ u: () => (show_unstable = !show_unstable),
437
+ l: () => (show_stable_labels = !show_stable_labels),
527
438
  }
528
439
  actions[event.key.toLowerCase()]?.()
529
440
  }
@@ -534,14 +445,16 @@
534
445
  if (data) on_file_drop?.(data)
535
446
  }
536
447
 
537
- async function copy_entry_data(
538
- entry: ConvexHullEntry,
539
- position: { x: number; y: number },
540
- ) {
541
- await helpers.copy_entry_to_clipboard(entry, position, (visible, pos) => {
542
- copy_feedback.visible = visible
543
- copy_feedback.position = pos
544
- })
448
+ async function copy_entry_data(entry: ConvexHullEntry, position: { x: number; y: number }) {
449
+ await helpers.copy_entry_to_clipboard(
450
+ entry,
451
+ position,
452
+ (visible, pos) => {
453
+ copy_feedback.visible = visible
454
+ copy_feedback.position = pos
455
+ },
456
+ entry_category,
457
+ )
545
458
  }
546
459
 
547
460
  function close_structure_popup() {
@@ -558,8 +471,7 @@
558
471
  if (!entry) return
559
472
 
560
473
  const now = Date.now()
561
- const is_double_click = last_clicked_entry === entry &&
562
- now - last_click_time < 300
474
+ const is_double_click = last_clicked_entry === entry && now - last_click_time < 300
563
475
 
564
476
  if (is_double_click) {
565
477
  // Double-click: copy to clipboard
@@ -597,33 +509,27 @@
597
509
  set_fullscreen_bg(wrapper, fullscreen, `--hull-2d-bg-fullscreen`)
598
510
  })
599
511
 
600
- let style = $derived(
601
- `--hull-stable-color:${merged_config.colors?.stable || `#0072B2`};
602
- --hull-unstable-color:${merged_config.colors?.unstable || `#E69F00`};
603
- --hull-edge-color:${merged_config.colors?.edge || `var(--text-color, #212121)`};
604
- --hull-text-color:${
605
- merged_config.colors?.annotation || `var(--text-color, #212121)`
606
- };`,
607
- )
512
+ let style = $derived(helpers.hull_style_css(merged_config.colors))
608
513
  </script>
609
514
 
610
515
  <svelte:document
611
516
  onfullscreenchange={() => {
612
- fullscreen = Boolean(document.fullscreenElement)
517
+ // tie fullscreen state to this component's own wrapper, not any fullscreen element
518
+ fullscreen = document.fullscreenElement === wrapper
613
519
  }}
614
520
  />
615
521
 
616
522
  <!-- Hover tooltip matching 3D/4D style (content only; container handled by ScatterPlot) -->
617
523
  {#snippet tooltip(point: ScatterHandlerProps<ConvexHullEntry>)}
618
524
  {@const entry = point.metadata}
619
- {@const entry_highlight = entry && is_highlighted(entry)
620
- ? merged_highlight_style
621
- : undefined}
525
+ {@const entry_highlight =
526
+ entry && is_highlighted(entry) ? merged_highlight_style : undefined}
622
527
  {#if entry}
623
528
  <ConvexHullTooltip
624
529
  {entry}
625
- {polymorph_stats_map}
530
+ polymorph_stats_map={hull_data.polymorph_stats_map}
626
531
  highlight_style={entry_highlight}
532
+ {entry_category}
627
533
  tooltip={custom_tooltip}
628
534
  />
629
535
  {/if}
@@ -650,6 +556,8 @@
650
556
  {unstable_entries}
651
557
  {show_stable}
652
558
  {show_unstable}
559
+ {entry_category}
560
+ {hidden_categories}
653
561
  {max_hull_dist_show_phases}
654
562
  {max_hull_dist_show_labels}
655
563
  {label_threshold}
@@ -657,35 +565,46 @@
657
565
  />
658
566
  {/if}
659
567
 
568
+ {#if fullscreen_toggle && controls_config.visible(`fullscreen`)}
569
+ <FullscreenButton {fullscreen} toggle={fullscreen_toggle} {wrapper} />
570
+ {/if}
571
+
660
572
  {#if controls_config.visible(`controls`)}
661
573
  <ConvexHullControls
662
- bind:controls_open={legend_pane_open}
574
+ bind:controls_open
663
575
  bind:color_mode
664
576
  bind:color_scale
665
577
  bind:show_stable
666
578
  bind:show_unstable
579
+ {entry_category}
580
+ bind:hidden_categories
667
581
  bind:show_stable_labels
668
582
  bind:show_unstable_labels
669
583
  bind:max_hull_dist_show_phases
670
584
  bind:max_hull_dist_show_labels
671
- {max_hull_dist_in_data}
585
+ max_hull_dist_in_data={hull_data.max_hull_dist_in_data}
672
586
  {stable_entries}
673
587
  {unstable_entries}
674
588
  {merged_controls}
675
589
  toggle_props={{ class: `control-btn legend-controls-btn` }}
676
590
  bind:energy_source_mode
677
- {has_precomputed_e_form}
678
- {can_compute_e_form}
679
- {has_precomputed_hull}
680
- {can_compute_hull}
591
+ has_precomputed_e_form={hull_data.has_precomputed_e_form}
592
+ can_compute_e_form={hull_data.can_compute_e_form}
593
+ has_precomputed_hull={hull_data.has_precomputed_hull}
594
+ can_compute_hull={hull_data.can_compute_hull}
681
595
  />
682
596
  {/if}
683
597
  {/if}
684
598
  {/snippet}
685
599
 
686
- {#snippet user_content(
687
- { x_scale_fn, pad, height, y_scale_fn, y_range, width }: UserContentProps,
688
- )}
600
+ {#snippet user_content({
601
+ x_scale_fn,
602
+ pad,
603
+ height,
604
+ y_scale_fn,
605
+ y_range,
606
+ width,
607
+ }: UserContentProps)}
689
608
  {@const [x0, x1, y0] = [x_scale_fn(0), x_scale_fn(1), y_scale_fn(y_range[0])]}
690
609
  {@const stroke = {
691
610
  stroke: `var(--scatter-grid-stroke, gray)`,
@@ -699,7 +618,7 @@
699
618
  {#key reset_counter}
700
619
  <ScatterPlot
701
620
  {...rest}
702
- class="convex-hull-2d {rest.class ?? ``} {drag_over ? `dragover` : ``}"
621
+ class={[`convex-hull-2d`, rest.class, drag_over && `dragover`]}
703
622
  style={`${style}; ${rest.style ?? ``}`}
704
623
  data-has-selection={selected_entry !== null}
705
624
  bind:wrapper
@@ -720,6 +639,7 @@
720
639
  series={scatter_series}
721
640
  bind:display
722
641
  controls={{ show: false }}
642
+ fullscreen_toggle={false}
723
643
  x_axis={{
724
644
  label: elements.length === 2 ? `x in ${elements[0]}₁₋ₓ ${elements[1]}ₓ` : `x`,
725
645
  range: x_domain,
@@ -750,9 +670,7 @@
750
670
  return
751
671
  }
752
672
  const { metadata: entry, event } = data
753
- hover_data = entry
754
- ? { entry, position: { x: event.clientX, y: event.clientY } }
755
- : null
673
+ hover_data = entry ? { entry, position: { x: event.clientX, y: event.clientY } } : null
756
674
  on_point_hover?.(hover_data)
757
675
  }}
758
676
  padding={{ t: 30, b: 60, l: 60, r: 30 }}
@@ -767,17 +685,17 @@
767
685
  {@html sanitize_html(merged_controls.title || phase_stats?.chemical_system || ``)}
768
686
  </h3>
769
687
 
770
- <ClickFeedback
771
- bind:visible={copy_feedback.visible}
772
- position={copy_feedback.position}
773
- />
774
- <DragOverlay visible={drag_over} />
688
+ <ClickFeedback bind:visible={copy_feedback.visible} position={copy_feedback.position} />
689
+ <DragOverlay visible={drag_over} message="Drop JSON file to load phase diagram data" />
775
690
 
776
- {#if has_temp_data && temperature !== undefined}
777
- <TemperatureSlider {available_temperatures} bind:temperature />
691
+ {#if hull_data.has_temp_data && temperature !== undefined}
692
+ <TemperatureSlider
693
+ available_temperatures={hull_data.available_temperatures}
694
+ bind:temperature
695
+ />
778
696
  {/if}
779
697
 
780
- {#if gas_analysis.has_gas_dependent_elements && merged_gas_config}
698
+ {#if hull_data.gas_analysis.has_gas_dependent_elements && merged_gas_config}
781
699
  <GasPressureControls
782
700
  config={merged_gas_config}
783
701
  bind:pressures={gas_pressures}
@@ -802,26 +720,28 @@
802
720
 
803
721
  <style>
804
722
  :global(.convex-hull-2d:fullscreen) {
805
- background: var(--hull-2d-bg-fullscreen, var(--hull-2d-bg, var(--hull-bg)))
806
- !important;
723
+ background: var(--hull-2d-bg-fullscreen, var(--hull-2d-bg, var(--hull-bg))) !important;
807
724
  overflow: hidden;
808
725
  }
809
726
  :global(.convex-hull-2d.dragover) {
810
727
  border: 2px dashed var(--accent-color, #1976d2) !important;
811
728
  }
812
- /* Styles for control buttons rendered via header_controls snippet */
813
- :global(.convex-hull-2d .control-btn) {
729
+ /* Styles for control buttons rendered via header_controls snippet
730
+ (.fullscreen-btn is FullscreenButton's built-in class) */
731
+ :global(.convex-hull-2d :is(.control-btn, .fullscreen-btn)) {
814
732
  background: transparent;
815
733
  border: none;
816
734
  padding: 4px;
817
735
  cursor: pointer;
818
736
  border-radius: 3px;
819
737
  color: var(--text-color, currentColor);
820
- transition: background-color 0.2s, opacity 0.2s;
738
+ transition:
739
+ background-color 0.2s,
740
+ opacity 0.2s;
821
741
  display: flex;
822
- font-size: clamp(0.85em, 2cqmin, 1.3em);
742
+ font-size: var(--ctrl-btn-icon-size, clamp(0.7rem, 2cqmin, 0.85rem));
823
743
  }
824
- :global(.convex-hull-2d .control-btn:hover) {
744
+ :global(.convex-hull-2d :is(.control-btn, .fullscreen-btn):hover) {
825
745
  background-color: color-mix(in srgb, currentColor 8%, transparent);
826
746
  }
827
747
  </style>