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.
Files changed (280) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +123 -82
  3. package/dist/Icon.svelte +18 -12
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -207
  7. package/dist/brillouin/BrillouinZone.svelte +292 -149
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +69 -42
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +275 -163
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +162 -27
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +451 -281
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +2148 -1642
  20. package/dist/chempot-diagram/ChemPotScene3D.svelte +8 -5
  21. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  22. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  23. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  24. package/dist/chempot-diagram/chempot-worker.js +11 -0
  25. package/dist/chempot-diagram/color.js +1 -2
  26. package/dist/chempot-diagram/compute.d.ts +10 -0
  27. package/dist/chempot-diagram/compute.js +250 -88
  28. package/dist/chempot-diagram/index.d.ts +2 -1
  29. package/dist/chempot-diagram/index.js +2 -1
  30. package/dist/chempot-diagram/temperature.js +8 -9
  31. package/dist/chempot-diagram/types.d.ts +3 -0
  32. package/dist/chempot-diagram/types.js +1 -0
  33. package/dist/colors/index.d.ts +1 -1
  34. package/dist/colors/index.js +5 -3
  35. package/dist/composition/BarChart.svelte +128 -55
  36. package/dist/composition/BubbleChart.svelte +102 -49
  37. package/dist/composition/Composition.svelte +100 -79
  38. package/dist/composition/Formula.svelte +108 -62
  39. package/dist/composition/FormulaFilter.svelte +665 -537
  40. package/dist/composition/PieChart.svelte +183 -108
  41. package/dist/composition/format.d.ts +5 -0
  42. package/dist/composition/format.js +20 -3
  43. package/dist/composition/parse.js +14 -9
  44. package/dist/convex-hull/ConvexHull.svelte +93 -40
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +549 -360
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +1296 -827
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +1004 -688
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  53. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +1 -1
  54. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  55. package/dist/convex-hull/ConvexHullStats.svelte +425 -328
  56. package/dist/convex-hull/ConvexHullTooltip.svelte +40 -16
  57. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  58. package/dist/convex-hull/StructurePopup.svelte +25 -4
  59. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  60. package/dist/convex-hull/barycentric-coords.js +13 -7
  61. package/dist/convex-hull/demo-temperature.js +8 -4
  62. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  63. package/dist/convex-hull/helpers.d.ts +9 -0
  64. package/dist/convex-hull/helpers.js +77 -34
  65. package/dist/convex-hull/thermodynamics.js +61 -56
  66. package/dist/convex-hull/types.d.ts +9 -14
  67. package/dist/convex-hull/types.js +0 -17
  68. package/dist/coordination/CoordinationBarPlot.svelte +227 -154
  69. package/dist/element/BohrAtom.svelte +55 -12
  70. package/dist/element/ElementHeading.svelte +7 -2
  71. package/dist/element/ElementPhoto.svelte +15 -9
  72. package/dist/element/ElementStats.svelte +10 -4
  73. package/dist/element/ElementTile.svelte +137 -73
  74. package/dist/element/Nucleus.svelte +39 -11
  75. package/dist/feedback/ClickFeedback.svelte +16 -5
  76. package/dist/feedback/DragOverlay.svelte +10 -2
  77. package/dist/feedback/Spinner.svelte +4 -2
  78. package/dist/feedback/StatusMessage.svelte +8 -2
  79. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  80. package/dist/fermi-surface/FermiSurface.svelte +328 -187
  81. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  82. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  83. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  84. package/dist/fermi-surface/FermiSurfaceScene.svelte +535 -342
  85. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  86. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  87. package/dist/fermi-surface/compute.js +16 -20
  88. package/dist/fermi-surface/parse.js +24 -14
  89. package/dist/fermi-surface/symmetry.js +2 -7
  90. package/dist/fermi-surface/types.d.ts +3 -5
  91. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1019 -765
  92. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +1 -1
  93. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +76 -22
  94. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +2 -3
  95. package/dist/icons.js +47 -0
  96. package/dist/index.d.ts +2 -1
  97. package/dist/index.js +2 -1
  98. package/dist/io/decompress.js +1 -1
  99. package/dist/io/export.d.ts +3 -0
  100. package/dist/io/export.js +129 -143
  101. package/dist/io/is-binary.js +2 -3
  102. package/dist/io/url-drop.js +1 -2
  103. package/dist/isosurface/Isosurface.svelte +202 -148
  104. package/dist/isosurface/IsosurfaceControls.svelte +46 -28
  105. package/dist/isosurface/parse.js +34 -29
  106. package/dist/isosurface/slice.js +5 -10
  107. package/dist/isosurface/types.d.ts +2 -1
  108. package/dist/isosurface/types.js +61 -12
  109. package/dist/labels.js +11 -8
  110. package/dist/layout/FullscreenToggle.svelte +11 -2
  111. package/dist/layout/InfoCard.svelte +38 -6
  112. package/dist/layout/InfoTag.svelte +63 -32
  113. package/dist/layout/PropertyFilter.svelte +82 -37
  114. package/dist/layout/SettingsSection.svelte +85 -55
  115. package/dist/layout/SubpageGrid.svelte +10 -2
  116. package/dist/layout/json-tree/JsonNode.svelte +183 -138
  117. package/dist/layout/json-tree/JsonTree.svelte +499 -413
  118. package/dist/layout/json-tree/JsonValue.svelte +127 -99
  119. package/dist/layout/json-tree/utils.js +4 -2
  120. package/dist/marching-cubes.js +25 -2
  121. package/dist/math.d.ts +13 -17
  122. package/dist/math.js +133 -67
  123. package/dist/overlays/ContextMenu.svelte +65 -40
  124. package/dist/overlays/DraggablePane.svelte +211 -139
  125. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  126. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  127. package/dist/periodic-table/PropertySelect.svelte +25 -7
  128. package/dist/periodic-table/TableInset.svelte +8 -3
  129. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +446 -309
  130. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  131. package/dist/phase-diagram/PhaseDiagramControls.svelte +102 -43
  132. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  133. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +63 -40
  134. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +71 -28
  135. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +1 -1
  136. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +158 -101
  137. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  138. package/dist/phase-diagram/build-diagram.js +9 -9
  139. package/dist/phase-diagram/colors.js +1 -3
  140. package/dist/phase-diagram/parse.js +10 -9
  141. package/dist/phase-diagram/svg-to-diagram.js +53 -49
  142. package/dist/phase-diagram/utils.d.ts +1 -0
  143. package/dist/phase-diagram/utils.js +80 -25
  144. package/dist/plot/AxisLabel.svelte +28 -3
  145. package/dist/plot/BarPlot.svelte +1182 -734
  146. package/dist/plot/BarPlot.svelte.d.ts +2 -2
  147. package/dist/plot/BarPlotControls.svelte +31 -5
  148. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  149. package/dist/plot/ColorBar.svelte +479 -329
  150. package/dist/plot/ColorScaleSelect.svelte +27 -6
  151. package/dist/plot/ElementScatter.svelte +36 -15
  152. package/dist/plot/FillArea.svelte +152 -95
  153. package/dist/plot/Histogram.svelte +934 -571
  154. package/dist/plot/Histogram.svelte.d.ts +1 -1
  155. package/dist/plot/HistogramControls.svelte +53 -9
  156. package/dist/plot/HistogramControls.svelte.d.ts +1 -1
  157. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  158. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  159. package/dist/plot/Line.svelte +63 -28
  160. package/dist/plot/PlotControls.svelte +157 -114
  161. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  162. package/dist/plot/PlotLegend.svelte +174 -91
  163. package/dist/plot/PlotTooltip.svelte +45 -6
  164. package/dist/plot/PortalSelect.svelte +175 -147
  165. package/dist/plot/ReferenceLine.svelte +76 -22
  166. package/dist/plot/ReferenceLine3D.svelte +132 -107
  167. package/dist/plot/ReferencePlane.svelte +146 -121
  168. package/dist/plot/ScatterPlot.svelte +1681 -1091
  169. package/dist/plot/ScatterPlot.svelte.d.ts +2 -2
  170. package/dist/plot/ScatterPlot3D.svelte +256 -131
  171. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  172. package/dist/plot/ScatterPlot3DControls.svelte +113 -63
  173. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  174. package/dist/plot/ScatterPlot3DScene.svelte +608 -403
  175. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  176. package/dist/plot/ScatterPlotControls.svelte +65 -25
  177. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  178. package/dist/plot/ScatterPoint.svelte +98 -26
  179. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  180. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  181. package/dist/plot/Surface3D.svelte +159 -108
  182. package/dist/plot/ZeroLines.svelte +55 -3
  183. package/dist/plot/ZoomRect.svelte +4 -2
  184. package/dist/plot/axis-utils.js +1 -3
  185. package/dist/plot/data-cleaning.js +12 -28
  186. package/dist/plot/data-transform.js +2 -1
  187. package/dist/plot/fill-utils.js +2 -0
  188. package/dist/plot/layout.d.ts +4 -1
  189. package/dist/plot/layout.js +33 -14
  190. package/dist/plot/reference-line.d.ts +2 -2
  191. package/dist/plot/reference-line.js +7 -5
  192. package/dist/plot/scales.js +24 -36
  193. package/dist/plot/types.d.ts +11 -23
  194. package/dist/plot/types.js +6 -11
  195. package/dist/plot/utils/label-placement.d.ts +32 -15
  196. package/dist/plot/utils/label-placement.js +227 -66
  197. package/dist/plot/utils/series-visibility.js +2 -3
  198. package/dist/rdf/RdfPlot.svelte +143 -91
  199. package/dist/rdf/calc-rdf.js +4 -5
  200. package/dist/sanitize.d.ts +4 -0
  201. package/dist/sanitize.js +107 -0
  202. package/dist/settings.d.ts +18 -6
  203. package/dist/settings.js +46 -16
  204. package/dist/spectral/Bands.svelte +632 -453
  205. package/dist/spectral/BandsAndDos.svelte +90 -49
  206. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  207. package/dist/spectral/Dos.svelte +389 -258
  208. package/dist/spectral/helpers.js +55 -43
  209. package/dist/state.svelte.d.ts +1 -1
  210. package/dist/state.svelte.js +3 -2
  211. package/dist/structure/Arrow.svelte +59 -20
  212. package/dist/structure/AtomLegend.svelte +215 -134
  213. package/dist/structure/Bond.svelte +73 -47
  214. package/dist/structure/CanvasTooltip.svelte +10 -2
  215. package/dist/structure/CellSelect.svelte +72 -45
  216. package/dist/structure/Cylinder.svelte +33 -17
  217. package/dist/structure/Lattice.svelte +88 -33
  218. package/dist/structure/Structure.svelte +1063 -797
  219. package/dist/structure/Structure.svelte.d.ts +1 -1
  220. package/dist/structure/StructureControls.svelte +349 -118
  221. package/dist/structure/StructureExportPane.svelte +124 -89
  222. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  223. package/dist/structure/StructureInfoPane.svelte +304 -237
  224. package/dist/structure/StructureScene.svelte +879 -443
  225. package/dist/structure/StructureScene.svelte.d.ts +15 -7
  226. package/dist/structure/atom-properties.js +8 -8
  227. package/dist/structure/bonding.js +6 -7
  228. package/dist/structure/export.js +14 -29
  229. package/dist/structure/ferrox-wasm.js +1 -1
  230. package/dist/structure/index.d.ts +13 -3
  231. package/dist/structure/index.js +83 -23
  232. package/dist/structure/measure.d.ts +2 -2
  233. package/dist/structure/measure.js +4 -44
  234. package/dist/structure/parse.js +113 -141
  235. package/dist/structure/partial-occupancy.js +7 -10
  236. package/dist/structure/pbc.d.ts +1 -0
  237. package/dist/structure/pbc.js +16 -6
  238. package/dist/structure/supercell.d.ts +2 -2
  239. package/dist/structure/supercell.js +12 -22
  240. package/dist/structure/validation.js +1 -2
  241. package/dist/symmetry/SymmetryStats.svelte +84 -41
  242. package/dist/symmetry/WyckoffTable.svelte +26 -6
  243. package/dist/symmetry/cell-transform.js +5 -3
  244. package/dist/symmetry/index.js +8 -7
  245. package/dist/symmetry/spacegroups.js +148 -148
  246. package/dist/table/HeatmapTable.svelte +790 -554
  247. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  248. package/dist/table/ToggleMenu.svelte +125 -92
  249. package/dist/table/index.js +2 -4
  250. package/dist/theme/ThemeControl.svelte +21 -12
  251. package/dist/time.js +4 -1
  252. package/dist/tooltip/TooltipContent.svelte +33 -8
  253. package/dist/trajectory/Trajectory.svelte +758 -558
  254. package/dist/trajectory/TrajectoryError.svelte +14 -3
  255. package/dist/trajectory/TrajectoryExportPane.svelte +137 -83
  256. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  257. package/dist/trajectory/extract.js +10 -26
  258. package/dist/trajectory/format-detect.js +5 -5
  259. package/dist/trajectory/frame-reader.d.ts +1 -1
  260. package/dist/trajectory/frame-reader.js +5 -12
  261. package/dist/trajectory/helpers.d.ts +0 -1
  262. package/dist/trajectory/helpers.js +2 -17
  263. package/dist/trajectory/index.js +14 -12
  264. package/dist/trajectory/parse/ase.js +5 -4
  265. package/dist/trajectory/parse/hdf5.js +26 -18
  266. package/dist/trajectory/parse/index.js +13 -18
  267. package/dist/trajectory/parse/lammps.js +17 -7
  268. package/dist/trajectory/parse/vasp.js +5 -2
  269. package/dist/trajectory/parse/xyz.js +8 -7
  270. package/dist/trajectory/plotting.js +13 -8
  271. package/dist/utils.d.ts +1 -0
  272. package/dist/utils.js +13 -0
  273. package/dist/xrd/XrdPlot.svelte +337 -247
  274. package/dist/xrd/broadening.js +14 -9
  275. package/dist/xrd/calc-xrd.js +12 -18
  276. package/dist/xrd/parse.d.ts +1 -1
  277. package/dist/xrd/parse.js +17 -17
  278. package/package.json +99 -103
  279. package/readme.md +1 -1
  280. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,168 +1,300 @@
