matterviz 0.4.1 → 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 (395) 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 +75 -85
  7. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  8. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  9. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  11. package/dist/brillouin/BrillouinZoneScene.svelte +26 -39
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  13. package/dist/chempot-diagram/ChemPotDiagram.svelte +33 -38
  14. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +62 -74
  15. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  16. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +511 -547
  17. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  18. package/dist/chempot-diagram/async-compute.svelte.js +1 -1
  19. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  20. package/dist/colors/index.d.ts +0 -4
  21. package/dist/colors/index.js +19 -20
  22. package/dist/composition/BarChart.svelte +37 -31
  23. package/dist/composition/BubbleChart.svelte +17 -17
  24. package/dist/composition/Composition.svelte +7 -11
  25. package/dist/composition/Formula.svelte +18 -25
  26. package/dist/composition/FormulaFilter.svelte +92 -95
  27. package/dist/composition/PieChart.svelte +55 -41
  28. package/dist/composition/format.js +1 -1
  29. package/dist/composition/index.d.ts +2 -0
  30. package/dist/composition/index.js +14 -0
  31. package/dist/composition/parse.d.ts +2 -2
  32. package/dist/composition/parse.js +11 -10
  33. package/dist/constants.js +11 -9
  34. package/dist/convex-hull/ConvexHull.svelte +12 -15
  35. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  36. package/dist/convex-hull/ConvexHull2D.svelte +93 -92
  37. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  38. package/dist/convex-hull/ConvexHull3D.svelte +109 -140
  39. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  40. package/dist/convex-hull/ConvexHull4D.svelte +75 -94
  41. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  42. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  43. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  44. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  45. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  46. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  47. package/dist/convex-hull/StructurePopup.svelte +17 -21
  48. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  49. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  50. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  51. package/dist/convex-hull/helpers.d.ts +8 -10
  52. package/dist/convex-hull/helpers.js +36 -36
  53. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  54. package/dist/convex-hull/thermodynamics.js +18 -17
  55. package/dist/coordination/CoordinationBarPlot.svelte +38 -33
  56. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  57. package/dist/coordination/calc-coordination.d.ts +1 -1
  58. package/dist/coordination/calc-coordination.js +28 -25
  59. package/dist/element/BohrAtom.svelte +5 -8
  60. package/dist/element/ElementHeading.svelte +4 -1
  61. package/dist/element/ElementPhoto.svelte +11 -9
  62. package/dist/element/ElementStats.svelte +12 -10
  63. package/dist/element/ElementTile.svelte +24 -29
  64. package/dist/element/Nucleus.svelte +4 -2
  65. package/dist/element/data.d.ts +1 -2
  66. package/dist/element/helpers.d.ts +4 -0
  67. package/dist/element/helpers.js +18 -0
  68. package/dist/element/index.d.ts +1 -4
  69. package/dist/element/index.js +3 -18
  70. package/dist/feedback/DragOverlay.svelte +5 -5
  71. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  72. package/dist/feedback/StatusMessage.svelte +7 -4
  73. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  74. package/dist/fermi-surface/FermiSurface.svelte +14 -22
  75. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -7
  76. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  77. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  78. package/dist/fermi-surface/FermiSurfaceScene.svelte +37 -64
  79. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  80. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  81. package/dist/fermi-surface/compute.js +3 -3
  82. package/dist/fermi-surface/parse.js +22 -24
  83. package/dist/heatmap-matrix/HeatmapMatrix.svelte +109 -148
  84. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  85. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  86. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  87. package/dist/heatmap-matrix/index.d.ts +5 -0
  88. package/dist/icons.d.ts +4 -0
  89. package/dist/icons.js +4 -0
  90. package/dist/io/ExportPane.svelte +10 -6
  91. package/dist/io/decompress.d.ts +2 -1
  92. package/dist/io/decompress.js +22 -35
  93. package/dist/io/export.d.ts +4 -0
  94. package/dist/io/export.js +5 -1
  95. package/dist/io/fetch.d.ts +0 -3
  96. package/dist/io/fetch.js +0 -11
  97. package/dist/io/index.d.ts +0 -1
  98. package/dist/io/index.js +2 -9
  99. package/dist/io/is-binary.d.ts +9 -0
  100. package/dist/io/is-binary.js +45 -1
  101. package/dist/io/url-drop.js +13 -25
  102. package/dist/isosurface/Isosurface.svelte +17 -23
  103. package/dist/isosurface/IsosurfaceControls.svelte +37 -42
  104. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  105. package/dist/isosurface/parse-vaspwave.js +138 -0
  106. package/dist/isosurface/parse.js +6 -6
  107. package/dist/labels.d.ts +6 -2
  108. package/dist/labels.js +43 -13
  109. package/dist/layout/FullscreenButton.svelte +2 -1
  110. package/dist/layout/FullscreenToggle.svelte +10 -4
  111. package/dist/layout/InfoCard.svelte +7 -18
  112. package/dist/layout/InfoTag.svelte +1 -3
  113. package/dist/layout/NumberRangeInput.svelte +46 -0
  114. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  115. package/dist/layout/PropertyFilter.svelte +2 -6
  116. package/dist/layout/SettingsSection.svelte +21 -17
  117. package/dist/layout/SubpageGrid.svelte +3 -1
  118. package/dist/layout/ViewerChrome.svelte +9 -10
  119. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  120. package/dist/layout/fullscreen.js +3 -5
  121. package/dist/layout/fullscreen.svelte.js +1 -2
  122. package/dist/layout/index.d.ts +1 -0
  123. package/dist/layout/index.js +1 -0
  124. package/dist/layout/json-tree/JsonNode.svelte +8 -11
  125. package/dist/layout/json-tree/JsonTree.svelte +53 -77
  126. package/dist/layout/json-tree/JsonValue.svelte +7 -15
  127. package/dist/layout/json-tree/utils.js +14 -23
  128. package/dist/math.d.ts +2 -0
  129. package/dist/math.js +19 -0
  130. package/dist/overlays/ContextMenu.svelte +4 -2
  131. package/dist/overlays/CopyButton.svelte +11 -5
  132. package/dist/overlays/DragControlTab.svelte +6 -1
  133. package/dist/overlays/DraggablePane.svelte +81 -26
  134. package/dist/overlays/DraggablePane.svelte.d.ts +1 -0
  135. package/dist/overlays/GlassChip.svelte +30 -0
  136. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  137. package/dist/overlays/InfoPaneCards.svelte +11 -23
  138. package/dist/overlays/index.d.ts +7 -0
  139. package/dist/overlays/index.js +26 -0
  140. package/dist/overlays/portal.d.ts +2 -0
  141. package/dist/overlays/portal.js +14 -0
  142. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  143. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  144. package/dist/periodic-table/PeriodicTableControls.svelte +11 -63
  145. package/dist/periodic-table/TableInset.svelte +9 -4
  146. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +50 -71
  147. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  148. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  149. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  150. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  151. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  152. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  153. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  154. package/dist/phase-diagram/build-diagram.js +3 -3
  155. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  156. package/dist/phase-diagram/parse.js +15 -15
  157. package/dist/phase-diagram/svg-to-diagram.js +21 -15
  158. package/dist/phase-diagram/utils.js +2 -3
  159. package/dist/plot/bar/BarPlot.svelte +430 -391
  160. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  161. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  162. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  163. package/dist/plot/bar/SpacegroupBarPlot.svelte +29 -36
  164. package/dist/plot/bar/data.d.ts +5 -4
  165. package/dist/plot/bar/data.js +2 -1
  166. package/dist/plot/box/BoxPlot.svelte +301 -209
  167. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  168. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  169. package/dist/plot/box/box-plot.js +1 -1
  170. package/dist/plot/core/auto-place.js +1 -1
  171. package/dist/plot/core/axis-utils.d.ts +12 -7
  172. package/dist/plot/core/axis-utils.js +48 -48
  173. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  174. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  175. package/dist/plot/core/components/ColorBar.svelte +101 -106
  176. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  177. package/dist/plot/core/components/FillArea.svelte +10 -17
  178. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  179. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  180. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  181. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  182. package/dist/plot/core/components/Line.svelte +18 -9
  183. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  184. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  185. package/dist/plot/core/components/PlotControls.svelte +65 -41
  186. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  187. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  188. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  189. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  190. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  191. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  192. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  193. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  194. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  195. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  196. package/dist/plot/core/components/index.d.ts +1 -0
  197. package/dist/plot/core/components/index.js +1 -0
  198. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  199. package/dist/plot/core/data-cleaning-signal.js +467 -0
  200. package/dist/plot/core/data-cleaning.d.ts +2 -42
  201. package/dist/plot/core/data-cleaning.js +27 -474
  202. package/dist/plot/core/data-transform.js +9 -5
  203. package/dist/plot/core/fill-utils.d.ts +3 -1
  204. package/dist/plot/core/fill-utils.js +28 -6
  205. package/dist/plot/core/index.d.ts +1 -0
  206. package/dist/plot/core/index.js +1 -0
  207. package/dist/plot/core/interactions.js +0 -2
  208. package/dist/plot/core/layout.d.ts +3 -1
  209. package/dist/plot/core/layout.js +22 -13
  210. package/dist/plot/core/marginals.d.ts +170 -0
  211. package/dist/plot/core/marginals.js +436 -0
  212. package/dist/plot/core/reference-line.js +1 -1
  213. package/dist/plot/core/scales.d.ts +23 -0
  214. package/dist/plot/core/scales.js +39 -13
  215. package/dist/plot/core/types/fills.d.ts +101 -0
  216. package/dist/plot/core/types/fills.js +15 -0
  217. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  218. package/dist/plot/core/types/plot-3d.js +4 -0
  219. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  220. package/dist/plot/core/types/reference-lines.js +9 -0
  221. package/dist/plot/core/types.d.ts +29 -324
  222. package/dist/plot/core/types.js +23 -20
  223. package/dist/plot/core/utils/hierarchy-chart.d.ts +51 -0
  224. package/dist/plot/core/utils/hierarchy-chart.js +179 -0
  225. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  226. package/dist/plot/core/utils/hierarchy-labels.js +99 -0
  227. package/dist/plot/core/utils/label-placement.js +2 -2
  228. package/dist/plot/histogram/Histogram.svelte +304 -325
  229. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  230. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  231. package/dist/plot/histogram/histogram.d.ts +31 -0
  232. package/dist/plot/histogram/histogram.js +70 -0
  233. package/dist/plot/histogram/index.d.ts +1 -0
  234. package/dist/plot/histogram/index.js +1 -0
  235. package/dist/plot/index.d.ts +1 -0
  236. package/dist/plot/index.js +1 -0
  237. package/dist/plot/sankey/Sankey.svelte +78 -69
  238. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  239. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  240. package/dist/plot/scatter/BinnedScatterPlot.svelte +263 -109
  241. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  242. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  243. package/dist/plot/scatter/ScatterPlot.svelte +477 -385
  244. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  245. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  246. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  247. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  248. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  249. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  250. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  251. package/dist/plot/scatter/scatter-data.js +8 -7
  252. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  253. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  254. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  255. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  256. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  257. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  258. package/dist/plot/sunburst/Sunburst.svelte +251 -329
  259. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  260. package/dist/plot/sunburst/index.d.ts +1 -1
  261. package/dist/plot/sunburst/index.js +2 -1
  262. package/dist/plot/sunburst/render.d.ts +2 -2
  263. package/dist/plot/sunburst/render.js +47 -22
  264. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  265. package/dist/plot/sunburst/sunburst.js +10 -3
  266. package/dist/plot/treemap/Treemap.svelte +907 -0
  267. package/dist/plot/treemap/Treemap.svelte.d.ts +84 -0
  268. package/dist/plot/treemap/index.d.ts +3 -0
  269. package/dist/plot/treemap/index.js +4 -0
  270. package/dist/plot/treemap/treemap.d.ts +26 -0
  271. package/dist/plot/treemap/treemap.js +99 -0
  272. package/dist/rdf/RdfPlot.svelte +22 -26
  273. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  274. package/dist/rdf/calc-rdf.js +4 -8
  275. package/dist/sanitize.js +1 -1
  276. package/dist/scene/bind-renderer.svelte.js +14 -6
  277. package/dist/settings.d.ts +19 -9
  278. package/dist/settings.js +77 -50
  279. package/dist/spectral/Bands.svelte +223 -230
  280. package/dist/spectral/BandsAndDos.svelte +11 -9
  281. package/dist/spectral/BrillouinBandsDos.svelte +19 -27
  282. package/dist/spectral/Dos.svelte +70 -73
  283. package/dist/spectral/helpers.d.ts +3 -3
  284. package/dist/spectral/helpers.js +25 -35
  285. package/dist/state.svelte.js +5 -18
  286. package/dist/structure/Arrow.svelte +5 -18
  287. package/dist/structure/ArrowInstances.svelte +160 -0
  288. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  289. package/dist/structure/AtomLegend.svelte +115 -75
  290. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  291. package/dist/structure/Bond.svelte +31 -23
  292. package/dist/structure/CanvasTooltip.svelte +15 -3
  293. package/dist/structure/CellSelect.svelte +11 -26
  294. package/dist/structure/Cylinder.svelte +24 -40
  295. package/dist/structure/InstancedAtoms.svelte +114 -0
  296. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  297. package/dist/structure/Lattice.svelte +85 -149
  298. package/dist/structure/SiteLabels.svelte +122 -0
  299. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  300. package/dist/structure/Structure.svelte +473 -419
  301. package/dist/structure/Structure.svelte.d.ts +4 -2
  302. package/dist/structure/StructureCarousel.svelte +630 -0
  303. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  304. package/dist/structure/StructureControls.svelte +157 -399
  305. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  306. package/dist/structure/StructureExportPane.svelte +17 -21
  307. package/dist/structure/StructureInfoPane.svelte +72 -66
  308. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  309. package/dist/structure/StructureScene.svelte +467 -476
  310. package/dist/structure/StructureScene.svelte.d.ts +3 -1
  311. package/dist/structure/StructureViewport.svelte +386 -0
  312. package/dist/structure/StructureViewport.svelte.d.ts +63 -0
  313. package/dist/structure/atom-label-placement.d.ts +16 -12
  314. package/dist/structure/atom-label-placement.js +70 -37
  315. package/dist/structure/atom-properties.d.ts +2 -0
  316. package/dist/structure/atom-properties.js +104 -38
  317. package/dist/structure/bonding.d.ts +10 -3
  318. package/dist/structure/bonding.js +84 -28
  319. package/dist/structure/edit-history.d.ts +6 -0
  320. package/dist/structure/edit-history.js +27 -0
  321. package/dist/structure/export.d.ts +1 -0
  322. package/dist/structure/export.js +39 -31
  323. package/dist/structure/format-detect.d.ts +1 -0
  324. package/dist/structure/format-detect.js +22 -0
  325. package/dist/structure/geometry.d.ts +9 -0
  326. package/dist/structure/geometry.js +27 -0
  327. package/dist/structure/index.d.ts +16 -1
  328. package/dist/structure/index.js +13 -2
  329. package/dist/structure/measure.d.ts +1 -1
  330. package/dist/structure/measure.js +6 -12
  331. package/dist/structure/parse.d.ts +2 -1
  332. package/dist/structure/parse.js +243 -222
  333. package/dist/structure/partial-occupancy.js +4 -2
  334. package/dist/structure/pbc.js +78 -98
  335. package/dist/structure/polyhedra.d.ts +0 -1
  336. package/dist/structure/polyhedra.js +3 -18
  337. package/dist/structure/supercell.d.ts +1 -2
  338. package/dist/structure/supercell.js +7 -13
  339. package/dist/symmetry/SymmetryElements.svelte +11 -15
  340. package/dist/symmetry/SymmetryStats.svelte +56 -68
  341. package/dist/symmetry/WyckoffTable.svelte +5 -24
  342. package/dist/symmetry/cell-transform.js +1 -0
  343. package/dist/symmetry/index.d.ts +1 -0
  344. package/dist/symmetry/index.js +8 -2
  345. package/dist/symmetry/spacegroups.js +3 -2
  346. package/dist/table/HeatmapTable.svelte +1102 -365
  347. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  348. package/dist/table/ToggleMenu.svelte +5 -12
  349. package/dist/table/index.d.ts +21 -6
  350. package/dist/table/index.js +34 -21
  351. package/dist/theme/ThemeControl.svelte +16 -8
  352. package/dist/theme/index.d.ts +1 -5
  353. package/dist/theme/index.js +4 -10
  354. package/dist/theme/themes.mjs +14 -7
  355. package/dist/tooltip/KCoords.svelte +4 -1
  356. package/dist/tooltip/TooltipContent.svelte +2 -5
  357. package/dist/trajectory/Trajectory.svelte +515 -308
  358. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  359. package/dist/trajectory/TrajectoryError.svelte +11 -8
  360. package/dist/trajectory/TrajectoryExportPane.svelte +14 -31
  361. package/dist/trajectory/TrajectoryInfoPane.svelte +85 -97
  362. package/dist/trajectory/extract.js +56 -34
  363. package/dist/trajectory/format-detect.js +11 -9
  364. package/dist/trajectory/frame-reader.d.ts +2 -0
  365. package/dist/trajectory/frame-reader.js +33 -29
  366. package/dist/trajectory/helpers.d.ts +2 -0
  367. package/dist/trajectory/helpers.js +18 -7
  368. package/dist/trajectory/index.d.ts +1 -0
  369. package/dist/trajectory/index.js +3 -0
  370. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  371. package/dist/trajectory/parse/h5-utils.js +109 -0
  372. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  373. package/dist/trajectory/parse/hdf5.js +116 -106
  374. package/dist/trajectory/parse/index.d.ts +2 -3
  375. package/dist/trajectory/parse/index.js +17 -20
  376. package/dist/trajectory/parse/lammps.js +8 -12
  377. package/dist/trajectory/parse/vasp.js +10 -7
  378. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  379. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  380. package/dist/trajectory/parse/vaspout-h5.d.ts +5 -0
  381. package/dist/trajectory/parse/vaspout-h5.js +284 -0
  382. package/dist/trajectory/parse/xyz.js +11 -7
  383. package/dist/trajectory/plotting.d.ts +8 -9
  384. package/dist/trajectory/plotting.js +99 -27
  385. package/dist/utils.d.ts +3 -0
  386. package/dist/utils.js +7 -0
  387. package/dist/xrd/XrdPlot.svelte +47 -61
  388. package/dist/xrd/broadening.js +2 -1
  389. package/dist/xrd/calc-xrd.js +2 -4
  390. package/dist/xrd/parse.d.ts +0 -1
  391. package/dist/xrd/parse.js +56 -73
  392. package/package.json +61 -33
  393. package/dist/api/mp.d.ts +0 -6
  394. package/dist/api/mp.js +0 -22
  395. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
