matterviz 0.3.2 → 0.3.3
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/EmptyState.svelte +10 -2
- package/dist/FilePicker.svelte +123 -82
- package/dist/Icon.svelte +18 -12
- package/dist/MillerIndexInput.svelte +27 -21
- package/dist/api/optimade.js +6 -6
- package/dist/app.css +216 -207
- package/dist/brillouin/BrillouinZone.svelte +292 -149
- package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
- package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
- package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
- package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
- package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
- package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
- package/dist/brillouin/compute.js +11 -6
- package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
- package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
- package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
- package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
- package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
- package/dist/chempot-diagram/async-compute.svelte.js +77 -0
- package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
- package/dist/chempot-diagram/chempot-worker.js +11 -0
- package/dist/chempot-diagram/color.js +1 -2
- package/dist/chempot-diagram/compute.d.ts +10 -0
- package/dist/chempot-diagram/compute.js +250 -88
- package/dist/chempot-diagram/index.d.ts +2 -1
- package/dist/chempot-diagram/index.js +2 -1
- package/dist/chempot-diagram/temperature.js +8 -9
- package/dist/chempot-diagram/types.d.ts +3 -0
- package/dist/chempot-diagram/types.js +1 -0
- package/dist/colors/index.d.ts +1 -1
- package/dist/colors/index.js +5 -3
- package/dist/composition/BarChart.svelte +128 -55
- package/dist/composition/BubbleChart.svelte +102 -49
- package/dist/composition/Composition.svelte +100 -79
- package/dist/composition/Formula.svelte +108 -62
- package/dist/composition/FormulaFilter.svelte +665 -537
- package/dist/composition/PieChart.svelte +183 -108
- package/dist/composition/format.d.ts +5 -0
- package/dist/composition/format.js +20 -3
- package/dist/composition/parse.js +14 -9
- package/dist/convex-hull/ConvexHull.svelte +93 -40
- package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull2D.svelte +549 -360
- package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
- package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
- package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullControls.svelte +115 -28
- package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
- package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
- package/dist/convex-hull/ConvexHullStats.svelte +425 -328
- package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
- package/dist/convex-hull/GasPressureControls.svelte +104 -61
- package/dist/convex-hull/StructurePopup.svelte +25 -4
- package/dist/convex-hull/TemperatureSlider.svelte +45 -25
- package/dist/convex-hull/barycentric-coords.js +13 -7
- package/dist/convex-hull/demo-temperature.js +8 -4
- package/dist/convex-hull/gas-thermodynamics.js +17 -12
- package/dist/convex-hull/helpers.d.ts +9 -0
- package/dist/convex-hull/helpers.js +77 -34
- package/dist/convex-hull/thermodynamics.js +61 -56
- package/dist/convex-hull/types.d.ts +9 -14
- package/dist/convex-hull/types.js +0 -17
- package/dist/coordination/CoordinationBarPlot.svelte +227 -154
- package/dist/element/BohrAtom.svelte +55 -12
- package/dist/element/ElementHeading.svelte +7 -2
- package/dist/element/ElementPhoto.svelte +15 -9
- package/dist/element/ElementStats.svelte +10 -4
- package/dist/element/ElementTile.svelte +137 -73
- package/dist/element/Nucleus.svelte +39 -11
- package/dist/feedback/ClickFeedback.svelte +16 -5
- package/dist/feedback/DragOverlay.svelte +10 -2
- package/dist/feedback/Spinner.svelte +4 -2
- package/dist/feedback/StatusMessage.svelte +8 -2
- package/dist/fermi-surface/FermiSlice.svelte +118 -88
- package/dist/fermi-surface/FermiSurface.svelte +328 -187
- package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
- package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
- package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
- package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
- package/dist/fermi-surface/compute.js +16 -20
- package/dist/fermi-surface/parse.js +24 -14
- package/dist/fermi-surface/symmetry.js +2 -7
- package/dist/fermi-surface/types.d.ts +3 -5
- package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
- package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
- package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
- package/dist/icons.js +47 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/io/decompress.js +1 -1
- package/dist/io/export.d.ts +3 -0
- package/dist/io/export.js +129 -143
- package/dist/io/is-binary.js +2 -3
- package/dist/io/url-drop.js +1 -2
- package/dist/isosurface/Isosurface.svelte +202 -148
- package/dist/isosurface/IsosurfaceControls.svelte +46 -28
- package/dist/isosurface/parse.js +34 -29
- package/dist/isosurface/slice.js +5 -10
- package/dist/isosurface/types.d.ts +2 -1
- package/dist/isosurface/types.js +61 -12
- package/dist/labels.js +11 -8
- package/dist/layout/FullscreenToggle.svelte +11 -2
- package/dist/layout/InfoCard.svelte +38 -6
- package/dist/layout/InfoTag.svelte +63 -32
- package/dist/layout/PropertyFilter.svelte +82 -37
- package/dist/layout/SettingsSection.svelte +85 -55
- package/dist/layout/SubpageGrid.svelte +10 -2
- package/dist/layout/json-tree/JsonNode.svelte +183 -138
- package/dist/layout/json-tree/JsonTree.svelte +499 -413
- package/dist/layout/json-tree/JsonValue.svelte +127 -99
- package/dist/layout/json-tree/utils.js +4 -2
- package/dist/marching-cubes.js +25 -2
- package/dist/math.d.ts +13 -17
- package/dist/math.js +133 -67
- package/dist/overlays/ContextMenu.svelte +65 -40
- package/dist/overlays/DraggablePane.svelte +211 -139
- package/dist/periodic-table/PeriodicTable.svelte +278 -145
- package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
- package/dist/periodic-table/PropertySelect.svelte +25 -7
- package/dist/periodic-table/TableInset.svelte +8 -3
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
- package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
- package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
- package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
- package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
- package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
- package/dist/phase-diagram/build-diagram.js +9 -9
- package/dist/phase-diagram/colors.js +1 -3
- package/dist/phase-diagram/parse.js +10 -9
- package/dist/phase-diagram/svg-to-diagram.js +53 -49
- package/dist/phase-diagram/utils.d.ts +1 -0
- package/dist/phase-diagram/utils.js +80 -25
- package/dist/plot/AxisLabel.svelte +28 -3
- package/dist/plot/BarPlot.svelte +1182 -734
- package/dist/plot/BarPlot.svelte.d.ts +2 -2
- package/dist/plot/BarPlotControls.svelte +31 -5
- package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ColorBar.svelte +479 -329
- package/dist/plot/ColorScaleSelect.svelte +27 -6
- package/dist/plot/ElementScatter.svelte +36 -15
- package/dist/plot/FillArea.svelte +152 -95
- package/dist/plot/Histogram.svelte +934 -571
- package/dist/plot/Histogram.svelte.d.ts +1 -1
- package/dist/plot/HistogramControls.svelte +53 -9
- package/dist/plot/HistogramControls.svelte.d.ts +1 -1
- package/dist/plot/InteractiveAxisLabel.svelte +34 -11
- package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
- package/dist/plot/Line.svelte +63 -28
- package/dist/plot/PlotControls.svelte +157 -114
- package/dist/plot/PlotControls.svelte.d.ts +1 -1
- package/dist/plot/PlotLegend.svelte +174 -91
- package/dist/plot/PlotTooltip.svelte +45 -6
- package/dist/plot/PortalSelect.svelte +175 -147
- package/dist/plot/ReferenceLine.svelte +76 -22
- package/dist/plot/ReferenceLine3D.svelte +132 -107
- package/dist/plot/ReferencePlane.svelte +146 -121
- package/dist/plot/ScatterPlot.svelte +1681 -1091
- package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3D.svelte +256 -131
- package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlot3DControls.svelte +113 -63
- package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
- package/dist/plot/ScatterPlot3DScene.svelte +608 -403
- package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
- package/dist/plot/ScatterPlotControls.svelte +65 -25
- package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
- package/dist/plot/ScatterPoint.svelte +98 -26
- package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
- package/dist/plot/SpacegroupBarPlot.svelte +142 -85
- package/dist/plot/Surface3D.svelte +159 -108
- package/dist/plot/ZeroLines.svelte +55 -3
- package/dist/plot/ZoomRect.svelte +4 -2
- package/dist/plot/axis-utils.js +1 -3
- package/dist/plot/data-cleaning.js +12 -28
- package/dist/plot/data-transform.js +2 -1
- package/dist/plot/fill-utils.js +2 -0
- package/dist/plot/layout.d.ts +4 -1
- package/dist/plot/layout.js +33 -14
- package/dist/plot/reference-line.d.ts +2 -2
- package/dist/plot/reference-line.js +7 -5
- package/dist/plot/scales.js +24 -36
- package/dist/plot/types.d.ts +11 -23
- package/dist/plot/types.js +6 -11
- package/dist/plot/utils/label-placement.d.ts +32 -15
- package/dist/plot/utils/label-placement.js +227 -66
- package/dist/plot/utils/series-visibility.js +2 -3
- package/dist/rdf/RdfPlot.svelte +143 -91
- package/dist/rdf/calc-rdf.js +4 -5
- package/dist/sanitize.d.ts +4 -0
- package/dist/sanitize.js +107 -0
- package/dist/settings.d.ts +18 -6
- package/dist/settings.js +46 -16
- package/dist/spectral/Bands.svelte +632 -453
- package/dist/spectral/BandsAndDos.svelte +90 -49
- package/dist/spectral/BrillouinBandsDos.svelte +151 -93
- package/dist/spectral/Dos.svelte +389 -258
- package/dist/spectral/helpers.js +55 -43
- package/dist/state.svelte.d.ts +1 -1
- package/dist/state.svelte.js +3 -2
- package/dist/structure/Arrow.svelte +59 -20
- package/dist/structure/AtomLegend.svelte +215 -134
- package/dist/structure/Bond.svelte +73 -47
- package/dist/structure/CanvasTooltip.svelte +10 -2
- package/dist/structure/CellSelect.svelte +72 -45
- package/dist/structure/Cylinder.svelte +33 -17
- package/dist/structure/Lattice.svelte +88 -33
- package/dist/structure/Structure.svelte +1063 -797
- package/dist/structure/Structure.svelte.d.ts +1 -1
- package/dist/structure/StructureControls.svelte +349 -118
- package/dist/structure/StructureExportPane.svelte +124 -89
- package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
- package/dist/structure/StructureInfoPane.svelte +304 -237
- package/dist/structure/StructureScene.svelte +879 -443
- package/dist/structure/StructureScene.svelte.d.ts +15 -7
- package/dist/structure/atom-properties.js +8 -8
- package/dist/structure/bonding.js +6 -7
- package/dist/structure/export.js +14 -29
- package/dist/structure/ferrox-wasm.js +1 -1
- package/dist/structure/index.d.ts +13 -3
- package/dist/structure/index.js +83 -23
- package/dist/structure/measure.d.ts +2 -2
- package/dist/structure/measure.js +4 -44
- package/dist/structure/parse.js +113 -141
- package/dist/structure/partial-occupancy.js +7 -10
- package/dist/structure/pbc.d.ts +1 -0
- package/dist/structure/pbc.js +16 -6
- package/dist/structure/supercell.d.ts +2 -2
- package/dist/structure/supercell.js +12 -22
- package/dist/structure/validation.js +1 -2
- package/dist/symmetry/SymmetryStats.svelte +84 -41
- package/dist/symmetry/WyckoffTable.svelte +26 -6
- package/dist/symmetry/cell-transform.js +5 -3
- package/dist/symmetry/index.js +8 -7
- package/dist/symmetry/spacegroups.js +148 -148
- package/dist/table/HeatmapTable.svelte +790 -554
- package/dist/table/HeatmapTable.svelte.d.ts +1 -1
- package/dist/table/ToggleMenu.svelte +125 -92
- package/dist/table/index.js +2 -4
- package/dist/theme/ThemeControl.svelte +21 -12
- package/dist/time.js +4 -1
- package/dist/tooltip/TooltipContent.svelte +33 -8
- package/dist/trajectory/Trajectory.svelte +758 -558
- package/dist/trajectory/TrajectoryError.svelte +14 -3
- package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
- package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
- package/dist/trajectory/extract.js +10 -26
- package/dist/trajectory/format-detect.js +5 -5
- package/dist/trajectory/frame-reader.d.ts +1 -1
- package/dist/trajectory/frame-reader.js +5 -12
- package/dist/trajectory/helpers.d.ts +0 -1
- package/dist/trajectory/helpers.js +2 -17
- package/dist/trajectory/index.js +14 -12
- package/dist/trajectory/parse/ase.js +5 -4
- package/dist/trajectory/parse/hdf5.js +26 -18
- package/dist/trajectory/parse/index.js +13 -18
- package/dist/trajectory/parse/lammps.js +17 -7
- package/dist/trajectory/parse/vasp.js +5 -2
- package/dist/trajectory/parse/xyz.js +8 -7
- package/dist/trajectory/plotting.js +13 -8
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +13 -0
- package/dist/xrd/XrdPlot.svelte +337 -247
- package/dist/xrd/broadening.js +14 -9
- package/dist/xrd/calc-xrd.js +12 -18
- package/dist/xrd/parse.d.ts +1 -1
- package/dist/xrd/parse.js +17 -17
- package/package.json +99 -103
- package/readme.md +1 -1
- /package/dist/theme/{themes.js → themes.mjs} +0 -0
|
@@ -1,224 +1,364 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
18
|
-
import {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { BrillouinZoneData } from '../brillouin'
|
|
3
|
+
import { compute_brillouin_zone, reciprocal_lattice } from '../brillouin'
|
|
4
|
+
import type { ShowControlsProp } from '../controls'
|
|
5
|
+
import { normalize_show_controls } from '../controls'
|
|
6
|
+
import EmptyState from '../EmptyState.svelte'
|
|
7
|
+
import { StatusMessage } from '../feedback'
|
|
8
|
+
import Spinner from '../feedback/Spinner.svelte'
|
|
9
|
+
import Icon from '../Icon.svelte'
|
|
10
|
+
import { create_file_drop_handler, load_from_url } from '../io'
|
|
11
|
+
import { set_fullscreen_bg, toggle_fullscreen } from '../layout'
|
|
12
|
+
import { PlotTooltip } from '../plot'
|
|
13
|
+
import type { CameraProjection } from '../settings'
|
|
14
|
+
import { DEFAULTS } from '../settings'
|
|
15
|
+
import type { Crystal } from '../structure'
|
|
16
|
+
import { Canvas } from '@threlte/core'
|
|
17
|
+
import type { ComponentProps, Snippet } from 'svelte'
|
|
18
|
+
import { untrack } from 'svelte'
|
|
19
|
+
import { tooltip } from 'svelte-multiselect/attachments'
|
|
20
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
21
|
+
import type { Camera, Scene } from 'three'
|
|
22
|
+
import { detect_irreducible_bz, extract_fermi_surface } from './compute'
|
|
23
|
+
import FermiSurfaceControls from './FermiSurfaceControls.svelte'
|
|
24
|
+
import FermiSurfaceScene from './FermiSurfaceScene.svelte'
|
|
25
|
+
import FermiSurfaceTooltip from './FermiSurfaceTooltip.svelte'
|
|
26
|
+
import { parse_fermi_file } from './parse'
|
|
27
|
+
import type {
|
|
28
|
+
BandGridData,
|
|
29
|
+
ColorProperty,
|
|
30
|
+
FermiErrorData,
|
|
31
|
+
FermiFileLoadData,
|
|
32
|
+
FermiHoverData,
|
|
33
|
+
FermiSurfaceData,
|
|
34
|
+
FermiTooltipConfig,
|
|
35
|
+
RepresentationMode,
|
|
36
|
+
} from './types'
|
|
37
|
+
|
|
38
|
+
type FermiHandlerData = {
|
|
39
|
+
fermi_data?: FermiSurfaceData
|
|
40
|
+
band_data?: BandGridData
|
|
41
|
+
bz_data?: BrillouinZoneData
|
|
42
|
+
filename?: string
|
|
43
|
+
file_size?: number
|
|
44
|
+
error_msg?: string
|
|
45
|
+
fullscreen?: boolean
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
let {
|
|
49
|
+
fermi_data = $bindable(),
|
|
50
|
+
band_data = $bindable(),
|
|
51
|
+
structure,
|
|
52
|
+
bz_data = $bindable(),
|
|
53
|
+
mu = $bindable(0),
|
|
54
|
+
controls_open = $bindable(false),
|
|
55
|
+
color_property = $bindable(`band`),
|
|
56
|
+
color_scale = $bindable(`interpolateViridis`),
|
|
57
|
+
custom_property_label,
|
|
58
|
+
representation = $bindable(`solid`),
|
|
59
|
+
surface_opacity = $bindable(0.8),
|
|
60
|
+
selected_bands = $bindable(),
|
|
61
|
+
show_bz = $bindable(true),
|
|
62
|
+
bz_opacity = $bindable(0.1),
|
|
63
|
+
show_vectors = $bindable(true),
|
|
64
|
+
tile_bz = $bindable(false),
|
|
65
|
+
// Clipping plane
|
|
66
|
+
clip_enabled = $bindable(false),
|
|
67
|
+
clip_axis = $bindable(`z`),
|
|
68
|
+
clip_position = $bindable(0),
|
|
69
|
+
clip_flip = $bindable(false),
|
|
70
|
+
// Interpolation
|
|
71
|
+
interpolation_factor = $bindable(1),
|
|
72
|
+
camera_projection = $bindable(`perspective`),
|
|
73
|
+
show_controls,
|
|
74
|
+
fullscreen = $bindable(false),
|
|
75
|
+
wrapper = $bindable(),
|
|
76
|
+
width = $bindable(0),
|
|
77
|
+
height = $bindable(0),
|
|
78
|
+
hovered = $bindable(false),
|
|
79
|
+
dragover = $bindable(false),
|
|
80
|
+
allow_file_drop = true,
|
|
81
|
+
fullscreen_toggle = DEFAULTS.structure.fullscreen_toggle,
|
|
82
|
+
data_url,
|
|
83
|
+
spinner_props = {},
|
|
84
|
+
loading = $bindable(false),
|
|
85
|
+
error_msg = $bindable(),
|
|
86
|
+
children,
|
|
87
|
+
tooltip_config,
|
|
88
|
+
on_file_drop,
|
|
89
|
+
on_file_load,
|
|
90
|
+
on_error,
|
|
91
|
+
on_fullscreen_change,
|
|
92
|
+
on_mu_change,
|
|
93
|
+
on_hover,
|
|
94
|
+
...rest
|
|
95
|
+
}: {
|
|
96
|
+
fermi_data?: FermiSurfaceData
|
|
97
|
+
band_data?: BandGridData
|
|
98
|
+
structure?: Crystal
|
|
99
|
+
bz_data?: BrillouinZoneData
|
|
100
|
+
mu?: number
|
|
101
|
+
controls_open?: boolean
|
|
102
|
+
color_property?: ColorProperty
|
|
103
|
+
color_scale?: string
|
|
104
|
+
// Label for custom property coloring (e.g. "λ(k)", "DOS", etc.)
|
|
105
|
+
custom_property_label?: string
|
|
106
|
+
representation?: RepresentationMode
|
|
107
|
+
surface_opacity?: number
|
|
108
|
+
selected_bands?: number[]
|
|
109
|
+
show_bz?: boolean
|
|
110
|
+
bz_opacity?: number
|
|
111
|
+
show_vectors?: boolean
|
|
112
|
+
tile_bz?: boolean
|
|
113
|
+
clip_enabled?: boolean
|
|
114
|
+
clip_axis?: `x` | `y` | `z`
|
|
115
|
+
clip_position?: number
|
|
116
|
+
clip_flip?: boolean
|
|
117
|
+
interpolation_factor?: number
|
|
118
|
+
camera_projection?: CameraProjection
|
|
119
|
+
/**
|
|
120
|
+
* Controls visibility configuration.
|
|
121
|
+
* - 'always': controls always visible
|
|
122
|
+
* - 'hover': controls visible on component hover (default)
|
|
123
|
+
* - 'never': controls never visible
|
|
124
|
+
* - object: { mode, hidden, style } for fine-grained control
|
|
125
|
+
*
|
|
126
|
+
* Control names: 'filename', 'fullscreen', 'controls'
|
|
127
|
+
*/
|
|
128
|
+
show_controls?: ShowControlsProp
|
|
129
|
+
fullscreen?: boolean
|
|
130
|
+
width?: number
|
|
131
|
+
height?: number
|
|
132
|
+
wrapper?: HTMLDivElement
|
|
133
|
+
hovered?: boolean
|
|
134
|
+
dragover?: boolean
|
|
135
|
+
allow_file_drop?: boolean
|
|
136
|
+
fullscreen_toggle?: Snippet<[{ fullscreen: boolean }]> | boolean
|
|
137
|
+
data_url?: string
|
|
138
|
+
spinner_props?: ComponentProps<typeof Spinner>
|
|
139
|
+
loading?: boolean
|
|
140
|
+
error_msg?: string
|
|
141
|
+
children?: Snippet<
|
|
142
|
+
[{ fermi_data?: FermiSurfaceData; bz_data?: BrillouinZoneData }]
|
|
143
|
+
>
|
|
144
|
+
on_file_drop?: (filename: string) => void
|
|
145
|
+
on_file_load?: (data: FermiFileLoadData) => void
|
|
146
|
+
on_error?: (data: FermiErrorData) => void
|
|
147
|
+
on_fullscreen_change?: (data: FermiHandlerData) => void
|
|
148
|
+
on_mu_change?: (mu: number) => void
|
|
149
|
+
tooltip_config?: Snippet<[{ hover_data: FermiHoverData }]> | FermiTooltipConfig
|
|
150
|
+
on_hover?: (data: FermiHoverData | null) => void
|
|
151
|
+
} & HTMLAttributes<HTMLDivElement> = $props()
|
|
152
|
+
|
|
153
|
+
let scene = $state<Scene | undefined>(undefined)
|
|
154
|
+
let camera = $state<Camera | undefined>(undefined)
|
|
155
|
+
let current_filename = $state<string | undefined>(undefined)
|
|
156
|
+
let recompute_job_id = 0 // monotonic counter to track latest recompute call
|
|
157
|
+
let hover_data = $state<FermiHoverData | null>(null)
|
|
158
|
+
|
|
159
|
+
// Call on_hover callback when hover_data changes
|
|
160
|
+
$effect(() => {
|
|
161
|
+
on_hover?.(hover_data)
|
|
162
|
+
})
|
|
163
|
+
|
|
164
|
+
let controls_config = $derived(normalize_show_controls(show_controls))
|
|
165
|
+
|
|
166
|
+
// Yield to browser so spinner can render before heavy computation
|
|
167
|
+
const tick = () =>
|
|
168
|
+
new Promise<void>((r) =>
|
|
169
|
+
requestAnimationFrame(() => requestAnimationFrame(() => r()))
|
|
170
|
+
)
|
|
171
|
+
|
|
172
|
+
// Parse and load Fermi surface from content (async for UI responsiveness)
|
|
173
|
+
async function parse_fermi_content(
|
|
174
|
+
content: string | ArrayBuffer,
|
|
175
|
+
filename: string,
|
|
176
|
+
) {
|
|
38
177
|
const text = content instanceof ArrayBuffer
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
178
|
+
? new TextDecoder().decode(content)
|
|
179
|
+
: content
|
|
180
|
+
|
|
181
|
+
const parsed = parse_fermi_file(text, filename)
|
|
182
|
+
if (!parsed) throw new Error(`Failed to parse Fermi surface from ${filename}`)
|
|
183
|
+
|
|
184
|
+
const file_size = new Blob([content]).size
|
|
185
|
+
current_filename = filename
|
|
186
|
+
|
|
46
187
|
// Check if it's already FermiSurfaceData or BandGridData
|
|
47
188
|
if (`isosurfaces` in parsed) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
fermi_data = extract_fermi_surface(band_data, { mu, wigner_seitz: true });
|
|
189
|
+
fermi_data = parsed as FermiSurfaceData
|
|
190
|
+
band_data = undefined
|
|
191
|
+
} else {
|
|
192
|
+
band_data = parsed as BandGridData
|
|
193
|
+
fermi_data = extract_fermi_surface(band_data, { mu, wigner_seitz: true })
|
|
54
194
|
}
|
|
55
|
-
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
195
|
+
|
|
196
|
+
on_file_load?.({ fermi_data, band_data, filename, file_size })
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Load with error handling
|
|
200
|
+
async function safe_parse(content: string | ArrayBuffer, filename: string) {
|
|
59
201
|
try {
|
|
60
|
-
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
202
|
+
await parse_fermi_content(content, filename)
|
|
203
|
+
} catch (err) {
|
|
204
|
+
error_msg = `Failed to parse ${filename}: ${
|
|
205
|
+
err instanceof Error ? err.message : err
|
|
206
|
+
}`
|
|
207
|
+
on_error?.({ error_msg, filename })
|
|
65
208
|
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
const job_id = ++recompute_job_id
|
|
72
|
-
await tick()
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
// Re-extract Fermi surface from band data with current settings
|
|
212
|
+
async function recompute_fermi_surface() {
|
|
213
|
+
if (!band_data) return
|
|
214
|
+
const job_id = ++recompute_job_id // capture this job's ID
|
|
215
|
+
await tick() // yield to check for newer jobs before committing to work
|
|
73
216
|
// Check if this job is still the latest before proceeding
|
|
74
217
|
// If stale, return without setting loading - the superseding job handles it
|
|
75
|
-
if (job_id !== recompute_job_id)
|
|
76
|
-
return;
|
|
218
|
+
if (job_id !== recompute_job_id) return
|
|
77
219
|
// Only set loading after stale check to avoid orphaned loading states
|
|
78
|
-
loading = true
|
|
220
|
+
loading = true
|
|
79
221
|
try {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
222
|
+
const result = extract_fermi_surface(band_data, {
|
|
223
|
+
mu,
|
|
224
|
+
wigner_seitz: true,
|
|
225
|
+
interpolation_factor,
|
|
226
|
+
})
|
|
227
|
+
// Only update state if this is still the latest job
|
|
228
|
+
if (job_id === recompute_job_id) {
|
|
229
|
+
fermi_data = result
|
|
230
|
+
}
|
|
231
|
+
} catch (err) {
|
|
232
|
+
console.error(`Failed to re-extract Fermi surface:`, err)
|
|
233
|
+
} finally {
|
|
234
|
+
// Only clear loading if this is still the latest job
|
|
235
|
+
if (job_id === recompute_job_id) loading = false
|
|
92
236
|
}
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
async function handle_export(format) {
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Debounce recompute to avoid excessive re-computation during rapid slider drags
|
|
240
|
+
let recompute_timeout: ReturnType<typeof setTimeout>
|
|
241
|
+
|
|
242
|
+
function handle_mu_change(new_mu: number) {
|
|
243
|
+
mu = new_mu
|
|
244
|
+
clearTimeout(recompute_timeout)
|
|
245
|
+
recompute_timeout = setTimeout(() => void recompute_fermi_surface(), 150)
|
|
246
|
+
on_mu_change?.(new_mu)
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function handle_interpolation_change(new_factor: number) {
|
|
250
|
+
interpolation_factor = new_factor
|
|
251
|
+
clearTimeout(recompute_timeout)
|
|
252
|
+
recompute_timeout = setTimeout(() => void recompute_fermi_surface(), 150)
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Export Fermi surface to various formats
|
|
256
|
+
async function handle_export(format: `stl` | `obj` | `gltf`) {
|
|
114
257
|
if (!scene) {
|
|
115
|
-
|
|
116
|
-
|
|
258
|
+
console.error(`No scene available for export`)
|
|
259
|
+
return
|
|
117
260
|
}
|
|
118
261
|
try {
|
|
119
|
-
|
|
120
|
-
|
|
262
|
+
const { export_scene } = await import(`./export`)
|
|
263
|
+
await export_scene(scene, format, current_filename || `fermi-surface`)
|
|
264
|
+
} catch (err) {
|
|
265
|
+
console.error(`Export failed:`, err)
|
|
266
|
+
error_msg = `Export failed: ${err instanceof Error ? err.message : err}`
|
|
121
267
|
}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
127
|
-
// Compute BZ when structure or fermi_data changes
|
|
128
|
-
$effect(() => {
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
// Compute BZ when structure or fermi_data changes
|
|
271
|
+
$effect(() => {
|
|
129
272
|
// Get k_lattice from available sources (priority order)
|
|
130
273
|
const k_lattice = fermi_data?.k_lattice ??
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
274
|
+
band_data?.k_lattice ??
|
|
275
|
+
(structure?.lattice?.matrix
|
|
276
|
+
? reciprocal_lattice(structure.lattice.matrix)
|
|
277
|
+
: null)
|
|
278
|
+
|
|
135
279
|
if (!k_lattice) {
|
|
136
|
-
|
|
137
|
-
|
|
280
|
+
bz_data = undefined
|
|
281
|
+
return
|
|
138
282
|
}
|
|
283
|
+
|
|
139
284
|
try {
|
|
140
|
-
|
|
285
|
+
bz_data = compute_brillouin_zone(k_lattice, 1)
|
|
286
|
+
} catch (err) {
|
|
287
|
+
const msg = err instanceof Error ? err.message : String(err)
|
|
288
|
+
console.warn(`BZ computation failed:`, msg)
|
|
289
|
+
bz_data = undefined
|
|
290
|
+
// Only report error for structure-derived lattice (user-provided data)
|
|
291
|
+
if (structure?.lattice?.matrix) {
|
|
292
|
+
const err_msg = `BZ computation failed: ${msg}`
|
|
293
|
+
error_msg = err_msg
|
|
294
|
+
untrack(() => on_error?.({ error_msg: err_msg }))
|
|
295
|
+
}
|
|
141
296
|
}
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
// Only report error for structure-derived lattice (user-provided data)
|
|
147
|
-
if (structure?.lattice?.matrix) {
|
|
148
|
-
const err_msg = `BZ computation failed: ${msg}`;
|
|
149
|
-
error_msg = err_msg;
|
|
150
|
-
untrack(() => on_error?.({ error_msg: err_msg }));
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
});
|
|
154
|
-
// Auto-enable BZ tiling when irreducible data is detected
|
|
155
|
-
$effect(() => {
|
|
297
|
+
})
|
|
298
|
+
|
|
299
|
+
// Auto-enable BZ tiling when irreducible data is detected
|
|
300
|
+
$effect(() => {
|
|
156
301
|
if (fermi_data && detect_irreducible_bz(fermi_data)) {
|
|
157
|
-
|
|
302
|
+
tile_bz = true
|
|
158
303
|
}
|
|
159
|
-
})
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
304
|
+
})
|
|
305
|
+
|
|
306
|
+
// Load from URL (with race condition protection for rapid URL changes)
|
|
307
|
+
let load_id = 0
|
|
308
|
+
$effect(() => {
|
|
163
309
|
if (data_url && !fermi_data && !band_data) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
310
|
+
const current_load_id = ++load_id
|
|
311
|
+
loading = true
|
|
312
|
+
error_msg = undefined
|
|
313
|
+
load_from_url(data_url, safe_parse)
|
|
314
|
+
.catch((err) => {
|
|
315
|
+
if (current_load_id !== load_id) return // stale request
|
|
316
|
+
error_msg = err instanceof Error ? err.message : String(err)
|
|
317
|
+
on_error?.({ error_msg, filename: data_url })
|
|
318
|
+
})
|
|
319
|
+
.finally(() => {
|
|
320
|
+
if (current_load_id === load_id) loading = false
|
|
173
321
|
})
|
|
174
|
-
.finally(() => {
|
|
175
|
-
if (current_load_id === load_id)
|
|
176
|
-
loading = false;
|
|
177
|
-
});
|
|
178
322
|
}
|
|
179
|
-
})
|
|
180
|
-
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
const handle_file_drop = create_file_drop_handler({
|
|
181
326
|
allow: () => allow_file_drop,
|
|
182
327
|
on_drop: async (content, filename) => {
|
|
183
|
-
|
|
184
|
-
|
|
328
|
+
on_file_drop?.(filename)
|
|
329
|
+
await safe_parse(content, filename)
|
|
185
330
|
},
|
|
186
331
|
on_error: (msg) => {
|
|
187
|
-
|
|
188
|
-
|
|
332
|
+
error_msg = msg
|
|
333
|
+
on_error?.({ error_msg: msg })
|
|
189
334
|
},
|
|
190
335
|
set_loading: (val) => {
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
[error_msg, dragover] = [undefined, false];
|
|
336
|
+
loading = val
|
|
337
|
+
if (val) [error_msg, dragover] = [undefined, false]
|
|
194
338
|
},
|
|
195
|
-
})
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
function handle_keydown(event: KeyboardEvent) {
|
|
342
|
+
const target = event.target as HTMLElement
|
|
343
|
+
if ([`INPUT`, `TEXTAREA`].includes(target.tagName)) return
|
|
200
344
|
// Only handle shortcuts when component is focused/hovered or contains focus
|
|
201
|
-
if (!wrapper?.contains(document.activeElement) && !hovered)
|
|
202
|
-
|
|
203
|
-
if (event.key === `f` && fullscreen_toggle)
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
return;
|
|
211
|
-
const fs_el = document.fullscreenElement;
|
|
345
|
+
if (!wrapper?.contains(document.activeElement) && !hovered) return
|
|
346
|
+
|
|
347
|
+
if (event.key === `f` && fullscreen_toggle) toggle_fullscreen(wrapper)
|
|
348
|
+
else if (event.key === `Escape`) controls_open = false
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
$effect(() => {
|
|
352
|
+
if (typeof window === `undefined`) return
|
|
353
|
+
const fs_el = document.fullscreenElement
|
|
212
354
|
if (fullscreen && fs_el !== wrapper && wrapper) {
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
set_fullscreen_bg(wrapper, fullscreen, `--fermi-bg-fullscreen`);
|
|
221
|
-
});
|
|
355
|
+
wrapper.requestFullscreen().catch((err) => {
|
|
356
|
+
console.error(err)
|
|
357
|
+
fullscreen = false
|
|
358
|
+
})
|
|
359
|
+
} else if (!fullscreen && fs_el === wrapper) document.exitFullscreen()
|
|
360
|
+
set_fullscreen_bg(wrapper, fullscreen, `--fermi-bg-fullscreen`)
|
|
361
|
+
})
|
|
222
362
|
</script>
|
|
223
363
|
|
|
224
364
|
<svelte:window onkeydown={handle_keydown} />
|
|
@@ -427,7 +567,8 @@ $effect(() => {
|
|
|
427
567
|
pointer-events: auto;
|
|
428
568
|
}
|
|
429
569
|
/* Mode: hover - controls visible on component hover */
|
|
430
|
-
.fermi-surface:hover section.control-buttons.hover-visible
|
|
570
|
+
.fermi-surface:hover section.control-buttons.hover-visible,
|
|
571
|
+
.fermi-surface:focus-within section.control-buttons.hover-visible {
|
|
431
572
|
opacity: 1;
|
|
432
573
|
pointer-events: auto;
|
|
433
574
|
}
|
|
@@ -78,6 +78,6 @@ type $$ComponentProps = {
|
|
|
78
78
|
}]> | FermiTooltipConfig;
|
|
79
79
|
on_hover?: (data: FermiHoverData | null) => void;
|
|
80
80
|
} & HTMLAttributes<HTMLDivElement>;
|
|
81
|
-
declare const FermiSurface: import("svelte").Component<$$ComponentProps, {}, "height" | "width" | "dragover" | "
|
|
81
|
+
declare const FermiSurface: import("svelte").Component<$$ComponentProps, {}, "height" | "width" | "dragover" | "fullscreen" | "hovered" | "controls_open" | "loading" | "camera_projection" | "color_scale" | "wrapper" | "error_msg" | "surface_opacity" | "show_vectors" | "bz_data" | "mu" | "selected_bands" | "interpolation_factor" | "fermi_data" | "band_data" | "color_property" | "representation" | "show_bz" | "bz_opacity" | "tile_bz" | "clip_enabled" | "clip_axis" | "clip_position" | "clip_flip">;
|
|
82
82
|
type FermiSurface = ReturnType<typeof FermiSurface>;
|
|
83
83
|
export default FermiSurface;
|