matterviz 0.1.12 → 0.1.13

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 (195) hide show
  1. package/dist/ContextMenu.svelte +1 -1
  2. package/dist/ContextMenu.svelte.d.ts +3 -3
  3. package/dist/DraggablePane.svelte +10 -5
  4. package/dist/DraggablePane.svelte.d.ts +3 -3
  5. package/dist/FilePicker.svelte.d.ts +3 -3
  6. package/dist/Icon.svelte.d.ts +3 -3
  7. package/dist/Nav.svelte +76 -31
  8. package/dist/SettingsSection.svelte.d.ts +3 -3
  9. package/dist/Spinner.svelte +18 -29
  10. package/dist/Spinner.svelte.d.ts +3 -3
  11. package/dist/app.css +4 -0
  12. package/dist/bands/Bands.svelte +216 -0
  13. package/dist/bands/Bands.svelte.d.ts +16 -0
  14. package/dist/bands/BandsAndDos.svelte +26 -0
  15. package/dist/bands/BandsAndDos.svelte.d.ts +16 -0
  16. package/dist/bands/Dos.svelte +124 -0
  17. package/dist/bands/Dos.svelte.d.ts +18 -0
  18. package/dist/bands/helpers.d.ts +11 -0
  19. package/dist/bands/helpers.js +195 -0
  20. package/dist/bands/index.d.ts +5 -0
  21. package/dist/bands/index.js +6 -0
  22. package/dist/bands/types.d.ts +54 -0
  23. package/dist/bands/types.js +2 -0
  24. package/dist/brillouin/BrillouinZone.svelte +373 -0
  25. package/dist/brillouin/BrillouinZone.svelte.d.ts +57 -0
  26. package/dist/brillouin/BrillouinZoneControls.svelte +88 -0
  27. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +14 -0
  28. package/dist/brillouin/BrillouinZoneExportPane.svelte +129 -0
  29. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  30. package/dist/brillouin/BrillouinZoneInfoPane.svelte +115 -0
  31. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  32. package/dist/brillouin/BrillouinZoneScene.svelte +180 -0
  33. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +34 -0
  34. package/dist/brillouin/compute.d.ts +7 -0
  35. package/dist/brillouin/compute.js +215 -0
  36. package/dist/brillouin/index.d.ts +7 -0
  37. package/dist/brillouin/index.js +7 -0
  38. package/dist/brillouin/types.d.ts +23 -0
  39. package/dist/brillouin/types.js +1 -0
  40. package/dist/composition/BarChart.svelte.d.ts +3 -3
  41. package/dist/composition/BubbleChart.svelte +7 -6
  42. package/dist/composition/BubbleChart.svelte.d.ts +3 -3
  43. package/dist/composition/Composition.svelte.d.ts +3 -3
  44. package/dist/composition/PieChart.svelte +1 -1
  45. package/dist/composition/PieChart.svelte.d.ts +3 -3
  46. package/dist/composition/parse.d.ts +3 -3
  47. package/dist/coordination/CoordinationBarPlot.svelte +241 -0
  48. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +29 -0
  49. package/dist/coordination/calc-coordination.d.ts +15 -0
  50. package/dist/coordination/calc-coordination.js +66 -0
  51. package/dist/coordination/index.d.ts +8 -0
  52. package/dist/coordination/index.js +7 -0
  53. package/dist/element/BohrAtom.svelte.d.ts +3 -3
  54. package/dist/element/ElementHeading.svelte.d.ts +3 -3
  55. package/dist/element/ElementPhoto.svelte.d.ts +3 -3
  56. package/dist/element/ElementStats.svelte.d.ts +3 -3
  57. package/dist/element/ElementTile.svelte +1 -1
  58. package/dist/element/ElementTile.svelte.d.ts +4 -4
  59. package/dist/element/Nucleus.svelte.d.ts +3 -3
  60. package/dist/icons.d.ts +4 -0
  61. package/dist/icons.js +4 -0
  62. package/dist/index.d.ts +5 -1
  63. package/dist/index.js +5 -1
  64. package/dist/io/export.d.ts +1 -6
  65. package/dist/io/export.js +12 -12
  66. package/dist/labels.d.ts +19 -0
  67. package/dist/labels.js +59 -0
  68. package/dist/math.d.ts +7 -2
  69. package/dist/math.js +24 -12
  70. package/dist/periodic-table/PeriodicTable.svelte.d.ts +3 -3
  71. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +3 -3
  72. package/dist/periodic-table/PropertySelect.svelte +1 -1
  73. package/dist/periodic-table/PropertySelect.svelte.d.ts +5 -4
  74. package/dist/periodic-table/TableInset.svelte.d.ts +3 -3
  75. package/dist/phase-diagram/PhaseDiagram2D.svelte +44 -107
  76. package/dist/phase-diagram/PhaseDiagram2D.svelte.d.ts +7 -27
  77. package/dist/phase-diagram/PhaseDiagram3D.svelte +67 -170
  78. package/dist/phase-diagram/PhaseDiagram3D.svelte.d.ts +7 -31
  79. package/dist/phase-diagram/PhaseDiagram4D.svelte +87 -145
  80. package/dist/phase-diagram/PhaseDiagram4D.svelte.d.ts +5 -28
  81. package/dist/phase-diagram/PhaseDiagramControls.svelte +9 -9
  82. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +6 -6
  83. package/dist/phase-diagram/PhaseDiagramInfoPane.svelte +4 -4
  84. package/dist/phase-diagram/PhaseDiagramInfoPane.svelte.d.ts +5 -5
  85. package/dist/phase-diagram/PhaseDiagramStats.svelte +9 -16
  86. package/dist/phase-diagram/PhaseDiagramStats.svelte.d.ts +3 -3
  87. package/dist/phase-diagram/StructurePopup.svelte.d.ts +3 -3
  88. package/dist/phase-diagram/barycentric-coords.js +13 -24
  89. package/dist/phase-diagram/helpers.d.ts +12 -14
  90. package/dist/phase-diagram/helpers.js +70 -23
  91. package/dist/phase-diagram/index.d.ts +58 -0
  92. package/dist/phase-diagram/index.js +44 -0
  93. package/dist/phase-diagram/thermodynamics.js +2 -3
  94. package/dist/phase-diagram/types.d.ts +3 -8
  95. package/dist/plot/BarPlot.svelte +474 -240
  96. package/dist/plot/BarPlot.svelte.d.ts +16 -37
  97. package/dist/plot/BarPlotControls.svelte +33 -201
  98. package/dist/plot/BarPlotControls.svelte.d.ts +11 -22
  99. package/dist/plot/ColorBar.svelte.d.ts +3 -3
  100. package/dist/plot/ColorScaleSelect.svelte +1 -1
  101. package/dist/plot/ColorScaleSelect.svelte.d.ts +3 -3
  102. package/dist/plot/ElementScatter.svelte +5 -5
  103. package/dist/plot/ElementScatter.svelte.d.ts +8 -8
  104. package/dist/plot/Histogram.svelte +318 -170
  105. package/dist/plot/Histogram.svelte.d.ts +21 -41
  106. package/dist/plot/HistogramControls.svelte +115 -347
  107. package/dist/plot/HistogramControls.svelte.d.ts +13 -28
  108. package/dist/plot/Line.svelte +1 -1
  109. package/dist/plot/Line.svelte.d.ts +4 -4
  110. package/dist/plot/PlotControls.svelte +280 -0
  111. package/dist/plot/PlotControls.svelte.d.ts +4 -0
  112. package/dist/plot/PlotLegend.svelte +9 -24
  113. package/dist/plot/PlotLegend.svelte.d.ts +3 -3
  114. package/dist/plot/ScatterPlot.svelte +536 -571
  115. package/dist/plot/ScatterPlot.svelte.d.ts +18 -90
  116. package/dist/plot/ScatterPlotControls.svelte +108 -316
  117. package/dist/plot/ScatterPlotControls.svelte.d.ts +11 -38
  118. package/dist/plot/ScatterPoint.svelte +1 -1
  119. package/dist/plot/ScatterPoint.svelte.d.ts +5 -5
  120. package/dist/plot/SpacegroupBarPlot.svelte +235 -0
  121. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
  122. package/dist/plot/data-transform.d.ts +2 -2
  123. package/dist/plot/data-transform.js +1 -5
  124. package/dist/plot/index.d.ts +12 -200
  125. package/dist/plot/index.js +14 -6
  126. package/dist/plot/layout.d.ts +10 -16
  127. package/dist/plot/layout.js +40 -25
  128. package/dist/plot/scales.d.ts +7 -8
  129. package/dist/plot/scales.js +22 -7
  130. package/dist/plot/types.d.ts +303 -0
  131. package/dist/plot/types.js +1 -0
  132. package/dist/rdf/RdfPlot.svelte +156 -0
  133. package/dist/rdf/RdfPlot.svelte.d.ts +20 -0
  134. package/dist/rdf/calc-rdf.d.ts +4 -0
  135. package/dist/rdf/calc-rdf.js +107 -0
  136. package/dist/rdf/index.d.ts +22 -0
  137. package/dist/rdf/index.js +2 -0
  138. package/dist/settings.d.ts +86 -75
  139. package/dist/settings.js +257 -155
  140. package/dist/structure/Bond.svelte +126 -110
  141. package/dist/structure/Bond.svelte.d.ts +7 -20
  142. package/dist/structure/CanvasTooltip.svelte.d.ts +4 -4
  143. package/dist/structure/Cylinder.svelte +29 -0
  144. package/dist/structure/Cylinder.svelte.d.ts +10 -0
  145. package/dist/structure/Lattice.svelte +1 -2
  146. package/dist/structure/Lattice.svelte.d.ts +3 -3
  147. package/dist/structure/Structure.svelte +23 -8
  148. package/dist/structure/Structure.svelte.d.ts +10 -7
  149. package/dist/structure/StructureControls.svelte +25 -134
  150. package/dist/structure/StructureControls.svelte.d.ts +4 -9
  151. package/dist/structure/StructureExportPane.svelte +188 -0
  152. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  153. package/dist/structure/StructureInfoPane.svelte.d.ts +3 -3
  154. package/dist/structure/StructureLegend.svelte +91 -27
  155. package/dist/structure/StructureLegend.svelte.d.ts +5 -4
  156. package/dist/structure/StructureScene.svelte +93 -100
  157. package/dist/structure/StructureScene.svelte.d.ts +15 -12
  158. package/dist/structure/Vector.svelte +19 -25
  159. package/dist/structure/Vector.svelte.d.ts +3 -3
  160. package/dist/structure/bonding.d.ts +16 -14
  161. package/dist/structure/bonding.js +207 -216
  162. package/dist/structure/export.d.ts +3 -0
  163. package/dist/structure/export.js +120 -0
  164. package/dist/structure/index.d.ts +15 -1
  165. package/dist/structure/index.js +2 -0
  166. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -3
  167. package/dist/symmetry/index.d.ts +1 -0
  168. package/dist/symmetry/index.js +1 -0
  169. package/dist/symmetry/spacegroups.d.ts +9 -0
  170. package/dist/symmetry/spacegroups.js +397 -0
  171. package/dist/theme/ThemeControl.svelte.d.ts +3 -3
  172. package/dist/theme/themes.js +2 -16
  173. package/dist/trajectory/Trajectory.svelte +52 -78
  174. package/dist/trajectory/Trajectory.svelte.d.ts +5 -5
  175. package/dist/trajectory/TrajectoryError.svelte.d.ts +3 -3
  176. package/dist/trajectory/TrajectoryExportPane.svelte +1 -1
  177. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +5 -5
  178. package/dist/trajectory/TrajectoryInfoPane.svelte +1 -1
  179. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -3
  180. package/dist/trajectory/extract.js +2 -1
  181. package/dist/trajectory/index.d.ts +1 -1
  182. package/dist/trajectory/index.js +1 -1
  183. package/dist/trajectory/parse.js +21 -14
  184. package/dist/utils.d.ts +1 -0
  185. package/dist/utils.js +17 -0
  186. package/dist/xrd/XrdPlot.svelte +14 -11
  187. package/dist/xrd/XrdPlot.svelte.d.ts +6 -5
  188. package/package.json +20 -12
  189. package/readme.md +1 -1
  190. package/dist/material/MaterialCard.svelte +0 -123
  191. package/dist/material/MaterialCard.svelte.d.ts +0 -9
  192. package/dist/material/index.d.ts +0 -1
  193. package/dist/material/index.js +0 -1
  194. package/dist/plot/formatting.d.ts +0 -7
  195. package/dist/plot/formatting.js +0 -53