@@ -22,6 +22,7 @@ type $$ComponentProps = SceneControlProps & {
22
22
  same_size_atoms?: boolean;
23
23
  camera_position?: [x: number, y: number, z: number];
24
24
  camera_target?: Vec3;
25
+ camera_direction?: Vec3;
25
26
  show_atoms?: boolean;
26
27
  show_bonds?: ShowBonds;
27
28
  show_site_labels?: boolean;
@@ -107,7 +108,8 @@ type $$ComponentProps = SceneControlProps & {
107
108
  dragging_atoms?: boolean;
108
109
  volumetric_data?: VolumetricData;
109
110
  isosurface_settings?: IsosurfaceSettings;
111
+ interactive?: boolean;
110
112
  };
111
- declare const StructureScene: import("svelte").Component<$$ComponentProps, {}, "cursor" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "selected_sites" | "site_label_offset" | "vector_configs" | "hovered_idx" | "hovered_site" | "polyhedra_rendered_elements" | "camera_is_moving" | "measured_sites" | "added_bonds" | "removed_bonds" | "bond_order_overrides" | "bond_edit_mode" | "active_sites" | "scene" | "camera" | "orbit_controls" | "rotation_target_ref" | "initial_computed_zoom" | "add_atom_mode" | "add_element" | "dragging_atoms">;
113
+ declare const StructureScene: import("svelte").Component<$$ComponentProps, {}, "cursor" | "camera" | "site_label_offset" | "vector_configs" | "orbit_controls" | "hovered_idx" | "hovered_site" | "polyhedra_rendered_elements" | "camera_is_moving" | "selected_sites" | "measured_sites" | "added_bonds" | "removed_bonds" | "bond_order_overrides" | "bond_edit_mode" | "active_sites" | "scene" | "rotation_target_ref" | "initial_computed_zoom" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "add_atom_mode" | "add_element" | "dragging_atoms">;
112
114
  type StructureScene = ReturnType<typeof StructureScene>;
113
115
  export default StructureScene;
@@ -0,0 +1,386 @@
1
+ <script lang="ts">
2
+ // A single subcanvas (one Threlte <Canvas> + <StructureScene>) used by Structure.svelte
3
+ // for both the regular single view and each pane of the 2x2 multi-side view.
4
+ //
5
+ // Each viewport owns its camera: move tracking, reset (on reset_token), and orbit-target
6
+ // recentering on structure change. The primary pane (index 0) additionally binds out
7
+ // scene/camera for the export pane and receives the on_camera_move/on_camera_reset
8
+ // callbacks so it drives Structure's external camera API. Camera state is per-pane:
9
+ // the primary pane binds it back to Structure's scene_props, while side panes keep it local.
10
+ import type { ElementSymbol } from '../element'
11
+ import type { IsosurfaceSettings, VolumetricData } from '../isosurface/types'
12
+ import type { Vec3 } from '../math'
13
+ import type { CameraProjection } from '../settings'
14
+ import type {
15
+ AnyStructure,
16
+ BondEditMode,
17
+ BondOrder,
18
+ MeasureMode,
19
+ StructureBond,
20
+ StructureHandlerData,
21
+ } from './'
22
+ import type { MoyoDataset } from '@spglib/moyo-wasm'
23
+ import { Canvas } from '@threlte/core'
24
+ import type { ComponentProps } from 'svelte'
25
+ import { untrack } from 'svelte'
26
+ import { SvelteMap, SvelteSet } from 'svelte/reactivity'
27
+ import { WebGLRenderer, type Camera, type OrthographicCamera, type Scene } from 'three'
28
+ import type { AtomColorConfig } from './atom-properties'
29
+ import StructureScene from './StructureScene.svelte'
30
+
31
+ // WebGL contexts survive renderer.dispose() unless explicitly released.
32
+ class StructureRenderer extends WebGLRenderer {
33
+ constructor(parameters: ConstructorParameters<typeof WebGLRenderer>[0]) {
34
+ super(parameters)
35
+ globalThis.addEventListener(`pagehide`, this.release_context, { once: true })
36
+ }
37
+
38
+ private release_context = (): void => {
39
+ if (!this.getContext().isContextLost()) this.forceContextLoss()
40
+ }
41
+
42
+ override dispose() {
43
+ globalThis.removeEventListener(`pagehide`, this.release_context)
44
+ super.dispose()
45
+ this.release_context()
46
+ }
47
+ }
48
+
49
+ const create_renderer = (canvas: HTMLCanvasElement) =>
50
+ new StructureRenderer({
51
+ canvas,
52
+ powerPreference: `high-performance`,
53
+ antialias: true,
54
+ alpha: true,
55
+ })
56
+
57
+ let {
58
+ // Multi-view chrome
59
+ in_grid = false,
60
+ active = false,
61
+ label = undefined,
62
+ reset_token = 0,
63
+ interactive = true,
64
+ onactivate = undefined,
65
+ report_moved = undefined,
66
+ on_camera_move = undefined,
67
+ on_camera_reset = undefined,
68
+
69
+ // Shared scene inputs (one-way)
70
+ structure = undefined,
71
+ base_structure = undefined,
72
+ scene_props = {},
73
+ gizmo = false,
74
+ lattice_props = {},
75
+ volumetric_data = undefined,
76
+ isosurface_settings = undefined,
77
+ bond_edits_enabled = true,
78
+ bond_edit_order = 1,
79
+ measure_mode = `distance`,
80
+ atom_color_config = undefined,
81
+ sym_data = null,
82
+ active_sites = [],
83
+ camera_direction = undefined,
84
+ camera_projection = `orthographic`,
85
+ camera_position = $bindable([0, 0, 0]),
86
+ camera_target = $bindable(undefined),
87
+
88
+ // Edit-mode callbacks
89
+ on_sites_moved = undefined,
90
+ on_operation_start = undefined,
91
+ on_bond_edit_start = undefined,
92
+ on_add_atom = undefined,
93
+
94
+ // scene + camera are bound out for the primary pane (consumed by the export pane)
95
+ scene = $bindable(undefined),
96
+ camera = $bindable(undefined),
97
+
98
+ // Shared two-way scene state
99
+ selected_sites = $bindable([]),
100
+ measured_sites = $bindable([]),
101
+ hovered_site_idx = $bindable(null),
102
+ hidden_elements = $bindable(new SvelteSet<ElementSymbol>()),
103
+ hidden_prop_vals = $bindable(new SvelteSet<number | string>()),
104
+ element_radius_overrides = $bindable({}),
105
+ site_radius_overrides = $bindable(new SvelteMap<number, number>()),
106
+ added_bonds = $bindable([]),
107
+ removed_bonds = $bindable([]),
108
+ bond_order_overrides = $bindable([]),
109
+ bond_edit_mode = $bindable(`add`),
110
+ add_atom_mode = $bindable(false),
111
+ add_element = $bindable(`C`),
112
+ dragging_atoms = $bindable(false),
113
+ polyhedra_rendered_elements = $bindable([]),
114
+ }: {
115
+ in_grid?: boolean
116
+ active?: boolean
117
+ label?: string
118
+ reset_token?: number
119
+ interactive?: boolean
120
+ onactivate?: () => void
121
+ report_moved?: (moved: boolean) => void
122
+ on_camera_move?: (data: StructureHandlerData) => void
123
+ on_camera_reset?: (data: StructureHandlerData) => void
124
+ structure?: AnyStructure
125
+ base_structure?: AnyStructure
126
+ scene_props?: ComponentProps<typeof StructureScene>
127
+ gizmo?: boolean | ComponentProps<typeof StructureScene>[`gizmo`]
128
+ lattice_props?: ComponentProps<typeof StructureScene>[`lattice_props`]
129
+ volumetric_data?: VolumetricData
130
+ isosurface_settings?: IsosurfaceSettings
131
+ bond_edits_enabled?: boolean
132
+ bond_edit_order?: BondOrder
133
+ measure_mode?: MeasureMode
134
+ atom_color_config?: Partial<AtomColorConfig>
135
+ sym_data?: MoyoDataset | null
136
+ active_sites?: number[]
137
+ camera_direction?: Vec3
138
+ camera_projection?: CameraProjection
139
+ camera_position?: Vec3
140
+ camera_target?: Vec3
141
+ on_sites_moved?: (scene_indices: number[], delta: Vec3) => void
142
+ on_operation_start?: () => void
143
+ on_bond_edit_start?: () => void
144
+ on_add_atom?: (xyz: Vec3, element: ElementSymbol) => void
145
+ scene?: Scene
146
+ camera?: Camera
147
+ selected_sites?: number[]
148
+ measured_sites?: number[]
149
+ hovered_site_idx?: number | null
150
+ hidden_elements?: Set<ElementSymbol>
151
+ hidden_prop_vals?: Set<number | string>
152
+ element_radius_overrides?: Partial<Record<ElementSymbol, number>>
153
+ site_radius_overrides?: Map<number, number> | SvelteMap<number, number>
154
+ added_bonds?: StructureBond[]
155
+ removed_bonds?: StructureBond[]
156
+ bond_order_overrides?: StructureBond[]
157
+ bond_edit_mode?: BondEditMode
158
+ add_atom_mode?: boolean
159
+ add_element?: ElementSymbol
160
+ dragging_atoms?: boolean
161
+ polyhedra_rendered_elements?: string[]
162
+ } = $props()
163
+
164
+ // Cell-local dimensions (each pane is responsible for its own zoom sizing) and cursor
165
+ let width = $state(0)
166
+ let height = $state(0)
167
+ let cursor = $state(`default`)
168
+
169
+ // Multi-view panes are ~half the viewer, so shrink the (fixed 86px) viewport gizmo to
170
+ // stay proportional. Single view keeps the default size.
171
+ let gizmo_prop = $derived.by(() => {
172
+ if (!gizmo || !in_grid) return gizmo
173
+ const fifth_of_min_dim = Math.min(width, height) * 0.2
174
+ const size = Math.round(Math.max(34, Math.min(72, fifth_of_min_dim)))
175
+ return { ...(typeof gizmo === `object` ? gizmo : {}), size }
176
+ })
177
+
178
+ // Internal orbit controls are bound from StructureScene; camera_position/target are
179
+ // bindable above so the primary viewport can persist moves into scene_props.
180
+ let orbit_controls =
181
+ $state<ComponentProps<typeof StructureScene>[`orbit_controls`]>(undefined)
182
+ let rotation_target_ref = $state<Vec3 | undefined>(undefined)
183
+ let initial_computed_zoom = $state<number | undefined>(undefined)
184
+ let camera_is_moving = $state(false)
185
+
186
+ const read_orbit_target = (): Vec3 | undefined => {
187
+ if (!orbit_controls?.target) return
188
+ const { x, y, z } = orbit_controls.target
189
+ return [x, y, z]
190
+ }
191
+
192
+ const read_camera_position = (): Vec3 | undefined =>
193
+ camera ? [camera.position.x, camera.position.y, camera.position.z] : camera_position
194
+
195
+ // Reset this pane's camera. The primary pane is given on_camera_reset, so it also emits.
196
+ function reset_camera() {
197
+ camera_position = [0, 0, 0]
198
+ camera_target = rotation_target_ref
199
+ report_moved?.(false)
200
+ if (orbit_controls && camera) {
201
+ if (`reset` in orbit_controls && typeof orbit_controls.reset === `function`) {
202
+ orbit_controls.reset()
203
+ }
204
+ if (orbit_controls.target && rotation_target_ref) {
205
+ orbit_controls.target.set(...rotation_target_ref)
206
+ }
207
+ if (`zoom` in camera && initial_computed_zoom !== undefined) {
208
+ const ortho_camera = camera as OrthographicCamera
209
+ ortho_camera.zoom = initial_computed_zoom
210
+ ortho_camera.updateProjectionMatrix()
211
+ }
212
+ if (typeof orbit_controls.update === `function`) orbit_controls.update()
213
+ camera_position = read_camera_position() ?? camera_position
214
+ camera_target = read_orbit_target()
215
+ }
216
+ on_camera_reset?.({ structure, camera_has_moved: false, camera_position, camera_target })
217
+ }
218
+
219
+ // Track camera movement: keep camera_target in sync with the orbit controls and emit
220
+ // on_camera_move (primary pane only) while the controls are active.
221
+ $effect(() => {
222
+ if (!camera_is_moving) return
223
+ report_moved?.(true)
224
+ const sync = () => {
225
+ const pos = read_camera_position()
226
+ if (!pos) return
227
+ const target = read_orbit_target()
228
+ camera_position = pos
229
+ camera_target = target
230
+ on_camera_move?.({
231
+ structure,
232
+ camera_has_moved: true,
233
+ camera_position: pos,
234
+ camera_target: target,
235
+ })
236
+ }
237
+ sync()
238
+ const interval = setInterval(sync, 200)
239
+ return () => clearInterval(interval)
240
+ })
241
+
242
+ // Reset on parent request (reset-all button bumps reset_token for every pane)
243
+ let last_reset_token: number | undefined
244
+ $effect(() => {
245
+ const token = reset_token
246
+ if (last_reset_token !== undefined && token !== last_reset_token) {
247
+ untrack(reset_camera)
248
+ }
249
+ last_reset_token = token
250
+ })
251
+
252
+ // Clear stale camera state on structure change so each pane re-frames the new cell
253
+ // along its configured direction.
254
+ let viewport_first_run = true
255
+ $effect(() => {
256
+ void structure
257
+ if (viewport_first_run) {
258
+ viewport_first_run = false
259
+ return
260
+ }
261
+ untrack(() => {
262
+ // Preserve explicit camera props supplied alongside a structure change.
263
+ if (camera_target !== undefined || camera_position.some((coord) => coord !== 0)) return
264
+ camera_position = [0, 0, 0]
265
+ camera_target = undefined
266
+ })
267
+ })
268
+
269
+ function handle_dblclick(event: MouseEvent) {
270
+ const target = event.target
271
+ if (
272
+ target instanceof HTMLElement &&
273
+ [`BUTTON`, `INPUT`, `SELECT`].includes(target.tagName)
274
+ )
275
+ return
276
+ reset_camera()
277
+ }
278
+ </script>
279
+
280
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
281
+ <div
282
+ class="viewport-cell"
283
+ class:active
284
+ class:multi={in_grid}
285
+ style:--canvas-cursor={cursor}
286
+ bind:clientWidth={width}
287
+ bind:clientHeight={height}
288
+ onpointerenter={onactivate}
289
+ ondblclick={handle_dblclick}
290
+ >
291
+ {#if label}<span class="viewport-label">{label}</span>{/if}
292
+ <Canvas createRenderer={create_renderer}>
293
+ <StructureScene
294
+ {structure}
295
+ {base_structure}
296
+ {...scene_props}
297
+ {...in_grid ? { auto_rotate: 0 } : {}}
298
+ {camera_position}
299
+ {camera_target}
300
+ {camera_projection}
301
+ {camera_direction}
302
+ {interactive}
303
+ gizmo={gizmo_prop}
304
+ {lattice_props}
305
+ {volumetric_data}
306
+ {isosurface_settings}
307
+ bind:camera_is_moving
308
+ bind:selected_sites
309
+ {active_sites}
310
+ bind:hovered_idx={hovered_site_idx}
311
+ bind:measured_sites
312
+ bind:scene
313
+ bind:camera
314
+ bind:orbit_controls
315
+ bind:rotation_target_ref
316
+ bind:initial_computed_zoom
317
+ bind:hidden_elements
318
+ bind:hidden_prop_vals
319
+ bind:element_radius_overrides
320
+ bind:site_radius_overrides
321
+ bind:added_bonds
322
+ bind:removed_bonds
323
+ bind:bond_order_overrides
324
+ {bond_edits_enabled}
325
+ bind:bond_edit_mode
326
+ {bond_edit_order}
327
+ {measure_mode}
328
+ {width}
329
+ {height}
330
+ {atom_color_config}
331
+ {sym_data}
332
+ {on_sites_moved}
333
+ {on_operation_start}
334
+ {on_bond_edit_start}
335
+ {on_add_atom}
336
+ bind:add_atom_mode
337
+ bind:add_element
338
+ bind:cursor
339
+ bind:dragging_atoms
340
+ bind:polyhedra_rendered_elements
341
+ />
342
+ </Canvas>
343
+ </div>
344
+
345
+ <style>
346
+ .viewport-cell {
347
+ position: relative;
348
+ overflow: hidden;
349
+ box-sizing: border-box;
350
+ height: 100%;
351
+ width: 100%;
352
+ min-width: 0;
353
+ min-height: 0;
354
+ }
355
+ /* In multi-view, give each pane a subtle separator and highlight the active one */
356
+ .viewport-cell.multi {
357
+ border: 1px solid var(--struct-viewport-border, rgba(128, 128, 128, 0.35));
358
+ }
359
+ /* Let the active pane's hover tooltip overflow into neighboring panes instead of
360
+ being clipped, and raise it above sibling panes so it paints on top. The WebGL
361
+ canvas is sized to the cell by JS, so only HTML overlays (the tooltip) overflow. */
362
+ .viewport-cell.multi.active {
363
+ border-color: var(--struct-viewport-active-border, var(--accent-color, #4a9eff));
364
+ overflow: visible;
365
+ z-index: 1;
366
+ }
367
+ .viewport-label {
368
+ position: absolute;
369
+ top: 3px;
370
+ left: 5px;
371
+ z-index: 1;
372
+ pointer-events: none;
373
+ font-size: var(--struct-viewport-label-font-size, 0.8em);
374
+ font-weight: 500;
375
+ padding: 1px 5px;
376
+ border-radius: var(--border-radius, 3pt);
377
+ color: var(--struct-viewport-label-color, var(--text-color, currentColor));
378
+ background: var(
379
+ --struct-viewport-label-bg,
380
+ color-mix(in srgb, var(--page-bg, Canvas) 65%, transparent)
381
+ );
382
+ }
383
+ .viewport-cell :global(canvas) {
384
+ cursor: var(--canvas-cursor, default);
385
+ }
386
+ </style>
@@ -0,0 +1,63 @@
1
+ import type { ElementSymbol } from '../element';
2
+ import type { IsosurfaceSettings, VolumetricData } from '../isosurface/types';
3
+ import type { Vec3 } from '../math';
4
+ import type { CameraProjection } from '../settings';
5
+ import type { AnyStructure, BondEditMode, BondOrder, MeasureMode, StructureBond, StructureHandlerData } from './';
6
+ import type { MoyoDataset } from '@spglib/moyo-wasm';
7
+ import type { ComponentProps } from 'svelte';
8
+ import { SvelteMap } from 'svelte/reactivity';
9
+ import { type Camera, type Scene } from 'three';
10
+ import type { AtomColorConfig } from './atom-properties';
11
+ import StructureScene from './StructureScene.svelte';
12
+ type $$ComponentProps = {
13
+ in_grid?: boolean;
14
+ active?: boolean;
15
+ label?: string;
16
+ reset_token?: number;
17
+ interactive?: boolean;
18
+ onactivate?: () => void;
19
+ report_moved?: (moved: boolean) => void;
20
+ on_camera_move?: (data: StructureHandlerData) => void;
21
+ on_camera_reset?: (data: StructureHandlerData) => void;
22
+ structure?: AnyStructure;
23
+ base_structure?: AnyStructure;
24
+ scene_props?: ComponentProps<typeof StructureScene>;
25
+ gizmo?: boolean | ComponentProps<typeof StructureScene>[`gizmo`];
26
+ lattice_props?: ComponentProps<typeof StructureScene>[`lattice_props`];
27
+ volumetric_data?: VolumetricData;
28
+ isosurface_settings?: IsosurfaceSettings;
29
+ bond_edits_enabled?: boolean;
30
+ bond_edit_order?: BondOrder;
31
+ measure_mode?: MeasureMode;
32
+ atom_color_config?: Partial<AtomColorConfig>;
33
+ sym_data?: MoyoDataset | null;
34
+ active_sites?: number[];
35
+ camera_direction?: Vec3;
36
+ camera_projection?: CameraProjection;
37
+ camera_position?: Vec3;
38
+ camera_target?: Vec3;
39
+ on_sites_moved?: (scene_indices: number[], delta: Vec3) => void;
40
+ on_operation_start?: () => void;
41
+ on_bond_edit_start?: () => void;
42
+ on_add_atom?: (xyz: Vec3, element: ElementSymbol) => void;
43
+ scene?: Scene;
44
+ camera?: Camera;
45
+ selected_sites?: number[];
46
+ measured_sites?: number[];
47
+ hovered_site_idx?: number | null;
48
+ hidden_elements?: Set<ElementSymbol>;
49
+ hidden_prop_vals?: Set<number | string>;
50
+ element_radius_overrides?: Partial<Record<ElementSymbol, number>>;
51
+ site_radius_overrides?: Map<number, number> | SvelteMap<number, number>;
52
+ added_bonds?: StructureBond[];
53
+ removed_bonds?: StructureBond[];
54
+ bond_order_overrides?: StructureBond[];
55
+ bond_edit_mode?: BondEditMode;
56
+ add_atom_mode?: boolean;
57
+ add_element?: ElementSymbol;
58
+ dragging_atoms?: boolean;
59
+ polyhedra_rendered_elements?: string[];
60
+ };
61
+ declare const StructureViewport: import("svelte").Component<$$ComponentProps, {}, "camera" | "camera_position" | "camera_target" | "polyhedra_rendered_elements" | "selected_sites" | "measured_sites" | "added_bonds" | "removed_bonds" | "bond_order_overrides" | "bond_edit_mode" | "scene" | "hidden_elements" | "hidden_prop_vals" | "element_radius_overrides" | "site_radius_overrides" | "add_atom_mode" | "add_element" | "dragging_atoms" | "hovered_site_idx">;
62
+ type StructureViewport = ReturnType<typeof StructureViewport>;
63
+ export default StructureViewport;
@@ -1,14 +1,18 @@
1
- import type { Vec2, Vec3 } from '../math';
2
- import type { Camera, Object3D } from 'three';
1
+ import type { Vec3 } from '../math';
2
+ import type { Camera } from 'three';
3
+ import { Matrix4 } from 'three';
3
4
  export declare const LABEL_OFFSET_EPS = 1e-9;
4
- type LabelOffsetSource = Vec3 | (() => Vec3);
5
5
  export declare const choose_site_label_offset: (bond_directions: Vec3[], base_offset: Vec3) => Vec3;
6
- export declare const label_screen_position: (atom_position: Vec3, label_offset: Vec3, visual_radius: number, label_screen_margin: number, label_camera: Camera, size: {
7
- width: number;
8
- height: number;
9
- }) => Vec2;
10
- export declare const make_label_position_calculator: (_atom_position: Vec3, label_offset: LabelOffsetSource, visual_radius: number, label_screen_margin: number) => (object: Object3D, label_camera: Camera, size: {
11
- width: number;
12
- height: number;
13
- }) => Vec2;
14
- export {};
6
+ export type LabelPlacement = {
7
+ x: number;
8
+ y: number;
9
+ visible: boolean;
10
+ };
11
+ export declare class LabelProjector {
12
+ #private;
13
+ update(camera: Camera, anchor_world_matrix: Matrix4, size: {
14
+ width: number;
15
+ height: number;
16
+ }, margin: number): void;
17
+ place(position: Vec3, offset: Vec3, visual_radius: number, out: LabelPlacement): void;
18
+ }
@@ -1,5 +1,5 @@
1
1
  import * as math from '../math';
2
- import { Vector3 } from 'three';
2
+ import { Matrix4 } from 'three';
3
3
  export const LABEL_OFFSET_EPS = 1e-9;
4
4
  const LABEL_OFFSET_DIRECTIONS = [
5
5
  [0, -1, 0],
@@ -44,39 +44,72 @@ export const choose_site_label_offset = (bond_directions, base_offset) => {
44
44
  }
45
45
  return math.scale(best_direction, offset_length);
46
46
  };
47
- const project_to_screen = (position, label_camera, size) => {
48
- const projected = new Vector3(...position).project(label_camera);
49
- return [
50
- (projected.x * size.width) / 2 + size.width / 2,
51
- (-projected.y * size.height) / 2 + size.height / 2,
52
- ];
53
- };
54
- export const label_screen_position = (atom_position, label_offset, visual_radius, label_screen_margin, label_camera, size) => {
55
- const atom_screen = project_to_screen(atom_position, label_camera, size);
56
- const offset_screen = project_to_screen(math.add(atom_position, label_offset), label_camera, size);
57
- const offset_x = offset_screen[0] - atom_screen[0];
58
- const offset_y = offset_screen[1] - atom_screen[1];
59
- const offset_length = Math.hypot(offset_x, offset_y);
60
- const direction_x = offset_length > LABEL_OFFSET_EPS ? offset_x / offset_length : 0;
61
- const direction_y = offset_length > LABEL_OFFSET_EPS ? offset_y / offset_length : label_offset[1] >= 0 ? -1 : 1;
62
- // Measure the atom's projected radius along the camera's right axis (always
63
- // view-perpendicular). Measuring along label_offset would collapse the clearance
64
- // to ~zero for offsets near the view axis, letting the label overlap the atom.
65
- const radius_dir = new Vector3()
66
- .setFromMatrixColumn(label_camera.matrixWorld, 0)
67
- .normalize()
68
- .multiplyScalar(visual_radius);
69
- const radius_edge = math.add(atom_position, [
70
- radius_dir.x,
71
- radius_dir.y,
72
- radius_dir.z,
73
- ]);
74
- const radius_screen = project_to_screen(radius_edge, label_camera, size);
75
- const atom_screen_radius = Math.hypot(radius_screen[0] - atom_screen[0], radius_screen[1] - atom_screen[1]);
76
- const screen_gap = atom_screen_radius + label_screen_margin;
77
- return [atom_screen[0] + direction_x * screen_gap, atom_screen[1] + direction_y * screen_gap];
78
- };
79
- export const make_label_position_calculator = (_atom_position, label_offset, visual_radius, label_screen_margin) => (object, label_camera, size) => {
80
- const world_position = object.getWorldPosition(new Vector3());
81
- return label_screen_position([world_position.x, world_position.y, world_position.z], typeof label_offset === `function` ? label_offset() : label_offset, visual_radius, label_screen_margin, label_camera, size);
82
- };
47
+ // Per-frame screen projector for label overlays. `update()` precomputes the
48
+ // combined model-view-projection once per frame; `place()` then resolves each
49
+ // label with a single clip-space transform and zero allocations (labels run
50
+ // per site per frame, so the old 3-projections-per-label path with fresh
51
+ // Vector3s dominated frame time on large supercells).
52
+ //
53
+ // Placement semantics match the previous label_screen_position helper: the
54
+ // label sits `atom_screen_radius + margin` px from the atom center along the
55
+ // screen direction of its offset. The projected radius is measured along the
56
+ // camera's right axis, which for both projections equals
57
+ // visual_radius * projection[5] * (height/2) / clip_w.
58
+ export class LabelProjector {
59
+ #mvp = new Matrix4(); // projection * view * anchor (local -> clip space)
60
+ #view = new Matrix4(); // view * anchor (local -> view space, for behind-camera test)
61
+ #half_width = 0;
62
+ #half_height = 0;
63
+ #radius_scale = 0; // clip-space multiplier for projected atom radius
64
+ #margin = 0;
65
+ update(camera, anchor_world_matrix, size, margin) {
66
+ this.#view.multiplyMatrices(camera.matrixWorldInverse, anchor_world_matrix);
67
+ this.#mvp.multiplyMatrices(camera.projectionMatrix, this.#view);
68
+ this.#half_width = size.width / 2;
69
+ this.#half_height = size.height / 2;
70
+ // projectionMatrix[5] = cot(fov/2) for perspective, 2/(top-bottom) for ortho
71
+ this.#radius_scale = camera.projectionMatrix.elements[5] * this.#half_height;
72
+ this.#margin = margin;
73
+ }
74
+ // position + offset: label anchor and preferred direction in anchor-local
75
+ // space; visual_radius: atom radius in the same units
76
+ place(position, offset, visual_radius, out) {
77
+ const [pos_x, pos_y, pos_z] = position;
78
+ const mvp = this.#mvp.elements;
79
+ const view = this.#view.elements;
80
+ // Behind-camera test in view space (camera looks down -z)
81
+ const view_z = view[2] * pos_x + view[6] * pos_y + view[10] * pos_z + view[14];
82
+ if (view_z > 0) {
83
+ out.visible = false;
84
+ return;
85
+ }
86
+ const clip_x = mvp[0] * pos_x + mvp[4] * pos_y + mvp[8] * pos_z + mvp[12];
87
+ const clip_y = mvp[1] * pos_x + mvp[5] * pos_y + mvp[9] * pos_z + mvp[13];
88
+ const clip_w = mvp[3] * pos_x + mvp[7] * pos_y + mvp[11] * pos_z + mvp[15];
89
+ const screen_x = (clip_x / clip_w) * this.#half_width + this.#half_width;
90
+ const screen_y = (-clip_y / clip_w) * this.#half_height + this.#half_height;
91
+ // Screen direction of the offset: project position + offset and take the
92
+ // screen-space delta. Projecting the second point (instead of just rotating
93
+ // the offset into view space) keeps perspective foreshortening exact for
94
+ // offsets with a depth component, matching the pre-projector behavior.
95
+ const [off_x, off_y, off_z] = offset;
96
+ const end_x = pos_x + off_x;
97
+ const end_y = pos_y + off_y;
98
+ const end_z = pos_z + off_z;
99
+ const end_clip_x = mvp[0] * end_x + mvp[4] * end_y + mvp[8] * end_z + mvp[12];
100
+ const end_clip_y = mvp[1] * end_x + mvp[5] * end_y + mvp[9] * end_z + mvp[13];
101
+ const end_clip_w = mvp[3] * end_x + mvp[7] * end_y + mvp[11] * end_z + mvp[15];
102
+ const delta_x = (end_clip_x / end_clip_w) * this.#half_width + this.#half_width - screen_x;
103
+ const delta_y = (-end_clip_y / end_clip_w) * this.#half_height + this.#half_height - screen_y;
104
+ const dir_len = Math.hypot(delta_x, delta_y);
105
+ // Offsets along the view axis have no screen direction; nudge upward like
106
+ // the previous implementation (screen y grows downward)
107
+ const dir_x = dir_len > LABEL_OFFSET_EPS ? delta_x / dir_len : 0;
108
+ const dir_y = dir_len > LABEL_OFFSET_EPS ? delta_y / dir_len : off_y >= 0 ? -1 : 1;
109
+ const atom_screen_radius = (visual_radius * this.#radius_scale) / clip_w;
110
+ const screen_gap = Math.abs(atom_screen_radius) + this.#margin;
111
+ out.x = screen_x + dir_x * screen_gap;
112
+ out.y = screen_y + dir_y * screen_gap;
113
+ out.visible = true;
114
+ }
115
+ }
@@ -1,4 +1,5 @@
1
1
  import type { ColorScaleType, D3InterpolateName } from '../colors';
2
+ import { type CoordinationData } from '../coordination/calc-coordination';
2
3
  import type { AtomColorMode } from '../settings';
3
4
  import type { AnyStructure, Site } from './';
4
5
  import type { BondingStrategy } from './bonding';
@@ -29,6 +30,7 @@ export declare const apply_categorical_color_scale: (vals: string[], scale?: str
29
30
  unique_values: string[];
30
31
  };
31
32
  export declare const get_orig_site_idx: (site: Site | undefined, site_idx: number) => number;
33
+ export declare function calc_structure_coordination(structure: AnyStructure, strategy?: BondingStrategy): CoordinationData;
32
34
  export declare function get_coordination_colors(structure: AnyStructure, strategy?: BondingStrategy, scale?: string, type?: ColorScaleType): AtomPropertyColors;
33
35
  export declare function get_wyckoff_colors(structure: AnyStructure, sym_data: SymmetryDataWithOrigMap | null, scale?: string): AtomPropertyColors;
34
36
  export declare function get_custom_colors(structure: AnyStructure, fn: (site: Site, idx: number) => number | string, scale?: string, type?: ColorScaleType): AtomPropertyColors;