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,180 +1,253 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PLOT_COLORS } from '../colors'
|
|
3
|
+
import { StatusMessage } from '../feedback'
|
|
4
|
+
import { create_file_drop_handler } from '../io'
|
|
5
|
+
import { format_value } from '../labels'
|
|
6
|
+
import { BarPlot } from '../plot'
|
|
7
|
+
import type {
|
|
8
|
+
AxisConfig,
|
|
9
|
+
BarHandlerProps,
|
|
10
|
+
BarSeries,
|
|
11
|
+
Orientation,
|
|
12
|
+
} from '../plot/types'
|
|
13
|
+
import type { AnyStructure } from '../structure'
|
|
14
|
+
import type { BondingStrategy } from '../structure/bonding'
|
|
15
|
+
import { parse_any_structure } from '../structure/parse'
|
|
16
|
+
import { is_crystal } from '../structure/validation'
|
|
17
|
+
import type { ComponentProps } from 'svelte'
|
|
18
|
+
import { SvelteMap, SvelteSet } from 'svelte/reactivity'
|
|
19
|
+
import { calc_coordination_nums, type CoordinationData } from './calc-coordination'
|
|
20
|
+
import type { SplitMode } from './index'
|
|
21
|
+
|
|
22
|
+
type CoordinationMetadata = {
|
|
23
|
+
element?: string
|
|
24
|
+
structure_label?: string
|
|
25
|
+
} & Record<string, unknown>
|
|
26
|
+
|
|
27
|
+
interface StructureEntry {
|
|
28
|
+
label: string
|
|
29
|
+
structure: AnyStructure
|
|
30
|
+
color?: string
|
|
31
|
+
data?: CoordinationData
|
|
32
|
+
}
|
|
33
|
+
let {
|
|
34
|
+
structures,
|
|
35
|
+
strategy = `electroneg_ratio`,
|
|
36
|
+
split_mode = `by_element`,
|
|
37
|
+
mode = $bindable(`grouped`),
|
|
38
|
+
orientation = `vertical` as Orientation,
|
|
39
|
+
x_axis = {},
|
|
40
|
+
y_axis = {},
|
|
41
|
+
allow_file_drop = true,
|
|
42
|
+
on_file_drop,
|
|
43
|
+
loading = $bindable(false),
|
|
44
|
+
error_msg = $bindable(),
|
|
45
|
+
...rest
|
|
46
|
+
}: Omit<ComponentProps<typeof BarPlot>, `series`> & {
|
|
47
|
+
structures:
|
|
48
|
+
| AnyStructure
|
|
49
|
+
| Record<string, AnyStructure | { structure: AnyStructure; color?: string }>
|
|
50
|
+
| StructureEntry[]
|
|
51
|
+
strategy?: BondingStrategy
|
|
52
|
+
split_mode?: SplitMode
|
|
53
|
+
x_axis?: AxisConfig
|
|
54
|
+
y_axis?: AxisConfig
|
|
55
|
+
allow_file_drop?: boolean
|
|
56
|
+
on_file_drop?: (content: string | ArrayBuffer, filename: string) => void
|
|
57
|
+
loading?: boolean
|
|
58
|
+
error_msg?: string
|
|
59
|
+
} = $props()
|
|
60
|
+
|
|
61
|
+
let dragover = $state(false)
|
|
62
|
+
let dropped_entries = $state<StructureEntry[]>([])
|
|
63
|
+
let is_horizontal = $derived(orientation === `horizontal`)
|
|
64
|
+
|
|
65
|
+
// Normalize input to consistent array of { label, structure, color }
|
|
66
|
+
const structure_entries = $derived.by<StructureEntry[]>(() => {
|
|
67
|
+
if (!structures) return []
|
|
68
|
+
|
|
18
69
|
const base_entries = Array.isArray(structures)
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
70
|
+
? (structures as StructureEntry[])
|
|
71
|
+
: (is_crystal(structures)
|
|
72
|
+
? [{ label: `Structure`, structure: structures as AnyStructure }]
|
|
73
|
+
: Object.entries(
|
|
74
|
+
structures as Record<
|
|
75
|
+
string,
|
|
76
|
+
AnyStructure | { structure: AnyStructure; color?: string }
|
|
77
|
+
>,
|
|
78
|
+
).map(([label, value]) =>
|
|
79
|
+
`structure` in value
|
|
80
|
+
? { label, ...value }
|
|
81
|
+
: { label, structure: value as AnyStructure }
|
|
82
|
+
))
|
|
83
|
+
|
|
25
84
|
// Merge user-provided structures with dropped structures
|
|
26
|
-
return [...base_entries, ...dropped_entries]
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
|
|
85
|
+
return [...base_entries, ...dropped_entries]
|
|
86
|
+
})
|
|
87
|
+
|
|
88
|
+
// Compute coordination data for each structure
|
|
89
|
+
const entries_with_data = $derived(structure_entries.map((entry) => ({
|
|
30
90
|
...entry,
|
|
31
91
|
data: calc_coordination_nums(entry.structure, strategy),
|
|
32
|
-
})))
|
|
33
|
-
|
|
34
|
-
|
|
92
|
+
})))
|
|
93
|
+
|
|
94
|
+
// Compute appropriate ranges
|
|
95
|
+
const ranges = $derived.by(() => {
|
|
35
96
|
// CN axis should always start at 0 and show at least [0,4]
|
|
36
|
-
let max_cn = 4
|
|
97
|
+
let max_cn = 4 // minimum max value
|
|
37
98
|
for (const entry of entries_with_data) {
|
|
38
|
-
|
|
39
|
-
max_cn = Math.max(max_cn, cn);
|
|
99
|
+
for (const [cn] of entry.data.cn_histogram) max_cn = Math.max(max_cn, cn)
|
|
40
100
|
}
|
|
41
|
-
const cn_range = [-0.5, max_cn + 0.5]
|
|
42
|
-
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
101
|
+
const cn_range: [number, number] = [-0.5, max_cn + 0.5]
|
|
102
|
+
|
|
103
|
+
return { count: [0, null] as [number, null], cn: cn_range } // Count axis should always start at 0
|
|
104
|
+
})
|
|
105
|
+
|
|
106
|
+
// Derive integer CN ticks for axis labels
|
|
107
|
+
const cn_ticks = $derived.by(() => {
|
|
108
|
+
const all_cns = new SvelteSet<number>()
|
|
47
109
|
// Always include minimum CN values 0-4
|
|
48
|
-
for (let idx = 0; idx <= 4; idx++)
|
|
49
|
-
all_cns.add(idx);
|
|
110
|
+
for (let idx = 0; idx <= 4; idx++) all_cns.add(idx)
|
|
50
111
|
// Add actual CN values from data
|
|
51
112
|
for (const entry of entries_with_data) {
|
|
52
|
-
|
|
53
|
-
all_cns.add(cn);
|
|
113
|
+
for (const [cn] of entry.data.cn_histogram) all_cns.add(cn)
|
|
54
114
|
}
|
|
55
|
-
return Array.from(all_cns).sort((cn1, cn2) => cn1 - cn2)
|
|
56
|
-
})
|
|
57
|
-
|
|
58
|
-
|
|
115
|
+
return Array.from(all_cns).sort((cn1, cn2) => cn1 - cn2)
|
|
116
|
+
})
|
|
117
|
+
|
|
118
|
+
// Build BarPlot series based on split_mode
|
|
119
|
+
const bar_series = $derived.by<BarSeries<CoordinationMetadata>[]>(() => {
|
|
59
120
|
if (split_mode === `by_element`) {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
// Convert map to array and ensure all series have same x-values
|
|
79
|
-
return Array.from(element_series_map.entries())
|
|
80
|
-
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
81
|
-
.map(([element, cn_map], idx) => {
|
|
82
|
-
return {
|
|
83
|
-
x: sorted_cns,
|
|
84
|
-
y: sorted_cns.map((cn) => cn_map.get(cn) ?? 0),
|
|
85
|
-
label: element,
|
|
86
|
-
color: PLOT_COLORS[idx % PLOT_COLORS.length],
|
|
87
|
-
bar_width: 0.8,
|
|
88
|
-
visible: true,
|
|
89
|
-
metadata: { element },
|
|
90
|
-
};
|
|
91
|
-
});
|
|
92
|
-
}
|
|
93
|
-
else if (split_mode === `by_structure`) {
|
|
94
|
-
// One series per structure
|
|
95
|
-
// First collect all unique CNs
|
|
96
|
-
const all_cns = new SvelteSet();
|
|
97
|
-
for (const entry of entries_with_data) {
|
|
98
|
-
for (const [cn] of entry.data.cn_histogram) {
|
|
99
|
-
all_cns.add(cn);
|
|
100
|
-
}
|
|
121
|
+
// One series per element across all structures
|
|
122
|
+
const element_series_map = new SvelteMap<string, Map<number, number>>()
|
|
123
|
+
|
|
124
|
+
// Collect all unique CNs across all elements
|
|
125
|
+
const all_cns = new SvelteSet<number>()
|
|
126
|
+
|
|
127
|
+
for (const entry of entries_with_data) {
|
|
128
|
+
for (const [element, cn_histogram] of entry.data.cn_histogram_by_element) {
|
|
129
|
+
if (!element_series_map.has(element)) {
|
|
130
|
+
element_series_map.set(element, new SvelteMap())
|
|
131
|
+
}
|
|
132
|
+
const element_map = element_series_map.get(element)
|
|
133
|
+
if (!element_map) continue
|
|
134
|
+
|
|
135
|
+
for (const [cn, count] of cn_histogram) {
|
|
136
|
+
all_cns.add(cn)
|
|
137
|
+
element_map.set(cn, (element_map.get(cn) ?? 0) + count)
|
|
138
|
+
}
|
|
101
139
|
}
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Sort CNs for consistent x-axis
|
|
143
|
+
const sorted_cns = Array.from(all_cns).sort((a, b) => a - b)
|
|
144
|
+
|
|
145
|
+
// Convert map to array and ensure all series have same x-values
|
|
146
|
+
return Array.from(element_series_map.entries())
|
|
147
|
+
.sort((a, b) => a[0].localeCompare(b[0]))
|
|
148
|
+
.map(([element, cn_map], idx) => {
|
|
149
|
+
return {
|
|
150
|
+
x: sorted_cns,
|
|
151
|
+
y: sorted_cns.map((cn) => cn_map.get(cn) ?? 0),
|
|
152
|
+
label: element,
|
|
153
|
+
color: PLOT_COLORS[idx % PLOT_COLORS.length],
|
|
154
|
+
bar_width: 0.8,
|
|
155
|
+
visible: true,
|
|
156
|
+
metadata: { element },
|
|
157
|
+
}
|
|
158
|
+
})
|
|
159
|
+
} else if (split_mode === `by_structure`) {
|
|
160
|
+
// One series per structure
|
|
161
|
+
// First collect all unique CNs
|
|
162
|
+
const all_cns = new SvelteSet<number>()
|
|
163
|
+
for (const entry of entries_with_data) {
|
|
164
|
+
for (const [cn] of entry.data.cn_histogram) {
|
|
165
|
+
all_cns.add(cn)
|
|
122
166
|
}
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
];
|
|
136
|
-
}
|
|
137
|
-
});
|
|
138
|
-
const compute_and_add = (content, filename) => {
|
|
139
|
-
try {
|
|
140
|
-
const text_content = content instanceof ArrayBuffer
|
|
141
|
-
? new TextDecoder().decode(content)
|
|
142
|
-
: content;
|
|
143
|
-
const parsed_structure = parse_any_structure(text_content, filename);
|
|
144
|
-
if (is_crystal(parsed_structure)) {
|
|
145
|
-
dropped_entries = [{
|
|
146
|
-
label: filename || `Dropped structure`,
|
|
147
|
-
structure: parsed_structure,
|
|
148
|
-
}, ...dropped_entries];
|
|
167
|
+
}
|
|
168
|
+
const sorted_cns = Array.from(all_cns).sort((a, b) => a - b)
|
|
169
|
+
|
|
170
|
+
return entries_with_data.map((entry, idx) => {
|
|
171
|
+
return {
|
|
172
|
+
x: sorted_cns,
|
|
173
|
+
y: sorted_cns.map((cn) => entry.data.cn_histogram.get(cn) ?? 0),
|
|
174
|
+
label: entry.label,
|
|
175
|
+
color: entry.color ?? PLOT_COLORS[idx % PLOT_COLORS.length],
|
|
176
|
+
bar_width: 0.8,
|
|
177
|
+
visible: true,
|
|
178
|
+
metadata: { structure_label: entry.label },
|
|
149
179
|
}
|
|
150
|
-
|
|
151
|
-
|
|
180
|
+
})
|
|
181
|
+
} else {
|
|
182
|
+
// split_mode === 'none': combine all into single series
|
|
183
|
+
const combined_histogram = new SvelteMap<number, number>()
|
|
184
|
+
|
|
185
|
+
for (const entry of entries_with_data) {
|
|
186
|
+
for (const [cn, count] of entry.data.cn_histogram) {
|
|
187
|
+
combined_histogram.set(cn, (combined_histogram.get(cn) ?? 0) + count)
|
|
152
188
|
}
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
const x_vals = Array.from(combined_histogram.keys()).sort((a, b) => a - b)
|
|
192
|
+
const y_vals = x_vals.map((cn) => combined_histogram.get(cn) ?? 0)
|
|
193
|
+
|
|
194
|
+
return [
|
|
195
|
+
{
|
|
196
|
+
x: x_vals,
|
|
197
|
+
y: y_vals,
|
|
198
|
+
label: `All Sites`,
|
|
199
|
+
color: PLOT_COLORS[0],
|
|
200
|
+
bar_width: 0.8,
|
|
201
|
+
visible: true,
|
|
202
|
+
metadata: {},
|
|
203
|
+
},
|
|
204
|
+
]
|
|
153
205
|
}
|
|
154
|
-
|
|
155
|
-
|
|
206
|
+
})
|
|
207
|
+
|
|
208
|
+
const compute_and_add = (content: string | ArrayBuffer, filename: string) => {
|
|
209
|
+
try {
|
|
210
|
+
const text_content = content instanceof ArrayBuffer
|
|
211
|
+
? new TextDecoder().decode(content)
|
|
212
|
+
: content
|
|
213
|
+
const parsed_structure = parse_any_structure(text_content, filename)
|
|
214
|
+
if (is_crystal(parsed_structure)) {
|
|
215
|
+
dropped_entries = [{
|
|
216
|
+
label: filename || `Dropped structure`,
|
|
217
|
+
structure: parsed_structure,
|
|
218
|
+
}, ...dropped_entries]
|
|
219
|
+
} else {
|
|
220
|
+
error_msg = `Structure has no lattice or sites; cannot compute coordination`
|
|
221
|
+
}
|
|
222
|
+
} catch (exc) {
|
|
223
|
+
error_msg = `Failed to process structure: ${
|
|
224
|
+
exc instanceof Error ? exc.message : String(exc)
|
|
225
|
+
}`
|
|
156
226
|
}
|
|
157
|
-
}
|
|
158
|
-
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
const handle_file_drop = create_file_drop_handler({
|
|
159
230
|
allow: () => allow_file_drop,
|
|
160
|
-
on_drop: (content, filename) =>
|
|
231
|
+
on_drop: (content, filename) =>
|
|
232
|
+
(on_file_drop || compute_and_add)(content, filename),
|
|
161
233
|
on_error: (msg) => {
|
|
162
|
-
|
|
234
|
+
error_msg = msg
|
|
163
235
|
},
|
|
164
236
|
set_loading: (val) => {
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
[error_msg, dragover] = [undefined, false];
|
|
237
|
+
loading = val
|
|
238
|
+
if (val) [error_msg, dragover] = [undefined, false]
|
|
168
239
|
},
|
|
169
|
-
})
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
display.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
240
|
+
})
|
|
241
|
+
|
|
242
|
+
let display = $state({ x_zero_line: false, y_zero_line: false })
|
|
243
|
+
// Update display when orientation changes
|
|
244
|
+
$effect(() => {
|
|
245
|
+
display.x_zero_line = is_horizontal
|
|
246
|
+
display.y_zero_line = !is_horizontal
|
|
247
|
+
})
|
|
248
|
+
|
|
249
|
+
const cn_axis = { label: `Coordination Number`, format: `d` }
|
|
250
|
+
const count_axis = { label: `Count`, format: `d` }
|
|
178
251
|
</script>
|
|
179
252
|
|
|
180
253
|
<StatusMessage bind:message={error_msg} type="error" dismissible />
|
|
@@ -1,26 +1,69 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { SVGAttributes } from 'svelte/elements'
|
|
3
|
+
|
|
4
|
+
type Props = SVGAttributes<SVGSVGElement> & {
|
|
5
|
+
// https://svelte.dev/repl/17d71b590f554b5a9eba6e04023dd41c
|
|
6
|
+
symbol?: string // usually H, He, etc. but can be anything
|
|
7
|
+
name?: string // usually Hydrogen, Helium, etc. but can be anything
|
|
8
|
+
shells: number[]
|
|
9
|
+
adapt_size?: boolean
|
|
10
|
+
shell_width?: number
|
|
11
|
+
size?: number
|
|
12
|
+
base_fill?: string
|
|
13
|
+
orbital_period?: number // time for inner-most electron orbit in seconds, 0 for no motion
|
|
14
|
+
// set properties like size, fill, stroke, stroke-width, for nucleus and electrons here
|
|
15
|
+
nucleus_props?: Record<string, string | number>
|
|
16
|
+
shell_props?: Record<string, string | number>
|
|
17
|
+
electron_props?: Record<string, string | number>
|
|
18
|
+
highlight_shell?: number | null
|
|
19
|
+
// if function, it'll be called with electron index and should return a string
|
|
20
|
+
number_electrons?:
|
|
21
|
+
| boolean
|
|
22
|
+
| `hierarchical`
|
|
23
|
+
| `sequential`
|
|
24
|
+
| ((idx: number) => string)
|
|
25
|
+
electron_label_props?: Record<string, string | number>
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
let {
|
|
29
|
+
symbol = ``,
|
|
30
|
+
name = ``,
|
|
31
|
+
shells,
|
|
32
|
+
adapt_size = true,
|
|
33
|
+
shell_width = 20,
|
|
34
|
+
size = adapt_size ? (shells.length + 1) * 2 * shell_width + 30 : 270,
|
|
35
|
+
base_fill = `var(--text-color)`,
|
|
36
|
+
orbital_period = 3,
|
|
37
|
+
nucleus_props = {},
|
|
38
|
+
shell_props = {},
|
|
39
|
+
electron_props = {},
|
|
40
|
+
highlight_shell = null,
|
|
41
|
+
number_electrons = false,
|
|
42
|
+
electron_label_props = {},
|
|
43
|
+
...rest
|
|
44
|
+
}: Props = $props()
|
|
45
|
+
|
|
46
|
+
// Bohr atom electron orbital period is given by
|
|
47
|
+
// T = (n^3 h^3) / (4pi^2 m K e^4 Z^2) = 1.52 * 10^-16 * n^3 / Z^2 s
|
|
48
|
+
// with n the shell number, Z the atomic number, m the mass of the electron
|
|
49
|
+
let _nucleus_props = $derived({
|
|
6
50
|
r: 20,
|
|
7
51
|
fill: base_fill,
|
|
8
52
|
'fill-opacity': `0.3`,
|
|
9
53
|
...nucleus_props,
|
|
10
|
-
})
|
|
11
|
-
let _shell_props = $derived({
|
|
54
|
+
})
|
|
55
|
+
let _shell_props = $derived({
|
|
12
56
|
stroke: base_fill,
|
|
13
57
|
fill: `none`,
|
|
14
58
|
...shell_props,
|
|
15
|
-
})
|
|
16
|
-
let _electron_props = $derived({
|
|
59
|
+
})
|
|
60
|
+
let _electron_props = $derived({
|
|
17
61
|
r: 3,
|
|
18
62
|
stroke: base_fill,
|
|
19
63
|
fill: `blue`,
|
|
20
64
|
...electron_props,
|
|
21
|
-
})
|
|
22
|
-
let viewBox = $derived(`-${size / 2}, -${size / 2}, ${size}, ${size}`)
|
|
23
|
-
export {};
|
|
65
|
+
})
|
|
66
|
+
let viewBox = $derived(`-${size / 2}, -${size / 2}, ${size}, ${size}`)
|
|
24
67
|
</script>
|
|
25
68
|
|
|
26
69
|
<svg
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ChemicalElement } from './'
|
|
3
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
4
|
+
|
|
5
|
+
let { element, ...rest }: HTMLAttributes<HTMLHeadingElement> & {
|
|
6
|
+
element: ChemicalElement
|
|
7
|
+
} = $props()
|
|
3
8
|
</script>
|
|
4
9
|
|
|
5
10
|
<h2 {...rest}>
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ChemicalElement } from './'
|
|
3
|
+
import Icon from '../Icon.svelte'
|
|
4
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
5
|
+
|
|
6
|
+
let { element, missing_msg = `No image for `, ...rest }:
|
|
7
|
+
& HTMLAttributes<HTMLImageElement | HTMLDivElement>
|
|
8
|
+
& { element: ChemicalElement; missing_msg?: string } = $props()
|
|
9
|
+
|
|
10
|
+
let { name, number } = $derived(element ?? {})
|
|
11
|
+
let file = $derived(`elements/${number}-${name?.toLowerCase()}.avif`)
|
|
12
|
+
let hidden = $state(false)
|
|
13
|
+
$effect.pre(() => {
|
|
14
|
+
if (file) hidden = false
|
|
15
|
+
}) // reset hidden to false when file changes
|
|
10
16
|
</script>
|
|
11
17
|
|
|
12
18
|
{#if name && number}
|
|
@@ -1,7 +1,13 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import
|
|
4
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import type { ChemicalElement } from './'
|
|
3
|
+
import Icon from '../Icon.svelte'
|
|
4
|
+
import { format_num } from '../labels'
|
|
5
|
+
import ElementHeading from './ElementHeading.svelte'
|
|
6
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
7
|
+
|
|
8
|
+
let { element, ...rest }: HTMLAttributes<HTMLDivElement> & {
|
|
9
|
+
element: ChemicalElement | null
|
|
10
|
+
} = $props()
|
|
5
11
|
</script>
|
|
6
12
|
|
|
7
13
|
{#if element}
|