@@ -1,10 +1,10 @@
1
1
  import type { HTMLAttributes } from 'svelte/elements';
2
2
  import type { PhaseStats, PlotEntry3D } from './types';
3
- interface Props extends HTMLAttributes<HTMLDivElement> {
3
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
4
4
  phase_stats: PhaseStats | null;
5
5
  stable_entries: PlotEntry3D[];
6
6
  unstable_entries: PlotEntry3D[];
7
- }
8
- declare const PhaseDiagramStats: import("svelte").Component<Props, {}, "">;
7
+ };
8
+ declare const PhaseDiagramStats: import("svelte").Component<$$ComponentProps, {}, "">;
9
9
  type PhaseDiagramStats = ReturnType<typeof PhaseDiagramStats>;
10
10
  export default PhaseDiagramStats;
@@ -1,6 +1,6 @@
1
1
  import type { AnyStructure } from '..';
2
2
  import type { HTMLAttributes } from 'svelte/elements';
3
- interface Props extends HTMLAttributes<HTMLDivElement> {
3
+ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
4
4
  structure: AnyStructure;
5
5
  place_right?: boolean;
6
6
  width?: number;
@@ -11,7 +11,7 @@ interface Props extends HTMLAttributes<HTMLDivElement> {
11
11
  e_above_hull?: number;
12
12
  e_form?: number;
13
13
  };
14
- }
15
- declare const StructurePopup: import("svelte").Component<Props, {}, "">;
14
+ };
15
+ declare const StructurePopup: import("svelte").Component<$$ComponentProps, {}, "">;
16
16
  type StructurePopup = ReturnType<typeof StructurePopup>;
