matterviz 0.4.1 → 0.4.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 (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -1,7 +1,7 @@
1
1
  <script lang="ts">
2
2
  import { sanitize_html } from '../sanitize'
3
3
  import type { HTMLAttributes } from 'svelte/elements'
4
- import { SvelteSet } from 'svelte/reactivity'
4
+ import { create_clipboard_feedback } from './'
5
5
  import CopyButton from './CopyButton.svelte'
6
6
 
7
7
  type InfoPaneRow = {
@@ -33,7 +33,7 @@
33
33
  } = $props()
34
34
 
35
35
  let info_filter = $state(``)
36
- const copied_items = new SvelteSet<string>()
36
+ const { copied, copy } = create_clipboard_feedback()
37
37
  const row_key = (card_title: string, row: InfoPaneRow, row_idx: number): string =>
38
38
  row.key ?? `${card_title}:${row.label}:${row.value}:${row_idx}`
39
39
 
@@ -44,27 +44,16 @@
44
44
  .map((card) => ({
45
45
  ...card,
46
46
  rows: card.rows.filter(({ label, value }) =>
47
- `${card.title} ${label} ${value}`.toLowerCase().includes(filter)
47
+ `${card.title} ${label} ${value}`.toLowerCase().includes(filter),
48
48
  ),
49
49
  }))
50
50
  .filter(({ rows }) => rows.length > 0)
51
51
  })
52
52
 
53
- async function copy_row(
54
- card_title: string,
55
- row: InfoPaneRow,
56
- row_idx: number,
57
- ): Promise<void> {
58
- const key = row_key(card_title, row, row_idx)
59
- try {
60
- await navigator.clipboard.writeText(`${row.label}: ${row.value}`)
61
- copied_items.add(key)
62
- setTimeout(() => copied_items.delete(key), 1000)
63
- } catch (error) {
64
- console.error(`Failed to copy to clipboard:`, error)
65
- }
66
- }
53
+ const copy_row = (card_title: string, row: InfoPaneRow, row_idx: number): Promise<void> =>
54
+ copy(`${row.label}: ${row.value}`, row_key(card_title, row, row_idx))
67
55
  </script>
