matterviz 0.4.0 → 0.4.2

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 (527) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +12 -14
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/app.css +53 -0
  6. package/dist/brillouin/BrillouinZone.svelte +132 -219
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +9 -20
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +47 -96
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +15 -42
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  13. package/dist/brillouin/BrillouinZoneScene.svelte +63 -230
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +3 -23
  15. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  16. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  17. package/dist/brillouin/compute.d.ts +2 -0
  18. package/dist/brillouin/compute.js +80 -77
  19. package/dist/brillouin/geometry.d.ts +8 -0
  20. package/dist/brillouin/geometry.js +57 -0
  21. package/dist/brillouin/index.d.ts +2 -0
  22. package/dist/brillouin/index.js +2 -0
  23. package/dist/brillouin/types.d.ts +2 -2
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  25. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +143 -246
  27. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +652 -976
  29. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  30. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  31. package/dist/chempot-diagram/color.d.ts +3 -6
  32. package/dist/chempot-diagram/color.js +5 -5
  33. package/dist/chempot-diagram/compute.d.ts +3 -3
  34. package/dist/chempot-diagram/compute.js +3 -1
  35. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  36. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  37. package/dist/chempot-diagram/export.d.ts +47 -0
  38. package/dist/chempot-diagram/export.js +133 -0
  39. package/dist/chempot-diagram/index.d.ts +1 -0
  40. package/dist/chempot-diagram/index.js +1 -0
  41. package/dist/chempot-diagram/pointer.d.ts +0 -10
  42. package/dist/chempot-diagram/pointer.js +4 -4
  43. package/dist/chempot-diagram/types.d.ts +3 -3
  44. package/dist/colors/index.d.ts +0 -4
  45. package/dist/colors/index.js +21 -22
  46. package/dist/composition/BarChart.svelte +37 -31
  47. package/dist/composition/BubbleChart.svelte +17 -17
  48. package/dist/composition/Composition.svelte +7 -11
  49. package/dist/composition/Formula.svelte +18 -25
  50. package/dist/composition/FormulaFilter.svelte +96 -98
  51. package/dist/composition/PieChart.svelte +60 -46
  52. package/dist/composition/chem-sys.js +3 -2
  53. package/dist/composition/format.js +4 -3
  54. package/dist/composition/index.d.ts +2 -0
  55. package/dist/composition/index.js +14 -0
  56. package/dist/composition/parse.d.ts +2 -3
  57. package/dist/composition/parse.js +27 -28
  58. package/dist/constants.js +11 -9
  59. package/dist/controls.d.ts +1 -0
  60. package/dist/controls.js +0 -1
  61. package/dist/convex-hull/ConvexHull.svelte +20 -25
  62. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  63. package/dist/convex-hull/ConvexHull2D.svelte +176 -256
  64. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  65. package/dist/convex-hull/ConvexHull3D.svelte +269 -804
  66. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  67. package/dist/convex-hull/ConvexHull4D.svelte +236 -755
  68. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  69. package/dist/convex-hull/ConvexHullChrome.svelte +264 -0
  70. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  71. package/dist/convex-hull/ConvexHullControls.svelte +128 -49
  72. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  73. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  74. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  75. package/dist/convex-hull/ConvexHullStats.svelte +210 -351
  76. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  77. package/dist/convex-hull/ConvexHullTooltip.svelte +16 -14
  78. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  79. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  80. package/dist/convex-hull/StructurePopup.svelte +17 -21
  81. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  82. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  83. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  84. package/dist/convex-hull/barycentric-coords.js +6 -33
  85. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  86. package/dist/convex-hull/canvas-interactions.svelte.js +279 -0
  87. package/dist/convex-hull/helpers.d.ts +47 -17
  88. package/dist/convex-hull/helpers.js +186 -101
  89. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  90. package/dist/convex-hull/hull-state.svelte.js +124 -0
  91. package/dist/convex-hull/index.d.ts +9 -7
  92. package/dist/convex-hull/index.js +7 -2
  93. package/dist/convex-hull/thermodynamics.js +109 -937
  94. package/dist/convex-hull/types.d.ts +12 -4
  95. package/dist/convex-hull/types.js +12 -0
  96. package/dist/coordination/CoordinationBarPlot.svelte +41 -43
  97. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  98. package/dist/coordination/calc-coordination.d.ts +1 -1
  99. package/dist/coordination/calc-coordination.js +28 -25
  100. package/dist/element/BohrAtom.svelte +6 -8
  101. package/dist/element/ElementHeading.svelte +4 -1
  102. package/dist/element/ElementPhoto.svelte +11 -9
  103. package/dist/element/ElementStats.svelte +12 -10
  104. package/dist/element/ElementTile.svelte +24 -29
  105. package/dist/element/ElementTile.svelte.d.ts +1 -1
  106. package/dist/element/Nucleus.svelte +4 -2
  107. package/dist/element/data.d.ts +1 -2
  108. package/dist/element/helpers.d.ts +4 -0
  109. package/dist/element/helpers.js +18 -0
  110. package/dist/element/index.d.ts +1 -0
  111. package/dist/element/index.js +3 -0
  112. package/dist/feedback/DragOverlay.svelte +5 -3
  113. package/dist/feedback/DragOverlay.svelte.d.ts +2 -1
  114. package/dist/feedback/StatusMessage.svelte +20 -7
  115. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  116. package/dist/fermi-surface/FermiSurface.svelte +78 -165
  117. package/dist/fermi-surface/FermiSurface.svelte.d.ts +9 -20
  118. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  119. package/dist/fermi-surface/FermiSurfaceScene.svelte +93 -272
  120. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  121. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  122. package/dist/fermi-surface/compute.js +14 -13
  123. package/dist/fermi-surface/export.js +4 -15
  124. package/dist/fermi-surface/index.d.ts +0 -1
  125. package/dist/fermi-surface/index.js +0 -1
  126. package/dist/fermi-surface/parse.d.ts +1 -1
  127. package/dist/fermi-surface/parse.js +84 -97
  128. package/dist/fermi-surface/types.d.ts +2 -2
  129. package/dist/heatmap-matrix/HeatmapMatrix.svelte +161 -185
  130. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +6 -5
  131. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +12 -9
  132. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  133. package/dist/heatmap-matrix/index.d.ts +8 -2
  134. package/dist/icons.d.ts +4 -0
  135. package/dist/icons.js +4 -0
  136. package/dist/index.d.ts +1 -0
  137. package/dist/index.js +1 -0
  138. package/dist/io/ExportPane.svelte +170 -0
  139. package/dist/io/ExportPane.svelte.d.ts +17 -0
  140. package/dist/io/decompress.d.ts +2 -1
  141. package/dist/io/decompress.js +22 -36
  142. package/dist/io/export.d.ts +9 -1
  143. package/dist/io/export.js +37 -29
  144. package/dist/io/fetch.d.ts +2 -4
  145. package/dist/io/fetch.js +0 -11
  146. package/dist/io/file-drop.d.ts +7 -0
  147. package/dist/io/file-drop.js +13 -0
  148. package/dist/io/index.d.ts +1 -0
  149. package/dist/io/index.js +3 -0
  150. package/dist/io/is-binary.d.ts +9 -0
  151. package/dist/io/is-binary.js +45 -1
  152. package/dist/io/types.d.ts +13 -0
  153. package/dist/io/url-drop.js +13 -25
  154. package/dist/isosurface/Isosurface.svelte +17 -23
  155. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  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 +50 -48
  159. package/dist/labels.d.ts +6 -2
  160. package/dist/labels.js +44 -14
  161. package/dist/layout/FullscreenButton.svelte +34 -0
  162. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  163. package/dist/layout/FullscreenToggle.svelte +12 -12
  164. package/dist/layout/InfoCard.svelte +7 -18
  165. package/dist/layout/InfoTag.svelte +1 -3
  166. package/dist/layout/NumberRangeInput.svelte +46 -0
  167. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  168. package/dist/layout/PropertyFilter.svelte +2 -6
  169. package/dist/layout/SettingsSection.svelte +21 -17
  170. package/dist/layout/SubpageGrid.svelte +3 -1
  171. package/dist/layout/ViewerChrome.svelte +115 -0
  172. package/dist/layout/ViewerChrome.svelte.d.ts +18 -0
  173. package/dist/layout/fullscreen.d.ts +4 -0
  174. package/dist/layout/fullscreen.js +3 -5
  175. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  176. package/dist/layout/fullscreen.svelte.js +36 -0
  177. package/dist/layout/index.d.ts +4 -0
  178. package/dist/layout/index.js +4 -0
  179. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  180. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  181. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  182. package/dist/layout/json-tree/utils.js +14 -23
  183. package/dist/math.d.ts +9 -3
  184. package/dist/math.js +37 -21
  185. package/dist/overlays/ContextMenu.svelte +4 -2
  186. package/dist/overlays/CopyButton.svelte +11 -5
  187. package/dist/overlays/DragControlTab.svelte +6 -1
  188. package/dist/overlays/DraggablePane.svelte +81 -26
  189. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  190. package/dist/overlays/GlassChip.svelte +30 -0
  191. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  192. package/dist/overlays/InfoPaneCards.svelte +11 -23
  193. package/dist/overlays/index.d.ts +11 -0
  194. package/dist/overlays/index.js +26 -0
  195. package/dist/overlays/portal.d.ts +2 -0
  196. package/dist/overlays/portal.js +14 -0
  197. package/dist/periodic-table/PeriodicTable.svelte +115 -146
  198. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  199. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  200. package/dist/periodic-table/TableInset.svelte +9 -4
  201. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  202. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  203. package/dist/phase-diagram/PhaseDiagramControls.svelte +73 -96
  204. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  205. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  206. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  207. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +49 -134
  208. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  209. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  210. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  211. package/dist/phase-diagram/build-diagram.js +3 -3
  212. package/dist/phase-diagram/colors.js +1 -1
  213. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  214. package/dist/phase-diagram/parse.d.ts +2 -1
  215. package/dist/phase-diagram/parse.js +15 -15
  216. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  217. package/dist/phase-diagram/utils.js +2 -3
  218. package/dist/plot/bar/BarPlot.svelte +494 -692
  219. package/dist/plot/bar/BarPlot.svelte.d.ts +9 -15
  220. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  221. package/dist/plot/bar/BarPlotControls.svelte.d.ts +5 -7
  222. package/dist/plot/bar/SpacegroupBarPlot.svelte +31 -37
  223. package/dist/plot/bar/data.d.ts +5 -4
  224. package/dist/plot/bar/data.js +2 -1
  225. package/dist/plot/box/BoxPlot.svelte +361 -439
  226. package/dist/plot/box/BoxPlot.svelte.d.ts +6 -3
  227. package/dist/plot/box/BoxPlotControls.svelte.d.ts +1 -1
  228. package/dist/plot/box/Violin.svelte.d.ts +2 -1
  229. package/dist/plot/box/box-plot.d.ts +3 -2
  230. package/dist/plot/box/box-plot.js +6 -3
  231. package/dist/plot/box/kde.d.ts +2 -1
  232. package/dist/plot/box/kde.js +4 -4
  233. package/dist/plot/core/auto-place.d.ts +1 -1
  234. package/dist/plot/core/auto-place.js +5 -2
  235. package/dist/plot/core/axis-utils.d.ts +12 -7
  236. package/dist/plot/core/axis-utils.js +48 -48
  237. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  238. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  239. package/dist/plot/core/components/ColorBar.svelte +106 -111
  240. package/dist/plot/core/components/ColorBar.svelte.d.ts +5 -4
  241. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  242. package/dist/plot/core/components/FillArea.svelte +10 -17
  243. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  244. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  245. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  246. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  247. package/dist/plot/core/components/Line.svelte +21 -11
  248. package/dist/plot/core/components/Line.svelte.d.ts +5 -2
  249. package/dist/plot/core/components/PlotAxis.svelte +42 -18
  250. package/dist/plot/core/components/PlotAxis.svelte.d.ts +2 -1
  251. package/dist/plot/core/components/PlotControls.svelte +65 -41
  252. package/dist/plot/core/components/PlotControls.svelte.d.ts +1 -1
  253. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  254. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  255. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  256. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  257. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  258. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  259. package/dist/plot/core/components/ReferenceLine3D.svelte +56 -59
  260. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +4 -4
  261. package/dist/plot/core/components/ReferencePlane.svelte +9 -10
  262. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +4 -4
  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 +29 -476
  271. package/dist/plot/core/data-transform.js +9 -5
  272. package/dist/plot/core/fill-utils.d.ts +7 -4
  273. package/dist/plot/core/fill-utils.js +34 -9
  274. package/dist/plot/core/index.d.ts +1 -0
  275. package/dist/plot/core/index.js +1 -0
  276. package/dist/plot/core/interactions.d.ts +5 -1
  277. package/dist/plot/core/interactions.js +14 -2
  278. package/dist/plot/core/layout.d.ts +3 -1
  279. package/dist/plot/core/layout.js +22 -13
  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 +35 -0
  283. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  284. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -0
  286. package/dist/plot/core/reference-line.d.ts +10 -10
  287. package/dist/plot/core/reference-line.js +7 -7
  288. package/dist/plot/core/scales.d.ts +40 -25
  289. package/dist/plot/core/scales.js +49 -21
  290. package/dist/plot/core/svg.d.ts +2 -1
  291. package/dist/plot/core/types/fills.d.ts +101 -0
  292. package/dist/plot/core/types/fills.js +15 -0
  293. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  294. package/dist/plot/core/types/plot-3d.js +4 -0
  295. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  296. package/dist/plot/core/types/reference-lines.js +9 -0
  297. package/dist/plot/core/types.d.ts +47 -331
  298. package/dist/plot/core/types.js +23 -20
  299. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  300. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  301. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  302. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  303. package/dist/plot/core/utils/label-placement.d.ts +1 -1
  304. package/dist/plot/core/utils/label-placement.js +5 -5
  305. package/dist/plot/core/utils.d.ts +2 -1
  306. package/dist/plot/histogram/Histogram.svelte +373 -631
  307. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  308. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  309. package/dist/plot/histogram/HistogramControls.svelte.d.ts +1 -1
  310. package/dist/plot/histogram/histogram.d.ts +31 -0
  311. package/dist/plot/histogram/histogram.js +70 -0
  312. package/dist/plot/histogram/index.d.ts +1 -0
  313. package/dist/plot/histogram/index.js +1 -0
  314. package/dist/plot/index.d.ts +1 -0
  315. package/dist/plot/index.js +1 -0
  316. package/dist/plot/sankey/Sankey.svelte +79 -73
  317. package/dist/plot/sankey/Sankey.svelte.d.ts +3 -3
  318. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  319. package/dist/plot/sankey/sankey.js +3 -1
  320. package/dist/plot/scatter/BinnedScatterPlot.svelte +264 -112
  321. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +11 -4
  322. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  323. package/dist/plot/scatter/ScatterPlot.svelte +623 -821
  324. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +9 -15
  325. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  326. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  327. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  328. package/dist/plot/scatter/binned-scatter-types.d.ts +6 -12
  329. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  330. package/dist/plot/scatter/index.d.ts +1 -1
  331. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  332. package/dist/plot/scatter/scatter-data.js +8 -7
  333. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +40 -60
  334. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +6 -14
  335. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +17 -15
  336. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +5 -5
  337. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +232 -234
  338. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +5 -14
  339. package/dist/plot/scatter-3d/Surface3D.svelte +9 -17
  340. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +4 -3
  341. package/dist/plot/sunburst/Sunburst.svelte +256 -338
  342. package/dist/plot/sunburst/Sunburst.svelte.d.ts +4 -3
  343. package/dist/plot/sunburst/index.d.ts +1 -1
  344. package/dist/plot/sunburst/index.js +2 -1
  345. package/dist/plot/sunburst/render.d.ts +2 -2
  346. package/dist/plot/sunburst/render.js +47 -22
  347. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  348. package/dist/plot/sunburst/sunburst.js +14 -4
  349. package/dist/plot/treemap/Treemap.svelte +907 -0
  350. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  351. package/dist/plot/treemap/index.d.ts +3 -0
  352. package/dist/plot/treemap/index.js +4 -0
  353. package/dist/plot/treemap/treemap.d.ts +26 -0
  354. package/dist/plot/treemap/treemap.js +99 -0
  355. package/dist/rdf/RdfPlot.svelte +22 -26
  356. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  357. package/dist/rdf/calc-rdf.js +4 -8
  358. package/dist/sanitize.js +14 -3
  359. package/dist/scene/SceneCamera.svelte +62 -0
  360. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  361. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  362. package/dist/scene/bind-renderer.svelte.js +22 -0
  363. package/dist/scene/index.d.ts +4 -0
  364. package/dist/scene/index.js +5 -0
  365. package/dist/scene/props.js +52 -0
  366. package/dist/scene/types.d.ts +26 -0
  367. package/dist/scene/types.js +1 -0
  368. package/dist/settings.d.ts +33 -11
  369. package/dist/settings.js +136 -51
  370. package/dist/spectral/Bands.svelte +231 -237
  371. package/dist/spectral/Bands.svelte.d.ts +3 -2
  372. package/dist/spectral/BandsAndDos.svelte +29 -29
  373. package/dist/spectral/BrillouinBandsDos.svelte +21 -29
  374. package/dist/spectral/Dos.svelte +75 -77
  375. package/dist/spectral/Dos.svelte.d.ts +2 -1
  376. package/dist/spectral/helpers.d.ts +9 -9
  377. package/dist/spectral/helpers.js +66 -70
  378. package/dist/state.svelte.d.ts +0 -7
  379. package/dist/state.svelte.js +5 -24
  380. package/dist/structure/Arrow.svelte +6 -21
  381. package/dist/structure/ArrowInstances.svelte +160 -0
  382. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  383. package/dist/structure/AtomLegend.svelte +115 -75
  384. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  385. package/dist/structure/Bond.svelte +31 -23
  386. package/dist/structure/CanvasTooltip.svelte +16 -3
  387. package/dist/structure/CellSelect.svelte +22 -29
  388. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  389. package/dist/structure/Cylinder.svelte +24 -40
  390. package/dist/structure/InstancedAtoms.svelte +114 -0
  391. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  392. package/dist/structure/Lattice.svelte +85 -149
  393. package/dist/structure/SiteLabels.svelte +122 -0
  394. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  395. package/dist/structure/Structure.svelte +725 -735
  396. package/dist/structure/Structure.svelte.d.ts +8 -16
  397. package/dist/structure/StructureCarousel.svelte +630 -0
  398. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  399. package/dist/structure/StructureControls.svelte +298 -325
  400. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  401. package/dist/structure/StructureExportPane.svelte +62 -168
  402. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  403. package/dist/structure/StructureInfoPane.svelte +77 -69
  404. package/dist/structure/StructureInfoPane.svelte.d.ts +6 -6
  405. package/dist/structure/StructureScene.svelte +758 -600
  406. package/dist/structure/StructureScene.svelte.d.ts +24 -20
  407. package/dist/structure/StructureViewport.svelte +386 -0
  408. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  409. package/dist/structure/atom-label-placement.d.ts +18 -0
  410. package/dist/structure/atom-label-placement.js +115 -0
  411. package/dist/structure/atom-properties.d.ts +3 -1
  412. package/dist/structure/atom-properties.js +115 -54
  413. package/dist/structure/bond-order-perception.js +2 -4
  414. package/dist/structure/bonding.d.ts +12 -2
  415. package/dist/structure/bonding.js +172 -73
  416. package/dist/structure/edit-history.d.ts +6 -0
  417. package/dist/structure/edit-history.js +27 -0
  418. package/dist/structure/export.d.ts +25 -4
  419. package/dist/structure/export.js +103 -153
  420. package/dist/structure/format-detect.d.ts +1 -0
  421. package/dist/structure/format-detect.js +22 -0
  422. package/dist/structure/geometry.d.ts +9 -0
  423. package/dist/structure/geometry.js +27 -0
  424. package/dist/structure/index.d.ts +18 -1
  425. package/dist/structure/index.js +15 -2
  426. package/dist/structure/measure.d.ts +1 -1
  427. package/dist/structure/measure.js +6 -12
  428. package/dist/structure/parse.d.ts +5 -3
  429. package/dist/structure/parse.js +551 -567
  430. package/dist/structure/partial-occupancy.d.ts +0 -1
  431. package/dist/structure/partial-occupancy.js +5 -3
  432. package/dist/structure/pbc.d.ts +1 -1
  433. package/dist/structure/pbc.js +204 -51
  434. package/dist/structure/polyhedra.d.ts +40 -0
  435. package/dist/structure/polyhedra.js +587 -0
  436. package/dist/structure/site.d.ts +4 -0
  437. package/dist/structure/site.js +1 -0
  438. package/dist/structure/supercell.d.ts +1 -2
  439. package/dist/structure/supercell.js +10 -15
  440. package/dist/structure/validation.js +5 -6
  441. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  442. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  443. package/dist/symmetry/SymmetryElements.svelte +350 -0
  444. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  445. package/dist/symmetry/SymmetryStats.svelte +142 -49
  446. package/dist/symmetry/WyckoffTable.svelte +58 -16
  447. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  448. package/dist/symmetry/cell-transform.js +8 -14
  449. package/dist/symmetry/index.d.ts +15 -4
  450. package/dist/symmetry/index.js +308 -81
  451. package/dist/symmetry/spacegroups.d.ts +5 -1
  452. package/dist/symmetry/spacegroups.js +18 -3
  453. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  454. package/dist/symmetry/symmetry-elements.js +521 -0
  455. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  456. package/dist/symmetry/wyckoff-db.js +87 -0
  457. package/dist/table/HeatmapTable.svelte +1104 -378
  458. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  459. package/dist/table/ToggleMenu.svelte +5 -12
  460. package/dist/table/index.d.ts +21 -6
  461. package/dist/table/index.js +34 -21
  462. package/dist/theme/ThemeControl.svelte +16 -8
  463. package/dist/theme/index.d.ts +1 -5
  464. package/dist/theme/index.js +4 -10
  465. package/dist/theme/themes.mjs +14 -7
  466. package/dist/tooltip/KCoords.svelte +4 -1
  467. package/dist/tooltip/TooltipContent.svelte +2 -5
  468. package/dist/trajectory/Trajectory.svelte +556 -352
  469. package/dist/trajectory/Trajectory.svelte.d.ts +10 -22
  470. package/dist/trajectory/TrajectoryError.svelte +11 -8
  471. package/dist/trajectory/TrajectoryExportPane.svelte +28 -54
  472. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  473. package/dist/trajectory/TrajectoryInfoPane.svelte +88 -99
  474. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  475. package/dist/trajectory/constants.js +6 -2
  476. package/dist/trajectory/extract.js +73 -71
  477. package/dist/trajectory/format-detect.d.ts +0 -1
  478. package/dist/trajectory/format-detect.js +13 -17
  479. package/dist/trajectory/frame-reader.d.ts +2 -1
  480. package/dist/trajectory/frame-reader.js +74 -136
  481. package/dist/trajectory/helpers.d.ts +12 -2
  482. package/dist/trajectory/helpers.js +68 -37
  483. package/dist/trajectory/index.d.ts +1 -0
  484. package/dist/trajectory/index.js +3 -0
  485. package/dist/trajectory/parse/ase.d.ts +9 -1
  486. package/dist/trajectory/parse/ase.js +47 -32
  487. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  488. package/dist/trajectory/parse/diagnostics.js +14 -0
  489. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  490. package/dist/trajectory/parse/h5-utils.js +109 -0
  491. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  492. package/dist/trajectory/parse/hdf5.js +116 -106
  493. package/dist/trajectory/parse/index.d.ts +3 -4
  494. package/dist/trajectory/parse/index.js +68 -119
  495. package/dist/trajectory/parse/lammps.d.ts +0 -2
  496. package/dist/trajectory/parse/lammps.js +14 -16
  497. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  498. package/dist/trajectory/parse/pymatgen.js +74 -0
  499. package/dist/trajectory/parse/vasp.js +13 -9
  500. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  501. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  502. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  503. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  504. package/dist/trajectory/parse/xyz.d.ts +9 -21
  505. package/dist/trajectory/parse/xyz.js +38 -39
  506. package/dist/trajectory/plotting.d.ts +8 -10
  507. package/dist/trajectory/plotting.js +102 -127
  508. package/dist/utils.d.ts +4 -0
  509. package/dist/utils.js +8 -1
  510. package/dist/xrd/XrdPlot.svelte +56 -85
  511. package/dist/xrd/broadening.d.ts +2 -1
  512. package/dist/xrd/broadening.js +2 -1
  513. package/dist/xrd/calc-xrd.js +8 -15
  514. package/dist/xrd/index.d.ts +2 -2
  515. package/dist/xrd/parse.d.ts +0 -1
  516. package/dist/xrd/parse.js +56 -73
  517. package/package.json +77 -36
  518. package/dist/api/mp.d.ts +0 -6
  519. package/dist/api/mp.js +0 -22
  520. package/dist/element/data.json +0 -11864
  521. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  522. package/dist/fermi-surface/marching-cubes.js +0 -2
  523. package/dist/plot/core/hover-lock.svelte.d.ts +0 -14
  524. package/dist/plot/core/hover-lock.svelte.js +0 -45
  525. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  526. package/dist/structure/label-placement.d.ts +0 -14
  527. package/dist/structure/label-placement.js +0 -72