17
17
  export default StructurePopup;
@@ -20,11 +20,10 @@ export function composition_to_barycentric_3d(composition, elements) {
20
20
  }
21
21
  // map barycentric coordinates to triangular 2D coordinates
22
22
  export function barycentric_to_ternary_xy(barycentric) {
23
+ const [v0, v1, v2] = TRIANGLE_VERTICES;
23
24
  const [a, b, c] = barycentric;
24
- const x = TRIANGLE_VERTICES[0][0] * a + TRIANGLE_VERTICES[1][0] * b +
25
- TRIANGLE_VERTICES[2][0] * c;
26
- const y = TRIANGLE_VERTICES[0][1] * a + TRIANGLE_VERTICES[1][1] * b +
27
- TRIANGLE_VERTICES[2][1] * c;
25
+ const x = v0[0] * a + v1[0] * b + v2[0] * c;
26
+ const y = v0[1] * a + v1[1] * b + v2[1] * c;
28
27
  return [x, y];
29
28
  }
30
29
  // map barycentric coordinates to ternary 3D coordinates
@@ -33,22 +32,21 @@ export function barycentric_to_ternary_xyz(barycentric, formation_energy) {
33
32
  return { x, y, z: formation_energy };
34
33
  }
35
34
  export function get_triangle_centroid() {
36
- const centroid_x = (TRIANGLE_VERTICES[0][0] + TRIANGLE_VERTICES[1][0] + TRIANGLE_VERTICES[2][0]) / 3;
37
- const centroid_y = (TRIANGLE_VERTICES[0][1] + TRIANGLE_VERTICES[1][1] + TRIANGLE_VERTICES[2][1]) / 3;
35
+ const [v0, v1, v2] = TRIANGLE_VERTICES;
36
+ const centroid_x = (v0[0] + v1[0] + v2[0]) / 3;
37
+ const centroid_y = (v0[1] + v1[1] + v2[1]) / 3;
38
38
  return { x: centroid_x, y: centroid_y, z: 0 };
39
39
  }