56
+
68
57
  {#if show_filter}
69
58
  <input
70
59
  class="info-filter"
@@ -78,7 +67,7 @@
78
67
  {#if filtered_cards.length === 0}
79
68
  <p class="empty-filter">No {empty_label} matches "{info_filter}".</p>
80
69
  {:else}
81
- <div {...rest} class="info-cards {rest.class ?? ``}" style:--row-label-min={row_label_min}>
70
+ <div {...rest} class={[`info-cards`, rest.class]} style:--row-label-min={row_label_min}>
82
71
  {#each filtered_cards as card (card.title)}
83
72
  <section class="info-card">
84
73
  <svelte:element this={`h${heading_level}`}>{card.title}</svelte:element>
@@ -89,7 +78,7 @@
89
78
  <CopyButton
90
79
  label="Copy {row.label}: {row.value}"
91
80
  title="Copy {row.label}"
92
- copied={copied_items.has(row_key(card.title, row, row_idx))}
81
+ copied={copied.has(row_key(card.title, row, row_idx))}
93
82
  onclick={() => copy_row(card.title, row, row_idx)}
94
83
  />
95
84
  </div>
@@ -129,10 +118,9 @@
129
118
  }
130
119
  .info-row {
131
120
  display: grid;
132
- grid-template-columns: minmax(var(--row-label-min), var(--row-label-max, 0.8fr)) minmax(
133
- 0,
134
- 1fr
135
- ) auto;
121
+ grid-template-columns:
122
+ minmax(var(--row-label-min), var(--row-label-max, 0.8fr)) minmax(0, 1fr)
123
+ auto;
136
124
  align-items: center;
137
125
  gap: 5pt;
138
126
  padding: var(--info-row-padding, 1pt 0);
@@ -1,7 +1,14 @@
1
1
  import type { ComponentProps } from 'svelte';
2
+ import { SvelteSet } from 'svelte/reactivity';
2
3
  import type DraggablePane from './DraggablePane.svelte';
3
4
  export { default as ContextMenu } from './ContextMenu.svelte';
4
5
  export { default as DraggablePane } from './DraggablePane.svelte';
5
6
  export { default as DragControlTab } from './DragControlTab.svelte';
7
+ export { default as GlassChip } from './GlassChip.svelte';
8
+ export * from './portal';
6
9
  export type PaneToggleProps = ComponentProps<typeof DraggablePane>[`toggle_props`];
7
10
  export type PaneProps = ComponentProps<typeof DraggablePane>[`pane_props`];
11
+ export declare function create_clipboard_feedback(duration?: number): {
12
+ copied: SvelteSet<string>;
13
+ copy: (text: string, key: string) => Promise<void>;
14
+ };
@@ -1,3 +1,29 @@
1
+ import { SvelteMap, SvelteSet } from 'svelte/reactivity';
1
2
  export { default as ContextMenu } from './ContextMenu.svelte';
2
3
  export { default as DraggablePane } from './DraggablePane.svelte';
3
4
  export { default as DragControlTab } from './DragControlTab.svelte';
5
+ export { default as GlassChip } from './GlassChip.svelte';
6
+ export * from './portal';
7
+ // Reactive clipboard-copy feedback shared by info panes. `copy(text, key)` writes
8
+ // `text` to the clipboard and flags `key` as recently-copied in the returned reactive
9
+ // `copied` set for `duration` ms, so UIs can show a transient "copied" checkmark.
10
+ export function create_clipboard_feedback(duration = 1000) {
11
+ const copied = new SvelteSet();
12
+ const timers = new SvelteMap();
13
+ const copy = async (text, key) => {
14
+ try {
15
+ await navigator.clipboard.writeText(text);
16
+ copied.add(key);
17
+ // reset any in-flight timer so a re-copy gets the full feedback duration
18
+ clearTimeout(timers.get(key));
19
+ timers.set(key, setTimeout(() => {
20
+ copied.delete(key);
21
+ timers.delete(key);
22
+ }, duration));
23
+ }
24
+ catch (error) {
25
+ console.error(`Failed to copy to clipboard:`, error);
26
+ }
27
+ };
28
+ return { copied, copy };
29
+ }
@@ -0,0 +1,2 @@
1
+ import type { Attachment } from 'svelte/attachments';
2
+ export declare const portal: (target: HTMLElement | null | undefined) => Attachment;
@@ -0,0 +1,14 @@
1
+ // Attachment that moves its element into `target` (e.g. a host panel's toolbar),
2
+ // so components can offer optional external placement of their chrome (search/
3
+ // export/settings buttons etc.) without duplicating markup: pass nothing and the
4
+ // element renders inline where declared; pass a target and it teleports there.
5
+ // A comment anchor marks the original position so the element is restored when
6
+ // the target changes or unmounts, keeping Svelte's teardown sound.
7
+ export const portal = (target) => (element) => {
8
+ if (!target)
9
+ return undefined;
10
+ const anchor = document.createComment(`portal`);
11
+ element.before(anchor);
12
+ target.append(element);
13
+ return () => anchor.replaceWith(element);
14
+ };
@@ -9,9 +9,13 @@
9
9
  import type { ComponentProps, Snippet } from 'svelte'
10
10
  import type { HTMLAttributes } from 'svelte/elements'
11
11
  import type { D3InterpolateName } from '../colors'
12
+ import type { MissingCellStyle } from '../heatmap-matrix'
12
13
  import type { ScaleContext } from './index'
13
14
  import { TableInset } from './index'
14
15
 
16
+ // a tile's heat value: scalar or 1-4-segment array of numbers/colors
17
+ type HeatValue = number | number[] | string | string[]
18
+
15
19
  const default_f_block_inset_tiles = [
16
20
  { name: `Lanthanides`, symbol: `La-Lu`, number: `57-71`, category: `lanthanide` },
17
21
  { name: `Actinides`, symbol: `Ac-Lr`, number: `89-103`, category: `actinide` },
@@ -36,7 +40,7 @@
36
40
  color_scale_range = [null, null],
37
41
  color_overrides = {},
38
42
  labels = {},
39
- missing_color = `element-category`,
43
+ missing = {},
40
44
  split_layout = undefined,
41
45
  show_color_bar = true,
42
46
  color_bar_props = {},
@@ -50,12 +54,10 @@
50
54
  tile_props?: Partial<ComponentProps<typeof ElementTile>>
51
55
  show_photo?: boolean
52
56
  disabled?: boolean // disable hover and click events from updating active_element
53
- // either array of numbers/colors (can be partial, missing elements default to 0) or object with
54
- // element symbol as key and heat value as value
55
- // NEW: each value can now be a single number/color or array of 1-4 numbers/colors for multi-segment display
56
- heatmap_values?:
57
- | Partial<Record<ElementSymbol, number | number[] | string | string[]>>
58
- | (number | number[] | string | string[])[]
57
+ // array (positional by atomic number, can be partial) or object keyed by element symbol.
58
+ // each value is a single number/color or an array of 1-4 numbers/colors for multi-segment
59
+ // tiles. null/omitted -> missing (uses the `missing` fallback); 0 is a real value
60
+ heatmap_values?: Partial<Record<ElementSymbol, HeatValue | null>> | (HeatValue | null)[]
59
61
  // links is either string with element property (name, symbol, number, ...) to use as link,
60
62
  // or object with mapping element symbols to link
61
63
  links?: keyof ChemicalElement | Record<ElementSymbol, string> | null
@@ -78,9 +80,7 @@
78
80
  color_scale_range?: [number | null, number | null]
79
81
  color_overrides?: Partial<Record<ElementSymbol, string>>
80
82
  labels?: Partial<Record<ElementSymbol, string>>
81
- // background color for elements missing from heatmap_values
82
- // "element-category" falls back to element category default color
83
- missing_color?: string
83
+ missing?: MissingCellStyle // styling for tiles with no heatmap value
84
84
  // control the layout of multi-value splits for all tiles
85
85
  split_layout?: `diagonal` | `horizontal` | `vertical` | `triangular` | `quadrant`
86
86
  // automatically show a color bar when heatmap_values is provided (default: true)
@@ -91,16 +91,16 @@
91
91
  bottom_left_inset?: Snippet<[{ active_element: ChemicalElement | null }]>
92
92
  tooltip?:
93
93
  | Snippet<
94
- [
95
- {
96
- element: ChemicalElement
97
- value: number | number[] | string | string[]
98
- active: boolean
99
- bg_color: string | null
100
- scale_context: ScaleContext
101
- },
102
- ]
103
- >
94
+ [
95
+ {
96
+ element: ChemicalElement
97
+ value: HeatValue | null
98
+ active: boolean
99
+ bg_color: string | null
100
+ scale_context: ScaleContext
101
+ },
102
+ ]
103
+ >
104
104
  | boolean
105
105
  children?: Snippet
106
106
  onenter?: (element: ChemicalElement) => void
@@ -114,7 +114,8 @@
114
114
  `each element possibly omitting elements at the end, got ${heatmap_values.length}`,
115
115
  )
116
116
  return []
117
- }return heatmap_values
117
+ }
118
+ return heatmap_values
118
119
  } else if (typeof heatmap_values === `object`) {
119
120
  const bad_keys = Object.keys(heatmap_values).filter(
120
121
  (key) => !ELEM_SYMBOLS.includes(key as ElementSymbol),
@@ -125,7 +126,9 @@
125
126
  )
126
127
  return []
127
128
  }
