matterviz 0.3.2 → 0.3.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 (280) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +123 -82
  3. package/dist/Icon.svelte +18 -12
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -207
  7. package/dist/brillouin/BrillouinZone.svelte +292 -149
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
  20. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
  21. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  22. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  23. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  24. package/dist/chempot-diagram/chempot-worker.js +11 -0
  25. package/dist/chempot-diagram/color.js +1 -2
  26. package/dist/chempot-diagram/compute.d.ts +10 -0
  27. package/dist/chempot-diagram/compute.js +250 -88
  28. package/dist/chempot-diagram/index.d.ts +2 -1
  29. package/dist/chempot-diagram/index.js +2 -1
  30. package/dist/chempot-diagram/temperature.js +8 -9
  31. package/dist/chempot-diagram/types.d.ts +3 -0
  32. package/dist/chempot-diagram/types.js +1 -0
  33. package/dist/colors/index.d.ts +1 -1
  34. package/dist/colors/index.js +5 -3
  35. package/dist/composition/BarChart.svelte +128 -55
  36. package/dist/composition/BubbleChart.svelte +102 -49
  37. package/dist/composition/Composition.svelte +100 -79
  38. package/dist/composition/Formula.svelte +108 -62
  39. package/dist/composition/FormulaFilter.svelte +665 -537
  40. package/dist/composition/PieChart.svelte +183 -108
  41. package/dist/composition/format.d.ts +5 -0
  42. package/dist/composition/format.js +20 -3
  43. package/dist/composition/parse.js +14 -9
  44. package/dist/convex-hull/ConvexHull.svelte +93 -40
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +549 -360
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  53. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  54. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  55. package/dist/convex-hull/ConvexHullStats.svelte +425 -328
  56. package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
  57. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  58. package/dist/convex-hull/StructurePopup.svelte +25 -4
  59. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  60. package/dist/convex-hull/barycentric-coords.js +13 -7
  61. package/dist/convex-hull/demo-temperature.js +8 -4
  62. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  63. package/dist/convex-hull/helpers.d.ts +9 -0
  64. package/dist/convex-hull/helpers.js +77 -34
  65. package/dist/convex-hull/thermodynamics.js +61 -56
  66. package/dist/convex-hull/types.d.ts +9 -14
  67. package/dist/convex-hull/types.js +0 -17
  68. package/dist/coordination/CoordinationBarPlot.svelte +227 -154
  69. package/dist/element/BohrAtom.svelte +55 -12
  70. package/dist/element/ElementHeading.svelte +7 -2
  71. package/dist/element/ElementPhoto.svelte +15 -9
  72. package/dist/element/ElementStats.svelte +10 -4
  73. package/dist/element/ElementTile.svelte +137 -73
  74. package/dist/element/Nucleus.svelte +39 -11
  75. package/dist/feedback/ClickFeedback.svelte +16 -5
  76. package/dist/feedback/DragOverlay.svelte +10 -2
  77. package/dist/feedback/Spinner.svelte +4 -2
  78. package/dist/feedback/StatusMessage.svelte +8 -2
  79. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  80. package/dist/fermi-surface/FermiSurface.svelte +328 -187
  81. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  82. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  83. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  84. package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
  85. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  86. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  87. package/dist/fermi-surface/compute.js +16 -20
  88. package/dist/fermi-surface/parse.js +24 -14
  89. package/dist/fermi-surface/symmetry.js +2 -7
  90. package/dist/fermi-surface/types.d.ts +3 -5
  91. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
  92. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
  93. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
  94. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
  95. package/dist/icons.js +47 -0
  96. package/dist/index.d.ts +2 -1
  97. package/dist/index.js +2 -1
  98. package/dist/io/decompress.js +1 -1
  99. package/dist/io/export.d.ts +3 -0
  100. package/dist/io/export.js +129 -143
  101. package/dist/io/is-binary.js +2 -3
  102. package/dist/io/url-drop.js +1 -2
  103. package/dist/isosurface/Isosurface.svelte +202 -148
  104. package/dist/isosurface/IsosurfaceControls.svelte +46 -28
  105. package/dist/isosurface/parse.js +34 -29
  106. package/dist/isosurface/slice.js +5 -10
  107. package/dist/isosurface/types.d.ts +2 -1
  108. package/dist/isosurface/types.js +61 -12
  109. package/dist/labels.js +11 -8
  110. package/dist/layout/FullscreenToggle.svelte +11 -2
  111. package/dist/layout/InfoCard.svelte +38 -6
  112. package/dist/layout/InfoTag.svelte +63 -32
  113. package/dist/layout/PropertyFilter.svelte +82 -37
  114. package/dist/layout/SettingsSection.svelte +85 -55
  115. package/dist/layout/SubpageGrid.svelte +10 -2
  116. package/dist/layout/json-tree/JsonNode.svelte +183 -138
  117. package/dist/layout/json-tree/JsonTree.svelte +499 -413
  118. package/dist/layout/json-tree/JsonValue.svelte +127 -99
  119. package/dist/layout/json-tree/utils.js +4 -2
  120. package/dist/marching-cubes.js +25 -2
  121. package/dist/math.d.ts +13 -17
  122. package/dist/math.js +133 -67
  123. package/dist/overlays/ContextMenu.svelte +65 -40
  124. package/dist/overlays/DraggablePane.svelte +211 -139
  125. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  126. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  127. package/dist/periodic-table/PropertySelect.svelte +25 -7
  128. package/dist/periodic-table/TableInset.svelte +8 -3
  129. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  131. package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  133. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
  134. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
  136. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
  137. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  138. package/dist/phase-diagram/build-diagram.js +9 -9
  139. package/dist/phase-diagram/colors.js +1 -3
  140. package/dist/phase-diagram/parse.js +10 -9
  141. package/dist/phase-diagram/svg-to-diagram.js +53 -49
  142. package/dist/phase-diagram/utils.d.ts +1 -0
  143. package/dist/phase-diagram/utils.js +80 -25
  144. package/dist/plot/AxisLabel.svelte +28 -3
  145. package/dist/plot/BarPlot.svelte +1182 -734
  146. package/dist/plot/BarPlot.svelte.d.ts +2 -2
  147. package/dist/plot/BarPlotControls.svelte +31 -5
  148. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  149. package/dist/plot/ColorBar.svelte +479 -329
  150. package/dist/plot/ColorScaleSelect.svelte +27 -6
  151. package/dist/plot/ElementScatter.svelte +36 -15
  152. package/dist/plot/FillArea.svelte +152 -95
  153. package/dist/plot/Histogram.svelte +934 -571
  154. package/dist/plot/Histogram.svelte.d.ts +1 -1
  155. package/dist/plot/HistogramControls.svelte +53 -9
  156. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  157. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  158. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  159. package/dist/plot/Line.svelte +63 -28
  160. package/dist/plot/PlotControls.svelte +157 -114
  161. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  162. package/dist/plot/PlotLegend.svelte +174 -91
  163. package/dist/plot/PlotTooltip.svelte +45 -6
  164. package/dist/plot/PortalSelect.svelte +175 -147
  165. package/dist/plot/ReferenceLine.svelte +76 -22
  166. package/dist/plot/ReferenceLine3D.svelte +132 -107
  167. package/dist/plot/ReferencePlane.svelte +146 -121
  168. package/dist/plot/ScatterPlot.svelte +1681 -1091
  169. package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
  170. package/dist/plot/ScatterPlot3D.svelte +256 -131
  171. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  172. package/dist/plot/ScatterPlot3DControls.svelte +113 -63
  173. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  174. package/dist/plot/ScatterPlot3DScene.svelte +608 -403
  175. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  176. package/dist/plot/ScatterPlotControls.svelte +65 -25
  177. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  178. package/dist/plot/ScatterPoint.svelte +98 -26
  179. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  180. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  181. package/dist/plot/Surface3D.svelte +159 -108
  182. package/dist/plot/ZeroLines.svelte +55 -3
  183. package/dist/plot/ZoomRect.svelte +4 -2
  184. package/dist/plot/axis-utils.js +1 -3
  185. package/dist/plot/data-cleaning.js +12 -28
  186. package/dist/plot/data-transform.js +2 -1
  187. package/dist/plot/fill-utils.js +2 -0
  188. package/dist/plot/layout.d.ts +4 -1
  189. package/dist/plot/layout.js +33 -14
  190. package/dist/plot/reference-line.d.ts +2 -2
  191. package/dist/plot/reference-line.js +7 -5
  192. package/dist/plot/scales.js +24 -36
  193. package/dist/plot/types.d.ts +11 -23
  194. package/dist/plot/types.js +6 -11
  195. package/dist/plot/utils/label-placement.d.ts +32 -15
  196. package/dist/plot/utils/label-placement.js +227 -66
  197. package/dist/plot/utils/series-visibility.js +2 -3
  198. package/dist/rdf/RdfPlot.svelte +143 -91
  199. package/dist/rdf/calc-rdf.js +4 -5
  200. package/dist/sanitize.d.ts +4 -0
  201. package/dist/sanitize.js +107 -0
  202. package/dist/settings.d.ts +18 -6
  203. package/dist/settings.js +46 -16
  204. package/dist/spectral/Bands.svelte +632 -453
  205. package/dist/spectral/BandsAndDos.svelte +90 -49
  206. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  207. package/dist/spectral/Dos.svelte +389 -258
  208. package/dist/spectral/helpers.js +55 -43
  209. package/dist/state.svelte.d.ts +1 -1
  210. package/dist/state.svelte.js +3 -2
  211. package/dist/structure/Arrow.svelte +59 -20
  212. package/dist/structure/AtomLegend.svelte +215 -134
  213. package/dist/structure/Bond.svelte +73 -47
  214. package/dist/structure/CanvasTooltip.svelte +10 -2
  215. package/dist/structure/CellSelect.svelte +72 -45
  216. package/dist/structure/Cylinder.svelte +33 -17
  217. package/dist/structure/Lattice.svelte +88 -33
  218. package/dist/structure/Structure.svelte +1063 -797
  219. package/dist/structure/Structure.svelte.d.ts +1 -1
  220. package/dist/structure/StructureControls.svelte +349 -118
  221. package/dist/structure/StructureExportPane.svelte +124 -89
  222. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  223. package/dist/structure/StructureInfoPane.svelte +304 -237
  224. package/dist/structure/StructureScene.svelte +879 -443
  225. package/dist/structure/StructureScene.svelte.d.ts +15 -7
  226. package/dist/structure/atom-properties.js +8 -8
  227. package/dist/structure/bonding.js +6 -7
  228. package/dist/structure/export.js +14 -29
  229. package/dist/structure/ferrox-wasm.js +1 -1
  230. package/dist/structure/index.d.ts +13 -3
  231. package/dist/structure/index.js +83 -23
  232. package/dist/structure/measure.d.ts +2 -2
  233. package/dist/structure/measure.js +4 -44
  234. package/dist/structure/parse.js +113 -141
  235. package/dist/structure/partial-occupancy.js +7 -10
  236. package/dist/structure/pbc.d.ts +1 -0
  237. package/dist/structure/pbc.js +16 -6
  238. package/dist/structure/supercell.d.ts +2 -2
  239. package/dist/structure/supercell.js +12 -22
  240. package/dist/structure/validation.js +1 -2
  241. package/dist/symmetry/SymmetryStats.svelte +84 -41
  242. package/dist/symmetry/WyckoffTable.svelte +26 -6
  243. package/dist/symmetry/cell-transform.js +5 -3
  244. package/dist/symmetry/index.js +8 -7
  245. package/dist/symmetry/spacegroups.js +148 -148
  246. package/dist/table/HeatmapTable.svelte +790 -554
  247. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  248. package/dist/table/ToggleMenu.svelte +125 -92
  249. package/dist/table/index.js +2 -4
  250. package/dist/theme/ThemeControl.svelte +21 -12
  251. package/dist/time.js +4 -1
  252. package/dist/tooltip/TooltipContent.svelte +33 -8
  253. package/dist/trajectory/Trajectory.svelte +758 -558
  254. package/dist/trajectory/TrajectoryError.svelte +14 -3
  255. package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
  256. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  257. package/dist/trajectory/extract.js +10 -26
  258. package/dist/trajectory/format-detect.js +5 -5
  259. package/dist/trajectory/frame-reader.d.ts +1 -1
  260. package/dist/trajectory/frame-reader.js +5 -12
  261. package/dist/trajectory/helpers.d.ts +0 -1
  262. package/dist/trajectory/helpers.js +2 -17
  263. package/dist/trajectory/index.js +14 -12
  264. package/dist/trajectory/parse/ase.js +5 -4
  265. package/dist/trajectory/parse/hdf5.js +26 -18
  266. package/dist/trajectory/parse/index.js +13 -18
  267. package/dist/trajectory/parse/lammps.js +17 -7
  268. package/dist/trajectory/parse/vasp.js +5 -2
  269. package/dist/trajectory/parse/xyz.js +8 -7
  270. package/dist/trajectory/plotting.js +13 -8
  271. package/dist/utils.d.ts +1 -0
  272. package/dist/utils.js +13 -0
  273. package/dist/xrd/XrdPlot.svelte +337 -247
  274. package/dist/xrd/broadening.js +14 -9
  275. package/dist/xrd/calc-xrd.js +12 -18
  276. package/dist/xrd/parse.d.ts +1 -1
  277. package/dist/xrd/parse.js +17 -17
  278. package/package.json +99 -103
  279. package/readme.md +1 -1
  280. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -43,6 +43,6 @@ type $$ComponentProps = {
43
43
  hovered_qpoint_index?: number | null;
44
44
  hover_data?: BZHoverData | null;
45
45
  };
