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.
- package/dist/ContextMenu.svelte +1 -1
- package/dist/ContextMenu.svelte.d.ts +3 -3
- package/dist/DraggablePane.svelte +10 -5
- package/dist/DraggablePane.svelte.d.ts +3 -3
- package/dist/FilePicker.svelte.d.ts +3 -3
- package/dist/Icon.svelte.d.ts +3 -3
- package/dist/Nav.svelte +76 -31
- package/dist/SettingsSection.svelte.d.ts +3 -3
- package/dist/Spinner.svelte +18 -29
- package/dist/Spinner.svelte.d.ts +3 -3
- package/dist/app.css +4 -0
- package/dist/bands/Bands.svelte +216 -0
- package/dist/bands/Bands.svelte.d.ts +16 -0
- package/dist/bands/BandsAndDos.svelte +26 -0
- package/dist/bands/BandsAndDos.svelte.d.ts +16 -0
- package/dist/bands/Dos.svelte +124 -0
- package/dist/bands/Dos.svelte.d.ts +18 -0
- package/dist/bands/helpers.d.ts +11 -0
- package/dist/bands/helpers.js +195 -0
- package/dist/bands/index.d.ts +5 -0
- package/dist/bands/index.js +6 -0
- package/dist/bands/types.d.ts +54 -0
- package/dist/bands/types.js +2 -0
- package/dist/brillouin/BrillouinZone.svelte +373 -0
- package/dist/brillouin/BrillouinZone.svelte.d.ts +57 -0
- package/dist/brillouin/BrillouinZoneControls.svelte +88 -0
- package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +14 -0
- package/dist/brillouin/BrillouinZoneExportPane.svelte +129 -0
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +115 -0
- package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
- package/dist/brillouin/BrillouinZoneScene.svelte +180 -0
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +34 -0
- package/dist/brillouin/compute.d.ts +7 -0
- package/dist/brillouin/compute.js +215 -0
- package/dist/brillouin/index.d.ts +7 -0
- package/dist/brillouin/index.js +7 -0
- package/dist/brillouin/types.d.ts +23 -0
- package/dist/brillouin/types.js +1 -0
- package/dist/composition/BarChart.svelte.d.ts +3 -3
- package/dist/composition/BubbleChart.svelte +7 -6
- package/dist/composition/BubbleChart.svelte.d.ts +3 -3
- package/dist/composition/Composition.svelte.d.ts +3 -3
- package/dist/composition/PieChart.svelte +1 -1
- package/dist/composition/PieChart.svelte.d.ts +3 -3
- package/dist/composition/parse.d.ts +3 -3
- package/dist/coordination/CoordinationBarPlot.svelte +241 -0
- package/dist/coordination/CoordinationBarPlot.svelte.d.ts +29 -0
- package/dist/coordination/calc-coordination.d.ts +15 -0
- package/dist/coordination/calc-coordination.js +66 -0
- package/dist/coordination/index.d.ts +8 -0
- package/dist/coordination/index.js +7 -0
- package/dist/element/BohrAtom.svelte.d.ts +3 -3
- package/dist/element/ElementHeading.svelte.d.ts +3 -3
- package/dist/element/ElementPhoto.svelte.d.ts +3 -3
- package/dist/element/ElementStats.svelte.d.ts +3 -3
- package/dist/element/ElementTile.svelte +1 -1
- package/dist/element/ElementTile.svelte.d.ts +4 -4
- package/dist/element/Nucleus.svelte.d.ts +3 -3
- package/dist/icons.d.ts +4 -0
- package/dist/icons.js +4 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +5 -1
- package/dist/io/export.d.ts +1 -6
- package/dist/io/export.js +12 -12
- package/dist/labels.d.ts +19 -0
- package/dist/labels.js +59 -0
- package/dist/math.d.ts +7 -2
- package/dist/math.js +24 -12
- package/dist/periodic-table/PeriodicTable.svelte.d.ts +3 -3
- package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +3 -3
- package/dist/periodic-table/PropertySelect.svelte +1 -1
- package/dist/periodic-table/PropertySelect.svelte.d.ts +5 -4
- package/dist/periodic-table/TableInset.svelte.d.ts +3 -3
- package/dist/phase-diagram/PhaseDiagram2D.svelte +44 -107
- package/dist/phase-diagram/PhaseDiagram2D.svelte.d.ts +7 -27
- package/dist/phase-diagram/PhaseDiagram3D.svelte +67 -170
- package/dist/phase-diagram/PhaseDiagram3D.svelte.d.ts +7 -31
- package/dist/phase-diagram/PhaseDiagram4D.svelte +87 -145
- package/dist/phase-diagram/PhaseDiagram4D.svelte.d.ts +5 -28
- package/dist/phase-diagram/PhaseDiagramControls.svelte +9 -9
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +6 -6
- package/dist/phase-diagram/PhaseDiagramInfoPane.svelte +4 -4
- package/dist/phase-diagram/PhaseDiagramInfoPane.svelte.d.ts +5 -5
- package/dist/phase-diagram/PhaseDiagramStats.svelte +9 -16
- package/dist/phase-diagram/PhaseDiagramStats.svelte.d.ts +3 -3
- package/dist/phase-diagram/StructurePopup.svelte.d.ts +3 -3
- package/dist/phase-diagram/barycentric-coords.js +13 -24
- package/dist/phase-diagram/helpers.d.ts +12 -14
- package/dist/phase-diagram/helpers.js +70 -23
- package/dist/phase-diagram/index.d.ts +58 -0
- package/dist/phase-diagram/index.js +44 -0
- package/dist/phase-diagram/thermodynamics.js +2 -3
- package/dist/phase-diagram/types.d.ts +3 -8
- package/dist/plot/BarPlot.svelte +474 -240
- package/dist/plot/BarPlot.svelte.d.ts +16 -37
- package/dist/plot/BarPlotControls.svelte +33 -201
- package/dist/plot/BarPlotControls.svelte.d.ts +11 -22
- package/dist/plot/ColorBar.svelte.d.ts +3 -3
- package/dist/plot/ColorScaleSelect.svelte +1 -1
- package/dist/plot/ColorScaleSelect.svelte.d.ts +3 -3
- package/dist/plot/ElementScatter.svelte +5 -5
- package/dist/plot/ElementScatter.svelte.d.ts +8 -8
- package/dist/plot/Histogram.svelte +318 -170
- package/dist/plot/Histogram.svelte.d.ts +21 -41
- package/dist/plot/HistogramControls.svelte +115 -347
- package/dist/plot/HistogramControls.svelte.d.ts +13 -28
- package/dist/plot/Line.svelte +1 -1
- package/dist/plot/Line.svelte.d.ts +4 -4
- package/dist/plot/PlotControls.svelte +280 -0
- package/dist/plot/PlotControls.svelte.d.ts +4 -0
- package/dist/plot/PlotLegend.svelte +9 -24
- package/dist/plot/PlotLegend.svelte.d.ts +3 -3
- package/dist/plot/ScatterPlot.svelte +536 -571
- package/dist/plot/ScatterPlot.svelte.d.ts +18 -90
- package/dist/plot/ScatterPlotControls.svelte +108 -316
- package/dist/plot/ScatterPlotControls.svelte.d.ts +11 -38
- package/dist/plot/ScatterPoint.svelte +1 -1
- package/dist/plot/ScatterPoint.svelte.d.ts +5 -5
- package/dist/plot/SpacegroupBarPlot.svelte +235 -0
- package/dist/plot/SpacegroupBarPlot.svelte.d.ts +9 -0
- package/dist/plot/data-transform.d.ts +2 -2
- package/dist/plot/data-transform.js +1 -5
- package/dist/plot/index.d.ts +12 -200
- package/dist/plot/index.js +14 -6
- package/dist/plot/layout.d.ts +10 -16
- package/dist/plot/layout.js +40 -25
- package/dist/plot/scales.d.ts +7 -8
- package/dist/plot/scales.js +22 -7
- package/dist/plot/types.d.ts +303 -0
- package/dist/plot/types.js +1 -0
- package/dist/rdf/RdfPlot.svelte +156 -0
- package/dist/rdf/RdfPlot.svelte.d.ts +20 -0
- package/dist/rdf/calc-rdf.d.ts +4 -0
- package/dist/rdf/calc-rdf.js +107 -0
- package/dist/rdf/index.d.ts +22 -0
- package/dist/rdf/index.js +2 -0
- package/dist/settings.d.ts +86 -75
- package/dist/settings.js +257 -155
- package/dist/structure/Bond.svelte +126 -110
- package/dist/structure/Bond.svelte.d.ts +7 -20
- package/dist/structure/CanvasTooltip.svelte.d.ts +4 -4
- package/dist/structure/Cylinder.svelte +29 -0
- package/dist/structure/Cylinder.svelte.d.ts +10 -0
- package/dist/structure/Lattice.svelte +1 -2
- package/dist/structure/Lattice.svelte.d.ts +3 -3
- package/dist/structure/Structure.svelte +23 -8
- package/dist/structure/Structure.svelte.d.ts +10 -7
- package/dist/structure/StructureControls.svelte +25 -134
- package/dist/structure/StructureControls.svelte.d.ts +4 -9
- package/dist/structure/StructureExportPane.svelte +188 -0
- package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
- package/dist/structure/StructureInfoPane.svelte.d.ts +3 -3
- package/dist/structure/StructureLegend.svelte +91 -27
- package/dist/structure/StructureLegend.svelte.d.ts +5 -4
- package/dist/structure/StructureScene.svelte +93 -100
- package/dist/structure/StructureScene.svelte.d.ts +15 -12
- package/dist/structure/Vector.svelte +19 -25
- package/dist/structure/Vector.svelte.d.ts +3 -3
- package/dist/structure/bonding.d.ts +16 -14
- package/dist/structure/bonding.js +207 -216
- package/dist/structure/export.d.ts +3 -0
- package/dist/structure/export.js +120 -0
- package/dist/structure/index.d.ts +15 -1
- package/dist/structure/index.js +2 -0
- package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -3
- package/dist/symmetry/index.d.ts +1 -0
- package/dist/symmetry/index.js +1 -0
- package/dist/symmetry/spacegroups.d.ts +9 -0
- package/dist/symmetry/spacegroups.js +397 -0
- package/dist/theme/ThemeControl.svelte.d.ts +3 -3
- package/dist/theme/themes.js +2 -16
- package/dist/trajectory/Trajectory.svelte +52 -78
- package/dist/trajectory/Trajectory.svelte.d.ts +5 -5
- package/dist/trajectory/TrajectoryError.svelte.d.ts +3 -3
- package/dist/trajectory/TrajectoryExportPane.svelte +1 -1
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +5 -5
- package/dist/trajectory/TrajectoryInfoPane.svelte +1 -1
- package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -3
- package/dist/trajectory/extract.js +2 -1
- package/dist/trajectory/index.d.ts +1 -1
- package/dist/trajectory/index.js +1 -1
- package/dist/trajectory/parse.js +21 -14
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +17 -0
- package/dist/xrd/XrdPlot.svelte +14 -11
- package/dist/xrd/XrdPlot.svelte.d.ts +6 -5
- package/package.json +20 -12
- package/readme.md +1 -1
- package/dist/material/MaterialCard.svelte +0 -123
- package/dist/material/MaterialCard.svelte.d.ts +0 -9
- package/dist/material/index.d.ts +0 -1
- package/dist/material/index.js +0 -1
- package/dist/plot/formatting.d.ts +0 -7
- package/dist/plot/formatting.js +0 -53
|
@@ -4,74 +4,33 @@ import { elem_symbol_to_name, get_electro_neg_formula } from '../composition';
|
|
|
4
4
|
import { format_fractional, format_num } from '../labels';
|
|
5
5
|
import { ColorBar } from '../plot';
|
|
6
6
|
import { barycentric_to_tetrahedral, compute_4d_coords, TETRAHEDRON_VERTICES, } from './barycentric-coords';
|
|
7
|
-
import
|
|
7
|
+
import * as helpers from './helpers';
|
|
8
|
+
import { default_controls, default_pd_config, PD_STYLE } from './index';
|
|
8
9
|
import PhaseDiagramControls from './PhaseDiagramControls.svelte';
|
|
9
10
|
import PhaseDiagramInfoPane from './PhaseDiagramInfoPane.svelte';
|
|
10
11
|
import StructurePopup from './StructurePopup.svelte';
|
|
11
|
-
import
|
|
12
|
-
let { entries, controls = {}, config = {}, on_point_click, on_point_hover, fullscreen = $bindable(false), enable_fullscreen = true, enable_info_pane = true, wrapper = $bindable(undefined), label_threshold = 50, show_stable = $bindable(true), show_unstable = $bindable(true), show_hull_faces = $bindable(true), hull_face_opacity = $bindable(0.06), color_mode = $bindable(`energy`), color_scale = $bindable(`interpolateViridis`), info_pane_open = $bindable(false), legend_pane_open = $bindable(false),
|
|
12
|
+
import * as thermo from './thermodynamics';
|
|
13
|
+
let { entries, controls = {}, config = {}, on_point_click, on_point_hover, fullscreen = $bindable(false), enable_fullscreen = true, enable_info_pane = true, wrapper = $bindable(undefined), label_threshold = 50, show_stable = $bindable(true), show_unstable = $bindable(true), show_hull_faces = $bindable(true), hull_face_opacity = $bindable(0.06), color_mode = $bindable(`energy`), color_scale = $bindable(`interpolateViridis`), info_pane_open = $bindable(false), legend_pane_open = $bindable(false), max_hull_dist_show_phases = $bindable(0.1), // eV/atom above hull for showing entries
|
|
13
14
|
on_file_drop, enable_structure_preview = true, energy_source_mode = $bindable(`precomputed`), phase_stats = $bindable(null), ...rest } = $props();
|
|
14
|
-
const merged_controls = $derived({
|
|
15
|
-
...default_controls,
|
|
16
|
-
...controls,
|
|
17
|
-
});
|
|
15
|
+
const merged_controls = $derived({ ...default_controls, ...controls });
|
|
18
16
|
const merged_config = $derived({
|
|
19
|
-
|
|
20
|
-
height: 600,
|
|
21
|
-
show_labels: true,
|
|
22
|
-
show_hull: true,
|
|
23
|
-
point_size: 8,
|
|
24
|
-
line_width: 2,
|
|
25
|
-
font_size: 12,
|
|
26
|
-
colors: {
|
|
27
|
-
stable: `#0072B2`,
|
|
28
|
-
unstable: `#E69F00`,
|
|
29
|
-
hull_line: `var(--accent-color, #1976D2)`,
|
|
30
|
-
background: `transparent`,
|
|
31
|
-
text: `var(--text-color, #212121)`,
|
|
32
|
-
edge: `var(--text-color, #212121)`,
|
|
33
|
-
tooltip_bg: `var(--tooltip-bg, rgba(0, 0, 0, 0.85))`,
|
|
34
|
-
tooltip_text: `var(--tooltip-text, white)`,
|
|
35
|
-
annotation: `var(--text-color, #212121)`,
|
|
36
|
-
},
|
|
17
|
+
...default_pd_config,
|
|
37
18
|
...config,
|
|
38
|
-
|
|
39
|
-
})
|
|
40
|
-
// Decide which energy source to use per entry (keep e_form and e_above_hull consistent)
|
|
41
|
-
const has_precomputed_e_form = $derived(entries.length > 0 && entries.every((e) => typeof e.e_form_per_atom === `number`));
|
|
42
|
-
const has_precomputed_hull = $derived(entries.length > 0 && entries.every((e) => typeof e.e_above_hull === `number`));
|
|
43
|
-
// Build unary references once from entries (needed for capability checking)
|
|
44
|
-
const unary_refs = $derived.by(() => find_lowest_energy_unary_refs(entries));
|
|
45
|
-
const can_compute_e_form = $derived.by(() => {
|
|
46
|
-
const elements_in_entries = Array.from(new Set(entries.flatMap((e) => Object.keys(e.composition))));
|
|
47
|
-
return elements_in_entries.every((el) => Boolean(unary_refs[el]));
|
|
48
|
-
});
|
|
49
|
-
// Quaternary on-the-fly hull distances ARE now implemented using 4D Quick Hull
|
|
50
|
-
const can_compute_hull = $derived(can_compute_e_form);
|
|
51
|
-
const energy_mode = $derived((has_precomputed_e_form && has_precomputed_hull)
|
|
52
|
-
? energy_source_mode
|
|
53
|
-
: ((can_compute_e_form && can_compute_hull) ? `on-the-fly` : `precomputed`));
|
|
54
|
-
const effective_entries = $derived.by(() => {
|
|
55
|
-
if (energy_mode === `precomputed`)
|
|
56
|
-
return entries;
|
|
57
|
-
// on-the-fly: compute formation energy per atom where possible
|
|
58
|
-
return entries.map((entry) => {
|
|
59
|
-
const e_form = compute_e_form_per_atom(entry, unary_refs);
|
|
60
|
-
if (e_form === null)
|
|
61
|
-
return entry;
|
|
62
|
-
return { ...entry, e_form_per_atom: e_form };
|
|
63
|
-
});
|
|
19
|
+
colors: { ...default_pd_config.colors, ...(config.colors || {}) },
|
|
20
|
+
margin: { t: 60, r: 60, b: 60, l: 60, ...(config.margin || {}) },
|
|
64
21
|
});
|
|
22
|
+
let { // Compute energy mode information
|
|
23
|
+
has_precomputed_e_form, has_precomputed_hull, can_compute_e_form, can_compute_hull, energy_mode, unary_refs, } = $derived(helpers.compute_energy_mode_info(entries, thermo.find_lowest_energy_unary_refs, energy_source_mode));
|
|
24
|
+
const effective_entries = $derived(helpers.get_effective_entries(entries, energy_mode, unary_refs, thermo.compute_e_form_per_atom));
|
|
65
25
|
// Process phase diagram data with unified PhaseEntry interface using effective entries
|
|
66
26
|
const processed_entries = $derived(effective_entries);
|
|
67
|
-
const pd_data = $derived(process_pd_entries(processed_entries));
|
|
27
|
+
const pd_data = $derived(thermo.process_pd_entries(processed_entries));
|
|
68
28
|
const elements = $derived.by(() => {
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
console.error(`PhaseDiagram4D: Dataset contains ${all_elements.length} elements, but quaternary diagrams require exactly 4. Found: [${all_elements.join(`, `)}]`);
|
|
29
|
+
if (pd_data.elements.length > 4) {
|
|
30
|
+
console.error(`PhaseDiagram4D: Dataset contains ${pd_data.elements.length} elements, but quaternary diagrams require exactly 4. Found: [${pd_data.elements.join(`, `)}]`);
|
|
72
31
|
return [];
|
|
73
32
|
}
|
|
74
|
-
return
|
|
33
|
+
return pd_data.elements;
|
|
75
34
|
});
|
|
76
35
|
// Compute 4D hull for visualization (always compute when we have formation energies)
|
|
77
36
|
const hull_4d = $derived.by(() => {
|
|
@@ -80,23 +39,23 @@ const hull_4d = $derived.by(() => {
|
|
|
80
39
|
try {
|
|
81
40
|
// Get coords with formation energies
|
|
82
41
|
const coords = compute_4d_coords(pd_data.entries, elements);
|
|
83
|
-
// Convert to 4D points for hull computation
|
|
84
|
-
const points_4d = coords
|
|
85
|
-
|
|
42
|
+
// Convert to 4D points for hull computation using barycentric coordinates (composition fractions)
|
|
43
|
+
const points_4d = coords
|
|
44
|
+
.filter((ent) => Number.isFinite(ent.e_form_per_atom) &&
|
|
45
|
+
[ent.x, ent.y, ent.z].every(Number.isFinite))
|
|
46
|
+
.map((ent) => {
|
|
47
|
+
const amounts = elements.map((el) => ent.composition[el] || 0);
|
|
86
48
|
const total = amounts.reduce((sum, amt) => sum + amt, 0);
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
});
|
|
95
|
-
// Filter out points with no formation energy
|
|
96
|
-
const valid_points = points_4d.filter((p) => typeof p.w === `number`);
|
|
49
|
+
if (!(total > 0))
|
|
50
|
+
return { x: NaN, y: NaN, z: NaN, w: NaN };
|
|
51
|
+
const [x, y, z] = amounts.map((amt) => amt / total);
|
|
52
|
+
return { x, y, z, w: ent.e_form_per_atom };
|
|
53
|
+
})
|
|
54
|
+
.filter((p) => [p.x, p.y, p.z, p.w].every(Number.isFinite));
|
|
55
|
+
const valid_points = points_4d;
|
|
97
56
|
if (valid_points.length < 5)
|
|
98
57
|
return []; // Need at least 5 points for 4D hull
|
|
99
|
-
return compute_lower_hull_4d(valid_points);
|
|
58
|
+
return thermo.compute_lower_hull_4d(valid_points);
|
|
100
59
|
}
|
|
101
60
|
catch (error) {
|
|
102
61
|
console.error(`Error computing 4D hull:`, error);
|
|
@@ -104,31 +63,40 @@ const hull_4d = $derived.by(() => {
|
|
|
104
63
|
}
|
|
105
64
|
});
|
|
106
65
|
const plot_entries = $derived.by(() => {
|
|
107
|
-
if (elements.length !== 4)
|
|
66
|
+
if (elements.length !== 4)
|
|
108
67
|
return [];
|
|
109
|
-
}
|
|
110
68
|
try {
|
|
111
69
|
const coords = compute_4d_coords(pd_data.entries, elements);
|
|
112
70
|
// Compute or use precomputed hull distances
|
|
113
71
|
const enriched = (() => {
|
|
114
72
|
if (energy_mode === `on-the-fly` && hull_4d.length > 0) {
|
|
115
|
-
// Build 4D points for distance calculation
|
|
116
|
-
|
|
73
|
+
// Build 4D points for distance calculation using barycentric coordinates
|
|
74
|
+
// Track indices to map hull distances back to original coords
|
|
75
|
+
const valid_entries = [];
|
|
76
|
+
coords.forEach((ent, idx) => {
|
|
77
|
+
if (Number.isFinite(ent.e_form_per_atom) &&
|
|
78
|
+
[ent.x, ent.y, ent.z].every(Number.isFinite))
|
|
79
|
+
valid_entries.push({ entry: ent, orig_idx: idx });
|
|
80
|
+
});
|
|
81
|
+
const points_4d = valid_entries
|
|
82
|
+
.map(({ entry }) => {
|
|
117
83
|
const amounts = elements.map((el) => entry.composition[el] || 0);
|
|
118
84
|
const total = amounts.reduce((sum, amt) => sum + amt, 0);
|
|
119
|
-
|
|
85
|
+
if (!(total > 0))
|
|
86
|
+
return { x: NaN, y: NaN, z: NaN, w: NaN };
|
|
87
|
+
const [x, y, z] = amounts.map((amt) => amt / total);
|
|
88
|
+
return { x, y, z, w: entry.e_form_per_atom };
|
|
89
|
+
})
|
|
90
|
+
.filter((p) => [p.x, p.y, p.z, p.w].every(Number.isFinite));
|
|
91
|
+
const e_hulls = thermo.compute_e_above_hull_4d(points_4d, hull_4d);
|
|
92
|
+
// Map hull distances back to all coords
|
|
93
|
+
return coords.map((entry, idx) => {
|
|
94
|
+
const valid_idx = valid_entries.findIndex((v) => v.orig_idx === idx);
|
|
120
95
|
return {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
z: normalized[2],
|
|
124
|
-
w: entry.e_form_per_atom ?? 0,
|
|
96
|
+
...entry,
|
|
97
|
+
e_above_hull: valid_idx >= 0 ? e_hulls[valid_idx] : undefined,
|
|
125
98
|
};
|
|
126
99
|
});
|
|
127
|
-
const e_hulls = compute_e_above_hull_4d(points_4d, hull_4d);
|
|
128
|
-
return coords.map((entry, idx) => ({
|
|
129
|
-
...entry,
|
|
130
|
-
e_above_hull: e_hulls[idx],
|
|
131
|
-
}));
|
|
132
100
|
}
|
|
133
101
|
return coords;
|
|
134
102
|
})();
|
|
@@ -141,7 +109,7 @@ const plot_entries = $derived.by(() => {
|
|
|
141
109
|
return true;
|
|
142
110
|
// Include other elemental polymorphs only if toggle is enabled AND e_above_hull is defined
|
|
143
111
|
return typeof entry.e_above_hull === `number` &&
|
|
144
|
-
entry.e_above_hull <=
|
|
112
|
+
entry.e_above_hull <= max_hull_dist_show_phases;
|
|
145
113
|
}
|
|
146
114
|
// Include stable entries (treat near-zero as stable)
|
|
147
115
|
if (entry.is_stable ||
|
|
@@ -149,7 +117,7 @@ const plot_entries = $derived.by(() => {
|
|
|
149
117
|
return true;
|
|
150
118
|
// Include unstable entries within threshold
|
|
151
119
|
return typeof entry.e_above_hull === `number` &&
|
|
152
|
-
entry.e_above_hull <=
|
|
120
|
+
entry.e_above_hull <= max_hull_dist_show_phases;
|
|
153
121
|
});
|
|
154
122
|
return energy_filtered
|
|
155
123
|
.map((entry) => {
|
|
@@ -222,14 +190,14 @@ $effect(() => {
|
|
|
222
190
|
$effect(() => {
|
|
223
191
|
// deno-fmt-ignore
|
|
224
192
|
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
|
|
225
|
-
[show_stable, show_unstable, show_hull_faces, color_mode, color_scale,
|
|
193
|
+
[show_stable, show_unstable, show_hull_faces, color_mode, color_scale, max_hull_dist_show_phases, camera.rotation_x, camera.rotation_y, camera.zoom, camera.center_x, camera.center_y, plot_entries, hull_face_color, hull_face_opacity];
|
|
226
194
|
render_once();
|
|
227
195
|
});
|
|
228
196
|
// Visibility toggles are now bindable props
|
|
229
197
|
// Label controls with smart defaults based on entry count
|
|
230
198
|
let show_stable_labels = $state(true);
|
|
231
199
|
let show_unstable_labels = $state(false);
|
|
232
|
-
let
|
|
200
|
+
let max_hull_dist_show_labels = $state(0.1); // eV/atom above hull for showing labels
|
|
233
201
|
// Smart label defaults - hide labels if too many entries
|
|
234
202
|
$effect(() => {
|
|
235
203
|
const total_entries = processed_entries.length;
|
|
@@ -248,7 +216,6 @@ function extract_structure_from_entry(entry) {
|
|
|
248
216
|
const original_entry = entries.find((orig_entry) => orig_entry.entry_id === entry.entry_id);
|
|
249
217
|
return original_entry?.structure || null;
|
|
250
218
|
}
|
|
251
|
-
const get_tooltip_text = (entry) => build_entry_tooltip_text(entry);
|
|
252
219
|
const reset_camera = () => Object.assign(camera, {
|
|
253
220
|
rotation_x: PD_DEFAULTS.quaternary.camera_rotation_x,
|
|
254
221
|
rotation_y: PD_DEFAULTS.quaternary.camera_rotation_y,
|
|
@@ -267,8 +234,8 @@ function reset_all() {
|
|
|
267
234
|
show_unstable = PD_DEFAULTS.quaternary.show_unstable;
|
|
268
235
|
show_stable_labels = PD_DEFAULTS.quaternary.show_stable_labels;
|
|
269
236
|
show_unstable_labels = PD_DEFAULTS.quaternary.show_unstable_labels;
|
|
270
|
-
|
|
271
|
-
|
|
237
|
+
max_hull_dist_show_phases = PD_DEFAULTS.quaternary.max_hull_dist_show_phases;
|
|
238
|
+
max_hull_dist_show_labels = PD_DEFAULTS.quaternary.max_hull_dist_show_labels;
|
|
272
239
|
show_hull_faces = PD_DEFAULTS.quaternary.show_hull_faces;
|
|
273
240
|
hull_face_color = PD_DEFAULTS.quaternary.hull_face_color;
|
|
274
241
|
hull_face_opacity = PD_DEFAULTS.quaternary.hull_face_opacity;
|
|
@@ -288,7 +255,7 @@ const handle_keydown = (event) => {
|
|
|
288
255
|
};
|
|
289
256
|
async function handle_file_drop(event) {
|
|
290
257
|
drag_over = false;
|
|
291
|
-
const data = await parse_pd_entries_from_drop(event);
|
|
258
|
+
const data = await helpers.parse_pd_entries_from_drop(event);
|
|
292
259
|
if (data)
|
|
293
260
|
on_file_drop?.(data);
|
|
294
261
|
}
|
|
@@ -298,15 +265,13 @@ async function copy_to_clipboard(text, position) {
|
|
|
298
265
|
copy_feedback_visible = true;
|
|
299
266
|
setTimeout(() => copy_feedback_visible = false, 1500);
|
|
300
267
|
}
|
|
301
|
-
|
|
302
|
-
return get_point_color_for_entry(entry, color_mode, merged_config.colors, energy_color_scale);
|
|
303
|
-
}
|
|
268
|
+
const get_point_color = (entry) => helpers.get_point_color_for_entry(entry, color_mode, merged_config.colors, energy_color_scale);
|
|
304
269
|
// Cache energy color scale per frame/setting
|
|
305
|
-
const energy_color_scale = $derived.by(() => get_energy_color_scale(color_mode, color_scale, plot_entries));
|
|
306
|
-
const
|
|
270
|
+
const energy_color_scale = $derived.by(() => helpers.get_energy_color_scale(color_mode, color_scale, plot_entries));
|
|
271
|
+
const max_hull_dist_in_data = $derived(helpers.calc_max_hull_dist_in_data(processed_entries));
|
|
307
272
|
// Phase diagram statistics - compute internally and expose via bindable prop
|
|
308
273
|
$effect(() => {
|
|
309
|
-
phase_stats = get_phase_diagram_stats(processed_entries, elements, 4);
|
|
274
|
+
phase_stats = thermo.get_phase_diagram_stats(processed_entries, elements, 4);
|
|
310
275
|
});
|
|
311
276
|
// Utility: convert hex color to rgba string with alpha
|
|
312
277
|
function hex_to_rgba(hex, alpha) {
|
|
@@ -570,7 +535,7 @@ function draw_data_points() {
|
|
|
570
535
|
// Draw labels based on controls (do not label elemental corners here; they are labeled near vertices)
|
|
571
536
|
const should_show_label = merged_config.show_labels && ((is_stable && show_stable_labels) ||
|
|
572
537
|
(!is_stable && show_unstable_labels &&
|
|
573
|
-
(entry.e_above_hull ?? 0) <=
|
|
538
|
+
(entry.e_above_hull ?? 0) <= max_hull_dist_show_labels));
|
|
574
539
|
if (should_show_label) {
|
|
575
540
|
ctx.fillStyle = styles.getPropertyValue(`--pd-text-color`) || `#212121`;
|
|
576
541
|
// For compound entries, use name, formula, or entry_id as fallback
|
|
@@ -646,7 +611,7 @@ const handle_hover = (event) => {
|
|
|
646
611
|
: null;
|
|
647
612
|
on_point_hover?.(hover_data);
|
|
648
613
|
};
|
|
649
|
-
const find_entry_at_mouse = (event) => find_pd_entry_at_mouse(canvas, event, plot_entries, (x, y, z) => {
|
|
614
|
+
const find_entry_at_mouse = (event) => helpers.find_pd_entry_at_mouse(canvas, event, plot_entries, (x, y, z) => {
|
|
650
615
|
const p = project_3d_point(x, y, z);
|
|
651
616
|
return { x: p.x, y: p.y };
|
|
652
617
|
});
|
|
@@ -665,25 +630,14 @@ const handle_click = (event) => {
|
|
|
665
630
|
if (structure) {
|
|
666
631
|
selected_structure = structure;
|
|
667
632
|
selected_entry = entry;
|
|
668
|
-
calculate_modal_side();
|
|
633
|
+
modal_place_right = helpers.calculate_modal_side(wrapper);
|
|
669
634
|
modal_open = true;
|
|
670
635
|
}
|
|
671
636
|
}
|
|
672
637
|
}
|
|
673
|
-
else if (modal_open)
|
|
638
|
+
else if (modal_open)
|
|
674
639
|
close_structure_popup();
|
|
675
|
-
}
|
|
676
640
|
};
|
|
677
|
-
// Decide side based on available viewport room
|
|
678
|
-
function calculate_modal_side() {
|
|
679
|
-
if (!wrapper)
|
|
680
|
-
return;
|
|
681
|
-
const rect = wrapper.getBoundingClientRect();
|
|
682
|
-
const viewport_width = globalThis.innerWidth;
|
|
683
|
-
const space_on_right = viewport_width - rect.right;
|
|
684
|
-
const space_on_left = rect.left;
|
|
685
|
-
modal_place_right = space_on_right >= space_on_left;
|
|
686
|
-
}
|
|
687
641
|
function close_structure_popup() {
|
|
688
642
|
modal_open = false;
|
|
689
643
|
selected_structure = null;
|
|
@@ -692,7 +646,7 @@ function close_structure_popup() {
|
|
|
692
646
|
const handle_double_click = (event) => {
|
|
693
647
|
const entry = find_entry_at_mouse(event);
|
|
694
648
|
if (entry) {
|
|
695
|
-
copy_to_clipboard(
|
|
649
|
+
copy_to_clipboard(helpers.build_entry_tooltip_text(entry), {
|
|
696
650
|
x: event.clientX,
|
|
697
651
|
y: event.clientY,
|
|
698
652
|
});
|
|
@@ -753,20 +707,14 @@ $effect(() => {
|
|
|
753
707
|
// Fullscreen handling with camera reset on transitions
|
|
754
708
|
let was_fullscreen = $state(fullscreen);
|
|
755
709
|
$effect(() => {
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
}
|
|
764
|
-
// Reset camera only on fullscreen transitions
|
|
765
|
-
if (fullscreen !== was_fullscreen) {
|
|
766
|
-
camera.center_x = 0;
|
|
767
|
-
camera.center_y = 20;
|
|
768
|
-
was_fullscreen = fullscreen;
|
|
769
|
-
}
|
|
710
|
+
helpers.setup_fullscreen_effect(fullscreen, wrapper, (entering_fullscreen) => {
|
|
711
|
+
// Reset camera only on fullscreen transitions
|
|
712
|
+
if (entering_fullscreen !== was_fullscreen) {
|
|
713
|
+
camera.center_x = 0;
|
|
714
|
+
camera.center_y = 20;
|
|
715
|
+
was_fullscreen = entering_fullscreen;
|
|
716
|
+
}
|
|
717
|
+
});
|
|
770
718
|
});
|
|
771
719
|
let style = $derived(`--pd-stable-color:${merged_config.colors?.stable || `#0072B2`};
|
|
772
720
|
--pd-unstable-color:${merged_config.colors?.unstable || `#E69F00`};
|
|
@@ -779,7 +727,7 @@ let style = $derived(`--pd-stable-color:${merged_config.colors?.stable || `#0072
|
|
|
779
727
|
fullscreen = Boolean(document.fullscreenElement)
|
|
780
728
|
}}
|
|
781
729
|
onmousemove={handle_mouse_move}
|
|
782
|
-
onmouseup={() =>
|
|
730
|
+
onmouseup={() => is_dragging = false}
|
|
783
731
|
/>
|
|
784
732
|
|
|
785
733
|
<div
|
|
@@ -817,13 +765,11 @@ let style = $derived(`--pd-stable-color:${merged_config.colors?.stable || `#0072
|
|
|
817
765
|
|
|
818
766
|
<!-- Energy above hull Color Bar -->
|
|
819
767
|
{#if color_mode === `energy` && plot_entries.length > 0}
|
|
820
|
-
{@const
|
|
768
|
+
{@const hull_distances = plot_entries
|
|
821
769
|
.map((e) => e.e_above_hull)
|
|
822
770
|
.filter((v): v is number => typeof v === `number`)}
|
|
823
|
-
{@const min_energy =
|
|
824
|
-
{@const max_energy =
|
|
825
|
-
? Math.max(...formation_energies, 0.1)
|
|
826
|
-
: 0.1}
|
|
771
|
+
{@const min_energy = hull_distances.length > 0 ? Math.min(...hull_distances) : 0}
|
|
772
|
+
{@const max_energy = hull_distances.length > 0 ? Math.max(...hull_distances, 0.1) : 0.1}
|
|
827
773
|
<ColorBar
|
|
828
774
|
title="Energy above hull (eV/atom)"
|
|
829
775
|
range={[min_energy, max_energy]}
|
|
@@ -852,12 +798,10 @@ let style = $derived(`--pd-stable-color:${merged_config.colors?.stable || `#0072
|
|
|
852
798
|
{phase_stats}
|
|
853
799
|
{stable_entries}
|
|
854
800
|
{unstable_entries}
|
|
855
|
-
{
|
|
856
|
-
{
|
|
801
|
+
{max_hull_dist_show_phases}
|
|
802
|
+
{max_hull_dist_show_labels}
|
|
857
803
|
{label_threshold}
|
|
858
|
-
toggle_props={{
|
|
859
|
-
class: `info-btn`,
|
|
860
|
-
}}
|
|
804
|
+
toggle_props={{ class: `info-btn` }}
|
|
861
805
|
/>
|
|
862
806
|
{/if}
|
|
863
807
|
|
|
@@ -881,17 +825,15 @@ let style = $derived(`--pd-stable-color:${merged_config.colors?.stable || `#0072
|
|
|
881
825
|
bind:show_unstable
|
|
882
826
|
bind:show_stable_labels
|
|
883
827
|
bind:show_unstable_labels
|
|
884
|
-
bind:
|
|
885
|
-
bind:
|
|
886
|
-
{
|
|
828
|
+
bind:max_hull_dist_show_phases
|
|
829
|
+
bind:max_hull_dist_show_labels
|
|
830
|
+
{max_hull_dist_in_data}
|
|
887
831
|
{stable_entries}
|
|
888
832
|
{unstable_entries}
|
|
889
833
|
{total_unstable_count}
|
|
890
834
|
{camera}
|
|
891
835
|
{merged_controls}
|
|
892
|
-
toggle_props={{
|
|
893
|
-
class: `legend-controls-btn`,
|
|
894
|
-
}}
|
|
836
|
+
toggle_props={{ class: `legend-controls-btn` }}
|
|
895
837
|
{show_hull_faces}
|
|
896
838
|
on_hull_faces_change={(value) => show_hull_faces = value}
|
|
897
839
|
{hull_face_color}
|
|
@@ -1,31 +1,8 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
import type {
|
|
3
|
-
|
|
4
|
-
interface Props extends HTMLAttributes<HTMLDivElement> {
|
|
5
|
-
entries: PhaseEntry[];
|
|
6
|
-
controls?: Partial<PDControlsType>;
|
|
7
|
-
config?: Partial<PhaseDiagramConfig>;
|
|
8
|
-
on_point_click?: (entry: PlotEntry3D) => void;
|
|
1
|
+
import type { BasePhaseDiagramProps, Hull3DProps } from './index';
|
|
2
|
+
import type { HoverData3D, PlotEntry3D } from './types';
|
|
3
|
+
type $$ComponentProps = BasePhaseDiagramProps<PlotEntry3D> & Hull3DProps & {
|
|
9
4
|
on_point_hover?: (data: HoverData3D | null) => void;
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
enable_info_pane?: boolean;
|
|
13
|
-
wrapper?: HTMLDivElement;
|
|
14
|
-
label_threshold?: number;
|
|
15
|
-
show_stable?: boolean;
|
|
16
|
-
show_unstable?: boolean;
|
|
17
|
-
show_hull_faces?: boolean;
|
|
18
|
-
hull_face_opacity?: number;
|
|
19
|
-
color_mode?: `stability` | `energy`;
|
|
20
|
-
color_scale?: D3InterpolateName;
|
|
21
|
-
info_pane_open?: boolean;
|
|
22
|
-
legend_pane_open?: boolean;
|
|
23
|
-
energy_threshold?: number;
|
|
24
|
-
on_file_drop?: (entries: PhaseEntry[]) => void;
|
|
25
|
-
enable_structure_preview?: boolean;
|
|
26
|
-
energy_source_mode?: `precomputed` | `on-the-fly`;
|
|
27
|
-
phase_stats?: PhaseStats | null;
|
|
28
|
-
}
|
|
29
|
-
declare const PhaseDiagram4D: import("svelte").Component<Props, {}, "color_mode" | "color_scale" | "show_stable" | "show_unstable" | "energy_threshold" | "fullscreen" | "info_pane_open" | "legend_pane_open" | "show_hull_faces" | "hull_face_opacity" | "wrapper" | "energy_source_mode" | "phase_stats">;
|
|
5
|
+
};
|
|
6
|
+
declare const PhaseDiagram4D: import("svelte").Component<$$ComponentProps, {}, "show_hull_faces" | "hull_face_opacity" | "color_mode" | "color_scale" | "show_stable" | "show_unstable" | "max_hull_dist_show_phases" | "fullscreen" | "info_pane_open" | "legend_pane_open" | "wrapper" | "energy_source_mode" | "phase_stats">;
|
|
30
7
|
type PhaseDiagram4D = ReturnType<typeof PhaseDiagram4D>;
|
|
31
8
|
export default PhaseDiagram4D;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">import { DraggablePane, format_num } from '..';
|
|
2
2
|
import { ColorScaleSelect } from '../plot';
|
|
3
3
|
import { tooltip } from 'svelte-multiselect';
|
|
4
|
-
let { color_mode = $bindable(`stability`), color_scale = $bindable(`interpolateViridis`), show_stable = $bindable(true), show_unstable = $bindable(true), show_stable_labels = $bindable(true), show_unstable_labels = $bindable(false), show_hull_faces = undefined, on_hull_faces_change, hull_face_color = `#0072B2`, on_hull_face_color_change, hull_face_opacity = $bindable(0.06), on_hull_face_opacity_change,
|
|
4
|
+
let { color_mode = $bindable(`stability`), color_scale = $bindable(`interpolateViridis`), show_stable = $bindable(true), show_unstable = $bindable(true), show_stable_labels = $bindable(true), show_unstable_labels = $bindable(false), show_hull_faces = undefined, on_hull_faces_change, hull_face_color = `#0072B2`, on_hull_face_color_change, hull_face_opacity = $bindable(0.06), on_hull_face_opacity_change, max_hull_dist_show_phases = $bindable(0), max_hull_dist_show_labels = $bindable(0.1), max_hull_dist_in_data = 0.5, energy_source_mode = $bindable(`precomputed`), has_precomputed_hull = false, can_compute_hull = false, has_precomputed_e_form = false, can_compute_e_form = false, stable_entries, unstable_entries, total_unstable_count, camera, merged_controls, controls_open = $bindable(false), toggle_props = $bindable({}), pane_props = $bindable({}), ...rest } = $props();
|
|
5
5
|
</script>
|
|
6
6
|
|
|
7
7
|
<DraggablePane
|
|
@@ -11,7 +11,7 @@ let { color_mode = $bindable(`stability`), color_scale = $bindable(`interpolateV
|
|
|
11
11
|
class: `phase-diagram-controls-pane ${pane_props?.class ?? ``}`,
|
|
12
12
|
}}
|
|
13
13
|
toggle_props={{
|
|
14
|
-
title:
|
|
14
|
+
title: controls_open ? `` : `Phase diagram controls`,
|
|
15
15
|
class: `phase-diagram-controls-toggle`,
|
|
16
16
|
...toggle_props,
|
|
17
17
|
}}
|
|
@@ -76,18 +76,18 @@ let { color_mode = $bindable(`stability`), color_scale = $bindable(`interpolateV
|
|
|
76
76
|
<input
|
|
77
77
|
type="number"
|
|
78
78
|
min="0"
|
|
79
|
-
max={
|
|
79
|
+
max={max_hull_dist_in_data}
|
|
80
80
|
step="0.01"
|
|
81
|
-
bind:value={
|
|
81
|
+
bind:value={max_hull_dist_show_phases}
|
|
82
82
|
class="threshold-input"
|
|
83
83
|
/>
|
|
84
84
|
<span style="white-space: nowrap; font-size: 0.85em">eV/atom</span>
|
|
85
85
|
<input
|
|
86
86
|
type="range"
|
|
87
87
|
min="0"
|
|
88
|
-
max={
|
|
88
|
+
max={max_hull_dist_in_data}
|
|
89
89
|
step="0.01"
|
|
90
|
-
bind:value={
|
|
90
|
+
bind:value={max_hull_dist_show_phases}
|
|
91
91
|
class="threshold-slider"
|
|
92
92
|
/>
|
|
93
93
|
</label>
|
|
@@ -180,14 +180,14 @@ let { color_mode = $bindable(`stability`), color_scale = $bindable(`interpolateV
|
|
|
180
180
|
<span class="control-label">Label threshold</span>
|
|
181
181
|
<label style="display: flex; align-items: center; gap: 4px; flex: 1">
|
|
182
182
|
<span style="white-space: nowrap; font-size: 0.85em">{
|
|
183
|
-
|
|
183
|
+
max_hull_dist_show_labels.toFixed(2)
|
|
184
184
|
} eV/atom</span>
|
|
185
185
|
<input
|
|
186
186
|
type="range"
|
|
187
187
|
min="0"
|
|
188
|
-
max={
|
|
188
|
+
max={max_hull_dist_in_data}
|
|
189
189
|
step="0.01"
|
|
190
|
-
bind:value={
|
|
190
|
+
bind:value={max_hull_dist_show_labels}
|
|
191
191
|
class="threshold-slider"
|
|
192
192
|
/>
|
|
193
193
|
</label>
|
|
@@ -12,7 +12,7 @@ interface CameraState {
|
|
|
12
12
|
center_x: number;
|
|
13
13
|
center_y: number;
|
|
14
14
|
}
|
|
15
|
-
|
|
15
|
+
type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclose`> & {
|
|
16
16
|
color_mode?: `stability` | `energy`;
|
|
17
17
|
color_scale?: D3InterpolateName;
|
|
18
18
|
show_stable?: boolean;
|
|
@@ -30,9 +30,9 @@ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, `onclose`> {
|
|
|
30
30
|
can_compute_hull?: boolean;
|
|
31
31
|
has_precomputed_e_form?: boolean;
|
|
32
32
|
can_compute_e_form?: boolean;
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
33
|
+
max_hull_dist_show_phases?: number;
|
|
34
|
+
max_hull_dist_show_labels?: number;
|
|
35
|
+
max_hull_dist_in_data?: number;
|
|
36
36
|
stable_entries: PlotEntry3D[];
|
|
37
37
|
unstable_entries: PlotEntry3D[];
|
|
38
38
|
total_unstable_count: number;
|
|
@@ -41,7 +41,7 @@ interface Props extends Omit<HTMLAttributes<HTMLDivElement>, `onclose`> {
|
|
|
41
41
|
controls_open?: boolean;
|
|
42
42
|
toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`];
|
|
43
43
|
pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`];
|
|
44
|
-
}
|
|
45
|
-
declare const PhaseDiagramControls: import("svelte").Component
|
|
44
|
+
};
|
|
45
|
+
declare const PhaseDiagramControls: import("svelte").Component<$$ComponentProps, {}, "hull_face_opacity" | "color_mode" | "color_scale" | "show_stable" | "show_unstable" | "show_stable_labels" | "show_unstable_labels" | "max_hull_dist_show_phases" | "max_hull_dist_show_labels" | "controls_open" | "toggle_props" | "pane_props" | "energy_source_mode">;
|
|
46
46
|
type PhaseDiagramControls = ReturnType<typeof PhaseDiagramControls>;
|
|
47
47
|
export default PhaseDiagramControls;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
<script lang="ts">import { DraggablePane } from '..';
|
|
2
2
|
import PhaseDiagramStats from './PhaseDiagramStats.svelte';
|
|
3
|
-
let { phase_stats, stable_entries, unstable_entries,
|
|
3
|
+
let { phase_stats, stable_entries, unstable_entries, max_hull_dist_show_phases, max_hull_dist_show_labels, label_threshold, pane_open = $bindable(false), toggle_props = $bindable({}), pane_props = $bindable({}), ...rest } = $props();
|
|
4
4
|
</script>
|
|
5
5
|
|
|
6
6
|
<DraggablePane
|
|
7
7
|
bind:show={pane_open}
|
|
8
8
|
max_width="24em"
|
|
9
9
|
toggle_props={{
|
|
10
|
-
title:
|
|
10
|
+
title: pane_open ? `` : `Phase diagram info`,
|
|
11
11
|
class: `phase-diagram-info-toggle`,
|
|
12
12
|
...toggle_props,
|
|
13
13
|
}}
|
|
@@ -42,11 +42,11 @@ let { phase_stats, stable_entries, unstable_entries, energy_threshold, label_ene
|
|
|
42
42
|
</div>
|
|
43
43
|
<div class="setting-item" data-testid="pd-show-threshold">
|
|
44
44
|
<span>Points threshold:</span>
|
|
45
|
-
<span>{
|
|
45
|
+
<span>{max_hull_dist_show_phases.toFixed(3)} eV/atom</span>
|
|
46
46
|
</div>
|
|
47
47
|
<div class="setting-item" data-testid="pd-label-threshold">
|
|
48
48
|
<span>Label threshold:</span>
|
|
49
|
-
<span>{
|
|
49
|
+
<span>{max_hull_dist_show_labels.toFixed(3)} eV/atom</span>
|
|
50
50
|
</div>
|
|
51
51
|
<div class="setting-item" data-testid="pd-entry-limit-labels">
|
|
52
52
|
<span>Entry limit for labels:</span>
|
|
@@ -2,17 +2,17 @@ import { DraggablePane } from '..';
|
|
|
2
2
|
import type { ComponentProps } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
4
|
import type { PhaseStats, PlotEntry3D } from './types';
|
|
5
|
-
|
|
5
|
+
type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `onclose`> & {
|
|
6
6
|
phase_stats: PhaseStats | null;
|
|
7
7
|
stable_entries: PlotEntry3D[];
|
|
8
8
|
unstable_entries: PlotEntry3D[];
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
max_hull_dist_show_phases: number;
|
|
10
|
+
max_hull_dist_show_labels: number;
|
|
11
11
|
label_threshold: number;
|
|
12
12
|
pane_open?: boolean;
|
|
13
13
|
toggle_props?: ComponentProps<typeof DraggablePane>[`toggle_props`];
|
|
14
14
|
pane_props?: ComponentProps<typeof DraggablePane>[`pane_props`];
|
|
15
|
-
}
|
|
16
|
-
declare const PhaseDiagramInfoPane: import("svelte").Component
|
|
15
|
+
};
|
|
16
|
+
declare const PhaseDiagramInfoPane: import("svelte").Component<$$ComponentProps, {}, "toggle_props" | "pane_props" | "pane_open">;
|
|
17
17
|
type PhaseDiagramInfoPane = ReturnType<typeof PhaseDiagramInfoPane>;
|
|
18
18
|
export default PhaseDiagramInfoPane;
|
|
@@ -13,7 +13,7 @@ async function copy_to_clipboard(label, value, key) {
|
|
|
13
13
|
}
|
|
14
14
|
}
|
|
15
15
|
// Prepare histogram data for formation energies and hull distances
|
|
16
|
-
let
|
|
16
|
+
let e_form_data = $derived.by(() => {
|
|
17
17
|
const all_entries = [...stable_entries, ...unstable_entries];
|
|
18
18
|
const energies = all_entries
|
|
19
19
|
.map((entry) => entry.e_form_per_atom ?? entry.energy_per_atom)
|
|
@@ -185,20 +185,17 @@ let pane_data = $derived.by(() => {
|
|
|
185
185
|
{/each}
|
|
186
186
|
|
|
187
187
|
{#if section.title === `Energy Statistics (eV/atom)` &&
|
|
188
|
-
|
|
188
|
+
e_form_data[0].y.length > 0}
|
|
189
189
|
<Histogram
|
|
190
|
-
series={
|
|
190
|
+
series={e_form_data}
|
|
191
191
|
bins={50}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
x_format=".2f"
|
|
195
|
-
y_ticks={3}
|
|
192
|
+
x_axis={{ label: ``, format: `.2f` }}
|
|
193
|
+
y_axis={{ label: ``, ticks: 3 }}
|
|
196
194
|
show_legend={false}
|
|
197
195
|
show_controls={false}
|
|
198
196
|
padding={{ t: 5, b: 25, l: 35, r: 5 }}
|
|
199
197
|
style="height: 100px; --histogram-min-height: 100px"
|
|
200
|
-
|
|
201
|
-
bar_opacity={0.7}
|
|
198
|
+
bar={{ color: `steelblue`, opacity: 0.7 }}
|
|
202
199
|
/>
|
|
203
200
|
{/if}
|
|
204
201
|
|
|
@@ -207,17 +204,13 @@ let pane_data = $derived.by(() => {
|
|
|
207
204
|
<Histogram
|
|
208
205
|
series={hull_distance_data}
|
|
209
206
|
bins={50}
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
x_format=".2f"
|
|
213
|
-
x_lim={[0, null]}
|
|
214
|
-
y_ticks={3}
|
|
207
|
+
x_axis={{ label: ``, format: `.2f`, range: [0, null] }}
|
|
208
|
+
y_axis={{ label: ``, ticks: 3 }}
|
|
215
209
|
show_legend={false}
|
|
216
210
|
show_controls={false}
|
|
217
211
|
padding={{ t: 5, b: 25, l: 35, r: 5 }}
|
|
218
212
|
style="height: 100px; --histogram-min-height: 100px"
|
|
219
|
-
|
|
220
|
-
bar_opacity={0.7}
|
|
213
|
+
bar={{ color: `coral`, opacity: 0.7 }}
|
|
221
214
|
/>
|
|
222
215
|
{/if}
|
|
223
216
|
</section>
|