128
- return ELEM_SYMBOLS.map((symbol) => heatmap_values[symbol] ?? 0)
129
+ // keep absent elements as null (distinct from a real 0 value) so they map to the
130
+ // missing fallback while explicit 0 maps through the color scale
131
+ return ELEM_SYMBOLS.map((symbol) => heatmap_values[symbol] ?? null)
129
132
  }
130
133
  return []
131
134
  })
@@ -158,14 +161,11 @@
158
161
  ArrowDown: row === 6 && in_f_block ? 9 : row === 7 && in_f_block ? 10 : row + 1,
159
162
  }
160
163
  const target_row = row_map[event.key] ?? row
161
- const target_col = event.key === `ArrowLeft`
162
- ? col - 1
163
- : event.key === `ArrowRight`
164
- ? col + 1
165
- : col
164
+ const target_col =
165
+ event.key === `ArrowLeft` ? col - 1 : event.key === `ArrowRight` ? col + 1 : col
166
166
  active_element =
167
167
  element_data.find((el) => el.column === target_col && el.row === target_row) ??
168
- active_element
168
+ active_element
169
169
  }
170
170
 
171
171
  function handle_tooltip_enter(element: ChemicalElement, event: MouseEvent) {
@@ -188,124 +188,92 @@
188
188
  typeof color_scale === `string` ? get_d3_interpolator(color_scale) : color_scale,
189
189
  )