@@ -10,10 +10,7 @@
10
10
  import { colors } from '../state.svelte'
11
11
  import type { AnyStructure } from './'
12
12
  import { atomic_radii } from './'
13
- import type {
14
- AtomColorConfig,
15
- AtomPropertyColors,
16
- } from './atom-properties'
13
+ import type { AtomColorConfig, AtomPropertyColors } from './atom-properties'
17
14
  import type { MoyoDataset } from '@spglib/moyo-wasm'
18
15
  import type { Snippet } from 'svelte'
19
16
  import { click_outside, tooltip } from 'svelte-multiselect/attachments'
@@ -77,8 +74,7 @@
77
74
  }
78
75
 
79
76
  let show_element_legend = $derived(
80
- atom_color_config.mode === `element` && elements &&
81
- Object.keys(elements).length > 0,
77
+ atom_color_config.mode === `element` && elements && Object.keys(elements).length > 0,
82
78
  )
83
79
  let show_property_legend = $derived(
84
80
  atom_color_config.mode !== `element` && property_colors?.colors.length,
@@ -111,33 +107,43 @@
111
107
  let format_value = (val: number | string): string => {
112
108
  if (typeof val === `number`) return format_num(val, `.3~f`)
113
109
 
114
- if (typeof val === `string` && val.includes(`|`)) { // Format Wyckoff orbit IDs
110
+ if (typeof val === `string` && val.includes(`|`)) {
111
+ // Format Wyckoff orbit IDs
115
112
  const [wyckoff, element] = val.split(`|`, 2)
116
113
  // Count how many sites have this wyckoff+element combination
117
- const count = property_colors?.values.filter((property_value) =>
118
- property_value === val
119
- ).length ?? 0
114
+ const count =
115
+ property_colors?.values.filter((property_value) => property_value === val).length ?? 0
120
116
  return `${element}:${count}${wyckoff}`
121
117
  }
122
118
  return String(val)
123
119
  }
124
120
 
125
- // Map from property value to color (computed once, reused in categorical legend)
126
- let color_map = $derived(
127
- new Map(
128
- // Use unique_values instead of values to avoid undefined colors from duplicates
129
- property_colors?.unique_values?.flatMap((val) => {
130
- const idx = property_colors.values.indexOf(val)
131
- return idx !== -1 ? [[val, property_colors.colors[idx]]] : []
132
- }),
133
- ),
134
- )
121
+ // Map each property value to its first color in a single O(n) pass (reused in
122
+ // categorical and discrete legends). Skips undefined colors if arrays ever drift.
123
+ let color_map = $derived.by(() => {
124
+ const map = new Map<number | string, string>()
125
+ const { values = [], colors: value_colors = [] } = property_colors ?? {}
126
+ for (const [idx, val] of values.entries()) {
127
+ const color = value_colors[idx]
128
+ if (color !== undefined && !map.has(val)) map.set(val, color)
129
+ }
130
+ return map
131
+ })
132
+
133
+ // Continuous integer properties (e.g. coordination numbers) render as a discrete
134
+ // segmented bar with one labeled block per integer value instead of a smooth gradient.
135
+ // Cap segment count so high-cardinality numeric properties keep the gradient bar.
136
+ const MAX_DISCRETE_SEGMENTS = 20
137
+ let is_discrete_numeric = $derived.by(() => {
138
+ const uniq = property_colors?.unique_values
139
+ // Number.isInteger is false for strings/non-numbers (no coercion), so it also
140
+ // excludes categorical (e.g. Wyckoff) data without a separate type check
141
+ return Boolean(
142
+ uniq?.length && uniq.length <= MAX_DISCRETE_SEGMENTS && uniq.every(Number.isInteger),
143
+ )
144
+ })
135
145
 
136
- function toggle_visibility<T>(
137
- set: Set<T>,
138
- value: T,
139
- event: MouseEvent,
140
- ): Set<T> {
146
+ function toggle_visibility<T>(set: Set<T>, value: T, event: MouseEvent): Set<T> {
141
147
  event.preventDefault()
142
148
  event.stopPropagation()
143
149
  const new_set = new SvelteSet(set)
@@ -156,8 +162,7 @@
156
162
  const query = remap_search.toLowerCase()
157
163
  return ELEM_SYMBOLS.filter((elem) => {
158
164
  const data = element_data?.find((el) => el.symbol === elem)
159
- return elem.toLowerCase().includes(query) ||
160
- data?.name?.toLowerCase().includes(query)
165
+ return elem.toLowerCase().includes(query) || data?.name?.toLowerCase().includes(query)
161
166
  })
162
167
  })
163
168
 
@@ -165,14 +170,13 @@
165
170
  let sorted_element_entries = $derived.by(() => {
166
171
  if (!elements) return []
167
172
  const element_amounts = elements as Record<string, number>
168
- const ordered_known_entries = ELEM_SYMBOLS
169
- .flatMap((element_symbol) => {
170
- const amount = element_amounts[element_symbol]
171
- return amount === undefined ? [] : [[element_symbol, amount] as const]
172
- })
173
+ const ordered_known_entries = ELEM_SYMBOLS.flatMap((element_symbol) => {
174
+ const amount = element_amounts[element_symbol]
175
+ return amount === undefined ? [] : [[element_symbol, amount] as const]
176
+ })
173
177
  const unknown_entries = Object.entries(element_amounts)
174
- .filter(([element_symbol]) =>
175
- !known_element_symbols.has(element_symbol as ElementSymbol)
178
+ .filter(
179
+ ([element_symbol]) => !known_element_symbols.has(element_symbol as ElementSymbol),
176
180
  )
177
181
  .sort(([element_a], [element_b]) => element_a.localeCompare(element_b))
178
182
  return [...ordered_known_entries, ...unknown_entries]
@@ -195,7 +199,7 @@
195
199
  const MAX_RADIUS = 5
196
200
 
197
201
  const parse_radius = (value: string): number | null => {
198
- const num = parseFloat(value)
202
+ const num = Number(value)
199
203
  return !isNaN(num) && num >= MIN_RADIUS && num <= MAX_RADIUS ? num : null
200
204
  }
201
205
 
@@ -238,7 +242,7 @@
238
242
  {#snippet mode_selector_snippet()}
239
243
  <div
240
244
  class="mode-selector"
241
- {@attach click_outside({ callback: () => mode_menu_open = false })}
245
+ {@attach click_outside({ callback: () => (mode_menu_open = false) })}
242
246
  >
243
247
  <button
244
248
  class="mode-toggle"
@@ -254,10 +258,7 @@
254
258
  </button>
255
259
  {#if mode_menu_open}
256
260
  <div class="mode-dropdown">
257
- {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as
258
- [value, label]
259
- (value)
260
- }
261
+ {#each Object.entries(SETTINGS_CONFIG.structure.atom_color_mode.enum || {}) as [value, label] (value)}
261
262
  <button
262
263
  class="mode-option"
263
264
  class:selected={atom_color_config.mode === value}
@@ -323,7 +324,7 @@
323
324
  {/snippet}
324
325
 
325
326
  {#if show_element_legend}
326
- <div {...rest} class="atom-legend element-legend {rest.class ?? ``}">
327
+ <div {...rest} class={[`atom-legend element-legend`, rest.class]}>
327
328
  {@render mode_selector_snippet()}
328
329
  {#each sorted_element_entries as [elem, amt], idx (elem)}
329
330
  {@const is_hidden = hidden_elements.has(elem as ElementSymbol)}
@@ -331,7 +332,8 @@
331
332
  <div class="legend-item">
332
333
  <label
333
334
  bind:this={labels[idx]}
334
- title="{element_data?.find((el) => el.symbol === displayed_elem)?.name ?? ``}{displayed_elem !== elem ? ` (remapped from ${elem})` : ``}"
335
+ title="{element_data?.find((el) => el.symbol === displayed_elem)?.name ??
336
+ ``}{displayed_elem !== elem ? ` (remapped from ${elem})` : ``}"
335
337
  {@attach tooltip()}
336
338
  style:background-color={colors.element[displayed_elem]}
337
339
  class:hidden={is_hidden}
@@ -364,13 +366,12 @@
364
366
  <button
365
367
  class="toggle-visibility"
366
368
  class:element-hidden={is_hidden}
367
- onclick={(
368
- event,
369
- ) => (hidden_elements = toggle_visibility(
370
- hidden_elements,
371
- elem as ElementSymbol,
372
- event,
373
- ))}
369
+ onclick={(event) =>
370
+ (hidden_elements = toggle_visibility(
371
+ hidden_elements,
372
+ elem as ElementSymbol,
373
+ event,
374
+ ))}
374
375
  title={is_hidden ? `Show ${elem} atoms` : `Hide ${elem} atoms`}
375
376
  {@attach tooltip({ placement: `top` })}
376
377
  type="button"
@@ -390,8 +391,8 @@
390
391
  <div class="radius-control">
391
392
  <label
392
393
  title={displayed_elem !== elem
393
- ? `Radius for ${elem} atoms (displayed as ${displayed_elem})`
394
- : `Radius for ${elem} atoms`}
394
+ ? `Radius for ${elem} atoms (displayed as ${displayed_elem})`
395
+ : `Radius for ${elem} atoms`}
395
396
  {@attach tooltip({ placement: `top` })}
396
397
  >
397
398
  <span>Radius ({elem})</span>
@@ -403,10 +404,7 @@
403
404
  value={get_element_radius(elem as ElementSymbol)}
404
405
  oninput={(event) => {
405
406
  if (event.target instanceof HTMLInputElement) {
406
- update_element_radius(
407
- elem as ElementSymbol,
408
- event.target.value,
409
- )
407
+ update_element_radius(elem as ElementSymbol, event.target.value)
410
408
  }
411
409
  }}
412
410
  />
@@ -480,11 +478,29 @@
480
478
  <h4>{legend_title}</h4>
481
479
  </div>
482
480
  {/if}
483
- {#if atom_color_config.scale_type === `continuous` && property_colors}
484
- <div
485
- title={legend_title}
486
- {@attach tooltip({ placement: `top` })}
487
- >
481
+ {#if atom_color_config.scale_type === `continuous` && property_colors && is_discrete_numeric}
482
+ <div class="discrete-colorbar">
483
+ {#each property_colors.unique_values ?? [] as value (value)}
484
+ {@const color = color_map.get(value)}
485
+ {@const is_hidden = hidden_prop_vals.has(value)}
486
+ <button
487
+ type="button"
488
+ class="discrete-segment"
489
+ class:hidden={is_hidden}
490
+ style:background-color={color}
491
+ aria-pressed={is_hidden}
492
+ onclick={(event) =>
493
+ (hidden_prop_vals = toggle_visibility(hidden_prop_vals, value, event))}
494
+ title={is_hidden ? `Show ${format_value(value)}` : `Hide ${format_value(value)}`}
495
+ {@attach tooltip({ placement: `top` })}
496
+ {@attach contrast_color()}
497
+ >
498
+ {format_value(value)}
499
+ </button>
500
+ {/each}
501
+ </div>
502
+ {:else if atom_color_config.scale_type === `continuous` && property_colors}
503
+ <div title={legend_title} {@attach tooltip({ placement: `top` })}>
488
504
  <ColorBar
489
505
  color_scale={atom_color_config.scale}
490
506
  range={[property_colors.min_value ?? 0, property_colors.max_value ?? 0]}
@@ -499,10 +515,7 @@
499
515
  />
500
516
  </div>
501
517
  {:else if atom_color_config.scale_type === `categorical` && property_colors}
502
- {#each property_colors.unique_values || [] as
503
- value
504
- (`${atom_color_config.mode}-${value}`)
505
- }
518
+ {#each property_colors.unique_values || [] as value (`${atom_color_config.mode}-${value}`)}
506
519
  {@const color = color_map.get(value)}
507
520
  {@const is_hidden = hidden_prop_vals.has(value)}
508
521
  <div class="legend-item">
@@ -517,13 +530,8 @@
517
530
  <button
518
531
  class="toggle-visibility"
519
532
  class:element-hidden={is_hidden}
520
- onclick={(
521
- event,
522
- ) => (hidden_prop_vals = toggle_visibility(
523
- hidden_prop_vals,
524
- value,
525
- event,
526
- ))}
533
+ onclick={(event) =>
534
+ (hidden_prop_vals = toggle_visibility(hidden_prop_vals, value, event))}
527
535
  title={is_hidden ? `Show ${format_value(value)}` : `Hide ${format_value(value)}`}
528
536
  {@attach tooltip({ placement: `top` })}
529
537
  type="button"
@@ -552,7 +560,9 @@
552
560
  gap: var(--struct-legend-gap, clamp(3pt, 2cqmin, 7pt));
553
561
  }
554
562
  .element-legend {
555
- font-size: var(--struct-legend-font, clamp(7pt, 2.5cqmin, 12pt));
563
+ /* 9pt floor keeps chips legible in small embeds (carousel cards) where
564
+ the cqmin term collapses */
565
+ font-size: var(--struct-legend-font, clamp(9pt, 2.5cqmin, 12pt));
556
566
  }
557
567
  .atom-legend .legend-item {
558
568
  position: relative;
@@ -598,7 +608,10 @@
598
608
  display: grid;
599
609
  place-items: center;
600
610
  opacity: 0;
601
- transition: opacity 0.2s ease, background 0.2s ease, transform 0.1s ease;
611
+ transition:
612
+ opacity 0.2s ease,
613
+ background 0.2s ease,
614
+ transform 0.1s ease;
602
615
  z-index: 2;
603
616
  pointer-events: auto;
604
617
  }
@@ -717,7 +730,7 @@
717
730
 
718
731
  /* Property Legend Styles */
719
732
  .property-legend {
720
- font-size: var(--struct-legend-font, clamp(8pt, 3cqmin, 14pt));
733
+ font-size: var(--struct-legend-font, clamp(9pt, 3cqmin, 14pt));
721
734
  }
722
735
  .mode-selector {
723
736
  position: relative;
@@ -753,7 +766,9 @@
753
766
  margin-bottom: 0.25rem;
754
767
  background: var(--surface-bg);
755
768
  border-radius: var(--border-radius, 3pt);
756
- box-shadow: 0 8px 16px -4px rgba(0, 0, 0, 0.3), 0 4px 8px -2px rgba(0, 0, 0, 0.1);
769
+ box-shadow:
770
+ 0 8px 16px -4px rgba(0, 0, 0, 0.3),
771
+ 0 4px 8px -2px rgba(0, 0, 0, 0.1);
757
772
  display: flex;
758
773
  flex-direction: column;
759
774
  z-index: 10;
@@ -795,6 +810,31 @@
795
810
  .mode-option span {
796
811
  white-space: nowrap;
797
812
  }
813
+ /* Discrete color bar: contiguous integer-labeled segments (e.g. coordination numbers) */
814
+ .discrete-colorbar {
815
+ display: flex;
816
+ height: var(--struct-discrete-bar-height, 16px);
817
+ border-radius: var(--border-radius, 3pt);
818
+ overflow: hidden;
819
+ }
820
+ .discrete-segment {
821
+ flex: 1 1 0;
822
+ min-width: 1.7em;
823
+ margin: 0;
824
+ padding: 0 4pt;
825
+ border: none;
826
+ border-radius: 0;
827
+ font-size: 0.85em;
828
+ line-height: 1;
829
+ cursor: pointer;
830
+ display: grid;
831
+ place-items: center;
832
+ transition: opacity 0.2s ease;
833
+ }
834
+ .discrete-segment.hidden {
835
+ opacity: 0.35;
836
+ text-decoration: line-through;
837
+ }
798
838
  .category-label {
799
839
  padding: var(--struct-legend-padding, 0 4pt);
800
840
  border-radius: var(--struct-legend-radius, var(--border-radius, 3pt));
@@ -30,6 +30,6 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLDivElement>, `children`> & {
30
30
  structure?: AnyStructure | null;
31
31
  }]>;
32
32
  };
33
- declare const AtomLegend: import("svelte").Component<$$ComponentProps, {}, "labels" | "site_radius_overrides" | "atom_color_config" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "element_mapping">;
33
+ declare const AtomLegend: import("svelte").Component<$$ComponentProps, {}, "labels" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "atom_color_config" | "element_mapping">;
34
34
  type AtomLegend = ReturnType<typeof AtomLegend>;
35
35
  export default AtomLegend;
@@ -4,7 +4,11 @@
4
4
  import type { InstancedMesh } from 'three'
5
5
  import { Color, InstancedBufferAttribute, Matrix4, ShaderMaterial } from 'three'
6
6
 
7
- let { group, saturation = 0.5, brightness = 0.7 }: {
7
+ let {
8
+ group,
9
+ saturation = 0.5,
10
+ brightness = 0.7,
11
+ }: {
8
12
  group: BondGroupWithGradients
9
13
  saturation?: number
10
14
  brightness?: number
@@ -104,12 +108,10 @@
104
108
 
105
109
  // Update geometry color attributes
106
110
  const { geometry } = mesh
107
- for (
108
- const [name, buffer] of [
109
- [`instanceColorStart`, colors_start],
110
- [`instanceColorEnd`, colors_end],
111
- ] as const
112
- ) {
111
+ for (const [name, buffer] of [
112
+ [`instanceColorStart`, colors_start],
113
+ [`instanceColorEnd`, colors_end],
114
+ ] as const) {
113
115
  const existing = geometry.getAttribute(name)
114
116
  if (existing?.array === buffer) existing.needsUpdate = true
115
117
  else geometry.setAttribute(name, new InstancedBufferAttribute(buffer, 3))
@@ -118,23 +120,29 @@
118
120
  mesh.count = count
119
121
  })
120
122
 
121
- let shader_material = $derived(
122
- new ShaderMaterial({
123
- vertexShader: vertex_shader,
124
- fragmentShader: fragment_shader,
125
- uniforms: {
126
- ambientIntensity: { value: group.ambient_light ?? 0.7 },
127
- directionalIntensity: { value: group.directional_light ?? 0.3 },
128
- saturation: { value: saturation },
129
- brightness: { value: brightness },
130
- },
131
- }),
132
- )
123
+ // Create the GPU material once + mutate uniforms reactively (a $derived would leak a new
124
+ // ShaderMaterial per lighting tweak). The $effect sets real uniform values before paint.
125
+ const shader_material = new ShaderMaterial({
126
+ vertexShader: vertex_shader,
127
+ fragmentShader: fragment_shader,
128
+ uniforms: {
129
+ ambientIntensity: { value: 0.7 },
130
+ directionalIntensity: { value: 0.3 },
131
+ saturation: { value: 0.5 },
132
+ brightness: { value: 0.7 },
133
+ },
134
+ })
135
+
136
+ $effect(() => {
137
+ shader_material.uniforms.ambientIntensity.value = group.ambient_light ?? 0.7
138
+ shader_material.uniforms.directionalIntensity.value = group.directional_light ?? 0.3
139
+ shader_material.uniforms.saturation.value = saturation
140
+ shader_material.uniforms.brightness.value = brightness
141
+ })
142
+
143
+ $effect(() => () => shader_material.dispose())
133
144
  </script>
134
145
 
135
- <T.InstancedMesh
136
- args={[undefined, shader_material, group.instances.length]}
137
- bind:ref={mesh}
138
- >
146
+ <T.InstancedMesh args={[undefined, shader_material, group.instances.length]} bind:ref={mesh}>
139
147
  <T.CylinderGeometry args={[group.thickness, group.thickness, 1, 8]} />
140
148
  </T.InstancedMesh>
@@ -4,13 +4,22 @@
4
4
  import type { HTMLAttributes } from 'svelte/elements'
5
5
  import type { Vec3 } from '../math'
6
6
 
7
- let { position, children, ...rest }: HTMLAttributes<HTMLDivElement> & {
7
+ let {
8
+ position,
9
+ children,
10
+ ...rest
11
+ }: HTMLAttributes<HTMLDivElement> & {
8
12
  position: Vec3
9
13
  children: Snippet<[{ position: Vec3 }]>
10
14
  } = $props()
11
15
  </script>
12
16
 
13
- <HTML {position} pointerEvents="none">
17
+ <!-- Constant zIndexRange: threlte's default [16777271, 0] maps camera distance
18
+ over [near, far], which extrapolates to a NEGATIVE z-index for sites beyond
19
+ camera.far (common in zoomed-out carousel cards) — painting the tooltip
20
+ behind the canvas. A degenerate range pins z-index at 1000, always above the
21
+ canvas and sibling overlays. -->
22
+ <HTML {position} pointerEvents="none" zIndexRange={[1000, 1000]}>
14
23
  <div {...rest} role="tooltip">
15
24
  {@render children({ position })}
16
25
  </div>
@@ -19,10 +28,14 @@
19
28
  <style>
20
29
  div {
21
30
  width: max-content;
31
+ max-width: var(--canvas-tooltip-max-width, 16em);
22
32
  box-sizing: border-box;
23
33
  text-align: var(--canvas-tooltip-text-align, left);
24
34
  border-radius: var(--canvas-tooltip-border-radius, var(--border-radius, 3pt));
25
- background: var(--canvas-tooltip-bg, light-dark(rgba(226, 232, 240, 0.96), rgba(15, 23, 42, 0.96)));
35
+ background: var(
36
+ --canvas-tooltip-bg,
37
+ light-dark(rgba(226, 232, 240, 0.96), rgba(15, 23, 42, 0.96))
38
+ );
26
39
  padding: var(--canvas-tooltip-padding, 1pt 5pt);
27
40
  color: var(--canvas-tooltip-text-color, light-dark(#0f172a, #f8fafc));
28
41
  font-family: var(--canvas-tooltip-font-family);
@@ -14,6 +14,7 @@
14
14
  loading = $bindable(false),
15
15
  direction = `down`,
16
16
  align = `right`,
17
+ suppress_hover = false,
17
18
  }: {
18
19
  supercell_scaling: string
19
20
  cell_type?: CellType
@@ -21,6 +22,7 @@
21
22
  loading?: boolean
22
23
  direction?: `up` | `down`
23
24
  align?: `left` | `right`
25
+ suppress_hover?: boolean // don't auto-open the menu on hover/focus (e.g. while a sibling popover is open)
24
26
  } = $props()
25
27
 
26
28
  let menu_open = $state(false)
@@ -66,7 +68,8 @@
66
68
  !(current_target instanceof Node) ||
67
69
  !(next_target instanceof Node) ||
68
70
  !current_target.contains(next_target)
69
- ) menu_open = false
71
+ )
72
+ menu_open = false
70
73
  }
71
74
 
72
75
  function handle_key_down(event: KeyboardEvent, submit_on_enter: boolean = false) {
@@ -80,20 +83,26 @@
80
83
  input_value = supercell_scaling
81
84
  }
82
85
  })
86
+
87
+ // Close + keep closed while suppressed so the menu can't obscure a sibling popover
88
+ // (e.g. the atom color-mode dropdown) the user is actively interacting with
89
+ $effect(() => {
90
+ if (suppress_hover) menu_open = false
91
+ })
83
92
  </script>
84
93
 
85
94
  <div
86
95
  class="cell-select"
87
96
  role="group"
88
97
  {@attach click_outside({ callback: () => (menu_open = false) })}
89
- onmouseenter={() => (menu_open = true)}
98
+ onmouseenter={() => (menu_open = !suppress_hover)}
90
99
  onmouseleave={() => (menu_open = false)}
91
- onfocusin={() => (menu_open = true)}
100
+ onfocusin={() => (menu_open = !suppress_hover)}
92
101
  onfocusout={handle_focus_out}
93
102
  >
94
103
  <button
95
104
  type="button"
96
- onclick={() => (menu_open = !menu_open)}
105
+ onclick={() => (menu_open = !suppress_hover && !menu_open)}
97
106
  onkeydown={handle_key_down}
98
107
  class="toggle-btn"
99
108
  class:active={menu_open}
@@ -105,9 +114,9 @@
105
114
  style="--spinner-border-width: 2px; --spinner-size: 1em; --spinner-margin: 0; display: inline-block; vertical-align: middle"
106
115
  />
107
116
  {:else}
108
- {cell_type !== `original` ? `${cell_labels[cell_type]} ` : ``}{
109
- format_supercell_label(supercell_scaling)
110
- }
117
+ {cell_type !== `original` ? `${cell_labels[cell_type]} ` : ``}{format_supercell_label(
118
+ supercell_scaling,
119
+ )}
111
120
  {/if}
112
121
  </button>
113
122
 
@@ -123,8 +132,8 @@
123
132
  {@const disabled = type !== `original` && !sym_data}
124
133
  {@const label = cell_labels[type]}
125
134
  {@const tooltip_text = disabled
126
- ? `${cell_tooltips[type]} - requires symmetry data`
127
- : cell_tooltips[type]}
135
+ ? `${cell_tooltips[type]} - requires symmetry data`
136
+ : cell_tooltips[type]}
128
137
  <button
129
138
  class="cell-type-btn"
130
139
  class:selected={cell_type === type}
@@ -274,16 +283,8 @@
274
283
  }
275
284
  .cell-type-btn.selected {
276
285
  color: var(--cell-select-accent);
277
- background: color-mix(
278
- in srgb,
279
- var(--cell-select-accent) 18%,
280
- var(--cell-select-surface)
281
- );
282
- border-color: color-mix(
283
- in srgb,
284
- var(--cell-select-accent) 45%,
285
- var(--cell-select-border)
286
- );
286
+ background: color-mix(in srgb, var(--cell-select-accent) 18%, var(--cell-select-surface));
287
+ border-color: color-mix(in srgb, var(--cell-select-accent) 45%, var(--cell-select-border));
287
288
  }
288
289
  .cell-type-btn.disabled {
289
290
  opacity: 0.4;
@@ -311,16 +312,8 @@
311
312
  }
312
313
  .preset-btn.selected {
313
314
  color: var(--cell-select-accent);
314
- background: color-mix(
315
- in srgb,
316
- var(--cell-select-accent) 18%,
317
- var(--cell-select-surface)
318
- );
319
- border-color: color-mix(
320
- in srgb,
321
- var(--cell-select-accent) 45%,
322
- var(--cell-select-border)
323
- );
315
+ background: color-mix(in srgb, var(--cell-select-accent) 18%, var(--cell-select-surface));
316
+ border-color: color-mix(in srgb, var(--cell-select-accent) 45%, var(--cell-select-border));
324
317
  }
325
318
 
326
319
  .custom-input-row {
@@ -7,7 +7,8 @@ type $$ComponentProps = {
7
7
  loading?: boolean;
8
8
  direction?: `up` | `down`;
9
9
  align?: `left` | `right`;
10
+ suppress_hover?: boolean;
10
11
  };
11
- declare const CellSelect: import("svelte").Component<$$ComponentProps, {}, "loading" | "supercell_scaling" | "cell_type">;
12
+ declare const CellSelect: import("svelte").Component<$$ComponentProps, {}, "supercell_scaling" | "cell_type" | "loading">;
12
13
  type CellSelect = ReturnType<typeof CellSelect>;
13
14
  export default CellSelect;
@@ -2,48 +2,32 @@
2
2
  import type { Vec3 } from '../math'
3
3
  import { T } from '@threlte/core'
4
4
  import type { ComponentProps } from 'svelte'
5
- import { Euler, Quaternion, Vector3 } from 'three'
5
+ import { cylinder_between } from './geometry'
6
6
 
7
- let { from, to, color = `#808080`, thickness = 0.1, opacity = 1, ...rest }:
8
- & ComponentProps<typeof T.Mesh>
9
- & {
10
- from: Vec3
11
- to: Vec3
12
- color?: string
13
- thickness?: number
14
- opacity?: number // < 1 renders semi/fully transparent (e.g. invisible hover proxies)
15
- } = $props()
7
+ let {
8
+ from,
9
+ to,
10
+ color = `#808080`,
11
+ thickness = 0.1,
12
+ opacity = 1,
13
+ ...rest
14
+ }: ComponentProps<typeof T.Mesh> & {
15
+ from: Vec3
16
+ to: Vec3
17
+ color?: string
18
+ thickness?: number
19
+ opacity?: number // < 1 renders semi/fully transparent (e.g. invisible hover proxies)
20
+ } = $props()
16
21
 
17
- let from_vec = $derived(new Vector3(...from))
18
- let to_vec = $derived(new Vector3(...to))
19
- let { position, rotation, height } = $derived(calc_bond(from_vec, to_vec))
20
-
21
- function calc_bond(
22
- start_vec: Vector3,
23
- end_vec: Vector3,
24
- ): { position: Vec3; rotation: Vec3; height: number } {
25
- // find the axis of the cylinder
26
- const delta_vec = end_vec.clone().sub(start_vec)
27
- // length of the cylinder
28
- const bond_height = delta_vec.length()
29
- // calculate position (midpoint between from and to)
30
- const bond_position = start_vec
31
- .clone()
32
- .add(delta_vec.multiplyScalar(0.5))
33
- .toArray() as Vec3
34
- // calculate rotation
35
- const quaternion = new Quaternion().setFromUnitVectors(
36
- new Vector3(0, 1, 0),
37
- delta_vec.normalize(),
38
- )
39
- const euler = new Euler().setFromQuaternion(quaternion)
40
- const bond_rotation: Vec3 = [euler.x, euler.y, euler.z]
41
- // return results
42
- return { height: bond_height, position: bond_position, rotation: bond_rotation }
43
- }
22
+ let { position, rotation, length } = $derived(cylinder_between(from, to))
44
23
  </script>
45
24
 
46
- <T.Mesh {...rest} {position} {rotation} scale={[thickness, height, thickness]}>
47
- <T.CylinderGeometry args={[thickness, thickness, 1, 8]} />
48
- <T.MeshStandardMaterial {color} transparent={opacity < 1} {opacity} depthWrite={opacity >= 1} />
25
+ <T.Mesh {...rest} {position} {rotation} scale={[thickness, length, thickness]}>
26
+ <T.CylinderGeometry args={[1, 1, 1, 8]} />
27
+ <T.MeshStandardMaterial
28
+ {color}
29
+ transparent={opacity < 1}
30
+ {opacity}
31
+ depthWrite={opacity >= 1}
32
+ />
49
33
  </T.Mesh>