matterviz 0.3.0 → 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/MillerIndexInput.svelte +60 -0
- package/dist/MillerIndexInput.svelte.d.ts +7 -0
- package/dist/app.css +38 -2
- package/dist/brillouin/BrillouinZone.svelte +20 -62
- 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 +770 -90
- package/dist/composition/FormulaFilter.svelte.d.ts +37 -1
- package/dist/composition/PieChart.svelte +43 -18
- package/dist/composition/PieChart.svelte.d.ts +1 -1
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +2 -0
- package/dist/convex-hull/ConvexHull.svelte +14 -1
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +14 -45
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +396 -134
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +93 -42
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullControls.svelte +94 -31
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +4 -2
- package/dist/convex-hull/ConvexHullStats.svelte +697 -128
- package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
- package/dist/convex-hull/ConvexHullTooltip.svelte +1 -0
- package/dist/convex-hull/GasPressureControls.svelte +72 -38
- package/dist/convex-hull/GasPressureControls.svelte.d.ts +2 -1
- package/dist/convex-hull/TemperatureSlider.svelte +46 -19
- package/dist/convex-hull/TemperatureSlider.svelte.d.ts +2 -1
- package/dist/convex-hull/demo-temperature.d.ts +6 -0
- package/dist/convex-hull/demo-temperature.js +36 -0
- package/dist/convex-hull/gas-thermodynamics.js +16 -5
- package/dist/convex-hull/helpers.d.ts +7 -1
- package/dist/convex-hull/helpers.js +45 -15
- package/dist/convex-hull/index.d.ts +15 -1
- 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 +7 -0
- package/dist/convex-hull/types.js +11 -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/index.d.ts +1 -1
- package/dist/element/index.js +1 -0
- package/dist/element/types.d.ts +1 -0
- package/dist/fermi-surface/FermiSurface.svelte +21 -65
- 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/compute.js +1 -21
- package/dist/fermi-surface/marching-cubes.d.ts +2 -13
- package/dist/fermi-surface/marching-cubes.js +2 -519
- package/dist/fermi-surface/parse.js +17 -23
- 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 +119 -0
- package/dist/icons.js +119 -0
- package/dist/index.d.ts +6 -1
- package/dist/index.js +6 -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 +231 -0
- package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
- package/dist/isosurface/IsosurfaceControls.svelte +273 -0
- package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
- package/dist/isosurface/index.d.ts +5 -0
- package/dist/isosurface/index.js +6 -0
- package/dist/isosurface/parse.d.ts +6 -0
- package/dist/isosurface/parse.js +548 -0
- package/dist/isosurface/slice.d.ts +11 -0
- package/dist/isosurface/slice.js +145 -0
- package/dist/isosurface/types.d.ts +55 -0
- package/dist/isosurface/types.js +178 -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 +226 -53
- package/dist/layout/json-tree/JsonTree.svelte +425 -51
- package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
- package/dist/layout/json-tree/JsonValue.svelte +218 -97
- package/dist/layout/json-tree/types.d.ts +27 -2
- package/dist/layout/json-tree/utils.d.ts +14 -1
- package/dist/layout/json-tree/utils.js +254 -0
- package/dist/marching-cubes.d.ts +14 -0
- package/dist/marching-cubes.js +519 -0
- package/dist/math.d.ts +8 -0
- package/dist/math.js +374 -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/ElementScatter.svelte +4 -3
- 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/data-cleaning.js +1 -5
- 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 +10 -19
- 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 +14 -11
- package/dist/plot/utils.d.ts +1 -0
- package/dist/plot/utils.js +14 -0
- package/dist/rdf/RdfPlot.svelte +55 -66
- package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
- package/dist/rdf/index.d.ts +1 -1
- package/dist/rdf/index.js +1 -1
- package/dist/settings.d.ts +5 -0
- package/dist/settings.js +37 -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 +31 -10
- package/dist/structure/AtomLegend.svelte.d.ts +1 -1
- package/dist/structure/CellSelect.svelte +92 -22
- package/dist/structure/Lattice.svelte +2 -0
- package/dist/structure/Structure.svelte +716 -173
- package/dist/structure/Structure.svelte.d.ts +7 -2
- package/dist/structure/StructureControls.svelte +26 -14
- package/dist/structure/StructureControls.svelte.d.ts +5 -1
- package/dist/structure/StructureInfoPane.svelte +7 -1
- package/dist/structure/StructureScene.svelte +386 -95
- package/dist/structure/StructureScene.svelte.d.ts +15 -4
- 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 +7 -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 +468 -69
- package/dist/table/HeatmapTable.svelte.d.ts +13 -1
- package/dist/table/ToggleMenu.svelte +291 -44
- package/dist/table/ToggleMenu.svelte.d.ts +4 -1
- package/dist/table/index.d.ts +3 -0
- package/dist/tooltip/index.d.ts +1 -1
- package/dist/tooltip/index.js +1 -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 +33 -23
- 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
|
@@ -3,11 +3,56 @@ import { FullscreenToggle, set_fullscreen_bg, setup_fullscreen_effect, } from '.
|
|
|
3
3
|
import { compute_bounding_box_2d, polygon_centroid } from '../math';
|
|
4
4
|
import { constrain_tooltip_position } from '../plot/layout';
|
|
5
5
|
import { scaleLinear } from 'd3-scale';
|
|
6
|
+
import { build_diagram } from './build-diagram';
|
|
6
7
|
import PhaseDiagramControls from './PhaseDiagramControls.svelte';
|
|
8
|
+
import PhaseDiagramEditorPane from './PhaseDiagramEditorPane.svelte';
|
|
7
9
|
import PhaseDiagramExportPane from './PhaseDiagramExportPane.svelte';
|
|
8
10
|
import PhaseDiagramTooltip from './PhaseDiagramTooltip.svelte';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
+
import { parse_phase_diagram_svg } from './svg-to-diagram';
|
|
12
|
+
import { calculate_lever_rule, calculate_vertical_lever_rule, compute_label_properties, convert_temp, find_phase_at_point, format_composition, format_formula_svg, format_hover_info_text, format_label_svg, generate_boundary_path, generate_region_path, get_multi_phase_gradient, get_phase_color, merge_phase_diagram_config, PHASE_COLOR_RGB, transform_vertices, } from './utils';
|
|
13
|
+
let { data, config = $bindable({}), on_phase_hover, fullscreen = $bindable(false), wrapper = $bindable(), hovered_region = $bindable(null), show_boundaries = $bindable(true), show_labels = $bindable(true), show_special_points = $bindable(true), show_grid = $bindable(true), show_component_labels = $bindable(true), fullscreen_toggle = true, enable_export = true, show_controls = true, display_temp_unit = $bindable(), controls_open = $bindable(false), controls_props = {}, export_pane_open = $bindable(false), png_dpi = $bindable(150), export_filename = `phase-diagram`, lever_rule_mode = $bindable(`horizontal`), diagram_input = $bindable(null), editor_open = $bindable(false), x_axis = $bindable({}), y_axis = $bindable({}), tooltip, children, ...rest } = $props();
|
|
14
|
+
// Shared icon/toggle styling for controls and export panes
|
|
15
|
+
const pane_icon_style = `width: 14px; height: 14px`;
|
|
16
|
+
const pane_toggle_props = { style: `padding: 0` };
|
|
17
|
+
// Rebuild diagram data when diagram_input changes ($derived auto-recomputes)
|
|
18
|
+
const rebuilt_data = $derived.by(() => {
|
|
19
|
+
if (!diagram_input)
|
|
20
|
+
return null;
|
|
21
|
+
try {
|
|
22
|
+
return build_diagram(diagram_input);
|
|
23
|
+
}
|
|
24
|
+
catch (err) {
|
|
25
|
+
console.warn(`Failed to rebuild diagram from input:`, err);
|
|
26
|
+
return null;
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// Override from direct PhaseDiagramData edits in the editor pane
|
|
30
|
+
let data_override = $state(null);
|
|
31
|
+
// Clear data_override when source data changes (e.g. new SVG dropped or data prop updated)
|
|
32
|
+
$effect(() => {
|
|
33
|
+
if (diagram_input || data)
|
|
34
|
+
data_override = null;
|
|
35
|
+
});
|
|
36
|
+
// Use editor override first (clears rebuilt_data path), then rebuilt, then data prop
|
|
37
|
+
const effective_data = $derived(data_override ?? rebuilt_data ?? data);
|
|
38
|
+
// Handle SVG file drop directly on the component
|
|
39
|
+
function handle_svg_drop(event) {
|
|
40
|
+
event.preventDefault();
|
|
41
|
+
const file = event.dataTransfer?.files[0];
|
|
42
|
+
if (!file || (!file.name.endsWith(`.svg`) && file.type !== `image/svg+xml`)) {
|
|
43
|
+
return;
|
|
44
|
+
}
|
|
45
|
+
const reader = new FileReader();
|
|
46
|
+
reader.onload = () => {
|
|
47
|
+
try {
|
|
48
|
+
diagram_input = parse_phase_diagram_svg(reader.result);
|
|
49
|
+
}
|
|
50
|
+
catch (err) {
|
|
51
|
+
console.error(`Failed to parse dropped SVG:`, err);
|
|
52
|
+
}
|
|
53
|
+
};
|
|
54
|
+
reader.readAsText(file);
|
|
55
|
+
}
|
|
11
56
|
// Merge config with centralized defaults using shared helper
|
|
12
57
|
const merged_config = $derived(merge_phase_diagram_config(config));
|
|
13
58
|
// Dimensions - use container size directly, no fallback to avoid layout shift
|
|
@@ -22,12 +67,67 @@ const top = $derived(margin.t);
|
|
|
22
67
|
const bottom = $derived(height - margin.b);
|
|
23
68
|
const plot_width = $derived(right - left);
|
|
24
69
|
const plot_height = $derived(bottom - top);
|
|
70
|
+
// Compute x domain from data extent, x_axis.range override, or default [0, 1]
|
|
71
|
+
// Auto-extends to 0/1 when edge regions contain a pure component
|
|
72
|
+
const x_domain = $derived.by(() => {
|
|
73
|
+
const lo = x_axis.range?.[0];
|
|
74
|
+
const hi = x_axis.range?.[1];
|
|
75
|
+
if (lo != null && hi != null)
|
|
76
|
+
return [lo, hi];
|
|
77
|
+
if (effective_data) {
|
|
78
|
+
// Loop-based min/max to avoid stack overflow with large datasets
|
|
79
|
+
let data_min = Infinity;
|
|
80
|
+
let data_max = -Infinity;
|
|
81
|
+
const update = (val) => {
|
|
82
|
+
if (val < data_min)
|
|
83
|
+
data_min = val;
|
|
84
|
+
if (val > data_max)
|
|
85
|
+
data_max = val;
|
|
86
|
+
};
|
|
87
|
+
for (const region of effective_data.regions) {
|
|
88
|
+
for (const vertex of region.vertices)
|
|
89
|
+
update(vertex[0]);
|
|
90
|
+
}
|
|
91
|
+
for (const boundary of effective_data.boundaries) {
|
|
92
|
+
for (const point of boundary.points)
|
|
93
|
+
update(point[0]);
|
|
94
|
+
}
|
|
95
|
+
for (const special_point of effective_data.special_points ?? []) {
|
|
96
|
+
update(special_point.position[0]);
|
|
97
|
+
}
|
|
98
|
+
if (data_min <= data_max) {
|
|
99
|
+
let x_min = lo ?? data_min;
|
|
100
|
+
let x_max = hi ?? data_max;
|
|
101
|
+
// Auto-extend to 0/1 when edge regions contain a pure component AND the
|
|
102
|
+
// data already nearly reaches the boundary. This prevents extending a
|
|
103
|
+
// section diagram (e.g. 0.3–0.7) to the full [0, 1] range.
|
|
104
|
+
// Word boundary regex avoids matching substrings (e.g. "Fe" won't match "Fe3C")
|
|
105
|
+
const comp_at_edge = (comp, x_val) => {
|
|
106
|
+
const re = new RegExp(`\\b${comp.replace(/[.*+?^${}()|[\]\\]/g, `\\$&`)}\\b`);
|
|
107
|
+
return effective_data.regions.some((region) => re.test(region.name) &&
|
|
108
|
+
region.vertices.some((vertex) => Math.abs(vertex[0] - x_val) < 1e-6));
|
|
109
|
+
};
|
|
110
|
+
if (lo == null && x_min < 0.05 &&
|
|
111
|
+
effective_data.components[0] &&
|
|
112
|
+
comp_at_edge(effective_data.components[0], x_min)) {
|
|
113
|
+
x_min = 0;
|
|
114
|
+
}
|
|
115
|
+
if (hi == null && x_max > 0.95 &&
|
|
116
|
+
effective_data.components[1] &&
|
|
117
|
+
comp_at_edge(effective_data.components[1], x_max)) {
|
|
118
|
+
x_max = 1;
|
|
119
|
+
}
|
|
120
|
+
return [x_min, x_max];
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
return [lo ?? 0, hi ?? 1];
|
|
124
|
+
});
|
|
25
125
|
// Scales
|
|
26
|
-
const x_scale = $derived(scaleLinear().domain(
|
|
126
|
+
const x_scale = $derived(scaleLinear().domain(x_domain).range([left, right]));
|
|
27
127
|
// Temperature units (guard for initial render when data may be undefined)
|
|
28
|
-
const data_temp_unit = $derived((
|
|
128
|
+
const data_temp_unit = $derived((effective_data?.temperature_unit ?? `K`));
|
|
29
129
|
const temp_unit = $derived(display_temp_unit ?? data_temp_unit);
|
|
30
|
-
const temp_range = $derived(
|
|
130
|
+
const temp_range = $derived(effective_data?.temperature_range ?? [0, 1000]);
|
|
31
131
|
// Convert temperature range for display
|
|
32
132
|
const display_temp_range = $derived([
|
|
33
133
|
convert_temp(temp_range[0], data_temp_unit, temp_unit),
|
|
@@ -40,13 +140,11 @@ const y_scale = $derived(scaleLinear().domain(temp_range).range([bottom, top]));
|
|
|
40
140
|
// Used for axis labels and ticks
|
|
41
141
|
const y_scale_display = $derived(scaleLinear().domain(display_temp_range).range([bottom, top]));
|
|
42
142
|
// Generate tick values using d3 scale's built-in ticks method
|
|
43
|
-
const
|
|
44
|
-
const y_tick_count = $derived(typeof y_axis.ticks === `number` ? y_axis.ticks : 6);
|
|
45
|
-
const x_ticks = $derived(x_scale.ticks(x_tick_count));
|
|
143
|
+
const x_ticks = $derived(x_scale.ticks(typeof x_axis.ticks === `number` ? x_axis.ticks : 5));
|
|
46
144
|
// Use display scale for y ticks so they show converted temperatures
|
|
47
|
-
const y_ticks = $derived(y_scale_display.ticks(
|
|
145
|
+
const y_ticks = $derived(y_scale_display.ticks(typeof y_axis.ticks === `number` ? y_axis.ticks : 6));
|
|
48
146
|
// Transform regions to SVG coordinates
|
|
49
|
-
const transformed_regions = $derived((
|
|
147
|
+
const transformed_regions = $derived((effective_data?.regions ?? []).map((region) => {
|
|
50
148
|
const svg_vertices = transform_vertices(region.vertices, x_scale, y_scale);
|
|
51
149
|
const { width, height } = compute_bounding_box_2d(svg_vertices);
|
|
52
150
|
const label_props = compute_label_properties(region.name, { width, height }, merged_config.font_size);
|
|
@@ -68,12 +166,12 @@ const transformed_regions = $derived((data?.regions ?? []).map((region) => {
|
|
|
68
166
|
};
|
|
69
167
|
}));
|
|
70
168
|
// Transform boundaries to SVG coordinates
|
|
71
|
-
const transformed_boundaries = $derived((
|
|
169
|
+
const transformed_boundaries = $derived((effective_data?.boundaries ?? []).map((boundary) => ({
|
|
72
170
|
...boundary,
|
|
73
171
|
svg_path: generate_boundary_path(transform_vertices(boundary.points, x_scale, y_scale)),
|
|
74
172
|
})));
|
|
75
173
|
// Transform special points to SVG coordinates
|
|
76
|
-
const transformed_special_points = $derived((
|
|
174
|
+
const transformed_special_points = $derived((effective_data?.special_points ?? []).map((point) => ({
|
|
77
175
|
...point,
|
|
78
176
|
svg_x: x_scale(point.position[0]),
|
|
79
177
|
svg_y: y_scale(point.position[1]),
|
|
@@ -110,7 +208,7 @@ async function handle_double_click(event) {
|
|
|
110
208
|
if (!hover_info)
|
|
111
209
|
return;
|
|
112
210
|
try {
|
|
113
|
-
await navigator.clipboard.writeText(format_hover_info_text(hover_info, temp_unit, comp_unit, component_a, component_b));
|
|
211
|
+
await navigator.clipboard.writeText(format_hover_info_text(hover_info, temp_unit, comp_unit, component_a, component_b, data_temp_unit, lever_rule_mode));
|
|
114
212
|
if (copy_feedback_timeout)
|
|
115
213
|
clearTimeout(copy_feedback_timeout);
|
|
116
214
|
copy_feedback_pos = { x: event.clientX, y: event.clientY };
|
|
@@ -153,14 +251,15 @@ function handle_pointer_move(event) {
|
|
|
153
251
|
const svg_x = event.clientX - rect.left;
|
|
154
252
|
const svg_y = event.clientY - rect.top;
|
|
155
253
|
// Check if within plot area
|
|
156
|
-
if (svg_x < left || svg_x > right || svg_y < top || svg_y > bottom ||
|
|
254
|
+
if (svg_x < left || svg_x > right || svg_y < top || svg_y > bottom ||
|
|
255
|
+
!effective_data) {
|
|
157
256
|
clear_hover();
|
|
158
257
|
return;
|
|
159
258
|
}
|
|
160
259
|
// Convert to data coordinates and find phase
|
|
161
260
|
const composition = x_scale.invert(svg_x);
|
|
162
261
|
const temperature = y_scale.invert(svg_y);
|
|
163
|
-
const region = find_phase_at_point(composition, temperature,
|
|
262
|
+
const region = find_phase_at_point(composition, temperature, effective_data);
|
|
164
263
|
// Check for nearby special point
|
|
165
264
|
const nearby_special = show_special_points
|
|
166
265
|
? find_nearby_special_point(svg_x, svg_y)
|
|
@@ -174,6 +273,8 @@ function handle_pointer_move(event) {
|
|
|
174
273
|
position: { x: event.clientX, y: event.clientY },
|
|
175
274
|
lever_rule: calculate_lever_rule(region, composition, temperature) ||
|
|
176
275
|
undefined,
|
|
276
|
+
vertical_lever_rule: calculate_vertical_lever_rule(region, composition, temperature) ||
|
|
277
|
+
undefined,
|
|
177
278
|
special_point: nearby_special || undefined,
|
|
178
279
|
};
|
|
179
280
|
on_phase_hover?.(hover_info);
|
|
@@ -218,17 +319,14 @@ $effect(() => {
|
|
|
218
319
|
};
|
|
219
320
|
});
|
|
220
321
|
// Component labels (guard for initial render when data may be undefined)
|
|
221
|
-
const component_a = $derived(
|
|
222
|
-
const component_b = $derived(
|
|
223
|
-
const comp_unit = $derived(
|
|
322
|
+
const component_a = $derived(effective_data?.components?.[0] ?? ``);
|
|
323
|
+
const component_b = $derived(effective_data?.components?.[1] ?? ``);
|
|
324
|
+
const comp_unit = $derived(effective_data?.composition_unit ?? `at%`);
|
|
224
325
|
// Pseudo-binary support: format compound names with subscripts when enabled
|
|
225
|
-
const use_subscripts = $derived(
|
|
326
|
+
const use_subscripts = $derived(effective_data?.pseudo_binary?.use_subscripts ?? true);
|
|
226
327
|
// Formatted component labels for SVG axis labels (with tspan subscripts if compound)
|
|
227
328
|
const component_a_svg = $derived(format_formula_svg(component_a, use_subscripts));
|
|
228
329
|
const component_b_svg = $derived(format_formula_svg(component_b, use_subscripts));
|
|
229
|
-
// Custom axis labels from data (for pseudo-binary or special cases)
|
|
230
|
-
const data_x_axis_label = $derived(data?.x_axis_label);
|
|
231
|
-
const data_y_axis_label = $derived(data?.y_axis_label);
|
|
232
330
|
// Default x-axis label as a single string (avoids mixing plain text with {@html})
|
|
233
331
|
const default_x_axis_label = $derived.by(() => {
|
|
234
332
|
const prefix = comp_unit === `fraction` ? `x ` : ``;
|
|
@@ -251,6 +349,50 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
251
349
|
{/each}
|
|
252
350
|
{/snippet}
|
|
253
351
|
|
|
352
|
+
<!-- Tie-line snippet: renders line with white outline, phase endpoints, and cursor marker -->
|
|
353
|
+
{#snippet tie_line_viz(
|
|
354
|
+
x1: number,
|
|
355
|
+
y1: number,
|
|
356
|
+
x2: number,
|
|
357
|
+
y2: number,
|
|
358
|
+
endpoints: Array<{ cx: number; cy: number; color: string }>,
|
|
359
|
+
cursor_cx: number,
|
|
360
|
+
cursor_cy: number,
|
|
361
|
+
)}
|
|
362
|
+
{@const tl = merged_config.tie_line}
|
|
363
|
+
<g class="tie-line" class:locked={locked_hover_info}>
|
|
364
|
+
{#each [`white`, `rgb(${PHASE_COLOR_RGB.tie_line})`] as stroke (stroke)}
|
|
365
|
+
<line
|
|
366
|
+
{x1}
|
|
367
|
+
{y1}
|
|
368
|
+
{x2}
|
|
369
|
+
{y2}
|
|
370
|
+
{stroke}
|
|
371
|
+
stroke-width={tl.stroke_width + (stroke === `white` ? 1 : 0)}
|
|
372
|
+
stroke-linecap="round"
|
|
373
|
+
/>
|
|
374
|
+
{/each}
|
|
375
|
+
{#each endpoints as ep, idx (idx)}
|
|
376
|
+
<circle
|
|
377
|
+
cx={ep.cx}
|
|
378
|
+
cy={ep.cy}
|
|
379
|
+
r={tl.endpoint_radius}
|
|
380
|
+
fill="rgb({ep.color})"
|
|
381
|
+
stroke="white"
|
|
382
|
+
stroke-width={1.5}
|
|
383
|
+
/>
|
|
384
|
+
{/each}
|
|
385
|
+
<circle
|
|
386
|
+
cx={cursor_cx}
|
|
387
|
+
cy={cursor_cy}
|
|
388
|
+
r={tl.cursor_radius}
|
|
389
|
+
fill="rgb({PHASE_COLOR_RGB.tie_line})"
|
|
390
|
+
stroke="white"
|
|
391
|
+
stroke-width={2}
|
|
392
|
+
/>
|
|
393
|
+
</g>
|
|
394
|
+
{/snippet}
|
|
395
|
+
|
|
254
396
|
<svelte:document
|
|
255
397
|
onfullscreenchange={() => {
|
|
256
398
|
fullscreen = Boolean(document.fullscreenElement)
|
|
@@ -266,7 +408,9 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
266
408
|
bind:clientWidth={width}
|
|
267
409
|
bind:clientHeight={height}
|
|
268
410
|
role="img"
|
|
269
|
-
aria-label={
|
|
411
|
+
aria-label="{component_a}-{component_b} binary phase diagram"
|
|
412
|
+
ondrop={handle_svg_drop}
|
|
413
|
+
ondragover={(ev) => ev.preventDefault()}
|
|
270
414
|
>
|
|
271
415
|
{#if width > 0 && height > 0}
|
|
272
416
|
<!-- Header controls -->
|
|
@@ -280,23 +424,36 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
280
424
|
bind:show_grid
|
|
281
425
|
bind:show_component_labels
|
|
282
426
|
bind:config
|
|
427
|
+
bind:lever_rule_mode
|
|
283
428
|
bind:x_axis
|
|
284
429
|
bind:y_axis
|
|
285
430
|
bind:png_dpi
|
|
286
|
-
{
|
|
431
|
+
data={effective_data}
|
|
287
432
|
{enable_export}
|
|
288
433
|
{...controls_props}
|
|
434
|
+
icon_style={pane_icon_style}
|
|
435
|
+
toggle_props={pane_toggle_props}
|
|
289
436
|
/>
|
|
290
437
|
{/if}
|
|
291
438
|
{#if enable_export}
|
|
292
439
|
<PhaseDiagramExportPane
|
|
293
440
|
bind:export_pane_open
|
|
294
441
|
bind:png_dpi
|
|
295
|
-
{
|
|
442
|
+
data={effective_data}
|
|
296
443
|
{wrapper}
|
|
297
444
|
filename={export_filename}
|
|
445
|
+
icon_style={pane_icon_style}
|
|
446
|
+
toggle_props={pane_toggle_props}
|
|
298
447
|
/>
|
|
299
448
|
{/if}
|
|
449
|
+
<PhaseDiagramEditorPane
|
|
450
|
+
bind:editor_open
|
|
451
|
+
bind:diagram_input
|
|
452
|
+
data={effective_data}
|
|
453
|
+
ondata={(edited) => data_override = edited}
|
|
454
|
+
icon_style={pane_icon_style}
|
|
455
|
+
toggle_props={pane_toggle_props}
|
|
456
|
+
/>
|
|
300
457
|
{#if fullscreen_toggle}
|
|
301
458
|
<FullscreenToggle bind:fullscreen />
|
|
302
459
|
{/if}
|
|
@@ -382,7 +539,7 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
382
539
|
<path
|
|
383
540
|
d={boundary.svg_path}
|
|
384
541
|
fill="none"
|
|
385
|
-
stroke={boundary.style?.color
|
|
542
|
+
stroke={boundary.style?.color ?? merged_config.colors.boundary}
|
|
386
543
|
stroke-width={boundary.style?.width || 2}
|
|
387
544
|
stroke-dasharray={boundary.style?.dash || ``}
|
|
388
545
|
stroke-linecap="round"
|
|
@@ -411,7 +568,7 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
411
568
|
font-weight="500"
|
|
412
569
|
class="region-label"
|
|
413
570
|
>
|
|
414
|
-
{line}
|
|
571
|
+
{@html format_label_svg(line, use_subscripts)}
|
|
415
572
|
</text>
|
|
416
573
|
{/each}
|
|
417
574
|
</g>
|
|
@@ -420,51 +577,40 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
420
577
|
{/if}
|
|
421
578
|
|
|
422
579
|
<!-- Tie-line visualization for two-phase regions -->
|
|
423
|
-
{#if effective_hover_info?.
|
|
424
|
-
{@const
|
|
580
|
+
{#if lever_rule_mode === `vertical` && effective_hover_info?.vertical_lever_rule}
|
|
581
|
+
{@const vlr = effective_hover_info.vertical_lever_rule}
|
|
582
|
+
{@const cx = x_scale(effective_hover_info.composition)}
|
|
583
|
+
{@const y_bot = y_scale(vlr.bottom_temperature)}
|
|
584
|
+
{@const y_top = y_scale(vlr.top_temperature)}
|
|
585
|
+
{@render tie_line_viz(
|
|
586
|
+
cx,
|
|
587
|
+
y_bot,
|
|
588
|
+
cx,
|
|
589
|
+
y_top,
|
|
590
|
+
[
|
|
591
|
+
{ cx, cy: y_bot, color: get_phase_color(vlr.bottom_phase, `rgb`) },
|
|
592
|
+
{ cx, cy: y_top, color: get_phase_color(vlr.top_phase, `rgb`) },
|
|
593
|
+
],
|
|
594
|
+
cx,
|
|
595
|
+
y_scale(effective_hover_info.temperature),
|
|
596
|
+
)}
|
|
597
|
+
{:else if lever_rule_mode === `horizontal` && effective_hover_info?.lever_rule}
|
|
425
598
|
{@const lr = effective_hover_info.lever_rule}
|
|
426
|
-
{@const
|
|
427
|
-
{@const
|
|
428
|
-
{@const
|
|
429
|
-
{@
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
{
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
y2={y_pos}
|
|
442
|
-
{stroke}
|
|
443
|
-
stroke-width={tie_line.stroke_width + (stroke === `white` ? 1 : 0)}
|
|
444
|
-
stroke-linecap="round"
|
|
445
|
-
/>
|
|
446
|
-
{/each}
|
|
447
|
-
<!-- Phase endpoints -->
|
|
448
|
-
{#each endpoints as { cx, color } (cx)}
|
|
449
|
-
<circle
|
|
450
|
-
{cx}
|
|
451
|
-
cy={y_pos}
|
|
452
|
-
r={tie_line.endpoint_radius}
|
|
453
|
-
fill="rgb({color})"
|
|
454
|
-
stroke="white"
|
|
455
|
-
stroke-width={1.5}
|
|
456
|
-
/>
|
|
457
|
-
{/each}
|
|
458
|
-
<!-- Cursor position marker -->
|
|
459
|
-
<circle
|
|
460
|
-
cx={x_scale(info.composition)}
|
|
461
|
-
cy={y_pos}
|
|
462
|
-
r={tie_line.cursor_radius}
|
|
463
|
-
fill="rgb({PHASE_COLOR_RGB.tie_line})"
|
|
464
|
-
stroke="white"
|
|
465
|
-
stroke-width={2}
|
|
466
|
-
/>
|
|
467
|
-
</g>
|
|
599
|
+
{@const cy = y_scale(effective_hover_info.temperature)}
|
|
600
|
+
{@const x_l = x_scale(lr.left_composition)}
|
|
601
|
+
{@const x_r = x_scale(lr.right_composition)}
|
|
602
|
+
{@render tie_line_viz(
|
|
603
|
+
x_l,
|
|
604
|
+
cy,
|
|
605
|
+
x_r,
|
|
606
|
+
cy,
|
|
607
|
+
[
|
|
608
|
+
{ cx: x_l, cy, color: get_phase_color(lr.left_phase, `rgb`) },
|
|
609
|
+
{ cx: x_r, cy, color: get_phase_color(lr.right_phase, `rgb`) },
|
|
610
|
+
],
|
|
611
|
+
x_scale(effective_hover_info.composition),
|
|
612
|
+
cy,
|
|
613
|
+
)}
|
|
468
614
|
{/if}
|
|
469
615
|
|
|
470
616
|
<!-- Special points (rendered last for highest z-index) -->
|
|
@@ -541,8 +687,8 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
541
687
|
>
|
|
542
688
|
{#if x_axis.label}
|
|
543
689
|
{@html x_axis.label}
|
|
544
|
-
{:else if
|
|
545
|
-
{@html
|
|
690
|
+
{:else if effective_data?.x_axis_label}
|
|
691
|
+
{@html effective_data.x_axis_label}
|
|
546
692
|
{:else}
|
|
547
693
|
{@html default_x_axis_label}
|
|
548
694
|
{/if}
|
|
@@ -577,15 +723,15 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
577
723
|
<text
|
|
578
724
|
transform="rotate(-90)"
|
|
579
725
|
x={-(top + plot_height / 2)}
|
|
580
|
-
y={
|
|
726
|
+
y={16}
|
|
581
727
|
text-anchor="middle"
|
|
582
728
|
fill={merged_config.colors.text}
|
|
583
729
|
font-size={merged_config.font_size + 2}
|
|
584
730
|
>
|
|
585
731
|
{#if y_axis.label}
|
|
586
732
|
{@html y_axis.label}
|
|
587
|
-
{:else if
|
|
588
|
-
{@html
|
|
733
|
+
{:else if effective_data?.y_axis_label}
|
|
734
|
+
{@html effective_data.y_axis_label}
|
|
589
735
|
{:else}
|
|
590
736
|
Temperature ({temp_unit})
|
|
591
737
|
{/if}
|
|
@@ -636,9 +782,13 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
636
782
|
<PhaseDiagramTooltip
|
|
637
783
|
hover_info={effective_hover_info}
|
|
638
784
|
temperature_unit={temp_unit}
|
|
785
|
+
data_temperature_unit={data_temp_unit}
|
|
639
786
|
composition_unit={comp_unit}
|
|
640
787
|
{component_a}
|
|
641
788
|
{component_b}
|
|
789
|
+
boundaries={effective_data?.boundaries ?? []}
|
|
790
|
+
{lever_rule_mode}
|
|
791
|
+
{use_subscripts}
|
|
642
792
|
{tooltip}
|
|
643
793
|
/>
|
|
644
794
|
{/if}
|
|
@@ -699,9 +849,14 @@ const default_x_axis_label = $derived.by(() => {
|
|
|
699
849
|
opacity: 0;
|
|
700
850
|
transition: opacity 0.2s ease;
|
|
701
851
|
}
|
|
852
|
+
/* Keep editor toggle always visible so users discover the edit feature */
|
|
853
|
+
.binary-phase-diagram :global(.pd-editor-toggle) {
|
|
854
|
+
opacity: 1;
|
|
855
|
+
}
|
|
702
856
|
.binary-phase-diagram:is(:hover, :focus-within)
|
|
703
857
|
:is(:global(.pane-toggle), .header-controls),
|
|
704
|
-
.binary-phase-diagram :global(.pane-toggle:is(:focus-visible, [aria-expanded='true']))
|
|
858
|
+
.binary-phase-diagram :global(.pane-toggle:is(:focus-visible, [aria-expanded='true'])),
|
|
859
|
+
.header-controls:has(:global(.pane-open)) {
|
|
705
860
|
opacity: 1;
|
|
706
861
|
}
|
|
707
862
|
.phase-regions path {
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import type { AxisConfig } from '../plot';
|
|
2
2
|
import type { ComponentProps, Snippet } from 'svelte';
|
|
3
3
|
import type { HTMLAttributes } from 'svelte/elements';
|
|
4
|
+
import type { DiagramInput } from './diagram-input';
|
|
4
5
|
import PhaseDiagramControls from './PhaseDiagramControls.svelte';
|
|
5
|
-
import type { PhaseDiagramConfig, PhaseDiagramData, PhaseDiagramTooltipConfig, PhaseHoverInfo, PhaseRegion } from './types';
|
|
6
|
+
import type { LeverRuleMode, PhaseDiagramConfig, PhaseDiagramData, PhaseDiagramTooltipConfig, PhaseHoverInfo, PhaseRegion } from './types';
|
|
6
7
|
type Props = HTMLAttributes<HTMLDivElement> & {
|
|
7
8
|
data: PhaseDiagramData;
|
|
8
9
|
config?: Partial<PhaseDiagramConfig>;
|
|
@@ -24,6 +25,9 @@ type Props = HTMLAttributes<HTMLDivElement> & {
|
|
|
24
25
|
export_pane_open?: boolean;
|
|
25
26
|
png_dpi?: number;
|
|
26
27
|
export_filename?: string;
|
|
28
|
+
lever_rule_mode?: LeverRuleMode;
|
|
29
|
+
diagram_input?: DiagramInput | null;
|
|
30
|
+
editor_open?: boolean;
|
|
27
31
|
x_axis?: AxisConfig;
|
|
28
32
|
y_axis?: AxisConfig;
|
|
29
33
|
tooltip?: Snippet<[PhaseHoverInfo]> | PhaseDiagramTooltipConfig | false;
|
|
@@ -35,6 +39,6 @@ type Props = HTMLAttributes<HTMLDivElement> & {
|
|
|
35
39
|
}
|
|
36
40
|
]>;
|
|
37
41
|
};
|
|
38
|
-
declare const IsobaricBinaryPhaseDiagram: import("svelte").Component<Props, {}, "
|
|
42
|
+
declare const IsobaricBinaryPhaseDiagram: import("svelte").Component<Props, {}, "controls_open" | "x_axis" | "y_axis" | "show_grid" | "fullscreen" | "wrapper" | "hovered_region" | "config" | "show_labels" | "export_pane_open" | "png_dpi" | "show_boundaries" | "show_special_points" | "show_component_labels" | "lever_rule_mode" | "editor_open" | "diagram_input" | "display_temp_unit">;
|
|
39
43
|
type IsobaricBinaryPhaseDiagram = ReturnType<typeof IsobaricBinaryPhaseDiagram>;
|
|
40
44
|
export default IsobaricBinaryPhaseDiagram;
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
<script lang="ts">// NOTE: Axis config objects must be reassigned (not mutated) to trigger $bindable reactivity.
|
|
2
|
+
import { css_color_to_hex } from '../colors';
|
|
2
3
|
import { format_num } from '../labels';
|
|
3
4
|
import SettingsSection from '../layout/SettingsSection.svelte';
|
|
4
5
|
import DraggablePane from '../overlays/DraggablePane.svelte';
|
|
5
|
-
import { css_color_to_hex } from '../colors';
|
|
6
6
|
import { tooltip } from 'svelte-multiselect/attachments';
|
|
7
7
|
import { merge_phase_diagram_config, PHASE_DIAGRAM_DEFAULTS } from './utils';
|
|
8
8
|
let { controls_open = $bindable(false),
|
|
@@ -10,6 +10,8 @@ let { controls_open = $bindable(false),
|
|
|
10
10
|
show_boundaries = $bindable(PHASE_DIAGRAM_DEFAULTS.show_boundaries), show_labels = $bindable(PHASE_DIAGRAM_DEFAULTS.show_labels), show_special_points = $bindable(PHASE_DIAGRAM_DEFAULTS.show_special_points), show_grid = $bindable(PHASE_DIAGRAM_DEFAULTS.show_grid), show_component_labels = $bindable(PHASE_DIAGRAM_DEFAULTS.show_component_labels),
|
|
11
11
|
// Configuration
|
|
12
12
|
config = $bindable({}),
|
|
13
|
+
// Lever rule mode
|
|
14
|
+
lever_rule_mode = $bindable(`horizontal`),
|
|
13
15
|
// Axis configuration
|
|
14
16
|
x_axis = $bindable({}), y_axis = $bindable({}),
|
|
15
17
|
// Data
|
|
@@ -65,7 +67,7 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
65
67
|
pane_props={{
|
|
66
68
|
...pane_props,
|
|
67
69
|
class: `phase-diagram-controls-pane ${pane_props?.class ?? ``}`,
|
|
68
|
-
style:
|
|
70
|
+
style: pane_props?.style ?? ``,
|
|
69
71
|
}}
|
|
70
72
|
toggle_props={{
|
|
71
73
|
title: controls_open ? `` : `Phase diagram controls`,
|
|
@@ -200,14 +202,29 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
200
202
|
title="Tie-line Display"
|
|
201
203
|
current_values={{
|
|
202
204
|
...merged_config.tie_line,
|
|
205
|
+
lever_rule_mode,
|
|
203
206
|
}}
|
|
204
207
|
on_reset={() => {
|
|
205
208
|
config = {
|
|
206
209
|
...config,
|
|
207
210
|
tie_line: { ...PHASE_DIAGRAM_DEFAULTS.tie_line },
|
|
208
211
|
}
|
|
212
|
+
lever_rule_mode = `horizontal`
|
|
209
213
|
}}
|
|
210
214
|
>
|
|
215
|
+
<span {@attach tooltip({ content: `Direction of the lever rule tie-line` })}>
|
|
216
|
+
Direction
|
|
217
|
+
<div class="pane-row">
|
|
218
|
+
<label>
|
|
219
|
+
<input type="radio" bind:group={lever_rule_mode} value="horizontal" />
|
|
220
|
+
Horizontal
|
|
221
|
+
</label>
|
|
222
|
+
<label>
|
|
223
|
+
<input type="radio" bind:group={lever_rule_mode} value="vertical" />
|
|
224
|
+
Vertical
|
|
225
|
+
</label>
|
|
226
|
+
</div>
|
|
227
|
+
</span>
|
|
211
228
|
{@render num_range(
|
|
212
229
|
`Line width`,
|
|
213
230
|
merged_config.tie_line.stroke_width,
|
|
@@ -215,7 +232,7 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
215
232
|
5,
|
|
216
233
|
0.5,
|
|
217
234
|
(val) => update_nested(`tie_line`, `stroke_width`, val),
|
|
218
|
-
`Thickness of the
|
|
235
|
+
`Thickness of the tie-line`,
|
|
219
236
|
)}
|
|
220
237
|
{@render num_range(
|
|
221
238
|
`Endpoint radius`,
|
|
@@ -291,6 +308,7 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
291
308
|
min={72}
|
|
292
309
|
max={600}
|
|
293
310
|
step={50}
|
|
311
|
+
style="width: 3.5em"
|
|
294
312
|
bind:value={png_dpi}
|
|
295
313
|
/>
|
|
296
314
|
<input
|
|
@@ -313,14 +331,16 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
313
331
|
:global(.phase-diagram-controls-pane) {
|
|
314
332
|
font-size: 0.85em;
|
|
315
333
|
max-width: 320px;
|
|
334
|
+
--pane-padding: 10px;
|
|
335
|
+
--pane-gap: 4px;
|
|
316
336
|
}
|
|
317
337
|
:global(.phase-diagram-controls-pane section) {
|
|
318
338
|
display: flex;
|
|
319
339
|
flex-direction: column;
|
|
320
|
-
gap:
|
|
340
|
+
gap: 4pt;
|
|
321
341
|
}
|
|
322
342
|
:global(.phase-diagram-controls-pane h4) {
|
|
323
|
-
margin:
|
|
343
|
+
margin: 6pt 0 2pt !important;
|
|
324
344
|
}
|
|
325
345
|
:global(.phase-diagram-controls-pane h4:first-of-type) {
|
|
326
346
|
margin-top: 0 !important;
|
|
@@ -328,18 +348,16 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
328
348
|
.pane-row {
|
|
329
349
|
display: flex;
|
|
330
350
|
gap: 12pt;
|
|
331
|
-
justify-content: space-between;
|
|
332
|
-
width: 100%;
|
|
333
351
|
}
|
|
334
352
|
.visibility-grid {
|
|
335
|
-
display:
|
|
336
|
-
|
|
337
|
-
gap:
|
|
353
|
+
display: flex;
|
|
354
|
+
flex-wrap: wrap;
|
|
355
|
+
gap: 4pt 10pt;
|
|
338
356
|
}
|
|
339
357
|
.color-grid {
|
|
340
358
|
display: grid;
|
|
341
359
|
grid-template-columns: repeat(3, 1fr);
|
|
342
|
-
gap:
|
|
360
|
+
gap: 6pt;
|
|
343
361
|
}
|
|
344
362
|
.color-grid label {
|
|
345
363
|
flex-direction: column;
|
|
@@ -355,6 +373,9 @@ const has_special_points = $derived((data?.special_points?.length ?? 0) > 0);
|
|
|
355
373
|
font-size: inherit;
|
|
356
374
|
font-family: inherit;
|
|
357
375
|
}
|
|
376
|
+
input[type='number'] {
|
|
377
|
+
width: 3.5em;
|
|
378
|
+
}
|
|
358
379
|
input[type='range'] {
|
|
359
380
|
flex: 1;
|
|
360
381
|
min-width: 40px;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import DraggablePane from '../overlays/DraggablePane.svelte';
|
|
2
2
|
import type { AxisConfig } from '../plot';
|
|
3
3
|
import type { ComponentProps, Snippet } from 'svelte';
|
|
4
|
-
import type { PhaseDiagramConfig, PhaseDiagramData } from './types';
|
|
4
|
+
import type { LeverRuleMode, PhaseDiagramConfig, PhaseDiagramData } from './types';
|
|
5
5
|
type Props = Omit<ComponentProps<typeof DraggablePane>, `children`> & {
|
|
6
6
|
controls_open?: boolean;
|
|
7
7
|
show_boundaries?: boolean;
|
|
@@ -10,6 +10,7 @@ type Props = Omit<ComponentProps<typeof DraggablePane>, `children`> & {
|
|
|
10
10
|
show_grid?: boolean;
|
|
11
11
|
show_component_labels?: boolean;
|
|
12
12
|
config?: Partial<PhaseDiagramConfig>;
|
|
13
|
+
lever_rule_mode?: LeverRuleMode;
|
|
13
14
|
x_axis?: AxisConfig;
|
|
14
15
|
y_axis?: AxisConfig;
|
|
15
16
|
data?: PhaseDiagramData;
|
|
@@ -24,6 +25,6 @@ type Props = Omit<ComponentProps<typeof DraggablePane>, `children`> & {
|
|
|
24
25
|
controls_open: boolean;
|
|
25
26
|
}]>;
|
|
26
27
|
};
|
|
27
|
-
declare const PhaseDiagramControls: import("svelte").Component<Props, {}, "controls_open" | "x_axis" | "y_axis" | "
|
|
28
|
+
declare const PhaseDiagramControls: import("svelte").Component<Props, {}, "controls_open" | "x_axis" | "y_axis" | "show_grid" | "config" | "show_labels" | "png_dpi" | "show_boundaries" | "show_special_points" | "show_component_labels" | "lever_rule_mode">;
|
|
28
29
|
type PhaseDiagramControls = ReturnType<typeof PhaseDiagramControls>;
|
|
29
30
|
export default PhaseDiagramControls;
|