190
190
 
191
+ // finite numeric heat value (numeric strings coerced; colors, null/false and non-finite
192
+ // excluded so they can't poison the color-scale domain). null => not a mappable number
193
+ const to_heat_num = (value: number | string | false | null | undefined): number | null => {
194
+ if (value == null || value === false || is_color(value)) return null
195
+ const num = Number(value)
196
+ return Number.isFinite(num) ? num : null
197
+ }
198
+
199
+ let heat_nums = $derived(
200
+ heat_values
201
+ .flat()
202
+ .map(to_heat_num)
203
+ .filter((num): num is number => num !== null),
204
+ )
205
+ // values usable by the active scale (log excludes non-positive)
206
+ let usable_heat_nums = $derived(log ? heat_nums.filter((num) => num > 0) : heat_nums)
207
+
191
208
  let cs_min = $derived(
192
- color_scale_range[0] ??
193
- (heat_values.length > 0
194
- ? Math.min(
195
- ...heat_values.flat().filter((val): val is number => typeof val === `number`),
196
- )
197
- : 0),
209
+ color_scale_range[0] ?? (heat_nums.length > 0 ? Math.min(...heat_nums) : 0),
198
210
  )
199
211
  let cs_max = $derived(
200
- color_scale_range[1] ??
201
- (heat_values.length > 0
202
- ? Math.max(
203
- ...heat_values.flat().filter((val): val is number => typeof val === `number`),
204
- )
205
- : 1),
212
+ color_scale_range[1] ?? (heat_nums.length > 0 ? Math.max(...heat_nums) : 1),
206
213
  )
207
214
 
208
215
  // smallest positive bound for log color mapping (matches the auto ColorBar's log scale)
209
216
  let cs_min_pos = $derived.by(() => {
210
217
  if (cs_min > 0) return cs_min
211
- const pos = heat_values.flat().filter((val): val is number =>
212
- typeof val === `number` && val > 0
213
- )
218
+ const pos = heat_nums.filter((num) => num > 0)
214
219
  return pos.length > 0 ? Math.min(...pos) : cs_max
215
220
  })
216
221
 
