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,152 +1,233 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { contrast_color, default_element_colors } from '../colors'
|
|
3
|
+
import type { CompositionType } from '../composition'
|
|
4
|
+
import type { ElementSymbol } from '../element'
|
|
5
|
+
import { element_data } from '../element'
|
|
6
|
+
import Icon from '../Icon.svelte'
|
|
7
|
+
import { ELEM_SYMBOLS, format_num } from '../labels'
|
|
8
|
+
import { ColorBar } from '../plot'
|
|
9
|
+
import { SETTINGS_CONFIG } from '../settings'
|
|
10
|
+
import { colors } from '../state.svelte'
|
|
11
|
+
import type { AnyStructure } from './'
|
|
12
|
+
import { atomic_radii } from './'
|
|
13
|
+
import type {
|
|
14
|
+
AtomColorConfig,
|
|
15
|
+
AtomPropertyColors,
|
|
16
|
+
} from './atom-properties'
|
|
17
|
+
import type { MoyoDataset } from '@spglib/moyo-wasm'
|
|
18
|
+
import type { Snippet } from 'svelte'
|
|
19
|
+
import { click_outside, tooltip } from 'svelte-multiselect/attachments'
|
|
20
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
21
|
+
import { SvelteMap, SvelteSet } from 'svelte/reactivity'
|
|
22
|
+
|
|
23
|
+
let {
|
|
24
|
+
atom_color_config = $bindable({
|
|
25
|
+
mode: `element`,
|
|
26
|
+
scale: undefined,
|
|
27
|
+
scale_type: `continuous`,
|
|
28
|
+
}),
|
|
29
|
+
property_colors = null,
|
|
30
|
+
elements,
|
|
31
|
+
elem_color_picker_title = `Double click to reset color`,
|
|
32
|
+
labels = $bindable([]),
|
|
33
|
+
amount_format = `.3~f`,
|
|
34
|
+
show_amounts = true,
|
|
35
|
+
get_element_label,
|
|
36
|
+
hidden_elements = $bindable(new SvelteSet()),
|
|
37
|
+
hidden_prop_vals = $bindable(new SvelteSet<number | string>()),
|
|
38
|
+
// Element remapping: maps original element symbols to new ones
|
|
39
|
+
element_mapping = $bindable(),
|
|
40
|
+
// Per-element and per-site radius overrides
|
|
41
|
+
element_radius_overrides = $bindable<Partial<Record<ElementSymbol, number>>>({}),
|
|
42
|
+
site_radius_overrides = $bindable<SvelteMap<number, number>>(new SvelteMap()),
|
|
43
|
+
selected_sites = [] as number[],
|
|
44
|
+
title = ``,
|
|
45
|
+
sym_data = null,
|
|
46
|
+
structure = undefined,
|
|
47
|
+
children,
|
|
48
|
+
...rest
|
|
49
|
+
}: Omit<HTMLAttributes<HTMLDivElement>, `children`> & {
|
|
50
|
+
atom_color_config?: Partial<AtomColorConfig>
|
|
51
|
+
property_colors?: AtomPropertyColors | null
|
|
52
|
+
elements?: CompositionType
|
|
53
|
+
elem_color_picker_title?: string
|
|
54
|
+
labels?: HTMLLabelElement[]
|
|
55
|
+
amount_format?: string // Float formatting for element amounts (default: 3 significant digits)
|
|
56
|
+
show_amounts?: boolean // Whether to show element amounts
|
|
57
|
+
get_element_label?: (element: string, amount: number) => string // Custom label function
|
|
58
|
+
hidden_elements?: Set<ElementSymbol>
|
|
59
|
+
hidden_prop_vals?: Set<number | string> // Track hidden property values (e.g. Wyckoff positions, coordination numbers)
|
|
60
|
+
// Element remapping: maps original element symbols to new ones (e.g. {'H': 'Na', 'He': 'Cl'})
|
|
61
|
+
element_mapping?: Partial<Record<ElementSymbol, ElementSymbol>>
|
|
62
|
+
// Per-element and per-site radius overrides (absolute values in Angstroms)
|
|
63
|
+
element_radius_overrides?: Partial<Record<ElementSymbol, number>>
|
|
64
|
+
site_radius_overrides?: Map<number, number> | SvelteMap<number, number>
|
|
65
|
+
selected_sites?: number[] // Currently selected site indices
|
|
66
|
+
title?: string
|
|
67
|
+
sym_data?: MoyoDataset | null
|
|
68
|
+
structure?: AnyStructure | null
|
|
69
|
+
children?: Snippet<[{ mode_menu_open: boolean; structure?: AnyStructure | null }]>
|
|
70
|
+
} = $props()
|
|
71
|
+
|
|
72
|
+
const titles = {
|
|
21
73
|
coordination: `Coordination`,
|
|
22
74
|
wyckoff: `Wyckoff Position`,
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
let
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
$
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
let show_element_legend = $derived(
|
|
78
|
+
atom_color_config.mode === `element` && elements &&
|
|
79
|
+
Object.keys(elements).length > 0,
|
|
80
|
+
)
|
|
81
|
+
let show_property_legend = $derived(
|
|
82
|
+
atom_color_config.mode !== `element` && property_colors?.colors.length,
|
|
83
|
+
)
|
|
84
|
+
let legend_title = $derived(
|
|
85
|
+
title || titles[atom_color_config.mode as keyof typeof titles] || ``,
|
|
86
|
+
)
|
|
87
|
+
|
|
88
|
+
// Dropdown state
|
|
89
|
+
let mode_menu_open = $state(false)
|
|
90
|
+
|
|
91
|
+
// Clear hidden property values when switching modes (since they may not be valid)
|
|
92
|
+
let previous_mode = $state(atom_color_config.mode)
|
|
93
|
+
$effect(() => {
|
|
33
94
|
if (atom_color_config.mode !== previous_mode) {
|
|
34
|
-
|
|
35
|
-
|
|
95
|
+
hidden_prop_vals.clear()
|
|
96
|
+
previous_mode = atom_color_config.mode
|
|
36
97
|
}
|
|
37
|
-
})
|
|
38
|
-
|
|
39
|
-
//
|
|
40
|
-
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// Normalize incoming Map to SvelteMap at boundary for reactivity
|
|
101
|
+
// This preserves identity for bindings while ensuring SvelteMap methods work
|
|
102
|
+
$effect(() => {
|
|
41
103
|
if (site_radius_overrides && !(site_radius_overrides instanceof SvelteMap)) {
|
|
42
|
-
|
|
104
|
+
site_radius_overrides = new SvelteMap(site_radius_overrides)
|
|
43
105
|
}
|
|
44
|
-
})
|
|
45
|
-
// Format display values based on mode
|
|
46
|
-
let format_value = (val) => {
|
|
47
|
-
if (typeof val === `number`)
|
|
48
|
-
|
|
106
|
+
})
|
|
107
|
+
// Format display values based on mode
|
|
108
|
+
let format_value = (val: number | string): string => {
|
|
109
|
+
if (typeof val === `number`) return format_num(val, `.3~f`)
|
|
110
|
+
|
|
49
111
|
if (typeof val === `string` && val.includes(`|`)) { // Format Wyckoff orbit IDs
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
112
|
+
const [wyckoff, element] = val.split(`|`, 2)
|
|
113
|
+
// Count how many sites have this wyckoff+element combination
|
|
114
|
+
const count = property_colors?.values.filter((v) => v === val).length ?? 0
|
|
115
|
+
return `${element}:${count}${wyckoff}`
|
|
54
116
|
}
|
|
55
|
-
return String(val)
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
117
|
+
return String(val)
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Map from property value to color (computed once, reused in categorical legend)
|
|
121
|
+
let color_map = $derived(
|
|
122
|
+
new Map(
|
|
123
|
+
// Use unique_values instead of values to avoid undefined colors from duplicates
|
|
124
|
+
property_colors?.unique_values?.flatMap((val) => {
|
|
125
|
+
const idx = property_colors.values.indexOf(val)
|
|
126
|
+
return idx >= 0 ? [[val, property_colors.colors[idx]]] : []
|
|
127
|
+
}) ?? [],
|
|
128
|
+
),
|
|
129
|
+
)
|
|
130
|
+
|
|
131
|
+
function toggle_visibility<T>(
|
|
132
|
+
set: Set<T>,
|
|
133
|
+
value: T,
|
|
134
|
+
event: MouseEvent,
|
|
135
|
+
): Set<T> {
|
|
136
|
+
event.preventDefault()
|
|
137
|
+
event.stopPropagation()
|
|
138
|
+
const new_set = new SvelteSet(set)
|
|
139
|
+
if (new_set.has(value)) new_set.delete(value)
|
|
140
|
+
else new_set.add(value)
|
|
141
|
+
return new_set
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
// Element remapping state
|
|
145
|
+
let remap_menu_open = $state<ElementSymbol | null>(null)
|
|
146
|
+
let remap_search = $state(``)
|
|
147
|
+
|
|
148
|
+
// Filtered elements based on search
|
|
149
|
+
let filtered_elements = $derived.by(() => {
|
|
150
|
+
if (!remap_search) return ELEM_SYMBOLS
|
|
151
|
+
const query = remap_search.toLowerCase()
|
|
82
152
|
return ELEM_SYMBOLS.filter((elem) => {
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
})
|
|
87
|
-
})
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const element_amounts = elements
|
|
153
|
+
const data = element_data?.find((el) => el.symbol === elem)
|
|
154
|
+
return elem.toLowerCase().includes(query) ||
|
|
155
|
+
data?.name?.toLowerCase().includes(query)
|
|
156
|
+
})
|
|
157
|
+
})
|
|
158
|
+
|
|
159
|
+
const known_element_symbols = new Set(ELEM_SYMBOLS)
|
|
160
|
+
let sorted_element_entries = $derived.by(() => {
|
|
161
|
+
if (!elements) return []
|
|
162
|
+
const element_amounts = elements as Record<string, number>
|
|
93
163
|
const ordered_known_entries = ELEM_SYMBOLS
|
|
94
|
-
|
|
95
|
-
const amount = element_amounts[element_symbol]
|
|
96
|
-
return amount === undefined ? [] : [[element_symbol, amount]]
|
|
97
|
-
|
|
164
|
+
.flatMap((element_symbol) => {
|
|
165
|
+
const amount = element_amounts[element_symbol]
|
|
166
|
+
return amount === undefined ? [] : [[element_symbol, amount] as const]
|
|
167
|
+
})
|
|
98
168
|
const unknown_entries = Object.entries(element_amounts)
|
|
99
|
-
|
|
100
|
-
.
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
169
|
+
.filter(([element_symbol]) =>
|
|
170
|
+
!known_element_symbols.has(element_symbol as ElementSymbol)
|
|
171
|
+
)
|
|
172
|
+
.sort(([element_a], [element_b]) => element_a.localeCompare(element_b))
|
|
173
|
+
return [...ordered_known_entries, ...unknown_entries]
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
function remap_element(from: ElementSymbol, to: ElementSymbol) {
|
|
104
177
|
if (from === to && element_mapping?.[from]) {
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
178
|
+
// Remove mapping if mapping back to original element
|
|
179
|
+
const { [from]: _, ...rest } = element_mapping
|
|
180
|
+
element_mapping = Object.keys(rest).length > 0 ? rest : undefined
|
|
181
|
+
} else if (from !== to) {
|
|
182
|
+
element_mapping = { ...element_mapping, [from]: to }
|
|
108
183
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
const
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
function update_element_radius(elem, value) {
|
|
123
|
-
const radius = parse_radius(value)
|
|
184
|
+
remap_menu_open = null
|
|
185
|
+
remap_search = ``
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
// Radius bounds (Angstroms) - max accommodates largest atomic radii (~2.6Å for Cs)
|
|
189
|
+
const MIN_RADIUS = 0.1
|
|
190
|
+
const MAX_RADIUS = 5
|
|
191
|
+
|
|
192
|
+
const parse_radius = (value: string): number | null => {
|
|
193
|
+
const num = parseFloat(value)
|
|
194
|
+
return !isNaN(num) && num >= MIN_RADIUS && num <= MAX_RADIUS ? num : null
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
function update_element_radius(elem: ElementSymbol, value: string) {
|
|
198
|
+
const radius = parse_radius(value)
|
|
124
199
|
if (radius !== null) {
|
|
125
|
-
|
|
200
|
+
element_radius_overrides = { ...element_radius_overrides, [elem]: radius }
|
|
126
201
|
}
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
site_radius_overrides?.
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
function clear_element_radius(elem: ElementSymbol) {
|
|
205
|
+
const { [elem]: _, ...rest } = element_radius_overrides ?? {}
|
|
206
|
+
element_radius_overrides = rest
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
const get_element_radius = (elem: ElementSymbol): number =>
|
|
210
|
+
element_radius_overrides?.[elem] ?? atomic_radii[elem] ?? 1
|
|
211
|
+
|
|
212
|
+
// Mutate in-place to preserve map identity for bindings (aligns with Structure.svelte pattern)
|
|
213
|
+
function update_site_radius(site_idx: number, value: string) {
|
|
214
|
+
const radius = parse_radius(value)
|
|
215
|
+
if (radius === null) return
|
|
216
|
+
site_radius_overrides?.set(site_idx, radius)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function clear_site_radius(site_idx: number) {
|
|
220
|
+
site_radius_overrides?.delete(site_idx)
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
const get_site_radius = (site_idx: number): number => {
|
|
224
|
+
const override = site_radius_overrides?.get(site_idx)
|
|
225
|
+
if (override !== undefined) return override
|
|
226
|
+
const element = structure?.sites?.[site_idx]?.species[0]?.element as
|
|
227
|
+
| ElementSymbol
|
|
228
|
+
| undefined
|
|
229
|
+
return element ? get_element_radius(element) : 1
|
|
230
|
+
}
|
|
150
231
|
</script>
|
|
151
232
|
|
|
152
233
|
{#snippet mode_selector_snippet()}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
let
|
|
8
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { BondGroupWithGradients } from './'
|
|
3
|
+
import { T } from '@threlte/core'
|
|
4
|
+
import type { InstancedMesh } from 'three'
|
|
5
|
+
import { Color, InstancedBufferAttribute, Matrix4, ShaderMaterial } from 'three'
|
|
6
|
+
|
|
7
|
+
let { group, saturation = 0.5, brightness = 0.7 }: {
|
|
8
|
+
group: BondGroupWithGradients
|
|
9
|
+
saturation?: number
|
|
10
|
+
brightness?: number
|
|
11
|
+
} = $props()
|
|
12
|
+
|
|
13
|
+
let mesh: InstancedMesh | undefined = $state()
|
|
14
|
+
// Reusable buffers to avoid reallocation on every update
|
|
15
|
+
let colors_start = new Float32Array(0)
|
|
16
|
+
let colors_end = new Float32Array(0)
|
|
17
|
+
|
|
18
|
+
const vertex_shader = `
|
|
9
19
|
attribute vec3 instanceColorStart;
|
|
10
20
|
attribute vec3 instanceColorEnd;
|
|
11
21
|
varying vec3 vColorStart;
|
|
@@ -20,8 +30,9 @@ const vertex_shader = `
|
|
|
20
30
|
vNormal = normalize(normalMatrix * normal);
|
|
21
31
|
gl_Position = projectionMatrix * modelViewMatrix * instanceMatrix * vec4(position, 1.0);
|
|
22
32
|
}
|
|
23
|
-
|
|
24
|
-
|
|
33
|
+
`
|
|
34
|
+
|
|
35
|
+
const fragment_shader = `
|
|
25
36
|
uniform float ambientIntensity;
|
|
26
37
|
uniform float directionalIntensity;
|
|
27
38
|
uniform float saturation;
|
|
@@ -53,57 +64,72 @@ const fragment_shader = `
|
|
|
53
64
|
|
|
54
65
|
gl_FragColor = vec4(linearTosRGB(final_color), 1.0);
|
|
55
66
|
}
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
buffer
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
67
|
+
`
|
|
68
|
+
|
|
69
|
+
function set_color_buffer(
|
|
70
|
+
buffer: Float32Array,
|
|
71
|
+
idx: number,
|
|
72
|
+
color: string,
|
|
73
|
+
temp_color: Color,
|
|
74
|
+
) {
|
|
75
|
+
temp_color.set(color).convertSRGBToLinear()
|
|
76
|
+
buffer[idx * 3] = temp_color.r
|
|
77
|
+
buffer[idx * 3 + 1] = temp_color.g
|
|
78
|
+
buffer[idx * 3 + 2] = temp_color.b
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
$effect(() => {
|
|
82
|
+
if (!mesh) return
|
|
83
|
+
|
|
84
|
+
const count = group.instances.length
|
|
85
|
+
const matrix = new Matrix4()
|
|
86
|
+
const temp_color = new Color()
|
|
87
|
+
|
|
69
88
|
// Reallocate buffers if instance count changed
|
|
70
89
|
if (colors_start.length !== count * 3) {
|
|
71
|
-
|
|
72
|
-
|
|
90
|
+
colors_start = new Float32Array(count * 3)
|
|
91
|
+
colors_end = new Float32Array(count * 3)
|
|
73
92
|
}
|
|
93
|
+
|
|
74
94
|
// Update instance matrices and colors
|
|
75
95
|
for (let idx = 0; idx < count; idx++) {
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
96
|
+
const instance = group.instances[idx]
|
|
97
|
+
matrix.fromArray(instance.matrix)
|
|
98
|
+
mesh.setMatrixAt(idx, matrix)
|
|
99
|
+
set_color_buffer(colors_start, idx, instance.color_start, temp_color)
|
|
100
|
+
set_color_buffer(colors_end, idx, instance.color_end, temp_color)
|
|
81
101
|
}
|
|
82
|
-
|
|
102
|
+
|
|
103
|
+
mesh.instanceMatrix.needsUpdate = true
|
|
104
|
+
|
|
83
105
|
// Update geometry color attributes
|
|
84
|
-
const { geometry } = mesh
|
|
85
|
-
for (
|
|
106
|
+
const { geometry } = mesh
|
|
107
|
+
for (
|
|
108
|
+
const [name, buffer] of [
|
|
86
109
|
[`instanceColorStart`, colors_start],
|
|
87
110
|
[`instanceColorEnd`, colors_end],
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
geometry.setAttribute(name, new InstancedBufferAttribute(buffer, 3));
|
|
111
|
+
] as const
|
|
112
|
+
) {
|
|
113
|
+
const existing = geometry.getAttribute(name)
|
|
114
|
+
if (existing?.array === buffer) existing.needsUpdate = true
|
|
115
|
+
else geometry.setAttribute(name, new InstancedBufferAttribute(buffer, 3))
|
|
94
116
|
}
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
117
|
+
|
|
118
|
+
mesh.count = count
|
|
119
|
+
})
|
|
120
|
+
|
|
121
|
+
let shader_material = $derived(
|
|
122
|
+
new ShaderMaterial({
|
|
123
|
+
vertexShader: vertex_shader,
|
|
124
|
+
fragmentShader: fragment_shader,
|
|
125
|
+
uniforms: {
|
|
101
126
|
ambientIntensity: { value: group.ambient_light ?? 0.7 },
|
|
102
127
|
directionalIntensity: { value: group.directional_light ?? 0.3 },
|
|
103
128
|
saturation: { value: saturation },
|
|
104
129
|
brightness: { value: brightness },
|
|
105
|
-
|
|
106
|
-
})
|
|
130
|
+
},
|
|
131
|
+
}),
|
|
132
|
+
)
|
|
107
133
|
</script>
|
|
108
134
|
|
|
109
135
|
<T.InstancedMesh
|
|
@@ -1,5 +1,13 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { Vec3 } from '../math'
|
|
3
|
+
import { HTML } from '@threlte/extras'
|
|
4
|
+
import type { Snippet } from 'svelte'
|
|
5
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
6
|
+
|
|
7
|
+
let { position, children, ...rest }: HTMLAttributes<HTMLDivElement> & {
|
|
8
|
+
position: Vec3
|
|
9
|
+
children: Snippet<[{ position: Vec3 }]>
|
|
10
|
+
} = $props()
|
|
3
11
|
</script>
|
|
4
12
|
|
|
5
13
|
<HTML {position} pointerEvents="none">
|