40
40
  export function calculate_face_normal(p1, p2, p3) {
41
41
  const edge1 = { x: p2.x - p1.x, y: p2.y - p1.y, z: p2.z - p1.z };
42
42
  const edge2 = { x: p3.x - p1.x, y: p3.y - p1.y, z: p3.z - p1.z };
43
- const normal = {
44
- x: edge1.y * edge2.z - edge1.z * edge2.y,
45
- y: edge1.z * edge2.x - edge1.x * edge2.z,
46
- z: edge1.x * edge2.y - edge1.y * edge2.x,
47
- };
48
- const magnitude = Math.sqrt(normal.x ** 2 + normal.y ** 2 + normal.z ** 2);
43
+ const nx = edge1.y * edge2.z - edge1.z * edge2.y;
44
+ const ny = edge1.z * edge2.x - edge1.x * edge2.z;
45
+ const nz = edge1.x * edge2.y - edge1.y * edge2.x;
46
+ const magnitude = Math.hypot(nx, ny, nz);
49
47
  if (magnitude === 0)
50
48
  return { x: 0, y: 0, z: 1 };
51
- return { x: normal.x / magnitude, y: normal.y / magnitude, z: normal.z / magnitude };
49
+ return { x: nx / magnitude, y: ny / magnitude, z: nz / magnitude };
52
50
  }