217
- let bg_color = $derived(
218
- (
219
- value: number | number[] | string | string[] | false,
220
- element?: ChemicalElement,
221
- ): string | null => {
222
- if (Array.isArray(value)) {
223
- // For arrays, return the color of the first value (used as fallback)
224
- return bg_color(value[0], element)
225
- }
226
-
227
- // If it's already a color string, return it directly
228
- if (is_color(value)) return value
229
-
230
- // Return missing color for zero/invalid values or when no heatmap data
231
- if (
232
- !value ||
233
- value === 0 ||
234
- (log && value <= 0) ||
235
- !heat_values?.length ||
236
- !color_scale_fn
237
- ) {
238
- // Use missing color for zero/missing values or when no heatmap data
239
- if (missing_color === `element-category` && element) {
240
- return colors.category[element.category] || `#cccccc`
241
- }
242
- return missing_color
243
- }
244
-
245
- // map value to [0, 1] range
246
- const span = cs_max - cs_min
247
- if (span === 0) return color_scale_fn?.(0.5) // midpoint when all values equal
222
+ // whether a value maps to a heatmap color (false => use the missing fallback). 0 is a
223
+ // real value; only absent/null/non-finite (and <=0 in log mode) count as missing. a
224
+ // multi-value tile is missing only when every segment is missing
225
+ const value_is_missing = (value: HeatValue | false | null): boolean => {
226
+ if (Array.isArray(value)) return value.every(value_is_missing) // [] -> true (missing)
227
+ if (is_color(value)) return false // explicit colors are real values, not missing
228
+ const num = to_heat_num(value)
229
+ return num === null || (log && num <= 0)
230
+ }
248
231
 
249
- if (log) {
250
- // log mapping matching the log ColorBar (value <= 0 returned missing_color above)
251
- const log_span = Math.log(cs_max) - Math.log(cs_min_pos)
252
- if (log_span === 0) return color_scale_fn?.(0.5)
253
- value = (Math.log(value as number) - Math.log(cs_min_pos)) / log_span
254
- } else value = ((value as number) - cs_min) / span
255
- return color_scale_fn?.(value as number)
256
- },
257
- )
232
+ const bg_color = (
233
+ value: HeatValue | false | null,
234
+ element?: ChemicalElement,
235
+ ): string | null => {
236
+ if (Array.isArray(value)) return bg_color(value[0], element) // arrays: use first value
237
+ if (is_color(value)) return value // already a color string
238
+
239
+ if (!heat_values.length || !color_scale_fn || value_is_missing(value)) {
240
+ const category_color = (element && colors.category[element.category]) || `#cccccc`
241
+ if (missing.color === `element-category`) return category_color
242
+ // default: category colors for a plain table, gray for missing heatmap data
243
+ return missing.color || (heat_values.length ? `#666` : category_color)
244
+ }
258
245
 
259
- let bg_colors = $derived(
260
- (
261
- value: number | number[] | string | string[] | false,
262
- element?: ChemicalElement,
263
- ) => {
264
- if (!Array.isArray(value)) return []
246
+ // map value to [0, 1] range
247
+ const num = Number(value)
248
+ const span = cs_max - cs_min
249
+ if (span === 0) return color_scale_fn(0.5) // midpoint when all values equal
250
+ if (log) {
251
+ const log_span = Math.log(cs_max) - Math.log(cs_min_pos)
252
+ if (log_span === 0) return color_scale_fn(0.5)
253
+ return color_scale_fn((Math.log(num) - Math.log(cs_min_pos)) / log_span)
254
+ }
255
+ return color_scale_fn((num - cs_min) / span)
256
+ }
265
257
 
266
- return value.map((val) => {
267
- // If it's already a color string, return it directly
268
- if (is_color(val)) return val
269
- // Otherwise, map it through the color scale
270
- return bg_color(val as number, element)
271
- })
272
- },
273
- )
258
+ // per-segment colors for multi-value tiles (bg_color already handles color strings)
259
+ const bg_colors = (value: HeatValue | false, element?: ChemicalElement) =>
260
+ Array.isArray(value) ? value.map((val) => bg_color(val, element)) : []
274
261
 
275
262
  // Determine whether to automatically show the color bar
276
- let should_show_color_bar = $derived.by(() => {
277
- if (!show_color_bar || inset || heat_values.length === 0) return false
278
-
279
- const num_vals = heat_values
280
- .flat()
281
- .filter((val): val is number => typeof val === `number`)
282
-
283
- const usable_values = log ? num_vals.filter((val) => val > 0) : num_vals
284
-
285
- return usable_values.length > 0
286
- })
263
+ let should_show_color_bar = $derived(show_color_bar && !inset && usable_heat_nums.length > 0)
287
264
 