46
- declare const BrillouinZoneScene: import("svelte").Component<$$ComponentProps, {}, "camera_position" | "camera_projection" | "scene" | "camera" | "camera_is_moving" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "bz_data" | "vector_scale" | "hover_data">;
46
+ declare const BrillouinZoneScene: import("svelte").Component<$$ComponentProps, {}, "camera_position" | "camera_projection" | "vector_scale" | "camera" | "scene" | "camera_is_moving" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "bz_data" | "hover_data">;
47
47
  type BrillouinZoneScene = ReturnType<typeof BrillouinZoneScene>;
48
48
  export default BrillouinZoneScene;
@@ -1,10 +1,20 @@
1
- <script lang="ts">// Tooltip component for Brillouin zone hover information
2
- // Displays k-coordinates, BZ order, volume, and IBZ-specific info
3
- import { format_num, format_vec3 } from '../labels';
4
- import { TooltipContent } from '../tooltip';
5
- let { hover_data, tooltip, } = $props();
6
- // Ordinal for BZ order (only 1-3 in practice)
7
- const ordinal = (num) => `${num}${[`th`, `st`, `nd`, `rd`][num] ?? `th`}`;
1
+ <script lang="ts">
2
+ // Tooltip component for Brillouin zone hover information
3
+ // Displays k-coordinates, BZ order, volume, and IBZ-specific info
4
+ import { format_num, format_vec3 } from '../labels'
5
+ import { TooltipContent } from '../tooltip'
6
+ import type { BZHoverData, BZTooltipProp } from './types'
7
+
8
+ let {
9
+ hover_data,
10
+ tooltip,
11
+ }: {
12
+ hover_data: BZHoverData
13
+ tooltip?: BZTooltipProp
14
+ } = $props()
15
+
16
+ // Ordinal for BZ order (only 1-3 in practice)
17
+ const ordinal = (num: number) => `${num}${[`th`, `st`, `nd`, `rd`][num] ?? `th`}`
8
18
  </script>