53
51
  export function calculate_face_centroid(p1, p2, p3) {
54
52
  return {
@@ -89,18 +87,9 @@ export function get_ternary_3d_coordinates(entries, elements, el_refs) {
89
87
  Number.isFinite(entry.e_form_per_atom)
90
88
  ? entry.e_form_per_atom
91
89
  : compute_e_form_per_atom(entry, refs) ?? NaN;
92
- const { x, y, z } = barycentric_to_ternary_xyz(barycentric, e_form);
90
+ const xyz = barycentric_to_ternary_xyz(barycentric, e_form);
93
91
  const is_element = is_unary_entry(entry);
94
- return {
95
- ...entry,
96
- x,
97
- y,
98
- z,
99
- barycentric,
100
- formation_energy: e_form,
101
- is_element,
102
- visible: true,
103
- };
92
+ return { ...entry, ...xyz, barycentric, e_form, is_element, visible: true };
104
93
  });
105
94
  return result;
106
95
  }
@@ -1,17 +1,6 @@
1
+ import type { EnergyModeInfo } from '..';
1
2
  import type { D3InterpolateName } from '../colors';
2
- import type { PDControlsType, PhaseDiagramConfig, PhaseEntry } from './types';
3
- export declare const default_controls: PDControlsType;
4
- export declare const PD_STYLE: Readonly<{
5
- structure_line: Readonly<{
6
- color: "rgba(128, 128, 128, 0.6)";
7
- dash: [number, number];
8
- line_width: 2;
9
- }>;
10
- z_index: Readonly<{
11
- tooltip: 6000;
12
- copy_feedback: 10000;
13
- }>;
14
- }>;
3
+ import type { PhaseDiagramConfig, PhaseEntry } from './types';
15
4
  export declare function get_energy_color_scale(color_mode: `stability` | `energy`, color_scale: D3InterpolateName, plot_entries: {
16
5
  e_above_hull?: number;
17
6
  }[]): ((value: number) => string) | null;
@@ -20,7 +9,7 @@ export declare function get_point_color_for_entry(entry: {
20
9
  e_above_hull?: number;
21
10
  }, color_mode: `stability` | `energy`, colors: PhaseDiagramConfig[`colors`] | undefined, energy_scale: ((value: number) => string) | null): string;
22
11
  export declare function parse_pd_entries_from_drop(event: DragEvent): Promise<PhaseEntry[] | null>;
23
- export declare function compute_max_energy_threshold(processed_entries: PhaseEntry[]): number;
12
+ export declare function calc_max_hull_dist_in_data(processed_entries: PhaseEntry[]): number;
24
13
  export declare function build_entry_tooltip_text(entry: PhaseEntry): string;
25
14
  export declare function find_pd_entry_at_mouse<T extends {
26
15
  x: number;
@@ -34,3 +23,12 @@ export declare function find_pd_entry_at_mouse<T extends {
34
23
  x: number;
35
24
  y: number;
36
25
  }): T | null;
26
+ export declare function calculate_modal_side(wrapper: HTMLDivElement | undefined): boolean;
27
+ export declare function setup_fullscreen_effect(fullscreen: boolean, wrapper: HTMLDivElement | undefined, on_fullscreen_change?: (entering_fullscreen: boolean) => void): void;
28
+ export declare function compute_energy_mode_info(entries: PhaseEntry[], // Array of phase entries to analyze
29
+ find_lowest_energy_unary_refs_fn: (entries: PhaseEntry[]) => Record<string, PhaseEntry>, // Function to find unary references
30
+ energy_source_mode: `precomputed` | `on-the-fly`): EnergyModeInfo;
31
+ export declare function get_effective_entries(entries: PhaseEntry[], // Original phase entries
32
+ energy_mode: `precomputed` | `on-the-fly`, // Energy source mode (precomputed or on-the-fly)
33
+ unary_refs: Record<string, PhaseEntry>, // Unary reference entries for energy computation
34
+ compute_e_form_fn: (entry: PhaseEntry, unary_refs: Record<string, PhaseEntry>) => number | null): PhaseEntry[];
@@ -3,28 +3,6 @@ import { format_fractional, format_num } from '../labels';
3
3
  import { scaleSequential } from 'd3-scale';
4
4
  import * as d3_sc from 'd3-scale-chromatic';
5
5
  import { is_unary_entry } from './types';