288
265
  // Calculate heat range for color bar
289
266
  let heat_range = $derived.by((): Vec2 => {
290
267
  if (!should_show_color_bar) return [0, 1]
291
-
292
- const numeric_values = heat_values
293
- .flat()
294
- .filter((val): val is number => typeof val === `number`)
295
- const usable_values = log ? numeric_values.filter((val) => val > 0) : numeric_values
296
-
297
- if (usable_values.length === 0) return [0, 1]
298
-
299
- const min = color_scale_range[0] ?? Math.min(...usable_values)
300
- const max = color_scale_range[1] ?? Math.max(...usable_values)
301
-
268
+ const min = color_scale_range[0] ?? Math.min(...usable_heat_nums)
269
+ const max = color_scale_range[1] ?? Math.max(...usable_heat_nums)
302
270
  return [min, max]
303
271
  })
304
272
  </script>
305
273
 
306
274
  <svelte:window bind:innerWidth={window_width} onkeydown={handle_key} />
307
275
 
308
- <div {...rest} class="periodic-table {rest.class ?? ``}">
276
+ <div {...rest} class={[`periodic-table`, rest.class]}>
309
277
  <div class="ptable-grid" style:gap>
310
278
  {#if should_show_color_bar}
311
279
  <TableInset class="auto-colorbar-inset">
@@ -326,28 +294,32 @@
326
294
  {#each element_data as element (element.number)}
327
295
  {@const { column, row, category, name, symbol } = element}
328
296
  {@const value = heat_values[element.number - 1]}
297
+ {@const override = color_overrides[symbol]}
298
+ {@const tile_missing = heat_values.length > 0 && !override && value_is_missing(value)}
329
299
  {@const is_active_elem = active_elements?.some((active_elem) =>
330
300
  typeof active_elem === `string`
331
301
  ? active_elem === symbol
332
- : active_elem?.symbol === symbol
302
+ : active_elem?.symbol === symbol,
333
303
  )}
334
- {@const active = active_category === category ||
335
- active_element?.name === name || is_active_elem}
336
- {@const style = `grid-column: ${column}; grid-row: ${row};`}
304
+ {@const active =
305
+ active_category === category || active_element?.name === name || is_active_elem}
306
+ {@const style = `grid-column: ${column}; grid-row: ${row};${
307
+ tile_props?.style ? ` ${tile_props.style}` : ``
308
+ }${tile_missing && missing.style ? ` ${missing.style}` : ``}`}
337
309
  <ElementTile
338
310
  {element}
339
311
  href={links
340
- ? typeof links == `string`
341
- ? `/${element[links]}`.toLowerCase()
342
- : links[symbol]
343
- : undefined}
344
- {style}
345
- {value}
346
- bg_color={color_overrides[symbol] ?? bg_color(value, element) ?? undefined}
347
- bg_colors={Array.isArray(value) ? bg_colors(value, element) : []}
312
+ ? typeof links == `string`
313
+ ? `/${element[links]}`.toLowerCase()
314
+ : links[symbol]
315
+ : undefined}
316
+ value={tile_missing ? undefined : (value ?? undefined)}
317
+ bg_color={override ?? bg_color(value, element) ?? undefined}
318
+ bg_colors={!override && Array.isArray(value) ? bg_colors(value, element) : []}
348
319
  {active}
349
- label={labels[symbol]}
320
+ label={labels[symbol] ?? (tile_missing ? missing.label : undefined)}
350
321
  {...tile_props}
322
+ {style}
351
323
  onmouseenter={(event: MouseEvent) => {
352
324
  set_active_element(element)()
353
325
  handle_tooltip_enter(element, event)
@@ -390,17 +362,16 @@
390
362
  {#if tooltip_visible && tooltip_element}
391
363
  {@const el = tooltip_element as ChemicalElement}
392
364
  {@const style = `left: ${tooltip_pos.x}px; top: ${tooltip_pos.y}px;`}
393
- {@const tooltip_value = heat_values[el.number - 1] ?? 0}
365
+ {@const tooltip_value = heat_values[el.number - 1]}
394
366
  {#if typeof tooltip == `function`}
395
367
  <div class="tooltip" {style}>
396
368
  {@render tooltip({
397
- element: el,
398
- value: tooltip_value,
399
- active: active_category === el.category ||
400
- active_element?.name === el.name,
401
- bg_color: color_overrides[el.symbol] ?? bg_color(tooltip_value, el),
402
- scale_context: { min: cs_min, max: cs_max, color_scale },
403
- })}
369
+ element: el,
370
+ value: tooltip_value ?? null,
371
+ active: active_category === el.category || active_element?.name === el.name,
372
+ bg_color: color_overrides[el.symbol] ?? bg_color(tooltip_value, el),
373
+ scale_context: { min: log ? cs_min_pos : cs_min, max: cs_max, color_scale },
374
+ })}
404
375
  </div>
405
376
  {:else if tooltip !== false}
406
377
  <div class="tooltip" {style}>
@@ -448,10 +419,7 @@
448
419
  .tooltip {
449
420
  position: absolute;
450
421
  transform: translate(-50%, -10%);
451
- background: var(
452
- --tooltip-bg,
453
- light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.85))
454
- );
422
+ background: var(--tooltip-bg, light-dark(rgba(255, 255, 255, 0.95), rgba(0, 0, 0, 0.85)));
455
423
  color: var(--tooltip-color, light-dark(#222, #eee));
456
424
  padding: var(--tooltip-padding, 4px 6px);
457
425
  border-radius: var(--tooltip-border-radius, var(--border-radius, 3pt));
@@ -4,12 +4,14 @@ import { ColorBar } from '../plot';
4
4
  import type { ComponentProps, Snippet } from 'svelte';
5
5
  import type { HTMLAttributes } from 'svelte/elements';
6
6
  import type { D3InterpolateName } from '../colors';
7
+ import type { MissingCellStyle } from '../heatmap-matrix';
7
8
  import type { ScaleContext } from './index';
9
+ type HeatValue = number | number[] | string | string[];
8
10
  type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
9
11
  tile_props?: Partial<ComponentProps<typeof ElementTile>>;
10
12
  show_photo?: boolean;
11
13
  disabled?: boolean;
12
- heatmap_values?: Partial<Record<ElementSymbol, number | number[] | string | string[]>> | (number | number[] | string | string[])[];
14
+ heatmap_values?: Partial<Record<ElementSymbol, HeatValue | null>> | (HeatValue | null)[];
13
15
  links?: keyof ChemicalElement | Record<ElementSymbol, string> | null;
14
16
  log?: boolean;
15
17
  color_scale?: D3InterpolateName | ((num: number) => string);
@@ -28,7 +30,7 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
28
30
  color_scale_range?: [number | null, number | null];
29
31
  color_overrides?: Partial<Record<ElementSymbol, string>>;
30
32
  labels?: Partial<Record<ElementSymbol, string>>;
31
- missing_color?: string;
33
+ missing?: MissingCellStyle;
32
34
  split_layout?: `diagonal` | `horizontal` | `vertical` | `triangular` | `quadrant`;
33
35
  show_color_bar?: boolean;
34
36
  color_bar_props?: Partial<ComponentProps<typeof ColorBar>>;
@@ -41,7 +43,7 @@ type $$ComponentProps = HTMLAttributes<HTMLDivElement> & {
41
43
  tooltip?: Snippet<[
42
44
  {
43
45
  element: ChemicalElement;
44
- value: number | number[] | string | string[];
46
+ value: HeatValue | null;
45
47
  active: boolean;
46
48
  bg_color: string | null;
47
49
  scale_context: ScaleContext;