matterviz 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FilePicker.svelte +37 -20
- package/dist/Icon.svelte +2 -2
- package/dist/app.css +29 -0
- package/dist/brillouin/BrillouinZone.svelte +19 -61
- package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneExportPane.svelte +12 -20
- package/dist/brillouin/BrillouinZoneScene.svelte +2 -2
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/chempot-diagram/ChemPotDiagram.svelte +192 -0
- package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +677 -0
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2688 -0
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
- package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -0
- package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
- package/dist/chempot-diagram/color.d.ts +10 -0
- package/dist/chempot-diagram/color.js +33 -0
- package/dist/chempot-diagram/compute.d.ts +38 -0
- package/dist/chempot-diagram/compute.js +650 -0
- package/dist/chempot-diagram/index.d.ts +5 -0
- package/dist/chempot-diagram/index.js +5 -0
- package/dist/chempot-diagram/pointer.d.ts +16 -0
- package/dist/chempot-diagram/pointer.js +40 -0
- package/dist/chempot-diagram/temperature.d.ts +15 -0
- package/dist/chempot-diagram/temperature.js +37 -0
- package/dist/chempot-diagram/types.d.ts +83 -0
- package/dist/chempot-diagram/types.js +27 -0
- package/dist/colors/index.d.ts +3 -1
- package/dist/colors/index.js +4 -0
- package/dist/composition/BarChart.svelte +13 -22
- package/dist/composition/BubbleChart.svelte +5 -3
- package/dist/composition/FormulaFilter.svelte +586 -94
- package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
- package/dist/composition/PieChart.svelte +43 -18
- package/dist/composition/PieChart.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull.svelte +4 -2
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +13 -44
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +16 -7
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +17 -7
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullStats.svelte +701 -226
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
- package/dist/convex-hull/demo-temperature.d.ts +6 -0
- package/dist/convex-hull/demo-temperature.js +36 -0
- package/dist/convex-hull/helpers.d.ts +1 -1
- package/dist/convex-hull/helpers.js +2 -4
- package/dist/convex-hull/index.d.ts +1 -0
- package/dist/convex-hull/index.js +1 -0
- package/dist/convex-hull/thermodynamics.d.ts +8 -21
- package/dist/convex-hull/thermodynamics.js +106 -17
- package/dist/convex-hull/types.d.ts +5 -0
- package/dist/convex-hull/types.js +5 -0
- package/dist/coordination/CoordinationBarPlot.svelte +29 -46
- package/dist/element/BohrAtom.svelte +1 -1
- package/dist/element/data.js +2 -14
- package/dist/element/data.json.gz +0 -0
- package/dist/element/types.d.ts +1 -0
- package/dist/fermi-surface/FermiSurface.svelte +20 -64
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/parse.js +16 -22
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +1273 -0
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +171 -0
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +31 -0
- package/dist/heatmap-matrix/index.d.ts +53 -0
- package/dist/heatmap-matrix/index.js +100 -0
- package/dist/heatmap-matrix/shared.d.ts +2 -0
- package/dist/heatmap-matrix/shared.js +4 -0
- package/dist/icons.d.ts +111 -0
- package/dist/icons.js +111 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.js +3 -1
- package/dist/io/export.js +15 -3
- package/dist/io/file-drop.d.ts +7 -0
- package/dist/io/file-drop.js +43 -0
- package/dist/io/index.d.ts +2 -2
- package/dist/io/index.js +2 -112
- package/dist/io/types.d.ts +1 -0
- package/dist/io/url-drop.d.ts +2 -0
- package/dist/io/url-drop.js +118 -0
- package/dist/isosurface/Isosurface.svelte +101 -45
- package/dist/isosurface/IsosurfaceControls.svelte +19 -0
- package/dist/isosurface/parse.js +73 -30
- package/dist/isosurface/slice.d.ts +2 -1
- package/dist/isosurface/slice.js +3 -3
- package/dist/isosurface/types.d.ts +13 -1
- package/dist/isosurface/types.js +98 -0
- package/dist/labels.d.ts +2 -1
- package/dist/labels.js +1 -0
- package/dist/layout/InfoTag.svelte +62 -62
- package/dist/layout/SubpageGrid.svelte +74 -0
- package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.js +1 -0
- package/dist/layout/json-tree/JsonNode.svelte +83 -85
- package/dist/layout/json-tree/JsonTree.svelte +20 -19
- package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
- package/dist/layout/json-tree/JsonValue.svelte +196 -116
- package/dist/layout/json-tree/types.d.ts +10 -2
- package/dist/layout/json-tree/utils.d.ts +2 -0
- package/dist/layout/json-tree/utils.js +33 -0
- package/dist/math.d.ts +7 -0
- package/dist/math.js +358 -7
- package/dist/overlays/ContextMenu.svelte +3 -2
- package/dist/overlays/DraggablePane.svelte +163 -58
- package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +232 -77
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
- package/dist/phase-diagram/PhaseDiagramControls.svelte +32 -11
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +103 -0
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +102 -95
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +7 -0
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +100 -26
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
- package/dist/phase-diagram/index.d.ts +2 -0
- package/dist/phase-diagram/index.js +2 -0
- package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
- package/dist/phase-diagram/svg-to-diagram.js +865 -0
- package/dist/phase-diagram/types.d.ts +10 -0
- package/dist/phase-diagram/utils.d.ts +7 -4
- package/dist/phase-diagram/utils.js +149 -59
- package/dist/plot/AxisLabel.svelte +26 -0
- package/dist/plot/AxisLabel.svelte.d.ts +16 -0
- package/dist/plot/BarPlot.svelte +473 -228
- package/dist/plot/BarPlot.svelte.d.ts +3 -3
- package/dist/plot/BarPlotControls.svelte +3 -2
- package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ColorBar.svelte +54 -54
- package/dist/plot/ColorBar.svelte.d.ts +1 -1
- package/dist/plot/ColorScaleSelect.svelte +1 -1
- package/dist/plot/ElementScatter.svelte +3 -2
- package/dist/plot/FillArea.svelte +4 -1
- package/dist/plot/Histogram.svelte +320 -230
- package/dist/plot/Histogram.svelte.d.ts +2 -2
- package/dist/plot/HistogramControls.svelte +29 -10
- package/dist/plot/HistogramControls.svelte.d.ts +6 -2
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +2 -2
- package/dist/plot/PlotControls.svelte +109 -27
- package/dist/plot/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/PlotLegend.svelte +1 -1
- package/dist/plot/PortalSelect.svelte +2 -1
- package/dist/plot/ReferenceLine.svelte +2 -1
- package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
- package/dist/plot/ReferencePlane.svelte +1 -3
- package/dist/plot/ScatterPlot.svelte +343 -209
- package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
- package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3DControls.svelte +203 -250
- package/dist/plot/ScatterPlot3DScene.svelte +4 -7
- package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlotControls.svelte +95 -55
- package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ZeroLines.svelte +44 -0
- package/dist/plot/ZeroLines.svelte.d.ts +32 -0
- package/dist/plot/ZoomRect.svelte +21 -0
- package/dist/plot/ZoomRect.svelte.d.ts +8 -0
- package/dist/plot/axis-utils.d.ts +1 -1
- package/dist/plot/index.d.ts +6 -2
- package/dist/plot/index.js +6 -2
- package/dist/plot/interactions.d.ts +8 -10
- package/dist/plot/interactions.js +2 -3
- package/dist/plot/layout.d.ts +7 -1
- package/dist/plot/layout.js +12 -4
- package/dist/plot/reference-line.d.ts +4 -21
- package/dist/plot/reference-line.js +7 -81
- package/dist/plot/types.d.ts +42 -17
- package/dist/plot/types.js +10 -0
- package/dist/plot/utils/label-placement.js +13 -10
- package/dist/plot/utils.d.ts +1 -0
- package/dist/plot/utils.js +14 -0
- package/dist/rdf/RdfPlot.svelte +55 -66
- package/dist/settings.d.ts +3 -0
- package/dist/settings.js +17 -3
- package/dist/spectral/Bands.svelte +515 -143
- package/dist/spectral/Bands.svelte.d.ts +22 -2
- package/dist/spectral/helpers.d.ts +23 -1
- package/dist/spectral/helpers.js +65 -9
- package/dist/spectral/types.d.ts +2 -0
- package/dist/structure/AtomLegend.svelte +29 -8
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CellSelect.svelte +92 -22
- package/dist/structure/Structure.svelte +108 -118
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureControls.svelte +25 -22
- package/dist/structure/StructureControls.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +7 -1
- package/dist/structure/StructureScene.svelte +104 -66
- package/dist/structure/StructureScene.svelte.d.ts +2 -1
- package/dist/structure/atom-properties.d.ts +6 -2
- package/dist/structure/atom-properties.js +38 -25
- package/dist/structure/export.js +10 -7
- package/dist/structure/ferrox-wasm-types.d.ts +3 -2
- package/dist/structure/ferrox-wasm-types.js +0 -3
- package/dist/structure/ferrox-wasm.d.ts +3 -2
- package/dist/structure/ferrox-wasm.js +1 -2
- package/dist/structure/index.d.ts +6 -0
- package/dist/structure/index.js +22 -0
- package/dist/structure/parse.js +19 -16
- package/dist/structure/partial-occupancy.d.ts +25 -0
- package/dist/structure/partial-occupancy.js +102 -0
- package/dist/structure/validation.js +6 -3
- package/dist/symmetry/SymmetryStats.svelte +18 -4
- package/dist/symmetry/WyckoffTable.svelte +18 -10
- package/dist/symmetry/index.d.ts +7 -4
- package/dist/symmetry/index.js +83 -18
- package/dist/table/HeatmapTable.svelte +425 -65
- package/dist/table/HeatmapTable.svelte.d.ts +12 -1
- package/dist/table/ToggleMenu.svelte +2 -0
- package/dist/table/index.d.ts +2 -0
- package/dist/trajectory/Trajectory.svelte +147 -145
- package/dist/trajectory/TrajectoryExportPane.svelte +13 -9
- package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
- package/dist/trajectory/constants.d.ts +6 -0
- package/dist/trajectory/constants.js +7 -0
- package/dist/trajectory/extract.js +3 -5
- package/dist/trajectory/format-detect.d.ts +9 -0
- package/dist/trajectory/format-detect.js +76 -0
- package/dist/trajectory/frame-reader.d.ts +17 -0
- package/dist/trajectory/frame-reader.js +339 -0
- package/dist/trajectory/helpers.d.ts +15 -0
- package/dist/trajectory/helpers.js +187 -0
- package/dist/trajectory/index.d.ts +1 -0
- package/dist/trajectory/index.js +11 -4
- package/dist/trajectory/parse/ase.d.ts +2 -0
- package/dist/trajectory/parse/ase.js +76 -0
- package/dist/trajectory/parse/hdf5.d.ts +2 -0
- package/dist/trajectory/parse/hdf5.js +121 -0
- package/dist/trajectory/parse/index.d.ts +12 -0
- package/dist/trajectory/parse/index.js +304 -0
- package/dist/trajectory/parse/lammps.d.ts +5 -0
- package/dist/trajectory/parse/lammps.js +169 -0
- package/dist/trajectory/parse/vasp.d.ts +2 -0
- package/dist/trajectory/parse/vasp.js +65 -0
- package/dist/trajectory/parse/xyz.d.ts +2 -0
- package/dist/trajectory/parse/xyz.js +109 -0
- package/dist/trajectory/types.d.ts +11 -0
- package/dist/trajectory/types.js +1 -0
- package/dist/utils.d.ts +2 -0
- package/dist/utils.js +4 -0
- package/dist/xrd/XrdPlot.svelte +6 -4
- package/dist/xrd/calc-xrd.js +0 -1
- package/package.json +30 -24
- package/readme.md +4 -4
- package/dist/trajectory/parse.d.ts +0 -42
- package/dist/trajectory/parse.js +0 -1267
- /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
|
@@ -0,0 +1,677 @@
|
|
|
1
|
+
<script lang="ts">import {} from '../colors';
|
|
2
|
+
import { get_hill_formula } from '../composition/format';
|
|
3
|
+
import { extract_formula_elements } from '../composition/parse';
|
|
4
|
+
import TemperatureSlider from '../convex-hull/TemperatureSlider.svelte';
|
|
5
|
+
import { export_svg_as_png, export_svg_as_svg } from '../io/export';
|
|
6
|
+
import { download } from '../io/fetch';
|
|
7
|
+
import DraggablePane from '../overlays/DraggablePane.svelte';
|
|
8
|
+
import { ColorBar, ScatterPlot } from '../plot';
|
|
9
|
+
import { onDestroy } from 'svelte';
|
|
10
|
+
import { SvelteMap } from 'svelte/reactivity';
|
|
11
|
+
import { get_chempot_color_bar_config, make_chempot_color_scale } from './color';
|
|
12
|
+
import { apply_element_padding, best_form_energy_for_formula, build_axis_ranges, compute_chempot_diagram, formula_key_from_composition, get_energy_per_atom, get_min_entries_and_el_refs, orthonormal_2d, pad_domain_points, } from './compute';
|
|
13
|
+
import { with_hover_pointer } from './pointer';
|
|
14
|
+
import { get_temp_filter_payload, get_valid_temperature } from './temperature';
|
|
15
|
+
import { CHEMPOT_DEFAULTS } from './types';
|
|
16
|
+
let { entries = [], config = {}, width = $bindable(800), height = $bindable(600),
|
|
17
|
+
// Auto-corrected to a valid available temperature when needed.
|
|
18
|
+
temperature = $bindable(undefined), interpolate_temperature = CHEMPOT_DEFAULTS.interpolate_temperature, max_interpolation_gap = CHEMPOT_DEFAULTS.max_interpolation_gap, hover_info = $bindable(null), render_local_tooltip = true, } = $props();
|
|
19
|
+
let container_width = $state(0);
|
|
20
|
+
const base_aspect_ratio = $derived(height > 0 && width > 0 ? height / width : 1);
|
|
21
|
+
const render_width = $derived(container_width > 0 ? container_width : width);
|
|
22
|
+
const render_height = $derived(Math.round(render_width * base_aspect_ratio));
|
|
23
|
+
// === Control overrides ===
|
|
24
|
+
let formal_chempots_override = $state(null);
|
|
25
|
+
let label_stable_override = $state(null);
|
|
26
|
+
let element_padding_override = $state(null);
|
|
27
|
+
let default_min_limit_override = $state(null);
|
|
28
|
+
const formal_chempots = $derived(formal_chempots_override ??
|
|
29
|
+
(config.formal_chempots ?? CHEMPOT_DEFAULTS.formal_chempots));
|
|
30
|
+
const label_stable = $derived(label_stable_override ?? (config.label_stable ?? CHEMPOT_DEFAULTS.label_stable));
|
|
31
|
+
const element_padding = $derived(element_padding_override ??
|
|
32
|
+
(config.element_padding ?? CHEMPOT_DEFAULTS.element_padding));
|
|
33
|
+
const default_min_limit = $derived(default_min_limit_override ??
|
|
34
|
+
(config.default_min_limit ?? CHEMPOT_DEFAULTS.default_min_limit));
|
|
35
|
+
let color_mode_override = $state(null);
|
|
36
|
+
let color_scale_override = $state(null);
|
|
37
|
+
let reverse_color_scale_override = $state(null);
|
|
38
|
+
const color_mode = $derived(color_mode_override ?? (config.color_mode ?? CHEMPOT_DEFAULTS.color_mode));
|
|
39
|
+
const color_scale = $derived(color_scale_override ?? (config.color_scale ?? CHEMPOT_DEFAULTS.color_scale));
|
|
40
|
+
const reverse_color_scale = $derived(reverse_color_scale_override ??
|
|
41
|
+
(config.reverse_color_scale ?? CHEMPOT_DEFAULTS.reverse_color_scale));
|
|
42
|
+
const arity_colors = [`#3498db`, `#2ecc71`, `#e67e22`, `#9b59b6`];
|
|
43
|
+
const show_tooltip = $derived(config.show_tooltip ?? CHEMPOT_DEFAULTS.show_tooltip);
|
|
44
|
+
const effective_config = $derived({
|
|
45
|
+
...config,
|
|
46
|
+
formal_chempots,
|
|
47
|
+
label_stable,
|
|
48
|
+
element_padding,
|
|
49
|
+
default_min_limit,
|
|
50
|
+
});
|
|
51
|
+
const { has_temp_data, available_temperatures, temp_filtered_entries } = $derived(get_temp_filter_payload(entries, temperature, config, {
|
|
52
|
+
interpolate_temperature,
|
|
53
|
+
max_interpolation_gap,
|
|
54
|
+
}));
|
|
55
|
+
$effect(() => {
|
|
56
|
+
// Keep bound temperature aligned with available data points.
|
|
57
|
+
const next_temperature = get_valid_temperature(temperature, has_temp_data, available_temperatures);
|
|
58
|
+
if (next_temperature !== temperature)
|
|
59
|
+
temperature = next_temperature;
|
|
60
|
+
});
|
|
61
|
+
const show_temperature_slider = $derived(has_temp_data && available_temperatures.length > 0);
|
|
62
|
+
function reset_controls() {
|
|
63
|
+
formal_chempots_override = null;
|
|
64
|
+
label_stable_override = null;
|
|
65
|
+
element_padding_override = null;
|
|
66
|
+
default_min_limit_override = null;
|
|
67
|
+
color_mode_override = null;
|
|
68
|
+
color_scale_override = null;
|
|
69
|
+
reverse_color_scale_override = null;
|
|
70
|
+
}
|
|
71
|
+
// === Diagram computation ===
|
|
72
|
+
const diagram_data = $derived.by(() => {
|
|
73
|
+
if (temp_filtered_entries.length < 2)
|
|
74
|
+
return null;
|
|
75
|
+
try {
|
|
76
|
+
return compute_chempot_diagram(temp_filtered_entries, effective_config);
|
|
77
|
+
}
|
|
78
|
+
catch (err) {
|
|
79
|
+
console.error(`ChemPotDiagram2D:`, err);
|
|
80
|
+
return null;
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
const plot_elements = $derived((diagram_data?.elements ?? config.elements ?? []).slice(0, 2));
|
|
84
|
+
const draw_domains = $derived.by(() => {
|
|
85
|
+
if (!diagram_data || plot_elements.length < 2)
|
|
86
|
+
return {};
|
|
87
|
+
const indices = [0, 1];
|
|
88
|
+
if (element_padding <= 0) {
|
|
89
|
+
return Object.fromEntries(Object.entries(diagram_data.domains).filter(([, pts]) => pts.length > 0));
|
|
90
|
+
}
|
|
91
|
+
const new_lims = apply_element_padding(diagram_data.domains, indices, element_padding, default_min_limit);
|
|
92
|
+
const result = {};
|
|
93
|
+
for (const [formula, pts] of Object.entries(diagram_data.domains)) {
|
|
94
|
+
const padded = pad_domain_points(pts, indices, new_lims, default_min_limit, element_padding);
|
|
95
|
+
if (padded.length > 0)
|
|
96
|
+
result[formula] = padded;
|
|
97
|
+
}
|
|
98
|
+
return result;
|
|
99
|
+
});
|
|
100
|
+
const domain_entries = $derived(Object.entries(draw_domains));
|
|
101
|
+
const domain_formulas = $derived(Object.keys(draw_domains));
|
|
102
|
+
const raw_el_refs = $derived(get_min_entries_and_el_refs(temp_filtered_entries).el_refs);
|
|
103
|
+
const entry_energy_stats_by_formula = $derived.by(() => {
|
|
104
|
+
const stats = new SvelteMap();
|
|
105
|
+
for (const entry of temp_filtered_entries) {
|
|
106
|
+
const formula_key = formula_key_from_composition(entry.composition);
|
|
107
|
+
const epa = get_energy_per_atom(entry);
|
|
108
|
+
const prev_stats = stats.get(formula_key);
|
|
109
|
+
if (!prev_stats) {
|
|
110
|
+
stats.set(formula_key, {
|
|
111
|
+
matching_entry_count: 1,
|
|
112
|
+
min_energy_per_atom: epa,
|
|
113
|
+
});
|
|
114
|
+
continue;
|
|
115
|
+
}
|
|
116
|
+
stats.set(formula_key, {
|
|
117
|
+
matching_entry_count: prev_stats.matching_entry_count + 1,
|
|
118
|
+
min_energy_per_atom: Math.min(prev_stats.min_energy_per_atom ?? epa, epa),
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
return stats;
|
|
122
|
+
});
|
|
123
|
+
const color_mode_labels = {
|
|
124
|
+
energy: `Energy per atom (eV)`,
|
|
125
|
+
formation_energy: `Formation energy (eV/atom)`,
|
|
126
|
+
entries: `Entry count`,
|
|
127
|
+
};
|
|
128
|
+
function get_numeric_color_value(formula, active_color_mode) {
|
|
129
|
+
if (active_color_mode === `energy`) {
|
|
130
|
+
return entry_energy_stats_by_formula.get(formula)?.min_energy_per_atom ?? null;
|
|
131
|
+
}
|
|
132
|
+
if (active_color_mode === `formation_energy`) {
|
|
133
|
+
return best_form_energy_for_formula(temp_filtered_entries, formula, raw_el_refs) ?? null;
|
|
134
|
+
}
|
|
135
|
+
return entry_energy_stats_by_formula.get(formula)?.matching_entry_count ?? 0;
|
|
136
|
+
}
|
|
137
|
+
const domain_color_values = $derived.by(() => {
|
|
138
|
+
if (color_mode === `none` || color_mode === `arity`)
|
|
139
|
+
return null;
|
|
140
|
+
const active_color_mode = color_mode;
|
|
141
|
+
const value_by_formula = new SvelteMap();
|
|
142
|
+
const values = [];
|
|
143
|
+
for (const formula of domain_formulas) {
|
|
144
|
+
const value = get_numeric_color_value(formula, active_color_mode);
|
|
145
|
+
if (value == null || !Number.isFinite(value))
|
|
146
|
+
continue;
|
|
147
|
+
values.push(value);
|
|
148
|
+
value_by_formula.set(formula, value);
|
|
149
|
+
}
|
|
150
|
+
return { value_by_formula, values };
|
|
151
|
+
});
|
|
152
|
+
const domain_colors = $derived.by(() => {
|
|
153
|
+
const colors = new SvelteMap();
|
|
154
|
+
if (color_mode === `none`)
|
|
155
|
+
return colors;
|
|
156
|
+
if (color_mode === `arity`) {
|
|
157
|
+
for (const formula of domain_formulas) {
|
|
158
|
+
const n_elements = extract_formula_elements(formula).length;
|
|
159
|
+
const color_idx = Math.min(n_elements, arity_colors.length) - 1;
|
|
160
|
+
colors.set(formula, arity_colors[Math.max(0, color_idx)]);
|
|
161
|
+
}
|
|
162
|
+
return colors;
|
|
163
|
+
}
|
|
164
|
+
const values_payload = domain_color_values;
|
|
165
|
+
const scale = make_chempot_color_scale(values_payload?.values ?? [], color_scale, reverse_color_scale);
|
|
166
|
+
for (const formula of domain_formulas) {
|
|
167
|
+
const color_val = values_payload?.value_by_formula.get(formula);
|
|
168
|
+
colors.set(formula, color_val != null && scale ? scale(color_val) : `#999`);
|
|
169
|
+
}
|
|
170
|
+
return colors;
|
|
171
|
+
});
|
|
172
|
+
const color_range = $derived.by(() => {
|
|
173
|
+
const values = domain_color_values?.values ?? [];
|
|
174
|
+
if (values.length === 0)
|
|
175
|
+
return null;
|
|
176
|
+
let min_val = values[0], max_val = values[0];
|
|
177
|
+
for (let idx = 1; idx < values.length; idx++) {
|
|
178
|
+
if (values[idx] < min_val)
|
|
179
|
+
min_val = values[idx];
|
|
180
|
+
if (values[idx] > max_val)
|
|
181
|
+
max_val = values[idx];
|
|
182
|
+
}
|
|
183
|
+
return {
|
|
184
|
+
min: min_val,
|
|
185
|
+
max: Math.max(max_val, min_val + 1e-6),
|
|
186
|
+
label: color_mode === `none` || color_mode === `arity`
|
|
187
|
+
? ``
|
|
188
|
+
: color_mode_labels[color_mode],
|
|
189
|
+
};
|
|
190
|
+
});
|
|
191
|
+
// === Convert domains to ScatterPlot DataSeries ===
|
|
192
|
+
const series = $derived(domain_entries.map(([formula, pts]) => ({
|
|
193
|
+
id: formula,
|
|
194
|
+
label: formula,
|
|
195
|
+
x: pts.map((pt) => pt[0]),
|
|
196
|
+
y: pts.map((pt) => pt[1]),
|
|
197
|
+
markers: `line+points`,
|
|
198
|
+
line_style: { stroke: domain_colors.get(formula) ?? `black`, stroke_width: 3 },
|
|
199
|
+
point_style: { fill: domain_colors.get(formula) ?? `black`, radius: 3 },
|
|
200
|
+
})));
|
|
201
|
+
// Axis label text
|
|
202
|
+
function axis_label(element) {
|
|
203
|
+
if (formal_chempots)
|
|
204
|
+
return `\u0394\u03BC(${element}) (eV)`;
|
|
205
|
+
return `\u03BC(${element}) (eV)`;
|
|
206
|
+
}
|
|
207
|
+
let x_axis = $state({ label: `` });
|
|
208
|
+
let y_axis = $state({ label: `` });
|
|
209
|
+
$effect(() => {
|
|
210
|
+
const next_x_label = axis_label(plot_elements[0] ?? ``);
|
|
211
|
+
const next_y_label = axis_label(plot_elements[1] ?? ``);
|
|
212
|
+
if (x_axis.label !== next_x_label)
|
|
213
|
+
x_axis = { ...x_axis, label: next_x_label };
|
|
214
|
+
if (y_axis.label !== next_y_label)
|
|
215
|
+
y_axis = { ...y_axis, label: next_y_label };
|
|
216
|
+
});
|
|
217
|
+
// === Domain label annotations (in data coordinates) ===
|
|
218
|
+
const annotations = $derived.by(() => {
|
|
219
|
+
if (!label_stable)
|
|
220
|
+
return [];
|
|
221
|
+
const result = [];
|
|
222
|
+
for (const [formula, pts] of Object.entries(draw_domains)) {
|
|
223
|
+
if (pts.length === 0)
|
|
224
|
+
continue;
|
|
225
|
+
const center_x = pts.reduce((s, p) => s + p[0], 0) / pts.length;
|
|
226
|
+
const center_y = pts.reduce((s, p) => s + p[1], 0) / pts.length;
|
|
227
|
+
let offset_x = 0;
|
|
228
|
+
let offset_y = 0;
|
|
229
|
+
if (pts.length >= 2) {
|
|
230
|
+
const [nx, ny] = orthonormal_2d(pts);
|
|
231
|
+
offset_x = nx * 0.25;
|
|
232
|
+
offset_y = ny * 0.25;
|
|
233
|
+
}
|
|
234
|
+
result.push({
|
|
235
|
+
formula,
|
|
236
|
+
data_x: center_x + offset_x,
|
|
237
|
+
data_y: center_y + offset_y,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
return result;
|
|
241
|
+
});
|
|
242
|
+
// === Hover info for external consumers ===
|
|
243
|
+
let locked_hover_formula = $state(null);
|
|
244
|
+
function set_hover_info(formula, pts, event) {
|
|
245
|
+
const bounds = scatter_wrapper?.getBoundingClientRect();
|
|
246
|
+
hover_info = with_hover_pointer({
|
|
247
|
+
formula,
|
|
248
|
+
view: `2d`,
|
|
249
|
+
n_points: pts.length,
|
|
250
|
+
axis_ranges: build_axis_ranges(pts, plot_elements),
|
|
251
|
+
}, event, bounds);
|
|
252
|
+
}
|
|
253
|
+
function clear_hover_lock() {
|
|
254
|
+
locked_hover_formula = null;
|
|
255
|
+
hover_info = null;
|
|
256
|
+
}
|
|
257
|
+
function handle_hover(data) {
|
|
258
|
+
if (!data) {
|
|
259
|
+
if (!locked_hover_formula)
|
|
260
|
+
hover_info = null;
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
const entry = domain_entries[data.point.series_idx];
|
|
264
|
+
if (!entry)
|
|
265
|
+
return;
|
|
266
|
+
const [formula, pts] = entry;
|
|
267
|
+
if (locked_hover_formula && locked_hover_formula !== formula)
|
|
268
|
+
return;
|
|
269
|
+
set_hover_info(formula, pts, data.event);
|
|
270
|
+
}
|
|
271
|
+
function handle_click(data) {
|
|
272
|
+
const entry = domain_entries[data.point.series_idx];
|
|
273
|
+
if (!entry)
|
|
274
|
+
return;
|
|
275
|
+
const [formula, pts] = entry;
|
|
276
|
+
if (locked_hover_formula === formula) {
|
|
277
|
+
clear_hover_lock();
|
|
278
|
+
return;
|
|
279
|
+
}
|
|
280
|
+
locked_hover_formula = formula;
|
|
281
|
+
set_hover_info(formula, pts, data.event);
|
|
282
|
+
}
|
|
283
|
+
// === Export ===
|
|
284
|
+
let scatter_wrapper = $state();
|
|
285
|
+
let export_pane_open = $state(false);
|
|
286
|
+
let copy_status = $state(false);
|
|
287
|
+
let copy_timeout_id = null;
|
|
288
|
+
function get_svg_element() {
|
|
289
|
+
return scatter_wrapper?.querySelector(`svg`) ?? null;
|
|
290
|
+
}
|
|
291
|
+
function get_json_string() {
|
|
292
|
+
return JSON.stringify({
|
|
293
|
+
elements: diagram_data?.elements ?? [],
|
|
294
|
+
domains: draw_domains,
|
|
295
|
+
lims: diagram_data?.lims ?? [],
|
|
296
|
+
}, null, 2);
|
|
297
|
+
}
|
|
298
|
+
function export_json_file() {
|
|
299
|
+
download(get_json_string(), `chempot-${plot_elements.join(`-`)}.json`, `application/json`);
|
|
300
|
+
}
|
|
301
|
+
async function copy_json() {
|
|
302
|
+
try {
|
|
303
|
+
await navigator.clipboard.writeText(get_json_string());
|
|
304
|
+
copy_status = true;
|
|
305
|
+
}
|
|
306
|
+
catch (err) {
|
|
307
|
+
copy_status = false;
|
|
308
|
+
console.error(`Failed to copy JSON to clipboard:`, err);
|
|
309
|
+
}
|
|
310
|
+
if (copy_timeout_id !== null)
|
|
311
|
+
clearTimeout(copy_timeout_id);
|
|
312
|
+
copy_timeout_id = setTimeout(() => {
|
|
313
|
+
copy_status = false;
|
|
314
|
+
copy_timeout_id = null;
|
|
315
|
+
}, 1000);
|
|
316
|
+
}
|
|
317
|
+
onDestroy(() => {
|
|
318
|
+
if (copy_timeout_id !== null)
|
|
319
|
+
clearTimeout(copy_timeout_id);
|
|
320
|
+
});
|
|
321
|
+
</script>
|
|
322
|
+
|
|
323
|
+
{#snippet domain_labels(props: UserContentProps)}
|
|
324
|
+
{#each annotations as { formula, data_x, data_y } (formula)}
|
|
325
|
+
<text
|
|
326
|
+
x={props.x_scale_fn(data_x)}
|
|
327
|
+
y={props.y_scale_fn(data_y)}
|
|
328
|
+
text-anchor="middle"
|
|
329
|
+
class="domain-label"
|
|
330
|
+
>
|
|
331
|
+
{get_hill_formula(formula, true, ``)}
|
|
332
|
+
</text>
|
|
333
|
+
{/each}
|
|
334
|
+
{/snippet}
|
|
335
|
+
|
|
336
|
+
{#snippet export_toggle()}
|
|
337
|
+
<DraggablePane
|
|
338
|
+
bind:show={export_pane_open}
|
|
339
|
+
open_icon="Cross"
|
|
340
|
+
closed_icon="Export"
|
|
341
|
+
pane_props={{ class: `chempot-export-pane` }}
|
|
342
|
+
toggle_props={{
|
|
343
|
+
class: `chempot-export-toggle`,
|
|
344
|
+
title: `Export chemical potential diagram`,
|
|
345
|
+
style:
|
|
346
|
+
`position: absolute; top: var(--ctrl-btn-top, 5pt); right: 36px; z-index: 10`,
|
|
347
|
+
}}
|
|
348
|
+
>
|
|
349
|
+
<h4 id="export-image">Export Image</h4>
|
|
350
|
+
<div class="export-row">
|
|
351
|
+
<label>
|
|
352
|
+
SVG
|
|
353
|
+
<button
|
|
354
|
+
type="button"
|
|
355
|
+
onclick={() => {
|
|
356
|
+
const svg = get_svg_element()
|
|
357
|
+
if (svg) {
|
|
358
|
+
export_svg_as_svg(svg, `chempot-${plot_elements.join(`-`)}.svg`)
|
|
359
|
+
}
|
|
360
|
+
}}
|
|
361
|
+
aria-label="Download SVG"
|
|
362
|
+
>
|
|
363
|
+
⬇
|
|
364
|
+
</button>
|
|
365
|
+
</label>
|
|
366
|
+
<label>
|
|
367
|
+
PNG
|
|
368
|
+
<button
|
|
369
|
+
type="button"
|
|
370
|
+
onclick={() => {
|
|
371
|
+
const svg = get_svg_element()
|
|
372
|
+
if (svg) {
|
|
373
|
+
export_svg_as_png(svg, `chempot-${plot_elements.join(`-`)}.png`)
|
|
374
|
+
}
|
|
375
|
+
}}
|
|
376
|
+
aria-label="Download PNG"
|
|
377
|
+
>
|
|
378
|
+
⬇
|
|
379
|
+
</button>
|
|
380
|
+
</label>
|
|
381
|
+
</div>
|
|
382
|
+
<h4 id="export-data">Export Data</h4>
|
|
383
|
+
<div class="export-row">
|
|
384
|
+
<label>
|
|
385
|
+
JSON
|
|
386
|
+
<button type="button" onclick={export_json_file} aria-label="Download JSON">
|
|
387
|
+
⬇
|
|
388
|
+
</button>
|
|
389
|
+
<button
|
|
390
|
+
type="button"
|
|
391
|
+
onclick={copy_json}
|
|
392
|
+
aria-label="Copy JSON to clipboard"
|
|
393
|
+
>
|
|
394
|
+
{copy_status ? `✅` : `📋`}
|
|
395
|
+
</button>
|
|
396
|
+
</label>
|
|
397
|
+
</div>
|
|
398
|
+
</DraggablePane>
|
|
399
|
+
{/snippet}
|
|
400
|
+
|
|
401
|
+
{#snippet chempot_controls(_props: unknown)}
|
|
402
|
+
<h4 id="chempot">ChemPot</h4>
|
|
403
|
+
<label>
|
|
404
|
+
<span>Formal chempots:</span>
|
|
405
|
+
<input
|
|
406
|
+
type="checkbox"
|
|
407
|
+
checked={formal_chempots}
|
|
408
|
+
onchange={() => {
|
|
409
|
+
formal_chempots_override = !formal_chempots
|
|
410
|
+
}}
|
|
411
|
+
/>
|
|
412
|
+
</label>
|
|
413
|
+
<label>
|
|
414
|
+
<span>Label stable:</span>
|
|
415
|
+
<input
|
|
416
|
+
type="checkbox"
|
|
417
|
+
checked={label_stable}
|
|
418
|
+
onchange={() => {
|
|
419
|
+
label_stable_override = !label_stable
|
|
420
|
+
}}
|
|
421
|
+
/>
|
|
422
|
+
</label>
|
|
423
|
+
<label>
|
|
424
|
+
<span>Element padding (eV):</span>
|
|
425
|
+
<input
|
|
426
|
+
type="number"
|
|
427
|
+
min="0"
|
|
428
|
+
step="0.1"
|
|
429
|
+
value={element_padding}
|
|
430
|
+
oninput={(event) => {
|
|
431
|
+
element_padding_override = Number(event.currentTarget.value) || 0
|
|
432
|
+
}}
|
|
433
|
+
/>
|
|
434
|
+
</label>
|
|
435
|
+
<label>
|
|
436
|
+
<span>Default min limit (eV):</span>
|
|
437
|
+
<input
|
|
438
|
+
type="number"
|
|
439
|
+
max="0"
|
|
440
|
+
step="1"
|
|
441
|
+
value={default_min_limit}
|
|
442
|
+
oninput={(event) => {
|
|
443
|
+
const raw = event.currentTarget.value
|
|
444
|
+
const parsed = parseFloat(raw)
|
|
445
|
+
default_min_limit_override = raw === `` || isNaN(parsed)
|
|
446
|
+
? default_min_limit
|
|
447
|
+
: parsed
|
|
448
|
+
}}
|
|
449
|
+
/>
|
|
450
|
+
</label>
|
|
451
|
+
<label>
|
|
452
|
+
<span>Color mode:</span>
|
|
453
|
+
<select
|
|
454
|
+
value={color_mode}
|
|
455
|
+
onchange={(event) => {
|
|
456
|
+
color_mode_override = event.currentTarget.value as typeof color_mode
|
|
457
|
+
}}
|
|
458
|
+
>
|
|
459
|
+
<option value="none">None</option>
|
|
460
|
+
<option value="energy">Energy/atom</option>
|
|
461
|
+
<option value="formation_energy">Formation energy</option>
|
|
462
|
+
<option value="arity">Element count</option>
|
|
463
|
+
<option value="entries">Entry count</option>
|
|
464
|
+
</select>
|
|
465
|
+
</label>
|
|
466
|
+
{#if color_mode !== `none` && color_mode !== `arity`}
|
|
467
|
+
<label>
|
|
468
|
+
<span>Color scale:</span>
|
|
469
|
+
<select
|
|
470
|
+
value={color_scale}
|
|
471
|
+
onchange={(event) => {
|
|
472
|
+
color_scale_override = event.currentTarget.value as D3InterpolateName
|
|
473
|
+
}}
|
|
474
|
+
>
|
|
475
|
+
<option value="interpolateViridis">Viridis</option>
|
|
476
|
+
<option value="interpolatePlasma">Plasma</option>
|
|
477
|
+
<option value="interpolateInferno">Inferno</option>
|
|
478
|
+
<option value="interpolateMagma">Magma</option>
|
|
479
|
+
<option value="interpolateCividis">Cividis</option>
|
|
480
|
+
<option value="interpolateTurbo">Turbo</option>
|
|
481
|
+
<option value="interpolateRdYlBu">RdYlBu</option>
|
|
482
|
+
<option value="interpolateSpectral">Spectral</option>
|
|
483
|
+
</select>
|
|
484
|
+
<span class="reverse-scale-toggle">
|
|
485
|
+
<span>Reverse:</span>
|
|
486
|
+
<input
|
|
487
|
+
type="checkbox"
|
|
488
|
+
checked={reverse_color_scale}
|
|
489
|
+
onchange={() => {
|
|
490
|
+
reverse_color_scale_override = !reverse_color_scale
|
|
491
|
+
}}
|
|
492
|
+
/>
|
|
493
|
+
</span>
|
|
494
|
+
</label>
|
|
495
|
+
{/if}
|
|
496
|
+
<button type="button" onclick={reset_controls}>Reset defaults</button>
|
|
497
|
+
{/snippet}
|
|
498
|
+
|
|
499
|
+
{#if !diagram_data}
|
|
500
|
+
<div class="error-state" role="alert" aria-live="polite">
|
|
501
|
+
<p>Cannot compute chemical potential diagram.</p>
|
|
502
|
+
<p>Need at least 2 elements with elemental reference entries.</p>
|
|
503
|
+
</div>
|
|
504
|
+
{:else}
|
|
505
|
+
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
506
|
+
<!-- svelte-ignore a11y_no_noninteractive_tabindex -->
|
|
507
|
+
<div
|
|
508
|
+
class="chempot-diagram-2d"
|
|
509
|
+
bind:clientWidth={container_width}
|
|
510
|
+
role="application"
|
|
511
|
+
tabindex="0"
|
|
512
|
+
onkeydown={(event) => {
|
|
513
|
+
if (event.key === `Escape`) clear_hover_lock()
|
|
514
|
+
}}
|
|
515
|
+
onpointerdown={(event) => {
|
|
516
|
+
const target = event.target
|
|
517
|
+
if (!locked_hover_formula) return
|
|
518
|
+
const is_background_click = target === scatter_wrapper ||
|
|
519
|
+
(target instanceof SVGElement &&
|
|
520
|
+
target.closest(`g[data-series-id]`) === null)
|
|
521
|
+
if (is_background_click) {
|
|
522
|
+
clear_hover_lock()
|
|
523
|
+
}
|
|
524
|
+
}}
|
|
525
|
+
>
|
|
526
|
+
{@render export_toggle()}
|
|
527
|
+
<ScatterPlot
|
|
528
|
+
bind:wrapper={scatter_wrapper}
|
|
529
|
+
{series}
|
|
530
|
+
bind:x_axis
|
|
531
|
+
bind:y_axis
|
|
532
|
+
legend={null}
|
|
533
|
+
controls={{ show: true }}
|
|
534
|
+
controls_extra={chempot_controls}
|
|
535
|
+
user_content={domain_labels}
|
|
536
|
+
on_point_hover={handle_hover}
|
|
537
|
+
on_point_click={handle_click}
|
|
538
|
+
style="--scatter-width: 100%; --scatter-height: {render_height}px; --fullscreen-btn-offset: 68px"
|
|
539
|
+
/>
|
|
540
|
+
{#if color_mode !== `none` && color_mode !== `arity` && color_range}
|
|
541
|
+
{@const color_bar_config = get_chempot_color_bar_config(
|
|
542
|
+
color_scale,
|
|
543
|
+
reverse_color_scale,
|
|
544
|
+
)}
|
|
545
|
+
<ColorBar
|
|
546
|
+
title={color_range.label}
|
|
547
|
+
range={[color_range.min, color_range.max]}
|
|
548
|
+
color_scale_fn={color_bar_config.color_scale_fn}
|
|
549
|
+
color_scale_domain={color_bar_config.color_scale_domain}
|
|
550
|
+
wrapper_style="position: absolute; bottom: 70px; left: 50px; width: 180px; z-index: 10;"
|
|
551
|
+
bar_style="height: 10px;"
|
|
552
|
+
title_style="margin-bottom: 3px;"
|
|
553
|
+
/>
|
|
554
|
+
{/if}
|
|
555
|
+
{#if color_mode === `arity`}
|
|
556
|
+
<div class="arity-legend">
|
|
557
|
+
{#each [`Unary`, `Binary`, `Ternary`, `4+`] as label_text, color_idx (label_text)}
|
|
558
|
+
<span>
|
|
559
|
+
<span style:background={arity_colors[color_idx]}></span>
|
|
560
|
+
{label_text}
|
|
561
|
+
</span>
|
|
562
|
+
{/each}
|
|
563
|
+
</div>
|
|
564
|
+
{/if}
|
|
565
|
+
{#if render_local_tooltip && show_tooltip && hover_info?.view === `2d`}
|
|
566
|
+
<aside
|
|
567
|
+
class="tooltip"
|
|
568
|
+
style:left="{hover_info.pointer?.x ?? 4}px"
|
|
569
|
+
style:top="{hover_info.pointer?.y ?? 4}px"
|
|
570
|
+
>
|
|
571
|
+
<strong>{@html get_hill_formula(hover_info.formula, false, ``)}</strong>
|
|
572
|
+
{#if locked_hover_formula === hover_info.formula}
|
|
573
|
+
<div>Pinned · Press Esc to unlock</div>
|
|
574
|
+
{/if}
|
|
575
|
+
</aside>
|
|
576
|
+
{/if}
|
|
577
|
+
{#if show_temperature_slider && temperature !== undefined}
|
|
578
|
+
<TemperatureSlider
|
|
579
|
+
class="chempot-temp-slider"
|
|
580
|
+
{available_temperatures}
|
|
581
|
+
bind:temperature
|
|
582
|
+
/>
|
|
583
|
+
{/if}
|
|
584
|
+
</div>
|
|
585
|
+
{/if}
|
|
586
|
+
|
|
587
|
+
<style>
|
|
588
|
+
.chempot-diagram-2d {
|
|
589
|
+
position: relative;
|
|
590
|
+
width: 100%;
|
|
591
|
+
}
|
|
592
|
+
.chempot-diagram-2d > :global(.pane-toggle) {
|
|
593
|
+
opacity: 0;
|
|
594
|
+
transition: opacity 0.2s, background-color 0.2s;
|
|
595
|
+
}
|
|
596
|
+
.chempot-diagram-2d:hover > :global(.pane-toggle),
|
|
597
|
+
.chempot-diagram-2d > :global(.pane-toggle:focus-visible),
|
|
598
|
+
.chempot-diagram-2d > :global(.pane-toggle[aria-expanded='true']) {
|
|
599
|
+
opacity: 1;
|
|
600
|
+
}
|
|
601
|
+
.chempot-diagram-2d :global(.draggable-pane label) {
|
|
602
|
+
display: flex;
|
|
603
|
+
align-items: center;
|
|
604
|
+
gap: 6pt;
|
|
605
|
+
margin: 4pt 0;
|
|
606
|
+
font-size: 0.95em;
|
|
607
|
+
}
|
|
608
|
+
.chempot-diagram-2d :global(.export-row) {
|
|
609
|
+
display: flex;
|
|
610
|
+
flex-wrap: wrap;
|
|
611
|
+
gap: 4pt 10pt;
|
|
612
|
+
margin: 0 0 4pt;
|
|
613
|
+
}
|
|
614
|
+
.chempot-diagram-2d :global(.export-row > label) {
|
|
615
|
+
margin: 0;
|
|
616
|
+
}
|
|
617
|
+
.chempot-diagram-2d :global(.chempot-temp-slider) {
|
|
618
|
+
top: var(--chempot-temp-slider-top, calc(1ex + 108px));
|
|
619
|
+
right: 4px;
|
|
620
|
+
z-index: 11;
|
|
621
|
+
}
|
|
622
|
+
.chempot-diagram-2d :global(.reverse-scale-toggle) {
|
|
623
|
+
display: flex;
|
|
624
|
+
align-items: center;
|
|
625
|
+
gap: 4pt;
|
|
626
|
+
margin-left: 4pt;
|
|
627
|
+
}
|
|
628
|
+
.error-state {
|
|
629
|
+
display: flex;
|
|
630
|
+
flex-direction: column;
|
|
631
|
+
align-items: center;
|
|
632
|
+
justify-content: center;
|
|
633
|
+
height: 100%;
|
|
634
|
+
color: var(--text-color, #666);
|
|
635
|
+
}
|
|
636
|
+
.domain-label {
|
|
637
|
+
font-size: 12px;
|
|
638
|
+
fill: var(--text-color, currentColor);
|
|
639
|
+
opacity: 0.7;
|
|
640
|
+
pointer-events: none;
|
|
641
|
+
}
|
|
642
|
+
.tooltip {
|
|
643
|
+
position: absolute;
|
|
644
|
+
background: var(
|
|
645
|
+
--tooltip-bg,
|
|
646
|
+
light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.9))
|
|
647
|
+
);
|
|
648
|
+
color: var(--tooltip-text, var(--text-color, #fff));
|
|
649
|
+
padding: 4px 8px;
|
|
650
|
+
border-radius: 4px;
|
|
651
|
+
font-size: 12px;
|
|
652
|
+
pointer-events: none;
|
|
653
|
+
white-space: nowrap;
|
|
654
|
+
z-index: 10;
|
|
655
|
+
}
|
|
656
|
+
.arity-legend {
|
|
657
|
+
position: absolute;
|
|
658
|
+
bottom: 52px;
|
|
659
|
+
left: 24px;
|
|
660
|
+
display: flex;
|
|
661
|
+
gap: 10px;
|
|
662
|
+
font-size: 12px;
|
|
663
|
+
z-index: 10;
|
|
664
|
+
pointer-events: none;
|
|
665
|
+
}
|
|
666
|
+
.arity-legend > span {
|
|
667
|
+
display: flex;
|
|
668
|
+
align-items: center;
|
|
669
|
+
gap: 4px;
|
|
670
|
+
}
|
|
671
|
+
.arity-legend > span > span {
|
|
672
|
+
width: 10px;
|
|
673
|
+
height: 10px;
|
|
674
|
+
border-radius: 50%;
|
|
675
|
+
flex-shrink: 0;
|
|
676
|
+
}
|
|
677
|
+
</style>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { PhaseData } from '../convex-hull/types';
|
|
2
|
+
import type { ChemPotDiagramConfig, ChemPotHoverInfo } from './types';
|
|
3
|
+
type $$ComponentProps = {
|
|
4
|
+
entries: PhaseData[];
|
|
5
|
+
config?: ChemPotDiagramConfig;
|
|
6
|
+
width?: number;
|
|
7
|
+
height?: number;
|
|
8
|
+
temperature?: number;
|
|
9
|
+
interpolate_temperature?: boolean;
|
|
10
|
+
max_interpolation_gap?: number;
|
|
11
|
+
hover_info?: ChemPotHoverInfo | null;
|
|
12
|
+
render_local_tooltip?: boolean;
|
|
13
|
+
};
|
|
14
|
+
declare const ChemPotDiagram2D: import("svelte").Component<$$ComponentProps, {}, "temperature" | "height" | "width" | "hover_info">;
|
|
15
|
+
type ChemPotDiagram2D = ReturnType<typeof ChemPotDiagram2D>;
|
|
16
|
+
export default ChemPotDiagram2D;
|