matterviz 0.3.2 → 0.3.4
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/element/data.js +1 -1
- 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,62 +1,103 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Vec2 } from '../math'
|
|
3
|
+
import type { AxisConfig } from '../plot/types'
|
|
4
|
+
import type { ComponentProps, Snippet } from 'svelte'
|
|
5
|
+
import { untrack } from 'svelte'
|
|
6
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
7
|
+
import Bands from './Bands.svelte'
|
|
8
|
+
import Dos from './Dos.svelte'
|
|
9
|
+
import {
|
|
10
|
+
compute_frequency_range,
|
|
11
|
+
detect_zoom_change,
|
|
12
|
+
extract_efermi,
|
|
13
|
+
is_valid_range,
|
|
14
|
+
ranges_equal,
|
|
15
|
+
} from './helpers'
|
|
16
|
+
import type { BaseBandStructure, DosInput, HoveredData } from './types'
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
band_structs,
|
|
20
|
+
doses,
|
|
21
|
+
bands_props = {},
|
|
22
|
+
dos_props = {},
|
|
23
|
+
shared_y_axis = true,
|
|
24
|
+
sync_y_zoom = true,
|
|
25
|
+
children,
|
|
26
|
+
...rest
|
|
27
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
28
|
+
band_structs: BaseBandStructure | Record<string, BaseBandStructure>
|
|
29
|
+
doses: DosInput | Record<string, DosInput>
|
|
30
|
+
bands_props?: Partial<ComponentProps<typeof Bands>>
|
|
31
|
+
dos_props?: Partial<ComponentProps<typeof Dos>>
|
|
32
|
+
shared_y_axis?: boolean
|
|
33
|
+
sync_y_zoom?: boolean
|
|
34
|
+
class?: string
|
|
35
|
+
children?: Snippet<[HoveredData]>
|
|
36
|
+
} = $props()
|
|
37
|
+
|
|
38
|
+
let shared_frequency_range = $derived(
|
|
39
|
+
shared_y_axis ? compute_frequency_range(band_structs, doses) : undefined,
|
|
40
|
+
)
|
|
41
|
+
let fermi_level = $derived(extract_efermi(band_structs) ?? extract_efermi(doses))
|
|
42
|
+
|
|
43
|
+
// Synced zoom state (null = use auto-computed range)
|
|
44
|
+
let synced_zoom_range = $state<Vec2 | null>(null)
|
|
45
|
+
let bands_y_axis = $state<AxisConfig>({})
|
|
46
|
+
let dos_y_axis = $state<AxisConfig>({ label: `` })
|
|
47
|
+
|
|
48
|
+
// Detect zoom changes and sync between components (runs first to capture child updates)
|
|
49
|
+
$effect(() => {
|
|
50
|
+
if (!sync_y_zoom || !shared_frequency_range) return
|
|
51
|
+
const result = detect_zoom_change(
|
|
52
|
+
bands_y_axis.range,
|
|
53
|
+
dos_y_axis.range,
|
|
54
|
+
shared_frequency_range,
|
|
55
|
+
untrack(() => synced_zoom_range),
|
|
56
|
+
)
|
|
57
|
+
if (result !== undefined) synced_zoom_range = result
|
|
58
|
+
})
|
|
59
|
+
|
|
60
|
+
// Propagate synced range to bands y-axis (untrack current to avoid overwriting child zoom)
|
|
61
|
+
$effect(() => {
|
|
62
|
+
const base_range = synced_zoom_range ?? shared_frequency_range
|
|
63
|
+
const current_range = untrack(() => bands_y_axis.range) as Vec2 | undefined
|
|
24
64
|
// Skip if current range already matches base, or is valid but differs (child zoom in progress)
|
|
25
|
-
if (ranges_equal(current_range, base_range))
|
|
26
|
-
return;
|
|
65
|
+
if (ranges_equal(current_range, base_range)) return
|
|
27
66
|
if (is_valid_range(current_range) && !ranges_equal(current_range, base_range)) {
|
|
28
|
-
|
|
67
|
+
return
|
|
29
68
|
}
|
|
30
69
|
// Only include range if it's valid (don't override child's auto-range with undefined)
|
|
31
70
|
bands_y_axis = shared_y_axis
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
const
|
|
71
|
+
? {
|
|
72
|
+
...(bands_props.y_axis ?? {}),
|
|
73
|
+
...(is_valid_range(base_range) && { range: base_range }),
|
|
74
|
+
}
|
|
75
|
+
: { ...(bands_props.y_axis ?? {}) }
|
|
76
|
+
})
|
|
77
|
+
|
|
78
|
+
// Propagate synced range to DOS y-axis (untrack current to avoid overwriting child zoom)
|
|
79
|
+
$effect(() => {
|
|
80
|
+
const base_range = synced_zoom_range ?? shared_frequency_range
|
|
81
|
+
const current_range = untrack(() => dos_y_axis.range) as Vec2 | undefined
|
|
42
82
|
// Skip if current range already matches base, or is valid but differs (child zoom in progress)
|
|
43
|
-
if (ranges_equal(current_range, base_range))
|
|
44
|
-
return;
|
|
83
|
+
if (ranges_equal(current_range, base_range)) return
|
|
45
84
|
if (is_valid_range(current_range) && !ranges_equal(current_range, base_range)) {
|
|
46
|
-
|
|
85
|
+
return
|
|
47
86
|
}
|
|
48
87
|
// Only include range if it's valid (don't override child's auto-range with undefined)
|
|
49
88
|
dos_y_axis = shared_y_axis
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
89
|
+
? {
|
|
90
|
+
label: ``,
|
|
91
|
+
...(dos_props.y_axis ?? {}),
|
|
92
|
+
...(is_valid_range(base_range) && { range: base_range }),
|
|
93
|
+
}
|
|
94
|
+
: { label: ``, ...(dos_props.y_axis ?? {}) }
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
let hovered_frequency = $state<number | null>(null)
|
|
98
|
+
|
|
99
|
+
// Ensure both plots use identical top/bottom padding for aligned y_scale_fn
|
|
100
|
+
const shared_tb_padding = { t: 20, b: 50 }
|
|
60
101
|
</script>
|
|
61
102
|
|
|
62
103
|
<div
|
|
@@ -1,104 +1,162 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
let
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { BrillouinZone, reciprocal_lattice } from '../brillouin'
|
|
3
|
+
import type { Vec2, Vec3 } from '../math'
|
|
4
|
+
import type { InternalPoint } from '../plot'
|
|
5
|
+
import type { AxisConfig } from '../plot/types'
|
|
6
|
+
import type { Crystal } from '../structure'
|
|
7
|
+
import type { ComponentProps, Snippet } from 'svelte'
|
|
8
|
+
import { untrack } from 'svelte'
|
|
9
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
10
|
+
import Bands from './Bands.svelte'
|
|
11
|
+
import Dos from './Dos.svelte'
|
|
12
|
+
import * as helpers from './helpers'
|
|
13
|
+
import type { BaseBandStructure, DosData, HoveredData } from './types'
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
structure,
|
|
17
|
+
band_structs,
|
|
18
|
+
doses,
|
|
19
|
+
bands_props = {},
|
|
20
|
+
dos_props = {},
|
|
21
|
+
bz_props = {},
|
|
22
|
+
sync_y_zoom = true,
|
|
23
|
+
children,
|
|
24
|
+
...rest
|
|
25
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
26
|
+
structure: Crystal
|
|
27
|
+
band_structs: BaseBandStructure | Record<string, BaseBandStructure>
|
|
28
|
+
doses: DosData | Record<string, DosData>
|
|
29
|
+
bands_props?: Partial<ComponentProps<typeof Bands>>
|
|
30
|
+
dos_props?: Partial<ComponentProps<typeof Dos>>
|
|
31
|
+
bz_props?: Partial<ComponentProps<typeof BrillouinZone>>
|
|
32
|
+
sync_y_zoom?: boolean // Sync frequency/energy axis zoom between plots (default: true)
|
|
33
|
+
children?: Snippet<[HoveredData]>
|
|
34
|
+
} = $props()
|
|
35
|
+
|
|
36
|
+
// Get the first normalized band structure for path calculations
|
|
37
|
+
// Support both qpoints (phonon) and kpoints (electronic) to detect single vs dict
|
|
38
|
+
let first_band_struct = $derived(
|
|
39
|
+
helpers.normalize_band_structure(
|
|
40
|
+
`qpoints` in (band_structs as object) || `kpoints` in (band_structs as object)
|
|
18
41
|
? band_structs
|
|
19
|
-
: Object.values(band_structs)[0]
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
42
|
+
: Object.values(band_structs)[0],
|
|
43
|
+
),
|
|
44
|
+
) as BaseBandStructure | null
|
|
45
|
+
|
|
46
|
+
// Compute shared frequency/energy range from both bands and DOS data
|
|
47
|
+
let shared_frequency_range = $derived(
|
|
48
|
+
helpers.compute_frequency_range(band_structs, doses),
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
// Extract Fermi level from electronic band structure or DOS data
|
|
52
|
+
let fermi_level = $derived.by((): number | undefined => {
|
|
53
|
+
// Check band structures for efermi
|
|
54
|
+
const bs_source = `efermi` in (band_structs as object)
|
|
55
|
+
? band_structs
|
|
56
|
+
: Object.values(band_structs)[0]
|
|
57
|
+
const bs_efermi = (bs_source as Record<string, unknown>)?.efermi
|
|
58
|
+
if (typeof bs_efermi === `number`) return bs_efermi
|
|
59
|
+
|
|
23
60
|
// Check DOS for efermi
|
|
24
|
-
const dos_source = `efermi` in doses ? doses : Object.values(doses)[0]
|
|
25
|
-
const dos_efermi = dos_source?.efermi
|
|
26
|
-
return typeof dos_efermi === `number` ? dos_efermi : undefined
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
let
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
let
|
|
57
|
-
let
|
|
58
|
-
|
|
59
|
-
$
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
61
|
+
const dos_source = `efermi` in (doses as object) ? doses : Object.values(doses)[0]
|
|
62
|
+
const dos_efermi = (dos_source as Record<string, unknown>)?.efermi
|
|
63
|
+
return typeof dos_efermi === `number` ? dos_efermi : undefined
|
|
64
|
+
})
|
|
65
|
+
|
|
66
|
+
// Convert fractional k-point coordinates to Cartesian reciprocal space
|
|
67
|
+
// using the structure's reciprocal lattice (consistent with BZ computation)
|
|
68
|
+
let k_path_points = $derived.by(() => {
|
|
69
|
+
if (!first_band_struct?.qpoints || !structure?.lattice?.matrix) return []
|
|
70
|
+
|
|
71
|
+
const k_lattice = reciprocal_lattice(structure.lattice.matrix)
|
|
72
|
+
return helpers.extract_k_path_points(first_band_struct, k_lattice)
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
let hovered_band_point = $state<InternalPoint | null>(null)
|
|
76
|
+
let bands_x_positions = $state<Record<string, [number, number]>>({})
|
|
77
|
+
let hovered_qpoint_index = $derived(
|
|
78
|
+
hovered_band_point && first_band_struct &&
|
|
79
|
+
Object.keys(bands_x_positions).length > 0
|
|
80
|
+
? helpers.find_qpoint_at_rescaled_x(
|
|
81
|
+
first_band_struct,
|
|
82
|
+
hovered_band_point.x,
|
|
83
|
+
bands_x_positions,
|
|
84
|
+
)
|
|
85
|
+
: null,
|
|
86
|
+
)
|
|
87
|
+
let hovered_k_point = $derived(
|
|
88
|
+
hovered_qpoint_index !== null
|
|
89
|
+
? (k_path_points[hovered_qpoint_index] as Vec3)
|
|
90
|
+
: null,
|
|
91
|
+
)
|
|
92
|
+
const [desktop_width, tablet_width] = [1200, 600]
|
|
93
|
+
let clientWidth = $state(desktop_width)
|
|
94
|
+
let is_desktop = $derived(clientWidth >= desktop_width)
|
|
95
|
+
let is_mobile = $derived(clientWidth < tablet_width)
|
|
96
|
+
let screen_class = $derived(
|
|
97
|
+
clientWidth >= desktop_width
|
|
98
|
+
? `desktop`
|
|
99
|
+
: clientWidth >= tablet_width
|
|
100
|
+
? `tablet`
|
|
101
|
+
: `phone`,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
// Synced zoom state (null = use auto-computed range)
|
|
105
|
+
let synced_zoom_range = $state<Vec2 | null>(null)
|
|
106
|
+
let bands_y_axis = $state<AxisConfig>({})
|
|
107
|
+
let dos_y_axis = $state<AxisConfig>({})
|
|
108
|
+
|
|
109
|
+
// Detect zoom changes and sync between components (runs first to capture child updates)
|
|
110
|
+
$effect(() => {
|
|
111
|
+
if (!sync_y_zoom || !shared_frequency_range) return
|
|
112
|
+
const result = helpers.detect_zoom_change(
|
|
113
|
+
bands_y_axis.range,
|
|
114
|
+
dos_y_axis.range,
|
|
115
|
+
shared_frequency_range,
|
|
116
|
+
untrack(() => synced_zoom_range),
|
|
117
|
+
is_desktop, // DOS sync only enabled on desktop
|
|
118
|
+
)
|
|
119
|
+
if (result !== undefined) synced_zoom_range = result
|
|
120
|
+
})
|
|
121
|
+
|
|
122
|
+
// Propagate synced range to bands y-axis (untrack current to avoid overwriting child zoom)
|
|
123
|
+
$effect(() => {
|
|
124
|
+
const base_range = synced_zoom_range ?? shared_frequency_range
|
|
125
|
+
const current_range = untrack(() => bands_y_axis.range) as Vec2 | undefined
|
|
70
126
|
// Skip if current range already matches base, or is valid but differs (child zoom in progress)
|
|
71
|
-
if (helpers.ranges_equal(current_range, base_range))
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
127
|
+
if (helpers.ranges_equal(current_range, base_range)) return
|
|
128
|
+
if (
|
|
129
|
+
helpers.is_valid_range(current_range) &&
|
|
130
|
+
!helpers.ranges_equal(current_range, base_range)
|
|
131
|
+
) return
|
|
76
132
|
// Only include range if it's valid (don't override child's auto-range with undefined)
|
|
77
133
|
bands_y_axis = {
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
}
|
|
81
|
-
})
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
const
|
|
134
|
+
...(bands_props.y_axis ?? {}),
|
|
135
|
+
...(helpers.is_valid_range(base_range) && { range: base_range }),
|
|
136
|
+
}
|
|
137
|
+
})
|
|
138
|
+
|
|
139
|
+
// Propagate synced range to DOS y-axis (untrack current to avoid overwriting child zoom)
|
|
140
|
+
$effect(() => {
|
|
141
|
+
const base_range = synced_zoom_range ?? shared_frequency_range
|
|
142
|
+
const current_range = untrack(() => dos_y_axis.range) as Vec2 | undefined
|
|
86
143
|
// Skip if current range already matches base, or is valid but differs (child zoom in progress)
|
|
87
|
-
if (helpers.ranges_equal(current_range, base_range))
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
144
|
+
if (helpers.ranges_equal(current_range, base_range)) return
|
|
145
|
+
if (
|
|
146
|
+
helpers.is_valid_range(current_range) &&
|
|
147
|
+
!helpers.ranges_equal(current_range, base_range)
|
|
148
|
+
) return
|
|
92
149
|
// Only include range if it's valid (don't override child's auto-range with undefined)
|
|
93
150
|
dos_y_axis = is_desktop
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
})
|
|
101
|
-
|
|
151
|
+
? {
|
|
152
|
+
label: ``,
|
|
153
|
+
...(dos_props.y_axis ?? {}),
|
|
154
|
+
...(helpers.is_valid_range(base_range) && { range: base_range }),
|
|
155
|
+
}
|
|
156
|
+
: { ...(dos_props.y_axis ?? {}) }
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
let hovered_frequency = $state<number | null>(null)
|
|
102
160
|
</script>
|
|
103
161
|
|
|
104
162
|
<div
|