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,168 +1,300 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
8
|
-
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { is_color } from '../colors'
|
|
3
|
+
import type { ChemicalElement, ElementCategory, ElementSymbol } from '../element'
|
|
4
|
+
import { element_data, ElementPhoto, ElementTile } from '../element'
|
|
5
|
+
import { ELEM_SYMBOLS } from '../labels'
|
|
6
|
+
import type { Vec2 } from '../math'
|
|
7
|
+
import type { XyObj } from '../plot'
|
|
8
|
+
import { ColorBar } from '../plot'
|
|
9
|
+
import { colors } from '../state.svelte'
|
|
10
|
+
import * as d3_sc from 'd3-scale-chromatic'
|
|
11
|
+
import type { ComponentProps, Snippet } from 'svelte'
|
|
12
|
+
import type { HTMLAttributes } from 'svelte/elements'
|
|
13
|
+
import type { D3InterpolateName } from '../colors'
|
|
14
|
+
import type { ScaleContext } from './index'
|
|
15
|
+
import { TableInset } from './index'
|
|
16
|
+
|
|
17
|
+
const default_f_block_inset_tiles = [
|
|
9
18
|
{ name: `Lanthanides`, symbol: `La-Lu`, number: `57-71`, category: `lanthanide` },
|
|
10
19
|
{ name: `Actinides`, symbol: `Ac-Lr`, number: `89-103`, category: `actinide` },
|
|
11
|
-
]
|
|
12
|
-
let {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
20
|
+
] as const
|
|
21
|
+
let {
|
|
22
|
+
tile_props,
|
|
23
|
+
show_photo = false,
|
|
24
|
+
disabled = false,
|
|
25
|
+
heatmap_values = [],
|
|
26
|
+
links = null,
|
|
27
|
+
log = false,
|
|
28
|
+
color_scale = $bindable(`interpolateViridis`),
|
|
29
|
+
active_element = $bindable(null),
|
|
30
|
+
active_category = $bindable(null),
|
|
31
|
+
active_elements = $bindable([]),
|
|
32
|
+
gap = `0.3cqw`,
|
|
33
|
+
inner_transition_metal_offset = 0.5,
|
|
34
|
+
lanth_act_tiles = tile_props?.show_symbol == false
|
|
35
|
+
? []
|
|
36
|
+
: [...default_f_block_inset_tiles],
|
|
37
|
+
lanth_act_style = ``,
|
|
38
|
+
color_scale_range = [null, null],
|
|
39
|
+
color_overrides = {},
|
|
40
|
+
labels = {},
|
|
41
|
+
missing_color = `element-category`,
|
|
42
|
+
split_layout = undefined,
|
|
43
|
+
show_color_bar = true,
|
|
44
|
+
color_bar_props = {},
|
|
45
|
+
inset,
|
|
46
|
+
bottom_left_inset,
|
|
47
|
+
tooltip = false,
|
|
48
|
+
onenter,
|
|
49
|
+
children,
|
|
50
|
+
...rest
|
|
51
|
+
}: HTMLAttributes<HTMLDivElement> & {
|
|
52
|
+
tile_props?: Partial<ComponentProps<typeof ElementTile>>
|
|
53
|
+
show_photo?: boolean
|
|
54
|
+
disabled?: boolean // disable hover and click events from updating active_element
|
|
55
|
+
// either array of numbers/colors (can be partial, missing elements default to 0) or object with
|
|
56
|
+
// element symbol as key and heat value as value
|
|
57
|
+
// NEW: each value can now be a single number/color or array of 1-4 numbers/colors for multi-segment display
|
|
58
|
+
heatmap_values?:
|
|
59
|
+
| Partial<Record<ElementSymbol, number | number[] | string | string[]>>
|
|
60
|
+
| (number | number[] | string | string[])[]
|
|
61
|
+
// links is either string with element property (name, symbol, number, ...) to use as link,
|
|
62
|
+
// or object with mapping element symbols to link
|
|
63
|
+
links?: keyof ChemicalElement | Record<ElementSymbol, string> | null
|
|
64
|
+
log?: boolean
|
|
65
|
+
color_scale?: D3InterpolateName | ((num: number) => string)
|
|
66
|
+
active_element?: ChemicalElement | null
|
|
67
|
+
active_category?: ElementCategory | null
|
|
68
|
+
// array of element symbols or ChemicalElement objects to highlight
|
|
69
|
+
active_elements?: (ElementSymbol | ChemicalElement)[]
|
|
70
|
+
gap?: string // gap between element tiles, default is 0.3% of container width
|
|
71
|
+
inner_transition_metal_offset?: number
|
|
72
|
+
// show lanthanides and actinides as tiles
|
|
73
|
+
lanth_act_tiles?: {
|
|
74
|
+
name: string
|
|
75
|
+
symbol: string
|
|
76
|
+
number: string
|
|
77
|
+
category: ElementCategory
|
|
78
|
+
}[]
|
|
79
|
+
lanth_act_style?: string
|
|
80
|
+
color_scale_range?: [number | null, number | null]
|
|
81
|
+
color_overrides?: Partial<Record<ElementSymbol, string>>
|
|
82
|
+
labels?: Partial<Record<ElementSymbol, string>>
|
|
83
|
+
// background color for elements missing from heatmap_values
|
|
84
|
+
// "element-category" falls back to element category default color
|
|
85
|
+
missing_color?: string
|
|
86
|
+
// control the layout of multi-value splits for all tiles
|
|
87
|
+
split_layout?: `diagonal` | `horizontal` | `vertical` | `triangular` | `quadrant`
|
|
88
|
+
// automatically show a color bar when heatmap_values is provided (default: true)
|
|
89
|
+
show_color_bar?: boolean
|
|
90
|
+
// props to pass to the ColorBar component (e.g. { title: 'Bar Title', tick_labels: 5 })
|
|
91
|
+
color_bar_props?: Partial<ComponentProps<typeof ColorBar>>
|
|
92
|
+
inset?: Snippet<[{ active_element: ChemicalElement | null }]>
|
|
93
|
+
bottom_left_inset?: Snippet<[{ active_element: ChemicalElement | null }]>
|
|
94
|
+
tooltip?:
|
|
95
|
+
| Snippet<
|
|
96
|
+
[
|
|
97
|
+
{
|
|
98
|
+
element: ChemicalElement
|
|
99
|
+
value: number | number[] | string | string[]
|
|
100
|
+
active: boolean
|
|
101
|
+
bg_color: string | null
|
|
102
|
+
scale_context: ScaleContext
|
|
103
|
+
},
|
|
104
|
+
]
|
|
105
|
+
>
|
|
106
|
+
| boolean
|
|
107
|
+
children?: Snippet
|
|
108
|
+
onenter?: (element: ChemicalElement) => void
|
|
109
|
+
} = $props()
|
|
110
|
+
|
|
111
|
+
let heat_values = $derived.by(() => {
|
|
16
112
|
if (Array.isArray(heatmap_values)) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
113
|
+
if (heatmap_values.length > 118) {
|
|
114
|
+
console.error(
|
|
115
|
+
`heatmap_values is an array of numbers/arrays, length should be 118 or less, one for ` +
|
|
116
|
+
`each element possibly omitting elements at the end, got ${heatmap_values.length}`,
|
|
117
|
+
)
|
|
118
|
+
return []
|
|
119
|
+
} else return heatmap_values
|
|
120
|
+
} else if (typeof heatmap_values == `object`) {
|
|
121
|
+
const bad_keys = Object.keys(heatmap_values).filter(
|
|
122
|
+
(key) => !ELEM_SYMBOLS.includes(key as ElementSymbol),
|
|
123
|
+
)
|
|
124
|
+
if (bad_keys.length > 0) {
|
|
125
|
+
console.error(
|
|
126
|
+
`heatmap_values is an object, keys should be element symbols, got ${bad_keys}`,
|
|
127
|
+
)
|
|
128
|
+
return []
|
|
129
|
+
}
|
|
130
|
+
return ELEM_SYMBOLS.map((symbol) => heatmap_values[symbol] ?? 0)
|
|
32
131
|
}
|
|
33
|
-
return []
|
|
34
|
-
})
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
active_element = element
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
let
|
|
42
|
-
let
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
event.
|
|
132
|
+
return []
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
let set_active_element = $derived((element: ChemicalElement | null) => () => {
|
|
136
|
+
if (disabled) return
|
|
137
|
+
active_element = element
|
|
138
|
+
})
|
|
139
|
+
|
|
140
|
+
let window_width: number = $state(0)
|
|
141
|
+
let tooltip_element: ChemicalElement | null = $state(null)
|
|
142
|
+
let tooltip_pos: XyObj = $state({ x: 0, y: 0 })
|
|
143
|
+
let tooltip_visible: boolean = $state(false)
|
|
144
|
+
|
|
145
|
+
function handle_key(event: KeyboardEvent) {
|
|
146
|
+
if (disabled || !active_element) return
|
|
147
|
+
if (event.key == `Enter`) onenter?.(active_element)
|
|
148
|
+
|
|
149
|
+
const arrow_keys = [`ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`]
|
|
150
|
+
if (!arrow_keys.includes(event.key)) return
|
|
151
|
+
|
|
152
|
+
event.preventDefault() // prevent scrolling the page
|
|
153
|
+
event.stopPropagation()
|
|
154
|
+
|
|
54
155
|
// Arrow key navigation including lanthanides (row 9) and actinides (row 10)
|
|
55
|
-
const { column: col, row } = active_element
|
|
56
|
-
const in_f_block = col >= 3 && col <= 17
|
|
57
|
-
const row_map = {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
}
|
|
61
|
-
const target_row = row_map[event.key] ?? row
|
|
156
|
+
const { column: col, row } = active_element
|
|
157
|
+
const in_f_block = col >= 3 && col <= 17
|
|
158
|
+
const row_map: Record<string, number> = {
|
|
159
|
+
ArrowUp: row === 9 ? 6 : row === 10 ? 7 : row - 1,
|
|
160
|
+
ArrowDown: row === 6 && in_f_block ? 9 : row === 7 && in_f_block ? 10 : row + 1,
|
|
161
|
+
}
|
|
162
|
+
const target_row = row_map[event.key] ?? row
|
|
62
163
|
const target_col = event.key === `ArrowLeft`
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
164
|
+
? col - 1
|
|
165
|
+
: event.key === `ArrowRight`
|
|
166
|
+
? col + 1
|
|
167
|
+
: col
|
|
67
168
|
active_element =
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
tooltip_element = element
|
|
75
|
-
const target = event.currentTarget
|
|
76
|
-
const rect = target.getBoundingClientRect()
|
|
77
|
-
const container_rect = target.closest(`.
|
|
169
|
+
element_data.find((el) => el.column === target_col && el.row === target_row) ??
|
|
170
|
+
active_element
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
function handle_tooltip_enter(element: ChemicalElement, event: MouseEvent) {
|
|
174
|
+
if (tooltip === false || disabled) return
|
|
175
|
+
tooltip_element = element
|
|
176
|
+
const target = event.currentTarget as HTMLElement
|
|
177
|
+
const rect = target.getBoundingClientRect()
|
|
178
|
+
const container_rect = target.closest(`.ptable-grid`)?.getBoundingClientRect()
|
|
78
179
|
if (container_rect) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
180
|
+
tooltip_pos = {
|
|
181
|
+
x: rect.left - container_rect.left + rect.width / 2,
|
|
182
|
+
y: rect.bottom - container_rect.top + 8,
|
|
183
|
+
}
|
|
83
184
|
}
|
|
84
|
-
tooltip_visible = true
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
let
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
let
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
185
|
+
tooltip_visible = true
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
let color_scale_fn = $derived(
|
|
189
|
+
typeof color_scale == `string` ? d3_sc[color_scale] : color_scale,
|
|
190
|
+
)
|
|
191
|
+
|
|
192
|
+
let cs_min = $derived(
|
|
193
|
+
color_scale_range[0] ??
|
|
194
|
+
(heat_values.length
|
|
195
|
+
? Math.min(
|
|
196
|
+
...heat_values.flat().filter((v): v is number => typeof v === `number`),
|
|
197
|
+
)
|
|
198
|
+
: 0),
|
|
199
|
+
)
|
|
200
|
+
let cs_max = $derived(
|
|
201
|
+
color_scale_range[1] ??
|
|
202
|
+
(heat_values.length
|
|
203
|
+
? Math.max(
|
|
204
|
+
...heat_values.flat().filter((v): v is number => typeof v === `number`),
|
|
205
|
+
)
|
|
206
|
+
: 1),
|
|
207
|
+
)
|
|
208
|
+
|
|
209
|
+
let bg_color = $derived(
|
|
210
|
+
(
|
|
211
|
+
value: number | number[] | string | string[] | false,
|
|
212
|
+
element?: ChemicalElement,
|
|
213
|
+
): string | null => {
|
|
214
|
+
if (Array.isArray(value)) {
|
|
97
215
|
// For arrays, return the color of the first value (used as fallback)
|
|
98
|
-
return bg_color(value[0], element)
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
216
|
+
return bg_color(value[0], element)
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
// If it's already a color string, return it directly
|
|
220
|
+
if (is_color(value)) return value as string
|
|
221
|
+
|
|
222
|
+
// Return missing color for zero/invalid values or when no heatmap data
|
|
223
|
+
if (
|
|
224
|
+
!value ||
|
|
105
225
|
value === 0 ||
|
|
106
226
|
(log && value <= 0) ||
|
|
107
227
|
!heat_values?.length ||
|
|
108
|
-
!color_scale_fn
|
|
228
|
+
!color_scale_fn
|
|
229
|
+
) {
|
|
109
230
|
// Use missing color for zero/missing values or when no heatmap data
|
|
110
231
|
if (missing_color === `element-category` && element) {
|
|
111
|
-
|
|
232
|
+
return colors.category[element.category] || `#cccccc`
|
|
112
233
|
}
|
|
113
|
-
return missing_color
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
234
|
+
return missing_color
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
// map value to [0, 1] range
|
|
238
|
+
const span = cs_max - cs_min
|
|
239
|
+
if (span === 0) return color_scale_fn?.(0.5) // midpoint when all values equal
|
|
240
|
+
|
|
241
|
+
if (log) value = Math.log((value as number) - cs_min + 1) / Math.log(span + 1)
|
|
242
|
+
else value = ((value as number) - cs_min) / span
|
|
243
|
+
return color_scale_fn?.(value as number)
|
|
244
|
+
},
|
|
245
|
+
)
|
|
246
|
+
|
|
247
|
+
let bg_colors = $derived(
|
|
248
|
+
(
|
|
249
|
+
value: number | number[] | string | string[] | false,
|
|
250
|
+
element?: ChemicalElement,
|
|
251
|
+
) => {
|
|
252
|
+
if (!Array.isArray(value)) return []
|
|
253
|
+
|
|
254
|
+
return value.map((v) => {
|
|
129
255
|
// If it's already a color string, return it directly
|
|
130
|
-
if (is_color(v))
|
|
131
|
-
return v;
|
|
256
|
+
if (is_color(v)) return v as string
|
|
132
257
|
// Otherwise, map it through the color scale
|
|
133
|
-
return bg_color(v, element)
|
|
134
|
-
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
258
|
+
return bg_color(v as number, element)
|
|
259
|
+
})
|
|
260
|
+
},
|
|
261
|
+
)
|
|
262
|
+
|
|
263
|
+
// Determine whether to automatically show the color bar
|
|
264
|
+
let should_show_color_bar = $derived.by(() => {
|
|
265
|
+
if (!show_color_bar || inset || heat_values.length === 0) return false
|
|
266
|
+
|
|
140
267
|
const num_vals = heat_values
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
268
|
+
.flat()
|
|
269
|
+
.filter((v): v is number => typeof v === `number`)
|
|
270
|
+
|
|
271
|
+
const usable_values = log ? num_vals.filter((v) => v > 0) : num_vals
|
|
272
|
+
|
|
273
|
+
return usable_values.length > 0
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
// Calculate heat range for color bar
|
|
277
|
+
let heat_range = $derived.by((): Vec2 => {
|
|
278
|
+
if (!should_show_color_bar) return [0, 1]
|
|
279
|
+
|
|
150
280
|
const numeric_values = heat_values
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
const usable_values = log ? numeric_values.filter((v) => v > 0) : numeric_values
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
const
|
|
158
|
-
|
|
159
|
-
|
|
281
|
+
.flat()
|
|
282
|
+
.filter((v): v is number => typeof v === `number`)
|
|
283
|
+
const usable_values = log ? numeric_values.filter((v) => v > 0) : numeric_values
|
|
284
|
+
|
|
285
|
+
if (usable_values.length === 0) return [0, 1]
|
|
286
|
+
|
|
287
|
+
const min = color_scale_range[0] ?? Math.min(...usable_values)
|
|
288
|
+
const max = color_scale_range[1] ?? Math.max(...usable_values)
|
|
289
|
+
|
|
290
|
+
return [min, max]
|
|
291
|
+
})
|
|
160
292
|
</script>
|
|
161
293
|
|
|
162
294
|
<svelte:window bind:innerWidth={window_width} onkeydown={handle_key} />
|
|
163
295
|
|
|
164
|
-
<div {...rest} class="periodic-table
|
|
165
|
-
<div class="
|
|
296
|
+
<div {...rest} class="periodic-table {rest.class ?? ``}">
|
|
297
|
+
<div class="ptable-grid" style:gap>
|
|
166
298
|
{#if should_show_color_bar}
|
|
167
299
|
<TableInset class="auto-colorbar-inset">
|
|
168
300
|
<ColorBar
|
|
@@ -275,11 +407,12 @@ let heat_range = $derived.by(() => {
|
|
|
275
407
|
</div>
|
|
276
408
|
|
|
277
409
|
<style>
|
|
278
|
-
.periodic-table
|
|
410
|
+
.periodic-table {
|
|
279
411
|
/* needed for gap: 0.3cqw; to work */
|
|
280
412
|
container-type: inline-size;
|
|
413
|
+
width: 100%; /* prevent collapse in shrink-to-fit contexts (inline-size containment) */
|
|
281
414
|
}
|
|
282
|
-
|
|
415
|
+
.ptable-grid {
|
|
283
416
|
display: grid;
|
|
284
417
|
grid-template-columns: repeat(18, 1fr);
|
|
285
418
|
position: relative;
|
|
@@ -287,13 +420,13 @@ let heat_range = $derived.by(() => {
|
|
|
287
420
|
gap: var(--ptable-gap, 0.3cqw);
|
|
288
421
|
}
|
|
289
422
|
/* Auto-generated color bar inset with fluid responsive sizing using container query units */
|
|
290
|
-
|
|
423
|
+
.ptable-grid :global(.auto-colorbar-inset) {
|
|
291
424
|
place-items: center;
|
|
292
425
|
padding: clamp(0.3em, 1.5cqw, 1em) clamp(0.4em, 3cqw, 2em);
|
|
293
426
|
--cbar-font-size: clamp(7pt, 1.8cqw, 9pt);
|
|
294
427
|
--cbar-thickness: clamp(8px, 2.5cqw, 14px);
|
|
295
428
|
}
|
|
296
|
-
|
|
429
|
+
.ptable-grid :global(.auto-colorbar-inset .colorbar) {
|
|
297
430
|
width: 90%;
|
|
298
431
|
}
|
|
299
432
|
div.spacer {
|