6
- // Default legend configuration shared by 3D and 4D diagrams
7
- export const default_controls = {
8
- title: ``,
9
- show: true,
10
- position: `top-right`,
11
- width: 280,
12
- show_counts: true,
13
- show_color_toggle: true,
14
- show_label_controls: true,
15
- };
16
- // Shared PD styles (single source of truth shared by 2D, 3D, and 4D)
17
- export const PD_STYLE = Object.freeze({
18
- structure_line: Object.freeze({
19
- color: `rgba(128, 128, 128, 0.6)`,
20
- dash: [3, 3],
21
- line_width: 2,
22
- }),
23
- z_index: Object.freeze({
24
- tooltip: 6000,
25
- copy_feedback: 10000,
26
- }),
27
- });
28
6
  // Energy color scale factory (shared)
29
7
  export function get_energy_color_scale(color_mode, color_scale, plot_entries) {
30
8
  if (color_mode !== `energy` || plot_entries.length === 0)
@@ -71,7 +49,7 @@ export async function parse_pd_entries_from_drop(event) {
71
49
  }
72
50
  }
73
51
  // Compute a consistent max energy threshold for controls (shared)
74
- export function compute_max_energy_threshold(processed_entries) {
52
+ export function calc_max_hull_dist_in_data(processed_entries) {
75
53
  if (processed_entries.length === 0)
76
54
  return 0.5;
77
55
  const hull_distances = processed_entries
@@ -135,3 +113,72 @@ export function find_pd_entry_at_mouse(canvas, event, plot_entries, project_poin
135
113
  }
136
114
  return null;
137
115
  }
116
+ // Calculate which side of the viewport has more space for modal placement
117
+ export function calculate_modal_side(wrapper) {
118
+ if (!wrapper)
119
+ return true;
120
+ const rect = wrapper.getBoundingClientRect();
121
+ const viewport_width = globalThis.innerWidth;
122
+ const space_on_right = viewport_width - rect.right;
123
+ const space_on_left = rect.left;
124
+ return space_on_right >= space_on_left;
125
+ }
126
+ // Setup fullscreen effect for phase diagrams with optional camera reset callback
127
+ export function setup_fullscreen_effect(fullscreen, wrapper, on_fullscreen_change) {
128
+ if (typeof window === `undefined`)
129
+ return;
130
+ if (fullscreen && !document.fullscreenElement && wrapper?.isConnected) {
131
+ wrapper.requestFullscreen().catch(console.error);
132
+ on_fullscreen_change?.(true);
133
+ }
134
+ else if (!fullscreen && document.fullscreenElement) {
135
+ document.exitFullscreen();
136
+ on_fullscreen_change?.(false);
137
+ }
138
+ }
139
+ // Compute energy source mode information for phase diagram entries. Returns energy mode information including capability flags and resolved mode.
140
+ // This determines whether we can use precomputed energies or need to compute on-the-fly.
141
+ export function compute_energy_mode_info(entries, // Array of phase entries to analyze
142
+ find_lowest_energy_unary_refs_fn, // Function to find unary references
143
+ energy_source_mode) {
144
+ const has_precomputed_e_form = entries.length > 0 &&
145
+ entries.every((e) => typeof e.e_form_per_atom === `number`);
146
+ const has_precomputed_hull = entries.length > 0 &&
147
+ entries.every((e) => typeof e.e_above_hull === `number`);
148
+ const unary_refs = find_lowest_energy_unary_refs_fn(entries);
149
+ const elements_in_entries = Array.from(new Set(entries.flatMap((e) => Object.keys(e.composition))));
150
+ const can_compute_e_form = elements_in_entries.every((el) => Boolean(unary_refs[el]));
151
+ const can_compute_hull = can_compute_e_form;
152
+ // Resolve mode to avoid inconsistent states:
153
+ // - If full precomputed available, honor user toggle
154
+ // - Else if we can compute both, use on-the-fly automatically
155
+ // - Else fall back to precomputed (best-effort)
156
+ const energy_mode = has_precomputed_e_form && has_precomputed_hull
157
+ ? energy_source_mode
158
+ : can_compute_e_form && can_compute_hull
159
+ ? `on-the-fly`
160
+ : `precomputed`;
161
+ return {
162
+ has_precomputed_e_form,
163
+ has_precomputed_hull,
164
+ can_compute_e_form,
165
+ can_compute_hull,
166
+ energy_mode,
167
+ unary_refs,
168
+ };
169
+ }
170
+ // Compute effective entries with formation energies based on the energy mode.
171
+ // Returns entries with formation energies populated (either precomputed or on-the-fly)
172
+ export function get_effective_entries(entries, // Original phase entries
173
+ energy_mode, // Energy source mode (precomputed or on-the-fly)
174
+ unary_refs, // Unary reference entries for energy computation
175
+ compute_e_form_fn) {
176
+ if (energy_mode === `precomputed`)
177
+ return entries;
178
+ return entries.map((entry) => {
179
+ const e_form = compute_e_form_fn(entry, unary_refs);
180
+ if (e_form === null)
181
+ return entry;
182
+ return { ...entry, e_form_per_atom: e_form };
183
+ });
184
+ }
@@ -1,3 +1,6 @@
1
+ import type { D3InterpolateName } from '../colors';
2
+ import type { HTMLAttributes } from 'svelte/elements';
3
+ import type { HoverData3D, PDControlsType, PhaseDiagramConfig, PhaseEntry, PhaseStats } from './types';
1
4
  export * from './barycentric-coords';
2
5
  export { default as PhaseDiagram2D } from './PhaseDiagram2D.svelte';
3
6
  export { default as PhaseDiagram3D } from './PhaseDiagram3D.svelte';
@@ -7,3 +10,58 @@ export { default as PhaseDiagramInfoPane } from './PhaseDiagramInfoPane.svelte';
7
10
  export { default as PhaseDiagramStats } from './PhaseDiagramStats.svelte';
8
11
  export * from './thermodynamics';
9
12
  export * from './types';
13
+ export interface BasePhaseDiagramProps<TEntry = PhaseEntry> extends Omit<HTMLAttributes<HTMLDivElement>, `entries`> {
14
+ entries: PhaseEntry[];
15
+ controls?: Partial<PDControlsType>;
16
+ config?: Partial<PhaseDiagramConfig>;
17
+ on_point_click?: (entry: TEntry) => void;
18
+ on_point_hover?: (data: HoverData3D<TEntry> | null) => void;
19
+ fullscreen?: boolean;
20
+ enable_fullscreen?: boolean;
21
+ enable_info_pane?: boolean;
22
+ wrapper?: HTMLDivElement;
23
+ label_threshold?: number;
24
+ show_stable?: boolean;
25
+ show_unstable?: boolean;
26
+ color_mode?: `stability` | `energy`;
27
+ color_scale?: D3InterpolateName;
28
+ info_pane_open?: boolean;
29
+ legend_pane_open?: boolean;
30
+ max_hull_dist_show_phases?: number;
31
+ max_hull_dist_show_labels?: number;
32
+ show_stable_labels?: boolean;
33
+ show_unstable_labels?: boolean;
34
+ on_file_drop?: (entries: PhaseEntry[]) => void;
35
+ enable_structure_preview?: boolean;
36
+ energy_source_mode?: `precomputed` | `on-the-fly`;
37
+ phase_stats?: PhaseStats | null;
38
+ }
39
+ export interface Hull3DProps {
40
+ show_hull_faces?: boolean;
41
+ hull_face_opacity?: number;
42
+ }
43
+ export interface MergedPDConfig {
44
+ controls: PDControlsType;
45
+ config: PhaseDiagramConfig;
46
+ }
47
+ export interface EnergyModeInfo {
48
+ has_precomputed_e_form: boolean;
49
+ has_precomputed_hull: boolean;
50
+ can_compute_e_form: boolean;
51
+ can_compute_hull: boolean;
52
+ energy_mode: `precomputed` | `on-the-fly`;
53
+ unary_refs: Record<string, PhaseEntry>;
54
+ }
55
+ export declare const default_controls: PDControlsType;
56
+ export declare const default_pd_config: PhaseDiagramConfig;
57
+ export declare const PD_STYLE: Readonly<{
58
+ structure_line: Readonly<{
59
+ color: "rgba(128, 128, 128, 0.6)";
60
+ dash: [number, number];
61
+ line_width: 2;
62
+ }>;
63
+ z_index: Readonly<{
64
+ tooltip: 6000;
65
+ copy_feedback: 10000;
66
+ }>;
67
+ }>;
@@ -7,3 +7,47 @@ export { default as PhaseDiagramInfoPane } from './PhaseDiagramInfoPane.svelte';
7
7
  export { default as PhaseDiagramStats } from './PhaseDiagramStats.svelte';
8
8
  export * from './thermodynamics';
9
9
  export * from './types';
10
+ // Default legend configuration shared by 3D and 4D diagrams
11
+ export const default_controls = {
12
+ title: ``,
13
+ show: true,
14
+ position: `top-right`,
15
+ width: 280,
16
+ show_counts: true,
17
+ show_color_toggle: true,
18
+ show_label_controls: true,
19
+ };
20
+ // Phase diagram defaults shared by 2D, 3D, and 4D
21
+ export const default_pd_config = {
22
+ width: 600,
23
+ height: 600,
24
+ unstable_threshold: 0.2,
25
+ show_labels: true,
26
+ show_hull: true,
27
+ point_size: 8,
28
+ line_width: 2,
29
+ font_size: 12,
30
+ colors: {
31
+ stable: `#0072B2`,
32
+ unstable: `#E69F00`,
33
+ hull_line: `var(--accent-color, #1976D2)`,
34
+ background: `transparent`,
35
+ text: `var(--text-color, #212121)`,
36
+ edge: `var(--text-color, #212121)`,
37
+ tooltip_bg: `var(--tooltip-bg, rgba(0, 0, 0, 0.85))`,
38
+ tooltip_text: `var(--tooltip-text, white)`,
39
+ annotation: `var(--text-color, #212121)`,
40
+ },
41
+ };
42
+ // Shared PD styles (single source of truth shared by 2D, 3D, and 4D)
43
+ export const PD_STYLE = Object.freeze({
44
+ structure_line: Object.freeze({
45
+ color: `rgba(128, 128, 128, 0.6)`,
46
+ dash: [3, 3],
47
+ line_width: 2,
48
+ }),
49
+ z_index: Object.freeze({
50
+ tooltip: 6000,
51
+ copy_feedback: 10000,
52
+ }),
53
+ });
@@ -60,7 +60,7 @@ export function find_lowest_energy_unary_refs(entries) {
60
60
  for (const entry of entries) {
61
61
  if (!is_unary_entry(entry))
62
62
  continue;
63
- const el = Object.keys(entry.composition).find((k) => entry.composition[k] > 0);
63
+ const el = Object.keys(entry.composition).find((el) => entry.composition[el] > 0);
64
64
  if (!el)
65
65
  continue;
66
66
  const atoms = Object.values(entry.composition).reduce((sum, amt) => sum + amt, 0);
@@ -87,8 +87,7 @@ export function find_lowest_energy_unary_refs(entries) {
87
87
  export function get_phase_diagram_stats(processed_entries, elements, max_arity) {
88
88
  if (!processed_entries || processed_entries.length === 0)
89
89
  return null;
90
- const composition_counts = (max_arity === 4 ? [1, 2, 3, 4] : [1, 2, 3]).map((target) => processed_entries.filter((entry) => Object.keys(entry.composition).filter((el) => entry.composition[el] > 0).length ===
91
- target).length);
90
+ const composition_counts = (max_arity === 4 ? [1, 2, 3, 4] : [1, 2, 3]).map((target) => processed_entries.filter((entry) => Object.keys(entry.composition).filter((el) => entry.composition[el] > 0).length === target).length);
92
91
  const [unary, binary, ternary, quaternaryMaybe] = composition_counts;
93
92
  const quaternary = max_arity === 4 ? (quaternaryMaybe ?? 0) : 0;
94
93
  const stable_count = processed_entries.filter((e) => e.is_stable === true ||
@@ -1,4 +1,4 @@
1
- import type { ElementSymbol } from '..';
1
+ import type { ElementSymbol, Sides } from '..';
2
2
  import type { Vec3 } from '../math';
3
3
  export interface PhaseEntry {
4
4
  composition: Record<ElementSymbol, number>;
@@ -41,12 +41,7 @@ export interface PlotEntry3D extends PhaseEntry, Point3D {
41
41
  export interface PhaseDiagramConfig {
42
42
  width?: number;
43
43
  height?: number;
44
- margin?: {
45
- top: number;
46
- right: number;
47
- bottom: number;
48
- left: number;
49
- };
44
+ margin?: Sides;
50
45
  unstable_threshold?: number;
51
46
  show_labels?: boolean;
52
47
  show_hull?: boolean;
@@ -91,7 +86,7 @@ export interface ConvexHullTriangle {
91
86
  }
92
87
  export interface TernaryPlotEntry extends PlotEntry3D {
93
88
  barycentric: [number, number, number];
94
- formation_energy: number;
89
+ e_form: number;
95
90
  }
96
91
  export interface HoverData3D<T = PlotEntry3D> {
97
92
  entry: T;