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
package/dist/FilePicker.svelte
CHANGED
|
@@ -14,6 +14,10 @@ let { files = [], active_files = [], show_category_filters = false, layout = `wr
|
|
|
14
14
|
yaml: `rgba(255, 0, 255, 0.8)`,
|
|
15
15
|
xdatcar: `rgba(255, 215, 0, 0.8)`,
|
|
16
16
|
tdb: `rgba(0, 188, 212, 0.8)`,
|
|
17
|
+
chgcar: `rgba(59, 130, 246, 0.8)`,
|
|
18
|
+
locpot: `rgba(245, 158, 11, 0.8)`,
|
|
19
|
+
elfcar: `rgba(16, 185, 129, 0.8)`,
|
|
20
|
+
cube: `rgba(168, 85, 247, 0.8)`,
|
|
17
21
|
}, ...rest } = $props();
|
|
18
22
|
let active_category_filter = $state(null);
|
|
19
23
|
let active_type_filter = $state(null);
|
|
@@ -28,11 +32,11 @@ const clear_click_timer = () => {
|
|
|
28
32
|
};
|
|
29
33
|
// Helper function to get the base file type (removing .gz extension)
|
|
30
34
|
const get_base_file_type = (file) => {
|
|
31
|
-
// Use custom type mapper if provided
|
|
32
35
|
if (type_mapper)
|
|
33
36
|
return type_mapper(file);
|
|
37
|
+
if (file.type)
|
|
38
|
+
return file.type.toLowerCase();
|
|
34
39
|
let base_name = file.name.toLowerCase();
|
|
35
|
-
// Remove .gz extension if present
|
|
36
40
|
if (base_name.endsWith(`.gz`))
|
|
37
41
|
base_name = base_name.slice(0, -3);
|
|
38
42
|
return base_name.split(`.`).pop() || `file`;
|
|
@@ -103,7 +107,10 @@ let uniq_categories = $derived([...new Set(files.map(get_category_id))].filter(B
|
|
|
103
107
|
{category}
|
|
104
108
|
</span>
|
|
105
109
|
{/each}
|
|
106
|
-
{#if uniq_categories.length > 0 &&
|
|
110
|
+
{#if show_category_filters && uniq_categories.length > 0 &&
|
|
111
|
+
uniq_formats.length > 0}
|
|
112
|
+
<span class="divider"></span>
|
|
113
|
+
{/if}
|
|
107
114
|
|
|
108
115
|
{#each uniq_formats as format (format)}
|
|
109
116
|
{@const is_active = active_type_filter === format}
|
|
@@ -137,11 +144,9 @@ let uniq_categories = $derived([...new Set(files.map(get_category_id))].filter(B
|
|
|
137
144
|
|
|
138
145
|
{#each filtered_files as file (file.name)}
|
|
139
146
|
{@const base_type = get_base_file_type(file)}
|
|
140
|
-
{@const is_compressed = file.name.toLowerCase().endsWith(`.gz`)}
|
|
141
147
|
<div
|
|
142
148
|
class="file-item"
|
|
143
149
|
class:active={active_files.includes(file.name)}
|
|
144
|
-
class:compressed={is_compressed}
|
|
145
150
|
style:background-color={file_type_colors[base_type]?.replace(`0.8`, `0.08`)}
|
|
146
151
|
draggable="true"
|
|
147
152
|
ondragstart={handle_drag_start(file)}
|
|
@@ -179,9 +184,14 @@ let uniq_categories = $derived([...new Set(files.map(get_category_id))].filter(B
|
|
|
179
184
|
? `Click to load or drag this ${base_type.toUpperCase()} file`
|
|
180
185
|
: `Drag this ${base_type.toUpperCase()} file`}
|
|
181
186
|
>
|
|
187
|
+
{#if file.label}
|
|
188
|
+
<span
|
|
189
|
+
class="file-type-badge"
|
|
190
|
+
style:background-color={file_type_colors[base_type] ?? `rgba(128,128,128,0.8)`}
|
|
191
|
+
>{base_type.toUpperCase()}</span>
|
|
192
|
+
{/if}
|
|
182
193
|
<div class="file-name">
|
|
183
|
-
{file.category ? `${file.category_icon} ` : ``}{file.name}
|
|
184
|
-
{#if is_compressed}<span class="compression-indicator">📦</span>{/if}
|
|
194
|
+
{file.category ? `${file.category_icon} ` : ``}{file.label ?? file.name}
|
|
185
195
|
</div>
|
|
186
196
|
</div>
|
|
187
197
|
{/each}
|
|
@@ -220,6 +230,12 @@ let uniq_categories = $derived([...new Set(files.map(get_category_id))].filter(B
|
|
|
220
230
|
opacity: 0.8;
|
|
221
231
|
margin: 0 0 0.5em;
|
|
222
232
|
}
|
|
233
|
+
.divider {
|
|
234
|
+
width: 1px;
|
|
235
|
+
align-self: stretch;
|
|
236
|
+
background: light-dark(rgba(0, 0, 0, 0.2), rgba(255, 255, 255, 0.2));
|
|
237
|
+
margin-inline: 0.3em;
|
|
238
|
+
}
|
|
223
239
|
.legend-item {
|
|
224
240
|
cursor: pointer;
|
|
225
241
|
padding: 0.2em 0.4em;
|
|
@@ -267,7 +283,10 @@ let uniq_categories = $derived([...new Set(files.map(get_category_id))].filter(B
|
|
|
267
283
|
cursor: grab;
|
|
268
284
|
background: light-dark(rgba(0, 0, 0, 0.02), rgba(255, 255, 255, 0.1));
|
|
269
285
|
transition: all 0.2s ease;
|
|
270
|
-
gap:
|
|
286
|
+
gap: 4pt;
|
|
287
|
+
&:has(.file-type-badge) {
|
|
288
|
+
padding-left: 3pt;
|
|
289
|
+
}
|
|
271
290
|
}
|
|
272
291
|
.file-item.active {
|
|
273
292
|
border-color: var(--success-color, #00ff00);
|
|
@@ -282,21 +301,19 @@ let uniq_categories = $derived([...new Set(files.map(get_category_id))].filter(B
|
|
|
282
301
|
background: light-dark(rgba(0, 122, 204, 0.15), rgba(0, 122, 204, 0.25));
|
|
283
302
|
filter: brightness(1.1);
|
|
284
303
|
}
|
|
304
|
+
.file-type-badge {
|
|
305
|
+
font-size: 0.5em;
|
|
306
|
+
font-weight: 700;
|
|
307
|
+
letter-spacing: 0.03em;
|
|
308
|
+
padding: 1px 5px;
|
|
309
|
+
border-radius: 10px;
|
|
310
|
+
color: white;
|
|
311
|
+
white-space: nowrap;
|
|
312
|
+
line-height: 1.4;
|
|
313
|
+
}
|
|
285
314
|
.file-name {
|
|
286
315
|
font-size: 0.7em;
|
|
287
316
|
line-height: 1.1;
|
|
288
317
|
white-space: pre-line;
|
|
289
318
|
}
|
|
290
|
-
.compression-indicator {
|
|
291
|
-
opacity: 0.7;
|
|
292
|
-
font-size: 0.8em;
|
|
293
|
-
margin-left: 0.2em;
|
|
294
|
-
}
|
|
295
|
-
.file-item.compressed {
|
|
296
|
-
border-style: dashed;
|
|
297
|
-
opacity: 0.9;
|
|
298
|
-
}
|
|
299
|
-
.file-item.compressed:hover {
|
|
300
|
-
opacity: 1;
|
|
301
|
-
}
|
|
302
319
|
</style>
|
package/dist/Icon.svelte
CHANGED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
<script lang="ts">let { value = $bindable([0, 0, 1]) } = $props();
|
|
2
|
+
// Format: compact "001" for single-digit, spaced "10 0 1" for multi-digit
|
|
3
|
+
let hkl_text = $derived(value.every((v) => Math.abs(v) < 10) ? value.join(``) : value.join(` `));
|
|
4
|
+
// Parse hkl string: supports compact "001"/"-101" and spaced/comma "10, 0, 1"
|
|
5
|
+
function parse_hkl(input) {
|
|
6
|
+
// Try spaced/comma format first (handles multi-digit)
|
|
7
|
+
const spaced = input.trim().split(/[,\s]+/);
|
|
8
|
+
if (spaced.length === 3) {
|
|
9
|
+
const nums = spaced.map(Number);
|
|
10
|
+
if (nums.every((n) => !isNaN(n)))
|
|
11
|
+
return nums;
|
|
12
|
+
}
|
|
13
|
+
// Fall back to compact single-digit format: "001", "-101"
|
|
14
|
+
const compact = input.replace(/\s+/g, ``);
|
|
15
|
+
const match = compact.match(/^(-?\d)(-?\d)(-?\d)$/);
|
|
16
|
+
if (match)
|
|
17
|
+
return [Number(match[1]), Number(match[2]), Number(match[3])];
|
|
18
|
+
return null;
|
|
19
|
+
}
|
|
20
|
+
function handle_input(event) {
|
|
21
|
+
const parsed = parse_hkl(event.target.value);
|
|
22
|
+
if (parsed)
|
|
23
|
+
value = parsed;
|
|
24
|
+
}
|
|
25
|
+
export {};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<label class="miller-input">
|
|
29
|
+
<span>hkl</span>
|
|
30
|
+
<input
|
|
31
|
+
type="text"
|
|
32
|
+
value={hkl_text}
|
|
33
|
+
oninput={handle_input}
|
|
34
|
+
placeholder="001"
|
|
35
|
+
maxlength="12"
|
|
36
|
+
title="Miller indices (e.g. 001, -101, or 10 0 1)"
|
|
37
|
+
/>
|
|
38
|
+
</label>
|
|
39
|
+
|
|
40
|
+
<style>
|
|
41
|
+
.miller-input {
|
|
42
|
+
display: flex;
|
|
43
|
+
align-items: center;
|
|
44
|
+
gap: 0.3em;
|
|
45
|
+
span {
|
|
46
|
+
font-weight: 600;
|
|
47
|
+
font-size: 0.85em;
|
|
48
|
+
}
|
|
49
|
+
input {
|
|
50
|
+
width: 4em;
|
|
51
|
+
padding: 0.15em 0.3em;
|
|
52
|
+
border: 1px solid var(--border-color, #ccc);
|
|
53
|
+
border-radius: 4px;
|
|
54
|
+
font-family: monospace;
|
|
55
|
+
font-size: 0.9em;
|
|
56
|
+
text-align: center;
|
|
57
|
+
box-sizing: border-box;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
</style>
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Vec3 } from './math';
|
|
2
|
+
type $$ComponentProps = {
|
|
3
|
+
value?: Vec3;
|
|
4
|
+
};
|
|
5
|
+
declare const MillerIndexInput: import("svelte").Component<$$ComponentProps, {}, "value">;
|
|
6
|
+
type MillerIndexInput = ReturnType<typeof MillerIndexInput>;
|
|
7
|
+
export default MillerIndexInput;
|
package/dist/app.css
CHANGED
|
@@ -8,12 +8,14 @@
|
|
|
8
8
|
--max-text-width: 50em;
|
|
9
9
|
|
|
10
10
|
--sms-max-width: 20em;
|
|
11
|
+
--sms-min-height: 19pt;
|
|
11
12
|
--sms-text-color: var(--text-color);
|
|
12
13
|
|
|
13
14
|
/* Svelte MultiSelect */
|
|
14
15
|
--sms-options-bg: var(--page-bg);
|
|
15
16
|
--sms-active-color: light-dark(var(--accent-color), cornflowerblue);
|
|
16
17
|
--sms-li-active-bg: light-dark(rgba(100, 149, 237, 0.25), cornflowerblue);
|
|
18
|
+
--sms-selected-bg: light-dark(rgba(0, 0, 0, 0.08), rgba(255, 255, 255, 0.15));
|
|
17
19
|
--border-radius: 3pt;
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -33,18 +35,23 @@
|
|
|
33
35
|
}
|
|
34
36
|
body {
|
|
35
37
|
background: var(--page-bg);
|
|
36
|
-
padding:
|
|
38
|
+
padding: 5vh 3vw 3vh;
|
|
37
39
|
font-family: -apple-system, BlinkMacSystemFont, Roboto, sans-serif;
|
|
38
40
|
margin: auto;
|
|
39
41
|
color: var(--text-color);
|
|
40
42
|
line-height: 1.5;
|
|
43
|
+
/* Sticky footer: footer stays at bottom when content is short */
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
min-height: 100vh;
|
|
47
|
+
box-sizing: border-box;
|
|
41
48
|
}
|
|
42
49
|
main {
|
|
43
50
|
margin: auto;
|
|
44
|
-
margin-bottom: 3em;
|
|
45
51
|
width: 100%;
|
|
46
52
|
max-width: var(--max-text-width);
|
|
47
53
|
container-type: inline-size;
|
|
54
|
+
flex: 1; /* Grow to fill available space (sticky footer) */
|
|
48
55
|
}
|
|
49
56
|
a {
|
|
50
57
|
color: var(--accent-color, cornflowerblue);
|
|
@@ -128,6 +135,35 @@ textarea {
|
|
|
128
135
|
margin: 1em auto;
|
|
129
136
|
}
|
|
130
137
|
|
|
138
|
+
/* Theme-aware form controls (works consistently in notebooks and VSCode/Cursor webviews) */
|
|
139
|
+
:is(
|
|
140
|
+
input:not([type='checkbox'], [type='radio'], [type='range'], [type='color']),
|
|
141
|
+
textarea,
|
|
142
|
+
select
|
|
143
|
+
) {
|
|
144
|
+
background-color: var(--surface-bg);
|
|
145
|
+
color: var(--text-color);
|
|
146
|
+
border: 1px solid var(--border-color);
|
|
147
|
+
border-radius: var(--border-radius);
|
|
148
|
+
padding: 2px 6px;
|
|
149
|
+
}
|
|
150
|
+
:is(
|
|
151
|
+
input:not([type='checkbox'], [type='radio'], [type='range'], [type='color']),
|
|
152
|
+
textarea,
|
|
153
|
+
select
|
|
154
|
+
):focus {
|
|
155
|
+
outline: none;
|
|
156
|
+
border-color: var(--accent-color);
|
|
157
|
+
box-shadow: 0 0 0 2px color-mix(in srgb, var(--accent-color) 25%, transparent);
|
|
158
|
+
}
|
|
159
|
+
:is(input, textarea)::placeholder {
|
|
160
|
+
color: var(--text-color-muted);
|
|
161
|
+
}
|
|
162
|
+
select option {
|
|
163
|
+
background-color: var(--surface-bg);
|
|
164
|
+
color: var(--text-color);
|
|
165
|
+
}
|
|
166
|
+
|
|
131
167
|
/* Modern flat input styling */
|
|
132
168
|
input {
|
|
133
169
|
border: none;
|
|
@@ -1,17 +1,17 @@
|
|
|
1
|
-
<script lang="ts">import {
|
|
2
|
-
import { normalize_show_controls } from '../controls';
|
|
1
|
+
<script lang="ts">import { normalize_show_controls } from '../controls';
|
|
3
2
|
import EmptyState from '../EmptyState.svelte';
|
|
3
|
+
import { StatusMessage } from '../feedback';
|
|
4
4
|
import Spinner from '../feedback/Spinner.svelte';
|
|
5
5
|
import Icon from '../Icon.svelte';
|
|
6
|
-
import {
|
|
7
|
-
import { set_fullscreen_bg } from '../layout';
|
|
6
|
+
import { create_file_drop_handler, load_from_url } from '../io';
|
|
7
|
+
import { set_fullscreen_bg, toggle_fullscreen } from '../layout';
|
|
8
|
+
import { PlotTooltip } from '../plot';
|
|
8
9
|
import { DEFAULTS } from '../settings';
|
|
9
10
|
import { parse_any_structure } from '../structure/parse';
|
|
10
11
|
import { analyze_structure_symmetry } from '../symmetry';
|
|
11
12
|
import { Canvas } from '@threlte/core';
|
|
12
13
|
import { untrack } from 'svelte';
|
|
13
14
|
import { tooltip } from 'svelte-multiselect/attachments';
|
|
14
|
-
import { PlotTooltip } from '../plot';
|
|
15
15
|
import BrillouinZoneControls from './BrillouinZoneControls.svelte';
|
|
16
16
|
import BrillouinZoneExportPane from './BrillouinZoneExportPane.svelte';
|
|
17
17
|
import BrillouinZoneInfoPane from './BrillouinZoneInfoPane.svelte';
|
|
@@ -131,33 +131,19 @@ $effect(() => {
|
|
|
131
131
|
}
|
|
132
132
|
}
|
|
133
133
|
});
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (file) {
|
|
148
|
-
const { content, filename } = await decompress_file(file);
|
|
149
|
-
if (content)
|
|
150
|
-
handler(content, filename);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
catch (err) {
|
|
154
|
-
error_msg = `File drop failed: ${err}`;
|
|
155
|
-
on_error?.({ error_msg });
|
|
156
|
-
}
|
|
157
|
-
finally {
|
|
158
|
-
loading = false;
|
|
159
|
-
}
|
|
160
|
-
}
|
|
134
|
+
const handle_file_drop = create_file_drop_handler({
|
|
135
|
+
allow: () => allow_file_drop,
|
|
136
|
+
on_drop: (content, filename) => (on_file_drop || safe_parse)(content, filename),
|
|
137
|
+
on_error: (msg) => {
|
|
138
|
+
error_msg = msg;
|
|
139
|
+
on_error?.({ error_msg: msg });
|
|
140
|
+
},
|
|
141
|
+
set_loading: (val) => {
|
|
142
|
+
loading = val;
|
|
143
|
+
if (val)
|
|
144
|
+
[error_msg, dragover] = [undefined, false];
|
|
145
|
+
},
|
|
146
|
+
});
|
|
161
147
|
function onkeydown(event) {
|
|
162
148
|
const target = event.target;
|
|
163
149
|
if (target.tagName === `INPUT` || target.tagName === `TEXTAREA`)
|
|
@@ -221,10 +207,7 @@ $effect(() => {
|
|
|
221
207
|
{#if loading}
|
|
222
208
|
<Spinner text="Loading structure..." {...spinner_props} />
|
|
223
209
|
{:else if error_msg}
|
|
224
|
-
<
|
|
225
|
-
<p class="error">{error_msg}</p>
|
|
226
|
-
<button onclick={() => (error_msg = undefined)}>Dismiss</button>
|
|
227
|
-
</div>
|
|
210
|
+
<StatusMessage bind:message={error_msg} type="error" dismissible />
|
|
228
211
|
{:else if structure && `lattice` in structure}
|
|
229
212
|
<section
|
|
230
213
|
class="control-buttons {controls_config.class}"
|
|
@@ -394,7 +377,7 @@ $effect(() => {
|
|
|
394
377
|
display: flex;
|
|
395
378
|
padding: 4px;
|
|
396
379
|
border-radius: var(--border-radius, 3pt);
|
|
397
|
-
font-size: clamp(0.85em, 2cqmin,
|
|
380
|
+
font-size: clamp(0.85em, 2cqmin, 1.3em);
|
|
398
381
|
}
|
|
399
382
|
section.control-buttons :global(button:hover) {
|
|
400
383
|
background-color: color-mix(in srgb, currentColor 8%, transparent);
|
|
@@ -414,29 +397,4 @@ $effect(() => {
|
|
|
414
397
|
text-align: center;
|
|
415
398
|
padding: 2rem;
|
|
416
399
|
}
|
|
417
|
-
.error-state {
|
|
418
|
-
display: flex;
|
|
419
|
-
flex-direction: column;
|
|
420
|
-
align-items: center;
|
|
421
|
-
justify-content: center;
|
|
422
|
-
height: 100%;
|
|
423
|
-
padding: 2rem;
|
|
424
|
-
text-align: center;
|
|
425
|
-
box-sizing: border-box;
|
|
426
|
-
}
|
|
427
|
-
.error-state p {
|
|
428
|
-
color: var(--error-color, #ff6b6b);
|
|
429
|
-
margin: 0 0 1rem;
|
|
430
|
-
}
|
|
431
|
-
.error-state button {
|
|
432
|
-
padding: 0.5rem 1rem;
|
|
433
|
-
background: var(--error-color, #ff6b6b);
|
|
434
|
-
color: white;
|
|
435
|
-
border: none;
|
|
436
|
-
border-radius: 4px;
|
|
437
|
-
cursor: pointer;
|
|
438
|
-
}
|
|
439
|
-
.error-state button:hover {
|
|
440
|
-
background: var(--error-color-hover, #ff5252);
|
|
441
|
-
}
|
|
442
400
|
</style>
|
|
@@ -78,6 +78,6 @@ type $$ComponentProps = {
|
|
|
78
78
|
on_fullscreen_change?: (data: BZHandlerData) => void;
|
|
79
79
|
on_hover?: (data: BZHoverData | null) => void;
|
|
80
80
|
} & HTMLAttributes<HTMLDivElement>;
|
|
81
|
-
declare const BrillouinZone: import("svelte").Component<$$ComponentProps, {}, "height" | "width" | "dragover" | "
|
|
81
|
+
declare const BrillouinZone: import("svelte").Component<$$ComponentProps, {}, "structure" | "height" | "width" | "dragover" | "controls_open" | "loading" | "fullscreen" | "hovered" | "camera_projection" | "info_pane_open" | "wrapper" | "error_msg" | "png_dpi" | "bz_order" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "show_ibz" | "ibz_color" | "ibz_opacity" | "bz_data" | "vector_scale" | "ibz_data">;
|
|
82
82
|
type BrillouinZone = ReturnType<typeof BrillouinZone>;
|
|
83
83
|
export default BrillouinZone;
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
<script lang="ts">import
|
|
2
|
-
import
|
|
1
|
+
<script lang="ts">import { export_canvas_as_png } from '../io/export';
|
|
2
|
+
import DraggablePane from '../overlays/DraggablePane.svelte';
|
|
3
|
+
import { CopyButton } from 'svelte-multiselect';
|
|
3
4
|
import { tooltip } from 'svelte-multiselect/attachments';
|
|
4
5
|
let { export_pane_open = $bindable(false), bz_data, wrapper, scene, camera, filename = `brillouin-zone`, png_dpi = $bindable(150), ...rest } = $props();
|
|
5
|
-
let
|
|
6
|
-
const copy_confirm = `✅`;
|
|
6
|
+
let json_copy_state = $state(`ready`);
|
|
7
7
|
function export_as_png() {
|
|
8
8
|
const canvas = wrapper?.querySelector(`canvas`);
|
|
9
9
|
if (!canvas || !scene || !camera)
|
|
@@ -38,16 +38,10 @@ function get_json_data() {
|
|
|
38
38
|
reciprocal_lattice: bz_data.k_lattice,
|
|
39
39
|
};
|
|
40
40
|
}
|
|
41
|
-
|
|
41
|
+
let json_string = $derived.by(() => {
|
|
42
42
|
const json_data = get_json_data();
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
await navigator.clipboard.writeText(JSON.stringify(json_data, null, 2));
|
|
46
|
-
copy_status = true;
|
|
47
|
-
setTimeout(() => {
|
|
48
|
-
copy_status = false;
|
|
49
|
-
}, 1000);
|
|
50
|
-
}
|
|
43
|
+
return json_data ? JSON.stringify(json_data, null, 2) : null;
|
|
44
|
+
});
|
|
51
45
|
</script>
|
|
52
46
|
|
|
53
47
|
<DraggablePane
|
|
@@ -97,14 +91,12 @@ async function copy_json() {
|
|
|
97
91
|
>
|
|
98
92
|
⬇
|
|
99
93
|
</button>
|
|
100
|
-
<
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
disabled={!
|
|
94
|
+
<CopyButton
|
|
95
|
+
content={json_string ?? ``}
|
|
96
|
+
bind:state={json_copy_state}
|
|
97
|
+
disabled={!json_string}
|
|
104
98
|
title="Copy JSON to clipboard"
|
|
105
|
-
|
|
106
|
-
{copy_status ? copy_confirm : `📋`}
|
|
107
|
-
</button>
|
|
99
|
+
/>
|
|
108
100
|
</label>
|
|
109
101
|
</DraggablePane>
|
|
110
102
|
|
|
@@ -243,7 +243,7 @@ function handle_leave(is_ibz) {
|
|
|
243
243
|
{/if}
|
|
244
244
|
|
|
245
245
|
<!-- BZ edges -->
|
|
246
|
-
{#each bz_data.edges as edge_segment (
|
|
246
|
+
{#each bz_data.edges as edge_segment, edge_idx (`bz-edge-${edge_idx}`)}
|
|
247
247
|
{@const [from, to] = edge_segment}
|
|
248
248
|
<Cylinder {from} {to} thickness={edge_width} color={edge_color} />
|
|
249
249
|
{/each}
|
|
@@ -267,7 +267,7 @@ function handle_leave(is_ibz) {
|
|
|
267
267
|
|
|
268
268
|
<!-- IBZ edges -->
|
|
269
269
|
{#if show_ibz && ibz_data}
|
|
270
|
-
{#each ibz_data.edges as edge_segment (
|
|
270
|
+
{#each ibz_data.edges as edge_segment, edge_idx (`ibz-edge-${edge_idx}`)}
|
|
271
271
|
{@const [from, to] = edge_segment}
|
|
272
272
|
<Cylinder {from} {to} thickness={edge_width * 1.5} color={ibz_color} />
|
|
273
273
|
{/each}
|
|
@@ -43,6 +43,6 @@ type $$ComponentProps = {
|
|
|
43
43
|
hovered_qpoint_index?: number | null;
|
|
44
44
|
hover_data?: BZHoverData | null;
|
|
45
45
|
};
|
|
46
|
-
declare const BrillouinZoneScene: import("svelte").Component<$$ComponentProps, {}, "camera_position" | "camera_projection" | "
|
|
46
|
+
declare const BrillouinZoneScene: import("svelte").Component<$$ComponentProps, {}, "camera_position" | "camera_projection" | "scene" | "camera" | "camera_is_moving" | "surface_color" | "surface_opacity" | "edge_color" | "edge_width" | "show_vectors" | "bz_data" | "vector_scale" | "hover_data">;
|
|
47
47
|
type BrillouinZoneScene = ReturnType<typeof BrillouinZoneScene>;
|
|
48
48
|
export default BrillouinZoneScene;
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
<script lang="ts">import { get_hill_formula } from '../composition/format';
|
|
2
|
+
import { format_num } from '../labels';
|
|
3
|
+
import ChemPotDiagram2D from './ChemPotDiagram2D.svelte';
|
|
4
|
+
import ChemPotDiagram3D from './ChemPotDiagram3D.svelte';
|
|
5
|
+
import { CHEMPOT_DEFAULTS } from './types';
|
|
6
|
+
let { entries = [], config = {}, width = $bindable(600), height = $bindable(600),
|
|
7
|
+
// Bound temperature may be auto-corrected by 2D/3D child components.
|
|
8
|
+
temperature = $bindable(), hover_info = $bindable(null), } = $props();
|
|
9
|
+
// Extract unique elements from all entries (composition keys are element symbols)
|
|
10
|
+
const all_elements = $derived([
|
|
11
|
+
...new Set(entries.flatMap((entry) => Object.entries(entry.composition)
|
|
12
|
+
.filter(([, amount]) => amount > 0)
|
|
13
|
+
.map(([element]) => element))),
|
|
14
|
+
].sort());
|
|
15
|
+
// How many display axes (2 = binary/2D, 3+ = ternary/3D)
|
|
16
|
+
const display_elements = $derived(config.elements ?? all_elements);
|
|
17
|
+
const n_display = $derived(display_elements.length);
|
|
18
|
+
const show_tooltip = $derived(config.show_tooltip ?? CHEMPOT_DEFAULTS.show_tooltip);
|
|
19
|
+
const tooltip_detail_level = $derived(config.tooltip_detail_level ?? CHEMPOT_DEFAULTS.tooltip_detail_level);
|
|
20
|
+
function is_hover_info_3d(value) {
|
|
21
|
+
return value?.view === `3d`;
|
|
22
|
+
}
|
|
23
|
+
</script>
|
|
24
|
+
|
|
25
|
+
<div class="chempot-diagram-wrapper">
|
|
26
|
+
{#if n_display < 2}
|
|
27
|
+
<div
|
|
28
|
+
class="chempot-error"
|
|
29
|
+
role="alert"
|
|
30
|
+
aria-live="polite"
|
|
31
|
+
style:width="{width}px"
|
|
32
|
+
style:height="{height}px"
|
|
33
|
+
>
|
|
34
|
+
<div>
|
|
35
|
+
<h3 id="unsupported-chemical-system">Unsupported Chemical System</h3>
|
|
36
|
+
<p>
|
|
37
|
+
Chemical potential diagrams require at least 2 elements. Found {n_display}
|
|
38
|
+
element{n_display === 1 ? `` : `s`}:
|
|
39
|
+
{display_elements.join(`, `) || `none`}
|
|
40
|
+
</p>
|
|
41
|
+
</div>
|
|
42
|
+
</div>
|
|
43
|
+
{:else if n_display === 2}
|
|
44
|
+
<ChemPotDiagram2D
|
|
45
|
+
{entries}
|
|
46
|
+
{config}
|
|
47
|
+
bind:width
|
|
48
|
+
bind:height
|
|
49
|
+
bind:temperature
|
|
50
|
+
bind:hover_info
|
|
51
|
+
render_local_tooltip={false}
|
|
52
|
+
/>
|
|
53
|
+
{:else}
|
|
54
|
+
<ChemPotDiagram3D
|
|
55
|
+
{entries}
|
|
56
|
+
{config}
|
|
57
|
+
bind:width
|
|
58
|
+
bind:height
|
|
59
|
+
bind:temperature
|
|
60
|
+
bind:hover_info
|
|
61
|
+
render_local_tooltip={false}
|
|
62
|
+
/>
|
|
63
|
+
{/if}
|
|
64
|
+
{#if show_tooltip && hover_info}
|
|
65
|
+
<aside
|
|
66
|
+
class="chempot-tooltip"
|
|
67
|
+
style:left="{hover_info.pointer?.x ?? 4}px"
|
|
68
|
+
style:top="{hover_info.pointer?.y ?? 4}px"
|
|
69
|
+
>
|
|
70
|
+
<h4>{@html get_hill_formula(hover_info.formula, false, ``)}</h4>
|
|
71
|
+
{#if hover_info.view === `2d`}
|
|
72
|
+
<p>2D domain · Points: {hover_info.n_points}</p>
|
|
73
|
+
{#if tooltip_detail_level === `detailed`}
|
|
74
|
+
<h5 id="axis-ranges">Axis ranges</h5>
|
|
75
|
+
{#each hover_info.axis_ranges as axis_range (axis_range.element)}
|
|
76
|
+
<p>
|
|
77
|
+
{axis_range.element}: {format_num(axis_range.min_val, `.4~g`)} to
|
|
78
|
+
{format_num(axis_range.max_val, `.4~g`)} eV
|
|
79
|
+
</p>
|
|
80
|
+
{/each}
|
|
81
|
+
{/if}
|
|
82
|
+
{:else if is_hover_info_3d(hover_info)}
|
|
83
|
+
<p>
|
|
84
|
+
{hover_info.is_elemental ? `Elemental phase` : `Compound phase`}
|
|
85
|
+
{#if hover_info.is_draw_formula}
|
|
86
|
+
<span> · Overlay target</span>
|
|
87
|
+
{/if}
|
|
88
|
+
</p>
|
|
89
|
+
<p>
|
|
90
|
+
Vertices: {hover_info.n_vertices} · Edges: {hover_info.n_edges} · Points:
|
|
91
|
+
{hover_info.n_points}
|
|
92
|
+
</p>
|
|
93
|
+
<p>
|
|
94
|
+
Entries: {hover_info.matching_entry_count}
|
|
95
|
+
{#if hover_info.min_energy_per_atom !== null &&
|
|
96
|
+
hover_info.max_energy_per_atom !== null}
|
|
97
|
+
· E/atom: {format_num(hover_info.min_energy_per_atom, `.4~g`)}
|
|
98
|
+
to {format_num(hover_info.max_energy_per_atom, `.4~g`)} eV
|
|
99
|
+
{/if}
|
|
100
|
+
</p>
|
|
101
|
+
{#if tooltip_detail_level === `detailed`}
|
|
102
|
+
<h5 id="axis-ranges-1">Axis ranges</h5>
|
|
103
|
+
{#each hover_info.axis_ranges as axis_range (axis_range.element)}
|
|
104
|
+
<p>
|
|
105
|
+
{axis_range.element}: {format_num(axis_range.min_val, `.4~g`)} to
|
|
106
|
+
{format_num(axis_range.max_val, `.4~g`)} eV
|
|
107
|
+
</p>
|
|
108
|
+
{/each}
|
|
109
|
+
<p>
|
|
110
|
+
Centroid: ({
|
|
111
|
+
hover_info.ann_loc.map((value) => format_num(value, `.3~g`)).join(
|
|
112
|
+
`, `,
|
|
113
|
+
)
|
|
114
|
+
})
|
|
115
|
+
</p>
|
|
116
|
+
{#if hover_info.neighbors.length > 0}
|
|
117
|
+
<h5 id="neighbors">Neighbors ({hover_info.neighbors.length})</h5>
|
|
118
|
+
<p>
|
|
119
|
+
{
|
|
120
|
+
hover_info.neighbors.map((f) => get_hill_formula(f, true, ``)).join(
|
|
121
|
+
`, `,
|
|
122
|
+
)
|
|
123
|
+
}
|
|
124
|
+
</p>
|
|
125
|
+
{/if}
|
|
126
|
+
{#if hover_info.touches_limits.length > 0}
|
|
127
|
+
<h5 id="touches-bounds">Touches bounds</h5>
|
|
128
|
+
<p>{hover_info.touches_limits.join(`, `)}</p>
|
|
129
|
+
{/if}
|
|
130
|
+
{/if}
|
|
131
|
+
{/if}
|
|
132
|
+
</aside>
|
|
133
|
+
{/if}
|
|
134
|
+
</div>
|
|
135
|
+
|
|
136
|
+
<style>
|
|
137
|
+
.chempot-diagram-wrapper {
|
|
138
|
+
position: relative;
|
|
139
|
+
}
|
|
140
|
+
.chempot-error {
|
|
141
|
+
display: flex;
|
|
142
|
+
align-items: center;
|
|
143
|
+
justify-content: center;
|
|
144
|
+
border: 1px solid var(--border-color, #ccc);
|
|
145
|
+
border-radius: var(--border-radius, 3pt);
|
|
146
|
+
background: var(--bg-color, transparent);
|
|
147
|
+
}
|
|
148
|
+
.chempot-error > div {
|
|
149
|
+
text-align: center;
|
|
150
|
+
padding: 2em;
|
|
151
|
+
color: var(--text-color, #666);
|
|
152
|
+
}
|
|
153
|
+
.chempot-error h3 {
|
|
154
|
+
margin: 0 0 1em;
|
|
155
|
+
}
|
|
156
|
+
.chempot-error p {
|
|
157
|
+
margin: 0;
|
|
158
|
+
}
|
|
159
|
+
.chempot-tooltip {
|
|
160
|
+
position: absolute;
|
|
161
|
+
max-width: min(32rem, 92vw);
|
|
162
|
+
background: var(
|
|
163
|
+
--tooltip-bg,
|
|
164
|
+
light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.9))
|
|
165
|
+
);
|
|
166
|
+
color: var(--tooltip-text, var(--text-color, #222));
|
|
167
|
+
border: 1px solid color-mix(in srgb, currentColor 18%, transparent);
|
|
168
|
+
border-radius: 6px;
|
|
169
|
+
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.18);
|
|
170
|
+
padding: 8px 10px;
|
|
171
|
+
font-size: 12px;
|
|
172
|
+
line-height: 1.35;
|
|
173
|
+
pointer-events: none;
|
|
174
|
+
z-index: 40;
|
|
175
|
+
}
|
|
176
|
+
.chempot-tooltip h4 {
|
|
177
|
+
margin: 0 0 4px;
|
|
178
|
+
font-size: 13px;
|
|
179
|
+
}
|
|
180
|
+
.chempot-tooltip p {
|
|
181
|
+
margin: 1px 0;
|
|
182
|
+
white-space: nowrap;
|
|
183
|
+
overflow: hidden;
|
|
184
|
+
text-overflow: ellipsis;
|
|
185
|
+
}
|
|
186
|
+
.chempot-tooltip h5 {
|
|
187
|
+
margin-top: 6px;
|
|
188
|
+
margin-bottom: 0;
|
|
189
|
+
font-size: 12px;
|
|
190
|
+
font-weight: 600;
|
|
191
|
+
}
|
|
192
|
+
</style>
|