9
19
 
10
20
  <TooltipContent data={hover_data} snippet_arg={{ hover_data }} {tooltip}>
@@ -29,11 +29,14 @@ export function extract_point_group_from_operations(operations) {
29
29
  }
30
30
  // Multiply two 3x3 matrices: C = A · B
31
31
  function mat3x3_multiply(A, B) {
32
- const result = [[0, 0, 0], [0, 0, 0], [0, 0, 0]];
32
+ const result = [
33
+ [0, 0, 0],
34
+ [0, 0, 0],
35
+ [0, 0, 0],
36
+ ];
33
37
  for (let row = 0; row < 3; row++) {
34
38
  for (let col = 0; col < 3; col++) {
35
- result[row][col] = A[row][0] * B[0][col] + A[row][1] * B[1][col] +
36
- A[row][2] * B[2][col];
39
+ result[row][col] = A[row][0] * B[0][col] + A[row][1] * B[1][col] + A[row][2] * B[2][col];
37
40
  }
38
41
  }
39
42
  return result;
@@ -164,7 +167,8 @@ max_planes_by_order = { 1: 26, 2: 80, 3: 150 }) {
164
167
  // Count how many planes this vertex is beyond (with early termination)
165
168
  let beyond_count = 0;
166
169
  for (let p_idx = 0; p_idx < normals.length; p_idx++) {
167
- const dot = vertex[0] * normals[p_idx][0] + vertex[1] * normals[p_idx][1] +
170
+ const dot = vertex[0] * normals[p_idx][0] +
171
+ vertex[1] * normals[p_idx][1] +
168
172
  vertex[2] * normals[p_idx][2];
169
173
  if (dot > distances[p_idx] + TOL) {
170
174
  beyond_count++;
@@ -207,9 +211,10 @@ export function compute_convex_hull(vertices, edge_sharp_angle_deg = 5) {
207
211
  const vert_map = new Map();
208
212
  for (let idx_vertex = 0; idx_vertex < pos.count; idx_vertex++) {
209
213
  const vert = [pos.getX(idx_vertex), pos.getY(idx_vertex), pos.getZ(idx_vertex)];
210
- const existing_idx = unique_verts.findIndex((u) => Math.abs(u[0] - vert[0]) < TOL && Math.abs(u[1] - vert[1]) < TOL &&
214
+ const existing_idx = unique_verts.findIndex((u) => Math.abs(u[0] - vert[0]) < TOL &&
215
+ Math.abs(u[1] - vert[1]) < TOL &&
211
216
  Math.abs(u[2] - vert[2]) < TOL);
212
- vert_map.set(idx_vertex, existing_idx === -1 ? (unique_verts.push(vert) - 1) : existing_idx);
217
+ vert_map.set(idx_vertex, existing_idx === -1 ? unique_verts.push(vert) - 1 : existing_idx);
213
218
  }
214
219
  // Build faces with deduplicated vertex indices
215
220
  const faces = [];
@@ -1,25 +1,107 @@
1
- <script lang="ts">import { get_hill_formula } from '../composition/format';
2
- import { format_num } from '../labels';
3
- import ChemPotDiagram2D from './ChemPotDiagram2D.svelte';
4
- import ChemPotDiagram3D from './ChemPotDiagram3D.svelte';
5
- import { CHEMPOT_DEFAULTS } from './types';
6
- let { entries = [], config = {}, width = $bindable(600), height = $bindable(600),
7
- // Bound temperature may be auto-corrected by 2D/3D child components.
8
- temperature = $bindable(), hover_info = $bindable(null), } = $props();
9
- // Extract unique elements from all entries (composition keys are element symbols)
10
- const all_elements = $derived([
11
- ...new Set(entries.flatMap((entry) => Object.entries(entry.composition)
12
- .filter(([, amount]) => amount > 0)
13
- .map(([element]) => element))),
14
- ].sort());
15
- // How many display axes (2 = binary/2D, 3+ = ternary/3D)
16
- const display_elements = $derived(config.elements ?? all_elements);
17
- const n_display = $derived(display_elements.length);
18
- const show_tooltip = $derived(config.show_tooltip ?? CHEMPOT_DEFAULTS.show_tooltip);
19
- const tooltip_detail_level = $derived(config.tooltip_detail_level ?? CHEMPOT_DEFAULTS.tooltip_detail_level);
20
- function is_hover_info_3d(value) {
21
- return value?.view === `3d`;
22
- }
1
+ <script lang="ts">
2
+ import { get_electro_neg_formula } from '../composition/format';
3
+ import type { PhaseData } from '../convex-hull/types';
4
+ import Spinner from '../feedback/Spinner.svelte';
5
+ import { format_num } from '../labels';
6
+ import { constrain_tooltip_position } from '../plot/layout';
7
+ import { sanitize_html } from '../sanitize';
8
+ import { compute_chempot_async } from './async-compute.svelte';
9
+ import ChemPotDiagram2D from './ChemPotDiagram2D.svelte';
10
+ import ChemPotDiagram3D from './ChemPotDiagram3D.svelte';
11
+ import { get_ternary_combinations } from './compute';
12
+ import type {
13
+ ChemPotDiagramConfig,
14
+ ChemPotHoverInfo,
15
+ ChemPotHoverInfo3D,
16
+ } from './types';
17
+ import { CHEMPOT_DEFAULTS } from './types';
18
+
19
+ let {
20
+ entries = [],
21
+ config = {},
22
+ width = $bindable(600),
23
+ height = $bindable(600),
24
+ // Bound temperature may be auto-corrected by 2D/3D child components.
25
+ temperature = $bindable(),
26
+ hover_info = $bindable<ChemPotHoverInfo | null>(null),
27
+ }: {
28
+ entries: PhaseData[]
29
+ config?: ChemPotDiagramConfig
30
+ width?: number
31
+ height?: number
32
+ temperature?: number
33
+ hover_info?: ChemPotHoverInfo | null
34
+ } = $props()
35
+
36
+ // Extract unique elements from all entries (composition keys are element symbols)
37
+ const all_elements = $derived(
38
+ [
39
+ ...new Set(entries.flatMap((entry) =>
40
+ Object.entries(entry.composition)
41
+ .filter(([, amount]) => amount > 0)
42
+ .map(([element]) => element)
43
+ )),
44
+ ].toSorted(),
45
+ )
46
+
47
+ // How many display axes (2 = binary/2D, 3+ = ternary/3D)
48
+ const display_elements = $derived(config.elements ?? all_elements)
49
+ const n_display = $derived(display_elements.length)
50
+ const show_tooltip = $derived(
51
+ config.show_tooltip ?? CHEMPOT_DEFAULTS.show_tooltip,
52
+ )
53
+ const tooltip_detail_level = $derived(
54
+ config.tooltip_detail_level ?? CHEMPOT_DEFAULTS.tooltip_detail_level,
55
+ )
56
+
57
+ const projection_mode = $derived(
58
+ config.projection_mode ?? CHEMPOT_DEFAULTS.projection_mode,
59
+ )
60
+ // For quaternary+ in grid mode, generate all C(n,3) ternary projections
61
+ // Uses display_elements (not all_elements) so config.elements scopes the grid
62
+ const ternary_combos = $derived(
63
+ n_display > 3 && projection_mode === `grid`
64
+ ? get_ternary_combinations(display_elements)
65
+ : [],
66
+ )
67
+ const show_grid = $derived(ternary_combos.length > 0 && ternary_combos.length <= 12)
68
+ // Scale down sub-diagrams in grid mode
69
+ const grid_width = $derived(Math.max(280, Math.round(width * 0.48)))
70
+ const grid_height = $derived(Math.max(240, Math.round(height * 0.48)))
71
+
72
+ // Pre-warm the worker's N-D computation cache before mounting heavy 3D
73
+ // children. Fires one async call with the first projection — subsequent
74
+ // child calls for different element triples hit the cached N-D result.
75
+ let grid_cache_ready = $state(false)
76
+ let grid_error = $state<string | null>(null)
77
+ $effect(() => {
78
+ grid_cache_ready = false
79
+ grid_error = null
80
+ if (!show_grid) return
81
+ let cancelled = false
82
+ compute_chempot_async(entries, { ...config, elements: ternary_combos[0] })
83
+ .then(() => { if (!cancelled) grid_cache_ready = true })
84
+ .catch((err) => {
85
+ if (cancelled) return
86
+ console.error(`Grid precompute failed:`, err)
87
+ grid_error = err instanceof Error ? err.message : String(err)
88
+ })
89
+ return () => { cancelled = true }
90
+ })
91
+ const is_hover_info_3d = (value: ChemPotHoverInfo | null): value is ChemPotHoverInfo3D => value?.view === `3d`
92
+
93
+ let tooltip_el = $state<HTMLElement>()
94
+ const tooltip_pos = $derived.by(() => {
95
+ const pointer = hover_info?.pointer
96
+ if (!pointer) return { x: 4, y: 4 }
97
+ return constrain_tooltip_position(
98
+ pointer.x, pointer.y,
99
+ tooltip_el?.offsetWidth ?? 200,
100
+ tooltip_el?.offsetHeight ?? 100,
101
+ width, height,
102
+ { offset: 0 },
103
+ )
104
+ })
23
105
  </script>
24
106
 
25
107
  <div class="chempot-diagram-wrapper">
@@ -50,7 +132,7 @@ function is_hover_info_3d(value) {
50
132
  bind:hover_info
51
133
  render_local_tooltip={false}
52
134
  />
53
- {:else}
135
+ {:else if n_display === 3 || !show_grid}
54
136
  <ChemPotDiagram3D
55
137
  {entries}
56
138
  {config}
@@ -60,14 +142,48 @@ function is_hover_info_3d(value) {
60
142
  bind:hover_info
61
143
  render_local_tooltip={false}
62
144
  />
145
+ {:else}
146
+ <p class="projection-info">
147
+ Showing all {ternary_combos.length} ternary projections of the
148
+ {display_elements.length}-element system ({display_elements.join(`-`)})
149
+ </p>
150
+ {#if grid_error}
151
+ <div class="chempot-error" role="alert">
152
+ <div>
153
+ <h3 id="grid-computation-failed">Grid computation failed</h3>
154
+ <p>{grid_error}</p>
155
+ </div>
156
+ </div>
157
+ {:else if !grid_cache_ready}
158
+ <Spinner
159
+ text="Computing {display_elements.length}-element chemical potential domains..."
160
+ style="--spinner-size: 1.2em"
161
+ />
162
+ {:else}
163
+ <div class="projection-grid">
164
+ {#each ternary_combos as combo (combo.join(`|`))}
165
+ <div class="projection-cell">
166
+ <h4 id="projection" class="projection-label">{combo.join(`-`)} projection</h4>
167
+ <ChemPotDiagram3D
168
+ {entries}
169
+ config={{ ...config, elements: combo }}
170
+ width={grid_width}
171
+ height={grid_height}
172
+ bind:temperature
173
+ />
174
+ </div>
175
+ {/each}
176
+ </div>
177
+ {/if}
63
178
  {/if}
64
179
  {#if show_tooltip && hover_info}
65
180
  <aside
181
+ bind:this={tooltip_el}
66
182
  class="chempot-tooltip"
67
- style:left="{hover_info.pointer?.x ?? 4}px"
68
- style:top="{hover_info.pointer?.y ?? 4}px"
183
+ style:left="{tooltip_pos.x}px"
184
+ style:top="{tooltip_pos.y}px"
69
185
  >
70
- <h4>{@html get_hill_formula(hover_info.formula, false, ``)}</h4>
186
+ <h4>{@html sanitize_html(get_electro_neg_formula(hover_info.formula, false, ``, `.3~s`))}</h4>
71
187
  {#if hover_info.view === `2d`}
72
188
  <p>2D domain · Points: {hover_info.n_points}</p>
73
189
  {#if tooltip_detail_level === `detailed`}
@@ -117,7 +233,7 @@ function is_hover_info_3d(value) {
117
233
  <h5 id="neighbors">Neighbors ({hover_info.neighbors.length})</h5>
118
234
  <p>
119
235
  {
120
- hover_info.neighbors.map((f) => get_hill_formula(f, true, ``)).join(
236
+ hover_info.neighbors.map((f) => get_electro_neg_formula(f, true, ``, `.3~s`)).join(
121
237
  `, `,
122
238
  )
123
239
  }
@@ -137,6 +253,25 @@ function is_hover_info_3d(value) {
137
253
  .chempot-diagram-wrapper {
138
254
  position: relative;
139
255
  }
256
+ .projection-info {
257
+ margin: 0 0 0.5em;
258
+ font-size: 0.9em;
259
+ color: var(--text-color-secondary, #666);
260
+ }
261
+ .projection-grid {
262
+ display: grid;
263
+ grid-template-columns: repeat(2, 1fr);
264
+ gap: 0.4em;
265
+ }
266
+ .projection-cell {
267
+ min-width: 0;
268
+ }
269
+ .projection-label {
270
+ margin: 0 0 0.3em;
271
+ font-size: 0.85em;
272
+ font-weight: 400;
273
+ text-align: center;
274
+ }
140
275
  .chempot-error {
141
276
  display: flex;
142
277
  align-items: center;