1
- <script lang="ts">import { is_color } from '../colors';
2
- import { element_data, ElementPhoto, ElementTile } from '../element';
3
- import { ELEM_SYMBOLS } from '../labels';
4
- import { ColorBar } from '../plot';
5
- import { colors } from '../state.svelte';
6
- import * as d3_sc from 'd3-scale-chromatic';
7
- import { TableInset } from './index';
8
- const default_f_block_inset_tiles = [
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 { tile_props, show_photo = false, disabled = false, heatmap_values = [], links = null, log = false, color_scale = $bindable(`interpolateViridis`), active_element = $bindable(null), active_category = $bindable(null), active_elements = $bindable([]), gap = `0.3cqw`, inner_transition_metal_offset = 0.5, lanth_act_tiles = tile_props?.show_symbol == false
13
- ? []
14
- : [...default_f_block_inset_tiles], lanth_act_style = ``, color_scale_range = [null, null], color_overrides = {}, labels = {}, missing_color = `element-category`, split_layout = undefined, show_color_bar = true, color_bar_props = {}, inset, bottom_left_inset, tooltip = false, onenter, children, ...rest } = $props();
15
- let heat_values = $derived.by(() => {
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
- if (heatmap_values.length > 118) {
18
- console.error(`heatmap_values is an array of numbers/arrays, length should be 118 or less, one for ` +
19
- `each element possibly omitting elements at the end, got ${heatmap_values.length}`);
20
- return [];
21
- }
22
- else
23
- return heatmap_values;
24
- }
25
- else if (typeof heatmap_values == `object`) {
26
- const bad_keys = Object.keys(heatmap_values).filter((key) => !ELEM_SYMBOLS.includes(key));
27
- if (bad_keys.length > 0) {
28
- console.error(`heatmap_values is an object, keys should be element symbols, got ${bad_keys}`);
29
- return [];
30
- }
31
- return ELEM_SYMBOLS.map((symbol) => heatmap_values[symbol] ?? 0);
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
- let set_active_element = $derived((element) => () => {
36
- if (disabled)
37
- return;
38
- active_element = element;
39
- });
40
- let window_width = $state(0);
41
- let tooltip_element = $state(null);
42
- let tooltip_pos = $state({ x: 0, y: 0 });
43
- let tooltip_visible = $state(false);
44
- function handle_key(event) {
45
- if (disabled || !active_element)
46
- return;
47
- if (event.key == `Enter`)
48
- onenter?.(active_element);
49
- const arrow_keys = [`ArrowUp`, `ArrowDown`, `ArrowLeft`, `ArrowRight`];
50
- if (!arrow_keys.includes(event.key))
51
- return;
52
- event.preventDefault(); // prevent scrolling the page
53
- event.stopPropagation();
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
- ArrowUp: row === 9 ? 6 : row === 10 ? 7 : row - 1,
59
- ArrowDown: row === 6 && in_f_block ? 9 : row === 7 && in_f_block ? 10 : row + 1,
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
- ? col - 1
64
- : event.key === `ArrowRight`
65
- ? col + 1
66
- : col;
164
+ ? col - 1
165
+ : event.key === `ArrowRight`
166
+ ? col + 1
167
+ : col
67
168
  active_element =
68
- element_data.find((el) => el.column === target_col && el.row === target_row) ??
69
- active_element;
70
- }
71
- function handle_tooltip_enter(element, event) {
72
- if (tooltip === false || disabled)
73
- return;
74
- tooltip_element = element;
75
- const target = event.currentTarget;
76
- const rect = target.getBoundingClientRect();
77
- const container_rect = target.closest(`.periodic-table`)?.getBoundingClientRect();
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
- tooltip_pos = {
80
- x: rect.left - container_rect.left + rect.width / 2,
81
- y: rect.bottom - container_rect.top + 8,
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
- let color_scale_fn = $derived(typeof color_scale == `string` ? d3_sc[color_scale] : color_scale);
87
- let cs_min = $derived(color_scale_range[0] ??
88
- (heat_values.length
89
- ? Math.min(...heat_values.flat().filter((v) => typeof v === `number`))
90
- : 0));
91
- let cs_max = $derived(color_scale_range[1] ??
92
- (heat_values.length
93
- ? Math.max(...heat_values.flat().filter((v) => typeof v === `number`))
94
- : 1));
95
- let bg_color = $derived((value, element) => {
96
- if (Array.isArray(value)) {
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
- // If it's already a color string, return it directly
101
- if (is_color(value))
102
- return value;
103
- // Return missing color for zero/invalid values or when no heatmap data
104
- if (!value ||
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
- return colors.category[element.category] || `#cccccc`;
232
+ return colors.category[element.category] || `#cccccc`
112
233
  }
113
- return missing_color;
114
- }
115
- // map value to [0, 1] range
116
- const span = cs_max - cs_min;
117
- if (span === 0)
118
- return color_scale_fn?.(0.5); // midpoint when all values equal
119
- if (log)
120
- value = Math.log(value - cs_min + 1) / Math.log(span + 1);
121
- else
122
- value = (value - cs_min) / span;
123
- return color_scale_fn?.(value);
124
- });
125
- let bg_colors = $derived((value, element) => {
126
- if (!Array.isArray(value))
127
- return [];
128
- return value.map((v) => {
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
- // Determine whether to automatically show the color bar
137
- let should_show_color_bar = $derived.by(() => {
138
- if (!show_color_bar || inset || heat_values.length === 0)
139
- return false;
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
- .flat()
142
- .filter((v) => typeof v === `number`);
143
- const usable_values = log ? num_vals.filter((v) => v > 0) : num_vals;
144
- return usable_values.length > 0;
145
- });
146
- // Calculate heat range for color bar
147
- let heat_range = $derived.by(() => {
148
- if (!should_show_color_bar)
149
- return [0, 1];
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
- .flat()
152
- .filter((v) => typeof v === `number`);
153
- const usable_values = log ? numeric_values.filter((v) => v > 0) : numeric_values;
154
- if (usable_values.length === 0)
155
- return [0, 1];
156
- const min = color_scale_range[0] ?? Math.min(...usable_values);
157
- const max = color_scale_range[1] ?? Math.max(...usable_values);
158
- return [min, max];
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-container {rest.class ?? ``}">
165
- <div class="periodic-table" style:gap>
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-container {
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
- div.periodic-table {
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
- div.periodic-table :global(.auto-colorbar-inset) {
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
- div.periodic-table :global(.auto-colorbar-inset .colorbar) {
429
+ .ptable-grid :global(.auto-colorbar-inset .colorbar) {
297
430
  width: 90%;
298
431
  }
299
432
  div.spacer {