matterviz 0.3.7 → 0.4.0

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 (324) hide show
  1. package/dist/Icon.svelte +7 -4
  2. package/dist/MillerIndexInput.svelte +1 -1
  3. package/dist/api/optimade.js +32 -26
  4. package/dist/app.css +0 -3
  5. package/dist/brillouin/BrillouinZone.svelte +8 -3
  6. package/dist/brillouin/BrillouinZone.svelte.d.ts +2 -1
  7. package/dist/brillouin/BrillouinZoneScene.svelte +52 -6
  8. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -0
  9. package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
  10. package/dist/brillouin/compute.js +10 -14
  11. package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
  12. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +12 -15
  13. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +8 -10
  14. package/dist/chempot-diagram/async-compute.svelte.js +3 -1
  15. package/dist/chempot-diagram/chempot-worker.js +2 -1
  16. package/dist/chempot-diagram/compute.d.ts +1 -1
  17. package/dist/chempot-diagram/compute.js +17 -19
  18. package/dist/colors/index.js +6 -5
  19. package/dist/composition/FormulaFilter.svelte +12 -6
  20. package/dist/composition/PieChart.svelte +6 -5
  21. package/dist/composition/chem-sys.d.ts +8 -0
  22. package/dist/composition/chem-sys.js +85 -0
  23. package/dist/composition/format.js +4 -2
  24. package/dist/composition/index.d.ts +1 -0
  25. package/dist/composition/index.js +1 -0
  26. package/dist/composition/parse.js +25 -13
  27. package/dist/convex-hull/ConvexHull2D.svelte +12 -10
  28. package/dist/convex-hull/ConvexHull3D.svelte +5 -5
  29. package/dist/convex-hull/ConvexHull4D.svelte +5 -9
  30. package/dist/convex-hull/ConvexHullStats.svelte +12 -12
  31. package/dist/convex-hull/GasPressureControls.svelte +4 -4
  32. package/dist/convex-hull/TemperatureSlider.svelte +2 -2
  33. package/dist/convex-hull/demo-temperature.d.ts +1 -1
  34. package/dist/convex-hull/demo-temperature.js +20 -22
  35. package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
  36. package/dist/convex-hull/gas-thermodynamics.js +22 -30
  37. package/dist/convex-hull/helpers.d.ts +3 -0
  38. package/dist/convex-hull/helpers.js +17 -9
  39. package/dist/convex-hull/index.d.ts +1 -1
  40. package/dist/convex-hull/thermodynamics.js +83 -78
  41. package/dist/convex-hull/types.d.ts +1 -1
  42. package/dist/coordination/CoordinationBarPlot.svelte +23 -23
  43. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  44. package/dist/element/ElementTile.svelte.d.ts +1 -1
  45. package/dist/fermi-surface/FermiSlice.svelte +13 -5
  46. package/dist/fermi-surface/FermiSurface.svelte +11 -5
  47. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  48. package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
  49. package/dist/fermi-surface/FermiSurfaceScene.svelte +3 -0
  50. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
  51. package/dist/fermi-surface/compute.js +59 -59
  52. package/dist/fermi-surface/export.js +3 -2
  53. package/dist/fermi-surface/parse.js +7 -4
  54. package/dist/fermi-surface/types.d.ts +1 -0
  55. package/dist/heatmap-matrix/HeatmapMatrix.svelte +23 -21
  56. package/dist/heatmap-matrix/index.js +1 -1
  57. package/dist/io/decompress.js +4 -2
  58. package/dist/io/export.d.ts +4 -4
  59. package/dist/io/export.js +47 -25
  60. package/dist/io/fetch.js +5 -1
  61. package/dist/io/file-drop.d.ts +1 -1
  62. package/dist/io/file-drop.js +35 -36
  63. package/dist/io/url-drop.js +64 -33
  64. package/dist/isosurface/parse.js +6 -7
  65. package/dist/isosurface/slice.js +5 -4
  66. package/dist/isosurface/types.js +1 -1
  67. package/dist/keyboard.d.ts +3 -0
  68. package/dist/keyboard.js +23 -0
  69. package/dist/labels.d.ts +1 -1
  70. package/dist/labels.js +8 -7
  71. package/dist/layout/PropertyFilter.svelte +3 -2
  72. package/dist/layout/SettingsSection.svelte +1 -1
  73. package/dist/layout/json-tree/JsonNode.svelte +1 -1
  74. package/dist/layout/json-tree/JsonTree.svelte +2 -2
  75. package/dist/layout/json-tree/utils.js +5 -4
  76. package/dist/marching-cubes.js +8 -13
  77. package/dist/math.d.ts +5 -1
  78. package/dist/math.js +24 -9
  79. package/dist/overlays/DraggablePane.svelte +4 -4
  80. package/dist/periodic-table/PeriodicTable.svelte +20 -9
  81. package/dist/periodic-table/PropertySelect.svelte +1 -0
  82. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
  83. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  84. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  85. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  86. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
  87. package/dist/phase-diagram/build-diagram.js +2 -2
  88. package/dist/phase-diagram/parse.js +6 -5
  89. package/dist/phase-diagram/types.d.ts +1 -1
  90. package/dist/phase-diagram/utils.d.ts +3 -3
  91. package/dist/phase-diagram/utils.js +8 -12
  92. package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +229 -587
  93. package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +5 -5
  94. package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
  95. package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
  96. package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +6 -6
  97. package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
  98. package/dist/plot/bar/data.d.ts +40 -0
  99. package/dist/plot/bar/data.js +154 -0
  100. package/dist/plot/bar/geometry.d.ts +39 -0
  101. package/dist/plot/bar/geometry.js +60 -0
  102. package/dist/plot/bar/index.d.ts +3 -0
  103. package/dist/plot/bar/index.js +3 -0
  104. package/dist/plot/box/BoxPlot.svelte +1462 -0
  105. package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
  106. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  107. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  108. package/dist/plot/box/Violin.svelte +14 -0
  109. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  110. package/dist/plot/box/box-plot.d.ts +55 -0
  111. package/dist/plot/box/box-plot.js +126 -0
  112. package/dist/plot/box/index.d.ts +5 -0
  113. package/dist/plot/box/index.js +5 -0
  114. package/dist/plot/box/kde.d.ts +16 -0
  115. package/dist/plot/box/kde.js +160 -0
  116. package/dist/plot/box/quantile.d.ts +3 -0
  117. package/dist/plot/box/quantile.js +53 -0
  118. package/dist/plot/{auto-place.js → core/auto-place.js} +2 -2
  119. package/dist/plot/core/axis-utils.d.ts +46 -0
  120. package/dist/plot/core/axis-utils.js +110 -0
  121. package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
  122. package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
  123. package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +36 -33
  124. package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +2 -2
  125. package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
  126. package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
  127. package/dist/plot/core/components/ControlPane.svelte +46 -0
  128. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  129. package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
  130. package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
  131. package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
  132. package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
  133. package/dist/plot/{Line.svelte → core/components/Line.svelte} +30 -13
  134. package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +7 -5
  135. package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +3 -2
  136. package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
  137. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  138. package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
  139. package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
  140. package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
  141. package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
  142. package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
  143. package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
  144. package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
  145. package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +4 -4
  146. package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +2 -2
  147. package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +7 -7
  148. package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +2 -2
  149. package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
  150. package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
  151. package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
  152. package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
  153. package/dist/plot/core/components/index.d.ts +17 -0
  154. package/dist/plot/core/components/index.js +17 -0
  155. package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
  156. package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +3 -5
  157. package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
  158. package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
  159. package/dist/plot/core/fill-utils.d.ts +33 -0
  160. package/dist/plot/core/fill-utils.js +388 -0
  161. package/dist/plot/{hover-lock.svelte.js → core/hover-lock.svelte.js} +5 -6
  162. package/dist/plot/core/index.d.ts +10 -0
  163. package/dist/plot/core/index.js +11 -0
  164. package/dist/plot/core/interactions.d.ts +35 -0
  165. package/dist/plot/core/interactions.js +195 -0
  166. package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
  167. package/dist/plot/{layout.js → core/layout.js} +16 -8
  168. package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +1 -1
  169. package/dist/plot/{reference-line.js → core/reference-line.js} +23 -36
  170. package/dist/plot/{scales.d.ts → core/scales.d.ts} +2 -2
  171. package/dist/plot/{scales.js → core/scales.js} +84 -85
  172. package/dist/plot/core/svg.d.ts +2 -0
  173. package/dist/plot/core/svg.js +41 -0
  174. package/dist/plot/{types.d.ts → core/types.d.ts} +19 -79
  175. package/dist/plot/{types.js → core/types.js} +1 -1
  176. package/dist/plot/{utils → core/utils}/label-placement.d.ts +2 -2
  177. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  178. package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
  179. package/dist/plot/core/utils.d.ts +11 -0
  180. package/dist/plot/core/utils.js +27 -0
  181. package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +154 -294
  182. package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
  183. package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
  184. package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
  185. package/dist/plot/histogram/index.d.ts +2 -0
  186. package/dist/plot/histogram/index.js +2 -0
  187. package/dist/plot/index.d.ts +8 -41
  188. package/dist/plot/index.js +10 -39
  189. package/dist/plot/sankey/Sankey.svelte +700 -0
  190. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  191. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  192. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  193. package/dist/plot/sankey/index.d.ts +4 -0
  194. package/dist/plot/sankey/index.js +3 -0
  195. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  196. package/dist/plot/sankey/sankey-types.js +4 -0
  197. package/dist/plot/sankey/sankey.d.ts +52 -0
  198. package/dist/plot/sankey/sankey.js +187 -0
  199. package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +61 -59
  200. package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +4 -4
  201. package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
  202. package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
  203. package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +221 -642
  204. package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +7 -7
  205. package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
  206. package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +1 -1
  207. package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
  208. package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
  209. package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
  210. package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
  211. package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +3 -3
  212. package/dist/plot/scatter/index.d.ts +7 -0
  213. package/dist/plot/scatter/index.js +5 -0
  214. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  215. package/dist/plot/scatter/scatter-data.js +212 -0
  216. package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +12 -10
  217. package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +7 -7
  218. package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +5 -4
  219. package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +2 -2
  220. package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +11 -11
  221. package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +3 -3
  222. package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +1 -1
  223. package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +1 -1
  224. package/dist/plot/scatter-3d/index.d.ts +4 -0
  225. package/dist/plot/scatter-3d/index.js +4 -0
  226. package/dist/plot/sunburst/Sunburst.svelte +1045 -0
  227. package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
  228. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  229. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  230. package/dist/plot/sunburst/index.d.ts +4 -0
  231. package/dist/plot/sunburst/index.js +4 -0
  232. package/dist/plot/sunburst/render.d.ts +34 -0
  233. package/dist/plot/sunburst/render.js +122 -0
  234. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  235. package/dist/plot/sunburst/sunburst.js +266 -0
  236. package/dist/rdf/RdfPlot.svelte +2 -1
  237. package/dist/rdf/calc-rdf.js +11 -24
  238. package/dist/sanitize.js +1 -1
  239. package/dist/settings.d.ts +65 -1
  240. package/dist/settings.js +262 -0
  241. package/dist/spectral/Bands.svelte +39 -29
  242. package/dist/spectral/Bands.svelte.d.ts +3 -4
  243. package/dist/spectral/BandsAndDos.svelte +1 -1
  244. package/dist/spectral/BrillouinBandsDos.svelte +39 -27
  245. package/dist/spectral/Dos.svelte +10 -19
  246. package/dist/spectral/Dos.svelte.d.ts +2 -2
  247. package/dist/spectral/helpers.d.ts +3 -1
  248. package/dist/spectral/helpers.js +95 -29
  249. package/dist/structure/AtomLegend.svelte +8 -9
  250. package/dist/structure/CellSelect.svelte +1 -2
  251. package/dist/structure/Cylinder.svelte +12 -8
  252. package/dist/structure/Cylinder.svelte.d.ts +4 -1
  253. package/dist/structure/Structure.svelte +78 -72
  254. package/dist/structure/Structure.svelte.d.ts +1 -1
  255. package/dist/structure/StructureInfoPane.svelte +5 -6
  256. package/dist/structure/StructureScene.svelte +11 -10
  257. package/dist/structure/atom-properties.js +6 -6
  258. package/dist/structure/bond-order-perception.js +1 -1
  259. package/dist/structure/bonding.d.ts +1 -0
  260. package/dist/structure/bonding.js +43 -15
  261. package/dist/structure/export.js +27 -23
  262. package/dist/structure/index.d.ts +2 -4
  263. package/dist/structure/index.js +1 -3
  264. package/dist/structure/label-placement.js +4 -4
  265. package/dist/structure/measure.d.ts +3 -2
  266. package/dist/structure/measure.js +6 -5
  267. package/dist/structure/parse.js +121 -103
  268. package/dist/structure/pbc.js +4 -0
  269. package/dist/symmetry/SymmetryStats.svelte +2 -2
  270. package/dist/symmetry/index.d.ts +1 -1
  271. package/dist/symmetry/index.js +22 -24
  272. package/dist/symmetry/spacegroups.d.ts +7 -0
  273. package/dist/symmetry/spacegroups.js +48 -13
  274. package/dist/table/HeatmapTable.svelte +63 -11
  275. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  276. package/dist/table/index.d.ts +1 -3
  277. package/dist/table/index.js +1 -1
  278. package/dist/theme/index.js +8 -8
  279. package/dist/tooltip/KCoords.svelte +45 -0
  280. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  281. package/dist/tooltip/index.d.ts +1 -0
  282. package/dist/tooltip/index.js +1 -0
  283. package/dist/trajectory/Trajectory.svelte +66 -40
  284. package/dist/trajectory/Trajectory.svelte.d.ts +2 -1
  285. package/dist/trajectory/TrajectoryExportPane.svelte +2 -1
  286. package/dist/trajectory/TrajectoryInfoPane.svelte +2 -1
  287. package/dist/trajectory/format-detect.d.ts +1 -0
  288. package/dist/trajectory/format-detect.js +25 -11
  289. package/dist/trajectory/frame-reader.js +17 -50
  290. package/dist/trajectory/helpers.js +1 -1
  291. package/dist/trajectory/index.js +1 -1
  292. package/dist/trajectory/parse/hdf5.js +1 -1
  293. package/dist/trajectory/parse/index.js +14 -6
  294. package/dist/trajectory/parse/vasp.js +36 -17
  295. package/dist/trajectory/parse/xyz.d.ts +24 -0
  296. package/dist/trajectory/parse/xyz.js +102 -89
  297. package/dist/trajectory/plotting.d.ts +1 -1
  298. package/dist/trajectory/plotting.js +15 -15
  299. package/dist/utils.d.ts +1 -0
  300. package/dist/utils.js +6 -4
  301. package/dist/xrd/XrdPlot.svelte +2 -1
  302. package/dist/xrd/calc-xrd.js +15 -12
  303. package/dist/xrd/parse.js +2 -2
  304. package/package.json +22 -18
  305. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  306. package/dist/plot/axis-utils.d.ts +0 -19
  307. package/dist/plot/axis-utils.js +0 -78
  308. package/dist/plot/defaults.d.ts +0 -19
  309. package/dist/plot/defaults.js +0 -9
  310. package/dist/plot/fill-utils.d.ts +0 -46
  311. package/dist/plot/fill-utils.js +0 -322
  312. package/dist/plot/interactions.d.ts +0 -12
  313. package/dist/plot/interactions.js +0 -101
  314. package/dist/plot/svg.d.ts +0 -1
  315. package/dist/plot/svg.js +0 -11
  316. package/dist/plot/utils/series-visibility.d.ts +0 -15
  317. package/dist/plot/utils.d.ts +0 -1
  318. package/dist/plot/utils.js +0 -14
  319. /package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +0 -0
  320. /package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +0 -0
  321. /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
  322. /package/dist/plot/{hover-lock.svelte.d.ts → core/hover-lock.svelte.d.ts} +0 -0
  323. /package/dist/plot/{utils → core/utils}/label-placement.js +0 -0
  324. /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { BarPlot } from '../plot';
2
- import type { AxisConfig } from '../plot/types';
2
+ import type { AxisConfig } from '../plot/core/types';
3
3
  import type { AnyStructure } from '../structure';
4
4
  import type { BondingStrategy } from '../structure/bonding';
5
5
  import type { ComponentProps } from 'svelte';
@@ -24,6 +24,6 @@ type $$ComponentProps = Omit<HTMLAttributes<HTMLElement>, `onclick`> & {
24
24
  event: MouseEvent;
25
25
  }) => void;
26
26
  };
27
- declare const ElementTile: import("svelte").Component<$$ComponentProps, {}, "text_color" | "node">;
27
+ declare const ElementTile: import("svelte").Component<$$ComponentProps, {}, "node" | "text_color">;
28
28
  type ElementTile = ReturnType<typeof ElementTile>;
29
29
  export default ElementTile;
@@ -8,6 +8,7 @@
8
8
  import { compute_fermi_slice } from './compute'
9
9
  import { BAND_COLORS } from './constants'
10
10
  import type { FermiSliceData, FermiSurfaceData } from './types'
11
+ import { to_error } from '../utils'
11
12
 
12
13
  let {
13
14
  fermi_data,
@@ -60,7 +61,7 @@
60
61
  slice_data = compute_fermi_slice(fermi_data, { miller_indices, distance })
61
62
  } catch (err) {
62
63
  slice_data = null
63
- on_error?.(err instanceof Error ? err : new Error(String(err)))
64
+ on_error?.(to_error(err))
64
65
  }
65
66
  })
66
67
 
@@ -114,7 +115,7 @@
114
115
  const band = slice_data?.isolines[series_idx]?.band_index
115
116
  if (band === undefined) return
116
117
  const all_bands = [
117
- ...new Set(slice_data?.isolines.map((iso) => iso.band_index) ?? []),
118
+ ...new Set(slice_data?.isolines.map((iso) => iso.band_index)),
118
119
  ]
119
120
  const is_solo = all_bands.every((bid) => bid === band || hidden_bands.has(bid))
120
121
  hidden_bands.clear()
@@ -136,12 +137,19 @@
136
137
  x_axis={{ ticks: [], range: [bounds.min[0], bounds.max[0]] }}
137
138
  y_axis={{ ticks: [], range: [bounds.min[1], bounds.max[1]] }}
138
139
  range_padding={0}
140
+ line_tween={{ duration: 0 }}
139
141
  display={{ x_grid: false, y_grid: false, x_zero_line: show_axes, y_zero_line: show_axes }}
140
142
  styles={{ show_points: false, show_lines: true }}
141
143
  controls={{ show: false }}
142
144
  fullscreen_toggle={false}
143
145
  legend={show_legend && series.length > 0
144
- ? { on_toggle: toggle_band, on_double_click: isolate_band, draggable: false }
146
+ ? {
147
+ on_toggle: toggle_band,
148
+ on_double_click: isolate_band,
149
+ draggable: false,
150
+ // pin bottom-right so it clears the top-left title/controls overlay (e.g. in the demo)
151
+ style: `left: auto; top: auto; right: 8px; bottom: 8px`,
152
+ }
145
153
  : null}
146
154
  padding={{ t: 5, b: 5, l: 5, r: 5 }}
147
155
  class="fermi-slice {rest.class ?? ``}"
@@ -177,12 +185,12 @@
177
185
  :global(.fermi-slice .zero-line) {
178
186
  display: none;
179
187
  }
180
- :global(.fermi-axis) {
188
+ .fermi-axis {
181
189
  stroke: var(--fermi-surface-axis-color, #888);
182
190
  stroke-dasharray: 4, 4;
183
191
  stroke-width: 1;
184
192
  }
185
- :global(.fermi-label) {
193
+ .fermi-label {
186
194
  fill: var(--fermi-surface-axis-color, #888);
187
195
  font: 12px system-ui, sans-serif;
188
196
  }
@@ -24,6 +24,7 @@
24
24
  import FermiSurfaceScene from './FermiSurfaceScene.svelte'
25
25
  import FermiSurfaceTooltip from './FermiSurfaceTooltip.svelte'
26
26
  import { parse_fermi_file } from './parse'
27
+ import { to_error } from '../utils'
27
28
  import type {
28
29
  BandGridData,
29
30
  ColorProperty,
@@ -202,7 +203,7 @@
202
203
  await parse_fermi_content(content, filename)
203
204
  } catch (err) {
204
205
  error_msg = `Failed to parse ${filename}: ${
205
- err instanceof Error ? err.message : err
206
+ to_error(err).message
206
207
  }`
207
208
  on_error?.({ error_msg, filename })
208
209
  }
@@ -263,7 +264,7 @@
263
264
  await export_scene(scene, format, current_filename || `fermi-surface`)
264
265
  } catch (err) {
265
266
  console.error(`Export failed:`, err)
266
- error_msg = `Export failed: ${err instanceof Error ? err.message : err}`
267
+ error_msg = `Export failed: ${to_error(err).message}`
267
268
  }
268
269
  }
269
270
 
@@ -284,7 +285,7 @@
284
285
  try {
285
286
  bz_data = compute_brillouin_zone(k_lattice, 1)
286
287
  } catch (err) {
287
- const msg = err instanceof Error ? err.message : String(err)
288
+ const msg = to_error(err).message
288
289
  console.warn(`BZ computation failed:`, msg)
289
290
  bz_data = undefined
290
291
  // Only report error for structure-derived lattice (user-provided data)
@@ -313,7 +314,7 @@
313
314
  load_from_url(data_url, safe_parse)
314
315
  .catch((err) => {
315
316
  if (current_load_id !== load_id) return // stale request
316
- error_msg = err instanceof Error ? err.message : String(err)
317
+ error_msg = to_error(err).message
317
318
  on_error?.({ error_msg, filename: data_url })
318
319
  })
319
320
  .finally(() => {
@@ -401,7 +402,12 @@
401
402
  {...spinner_props}
402
403
  />
403
404
  {:else if error_msg}
404
- <StatusMessage bind:message={error_msg} type="error" dismissible />
405
+ <StatusMessage
406
+ bind:message={error_msg}
407
+ type="error"
408
+ dismissible
409
+ style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); max-width: 90%; text-align: center"
410
+ />
405
411
  {:else if fermi_data || band_data}
406
412
  <section
407
413
  class="control-buttons {controls_config.class}"
@@ -78,6 +78,6 @@ type $$ComponentProps = {
78
78
  }]> | FermiTooltipConfig;
79
79
  on_hover?: (data: FermiHoverData | null) => void;
80
80
  } & HTMLAttributes<HTMLDivElement>;
81
- declare const FermiSurface: import("svelte").Component<$$ComponentProps, {}, "height" | "width" | "dragover" | "loading" | "fullscreen" | "hovered" | "controls_open" | "camera_projection" | "color_scale" | "wrapper" | "error_msg" | "surface_opacity" | "show_vectors" | "bz_data" | "mu" | "selected_bands" | "interpolation_factor" | "fermi_data" | "band_data" | "color_property" | "representation" | "show_bz" | "bz_opacity" | "tile_bz" | "clip_enabled" | "clip_axis" | "clip_position" | "clip_flip">;
81
+ declare const FermiSurface: import("svelte").Component<$$ComponentProps, {}, "dragover" | "height" | "width" | "fullscreen" | "hovered" | "controls_open" | "loading" | "camera_projection" | "color_scale" | "wrapper" | "error_msg" | "surface_opacity" | "show_vectors" | "bz_data" | "mu" | "selected_bands" | "interpolation_factor" | "fermi_data" | "band_data" | "color_property" | "representation" | "show_bz" | "bz_opacity" | "tile_bz" | "clip_enabled" | "clip_axis" | "clip_position" | "clip_flip">;
82
82
  type FermiSurface = ReturnType<typeof FermiSurface>;
83
83
  export default FermiSurface;
@@ -111,7 +111,7 @@
111
111
  return
112
112
  }
113
113
  const idx = selected_bands.indexOf(band_idx)
114
- if (idx >= 0) {
114
+ if (idx !== -1) {
115
115
  selected_bands = selected_bands.filter((band) => band !== band_idx)
116
116
  } else {
117
117
  selected_bands = [...selected_bands, band_idx].toSorted((a, b) => a - b)
@@ -665,6 +665,9 @@
665
665
  vector={scaled_vec}
666
666
  color={vector_colors[idx]}
667
667
  scale={1}
668
+ shaft_radius={scene_size * 0.008}
669
+ arrow_head_radius={scene_size * 0.028}
670
+ arrow_head_length={-0.1}
668
671
  />
669
672
  <extras.HTML center position={label_position}>
670
673
  <span style:color={vector_colors[idx]} style:font-size="1.2em">
@@ -1,14 +1,11 @@
1
1
  <script lang="ts">
2
2
  // Tooltip component for Fermi surface hover information
3
3
  // Displays band index, spin, k-coordinates, and optional property values
4
- import { format_num, format_vec3 } from '../labels'
5
- import { TooltipContent } from '../tooltip'
4
+ import { format_num } from '../labels'
5
+ import { KCoords, TooltipContent } from '../tooltip'
6
6
  import type { FermiHoverData, FermiTooltipProp } from './types'
7
7
 
8
- let {
9
- hover_data,
10
- tooltip,
11
- }: {
8
+ let { hover_data, tooltip }: {
12
9
  hover_data: FermiHoverData
13
10
  tooltip?: FermiTooltipProp
14
11
  } = $props()
@@ -23,18 +20,10 @@
23
20
  {/if}
24
21
  </div>
25
22
 
26
- <div class="coords-section">
27
- <div class="coord-row">
28
- <span class="coord-label">k (Å⁻¹):</span>
29
- <span class="coord-values">{format_vec3(hover_data.position_cartesian)}</span>
30
- </div>
31
- {#if hover_data.position_fractional}
32
- <div class="coord-row">
33
- <span class="coord-label">k (frac):</span>
34
- <span class="coord-values">{format_vec3(hover_data.position_fractional)}</span>
35
- </div>
36
- {/if}
37
- </div>
23
+ <KCoords
24
+ cartesian={hover_data.position_cartesian}
25
+ fractional={hover_data.position_fractional}
26
+ />
38
27
 
39
28
  {#if hover_data.property_value != null}
40
29
  <div class="property-row">
@@ -56,7 +45,7 @@
56
45
 
57
46
  <style>
58
47
  .tooltip-content {
59
- max-width: var(--tooltip-max-width, 220px);
48
+ max-width: var(--tooltip-max-width, 250px);
60
49
  }
61
50
  .tooltip-title {
62
51
  display: flex;
@@ -78,21 +67,6 @@
78
67
  background: #377eb8;
79
68
  color: white;
80
69
  }
81
- .coords-section {
82
- margin: 4px 0;
83
- }
84
- .coord-row {
85
- display: flex;
86
- gap: 4px;
87
- font-size: 0.9em;
88
- }
89
- .coord-label {
90
- opacity: 0.8;
91
- min-width: 55px;
92
- }
93
- .coord-values {
94
- font-family: monospace;
95
- }
96
70
  .property-row {
97
71
  margin-top: 4px;
98
72
  font-size: 0.9em;
@@ -15,8 +15,10 @@ function catmull_rom_coeffs(t) {
15
15
  const c4 = 0.5 * (-t2 + t3);
16
16
  return [c1, c2, c3, c4];
17
17
  }
18
- // Tricubic interpolation with cached wrap indices and precomputed coefficients
19
- function tricubic_interpolate(grid, fx, fy, fz, nx, ny, nz) {
18
+ // Tricubic interpolation with cached wrap indices and precomputed coefficients.
19
+ // px/py/pz are the wrap periods (unique points per axis): n for periodic grids,
20
+ // n−1 for endpoint-inclusive grids whose last point duplicates the first.
21
+ function tricubic_interpolate(grid, fx, fy, fz, px, py, pz) {
20
22
  // Get integer and fractional parts
21
23
  const ix = Math.floor(fx);
22
24
  const iy = Math.floor(fy);
@@ -25,13 +27,10 @@ function tricubic_interpolate(grid, fx, fy, fz, nx, ny, nz) {
25
27
  const [cx0, cx1, cx2, cx3] = catmull_rom_coeffs(fx - ix);
26
28
  const [cy0, cy1, cy2, cy3] = catmull_rom_coeffs(fy - iy);
27
29
  const [cz0, cz1, cz2, cz3] = catmull_rom_coeffs(fz - iz);
28
- // Precompute wrapped indices (avoid modulo in inner loop)
29
- const wrap_x = (v) => ((v % nx) + nx) % nx;
30
- const wrap_y = (v) => ((v % ny) + ny) % ny;
31
- const wrap_z = (v) => ((v % nz) + nz) % nz;
32
- const wx = [wrap_x(ix - 1), wrap_x(ix), wrap_x(ix + 1), wrap_x(ix + 2)];
33
- const wy = [wrap_y(iy - 1), wrap_y(iy), wrap_y(iy + 1), wrap_y(iy + 2)];
34
- const wz = [wrap_z(iz - 1), wrap_z(iz), wrap_z(iz + 1), wrap_z(iz + 2)];
30
+ // Wrapped stencil indices (modulo hoisted out of the inner loop); a zero period
31
+ // (single-point axis) has no neighbours, so collapse the stencil onto index 0
32
+ const stencil = (idx, period) => [idx - 1, idx, idx + 1, idx + 2].map((v) => period > 0 ? ((v % period) + period) % period : 0);
33
+ const [wx, wy, wz] = [stencil(ix, px), stencil(iy, py), stencil(iz, pz)];
35
34
  // Interpolate along z, then y, then x (fully inlined)
36
35
  let result = 0;
37
36
  const cx = [cx0, cx1, cx2, cx3];
@@ -51,26 +50,29 @@ function tricubic_interpolate(grid, fx, fy, fz, nx, ny, nz) {
51
50
  }
52
51
  return result;
53
52
  }
54
- // Upsample a 3D grid using tricubic interpolation for smoother surfaces
55
- function upsample_grid(grid, factor) {
53
+ // Upsample a 3D grid with tricubic interpolation, preserving the grid convention:
54
+ // endpoint-inclusive (BXSF, point i ↔ frac i/(n−1)) vs periodic (FRMSF, i ↔ i/n).
55
+ // Mixing conventions rescales the surface and distorts the zone boundary.
56
+ function upsample_grid(grid, factor, periodic = false) {
56
57
  if (factor <= 1)
57
58
  return grid;
58
- const nx = grid.length;
59
- const ny = grid[0]?.length || 0;
60
- const nz = grid[0]?.[0]?.length || 0;
61
- const new_nx = Math.round(nx * factor);
62
- const new_ny = Math.round(ny * factor);
63
- const new_nz = Math.round(nz * factor);
64
- // Precompute fractional coordinates for each axis
65
- const fx_arr = new Float64Array(new_nx);
66
- const fy_arr = new Float64Array(new_ny);
67
- const fz_arr = new Float64Array(new_nz);
68
- for (let ix = 0; ix < new_nx; ix++)
69
- fx_arr[ix] = (ix / new_nx) * nx;
70
- for (let iy = 0; iy < new_ny; iy++)
71
- fy_arr[iy] = (iy / new_ny) * ny;
72
- for (let iz = 0; iz < new_nz; iz++)
73
- fz_arr[iz] = (iz / new_nz) * nz;
59
+ // Endpoint-inclusive grids carry one duplicated boundary sample per axis; the wrap
60
+ // period (count of unique points) doubles as the resampling span numerator
61
+ const endpoint = periodic ? 0 : 1;
62
+ const dims = [grid.length, grid[0]?.length || 0, grid[0]?.[0]?.length || 0];
63
+ const [px, py, pz] = dims.map((n) => n - endpoint);
64
+ const [new_nx, new_ny, new_nz] = [px, py, pz].map((p) => Math.round(p * factor) + endpoint);
65
+ // Map new index source coordinate; a single-point axis (span 0) pins its lone
66
+ // output to source 0 to avoid 0/0 = NaN
67
+ const src_coords = (new_n, period) => {
68
+ const span = new_n - endpoint;
69
+ return Float64Array.from({ length: new_n }, (_, idx) => span > 0 ? (idx / span) * period : 0);
70
+ };
71
+ const [fx_arr, fy_arr, fz_arr] = [
72
+ [new_nx, px],
73
+ [new_ny, py],
74
+ [new_nz, pz],
75
+ ].map(([new_n, period]) => src_coords(new_n, period));
74
76
  // Preallocate output grid
75
77
  const new_grid = Array(new_nx);
76
78
  for (let ix = 0; ix < new_nx; ix++) {
@@ -80,7 +82,7 @@ function upsample_grid(grid, factor) {
80
82
  const fy = fy_arr[iy];
81
83
  const iz_arr = new Float64Array(new_nz);
82
84
  for (let iz = 0; iz < new_nz; iz++) {
83
- iz_arr[iz] = tricubic_interpolate(grid, fx, fy, fz_arr[iz], nx, ny, nz);
85
+ iz_arr[iz] = tricubic_interpolate(grid, fx, fy, fz_arr[iz], px, py, pz);
84
86
  }
85
87
  // Convert Float64Array back to regular array for compatibility
86
88
  iy_arr[iy] = Array.from(iz_arr);
@@ -109,15 +111,16 @@ export function extract_fermi_surface(band_data, options = {}) {
109
111
  // Check if Fermi level intersects this band
110
112
  if (!band_intersects_fermi(raw_energies, iso_value))
111
113
  continue;
114
+ // BXSF grids are endpoint-inclusive (store both equivalent k=0 and k=1 → false);
115
+ // FRMSF grids store k=i/n without the duplicated endpoint (→ true)
116
+ const periodic = band_data.periodic ?? false;
112
117
  // Apply interpolation for smoother surfaces
113
118
  const energies = interpolation_factor > 1
114
- ? upsample_grid(raw_energies, interpolation_factor)
119
+ ? upsample_grid(raw_energies, interpolation_factor, periodic)
115
120
  : raw_energies;
116
121
  // Extract isosurface using marching cubes
117
- // Use periodic: false because BXSF grids include both endpoints (k=0 and k=1)
118
- // which are equivalent due to BZ periodicity. This matches scikit-image behavior.
119
122
  const mc_result = marching_cubes(energies, iso_value, band_data.k_lattice, {
120
- periodic: false,
123
+ periodic,
121
124
  interpolate: true,
122
125
  });
123
126
  if (mc_result.vertices.length === 0)
@@ -137,13 +140,13 @@ export function extract_fermi_surface(band_data, options = {}) {
137
140
  total_area += isosurface.area;
138
141
  // Compute Fermi velocities if requested
139
142
  if (compute_velocities && band_data.velocities) {
140
- isosurface.properties = compute_fermi_velocities(isosurface, band_data.velocities[spin_idx][band_idx], band_data.k_lattice, band_data.k_grid);
143
+ isosurface.properties = compute_fermi_velocities(isosurface, band_data.velocities[spin_idx][band_idx], band_data.k_lattice, band_data.k_grid, periodic);
141
144
  isosurface.avg_velocity =
142
145
  isosurface.properties.reduce((s, v) => s + v, 0) / isosurface.properties.length;
143
146
  }
144
147
  // Compute dimensionality if requested
145
148
  if (compute_dimensionality) {
146
- const { dimensionality, orientation } = analyze_surface_topology(isosurface, null);
149
+ const { dimensionality, orientation } = analyze_surface_topology(isosurface, band_data.k_lattice);
147
150
  isosurface.dimensionality = dimensionality;
148
151
  isosurface.orientation = orientation;
149
152
  }
@@ -205,24 +208,22 @@ export function compute_surface_area(surface) {
205
208
  return total_area;
206
209
  }
207
210
  // Compute Fermi velocities at surface vertices
208
- function compute_fermi_velocities(surface, velocity_grid, k_lattice, k_grid) {
211
+ function compute_fermi_velocities(surface, velocity_grid, k_lattice, k_grid, periodic = false) {
209
212
  const [nx, ny, nz] = k_grid;
210
213
  const velocities = [];
211
- // Inverse of k_lattice for Cartesian to fractional conversion
212
- const k_inv = math.matrix_inverse_3x3(k_lattice);
214
+ // Invert the marching-cubes transform cart = k_latticeᵀ·(frac 0.5): frac =
215
+ // (k_latticeᵀ)⁻¹·cart + 0.5. Omitting the transpose samples wrong k-points for
216
+ // non-symmetric lattices; skipping the +0.5 is off by half a reciprocal cell.
217
+ const k_inv = math.matrix_inverse_3x3(math.transpose_3x3_matrix(k_lattice));
218
+ // Grid point i sits at frac i/(n−1) (endpoint-inclusive BXSF) or i/n (periodic)
219
+ const [sx, sy, sz] = periodic ? [nx, ny, nz] : [nx - 1, ny - 1, nz - 1];
220
+ // Clamp guards float jitter at the cell boundary
221
+ const clamp01 = (val) => Math.min(Math.max(val, 0), 1);
213
222
  for (const vertex of surface.vertices) {
214
- // Convert Cartesian to fractional coordinates
215
- const frac = math.mat3x3_vec3_multiply(k_inv, vertex);
216
- // Wrap to [0, 1)
217
- const wrapped = [
218
- ((frac[0] % 1) + 1) % 1,
219
- ((frac[1] % 1) + 1) % 1,
220
- ((frac[2] % 1) + 1) % 1,
221
- ];
222
- // Grid indices (with interpolation)
223
- const gx = wrapped[0] * nx;
224
- const gy = wrapped[1] * ny;
225
- const gz = wrapped[2] * nz;
223
+ const frac = math.mat3x3_vec3_multiply(k_inv, vertex); // centered, in [-0.5, 0.5]
224
+ const gx = clamp01(frac[0] + 0.5) * sx;
225
+ const gy = clamp01(frac[1] + 0.5) * sy;
226
+ const gz = clamp01(frac[2] + 0.5) * sz;
226
227
  // Trilinear interpolation of velocity
227
228
  const velocity = trilinear_interpolate_vec3(velocity_grid, gx, gy, gz);
228
229
  velocities.push(Math.hypot(...velocity)); // magnitude
@@ -265,14 +266,15 @@ function trilinear_interpolate_vec3(grid, x, y, z) {
265
266
  return math.lerp_vec3(c0, c1, zd);
266
267
  }
267
268
  // Analyze surface topology to determine dimensionality
268
- function analyze_surface_topology(surface, bz_data) {
269
+ function analyze_surface_topology(surface, k_lattice) {
269
270
  if (surface.vertices.length === 0) {
270
271
  return { dimensionality: `3D`, orientation: null };
271
272
  }
272
- // Check if surface spans the full BZ in each direction
273
- const bz_extent = bz_data
274
- ? math.compute_bounding_box(bz_data.vertices)
275
- : { min: [-1, -1, -1], max: [1, 1, 1] };
273
+ // Vertices live in the centered parallelepiped k_latticeᵀ·[-0.5, 0.5]³, whose bounding
274
+ // box along Cartesian axis j has half-extent 0.5·Σᵢ|k_lattice[i][j]| (a hardcoded box
275
+ // would make dimensionality depend on the absolute lattice scale)
276
+ const half_extent = [0, 1, 2].map((axis_idx) => 0.5 * k_lattice.reduce((sum, row) => sum + Math.abs(row[axis_idx]), 0));
277
+ const bz_extent = { min: half_extent.map((ext) => -ext), max: half_extent };
276
278
  const surface_extent = math.compute_bounding_box(surface.vertices);
277
279
  // Check spanning in each direction
278
280
  const spans = [false, false, false];
@@ -301,10 +303,8 @@ function analyze_surface_topology(surface, bz_data) {
301
303
  orientation[axis_idx] = 1;
302
304
  return { dimensionality: `1D`, orientation };
303
305
  }
304
- else {
305
- // Spans all 3 directions - complex warped network
306
- return { dimensionality: `quasi-2D`, orientation: null };
307
- }
306
+ // Spans all 3 directions - complex warped network
307
+ return { dimensionality: `quasi-2D`, orientation: null };
308
308
  }
309
309
  // Compute 2D Fermi slice along a specified plane
310
310
  export function compute_fermi_slice(fermi_data, options = {}) {
@@ -319,7 +319,7 @@ export function compute_fermi_slice(fermi_data, options = {}) {
319
319
  if (normal_len < EPS) {
320
320
  throw new Error(`Degenerate plane normal: k_lattice vectors produce a zero-length normal for miller indices [${miller_indices.join(`, `)}]`);
321
321
  }
322
- const unit_normal = math.normalize_vec3(plane_normal);
322
+ const unit_normal = math.normalize_vec(plane_normal);
323
323
  // Compute in-plane basis vectors
324
324
  const [in_plane_u, in_plane_v] = math.compute_in_plane_basis(unit_normal);
325
325
  // Slice each isosurface
@@ -1,3 +1,4 @@
1
+ import { to_error } from '../utils';
1
2
  // Helper to trigger file download
2
3
  function download_file(content, filename, mime_type) {
3
4
  const blob = new Blob([content], { type: mime_type });
@@ -5,7 +6,7 @@ function download_file(content, filename, mime_type) {
5
6
  const link = document.createElement(`a`);
6
7
  link.href = url;
7
8
  link.download = filename;
8
- document.body.appendChild(link);
9
+ document.body.append(link);
9
10
  link.click();
10
11
  document.body.removeChild(link);
11
12
  URL.revokeObjectURL(url);
@@ -35,7 +36,7 @@ export async function export_to_gltf(scene, filename) {
35
36
  const output = JSON.stringify(gltf, null, 2);
36
37
  download_file(output, `${filename}.gltf`, `application/json`);
37
38
  resolve();
38
- }, (error) => reject(error), { binary: false });
39
+ }, (error) => reject(to_error(error)), { binary: false });
39
40
  });
40
41
  }
41
42
  // Main export function that dispatches to the appropriate format
@@ -2,7 +2,7 @@ import * as constants from './constants';
2
2
  import { compute_vertex_normals } from './marching-cubes';
3
3
  const parse_number_tokens = (line) => line.split(/\s+/).filter(Boolean);
4
4
  // Parse whitespace-separated floats from a line (optimized with unary +)
5
- const parse_floats = (line) => parse_number_tokens(line).map((part) => +part);
5
+ const parse_floats = (line) => parse_number_tokens(line).map(Number);
6
6
  // Parse whitespace-separated integers from a line
7
7
  const parse_ints = (line) => parse_number_tokens(line).map((part) => parseInt(part, 10));
8
8
  // Parse BXSF (Band-XSF) format used by XCrySDen, Quantum ESPRESSO, etc.
@@ -219,6 +219,7 @@ function parse_frmsf(content) {
219
219
  fermi_energy: 0, // FRMSF typically expects Fermi level at 0
220
220
  n_bands,
221
221
  n_spins,
222
+ periodic: true, // FRMSF stores k=i/n with no duplicated endpoint (unlike BXSF)
222
223
  };
223
224
  }
224
225
  // Validate that an object has the required Isosurface shape
@@ -306,8 +307,10 @@ function parse_fermi_json(content) {
306
307
  k_grid: bs.k_grid ?? bs.kgrid,
307
308
  k_lattice: bs.k_lattice ?? bs.reciprocal_lattice,
308
309
  fermi_energy: bs.fermi_energy ?? bs.efermi ?? 0,
309
- n_bands: bs.n_bands || bs.nbands || bs.energies[0]?.length || 0,
310
- n_spins: bs.n_spins || bs.nspins || bs.energies.length || 1,
310
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- numeric fallback chain (0 falls through)
311
+ n_bands: (bs.n_bands ?? bs.nbands) || bs.energies[0]?.length || 0,
312
+ // oxlint-disable-next-line @typescript-eslint/prefer-nullish-coalescing -- numeric fallback chain (0 falls through)
313
+ n_spins: (bs.n_spins ?? bs.nspins) || bs.energies.length || 1,
311
314
  };
312
315
  }
313
316
  // Check for pymatgen BandStructure format (k-path, not k-grid)
@@ -426,7 +429,7 @@ function parse_ifermi_surface(data) {
426
429
  }
427
430
  // Auto-detect file format and parse accordingly
428
431
  export function parse_fermi_file(content, filename) {
429
- const lower_name = filename?.toLowerCase() || ``;
432
+ const lower_name = filename?.toLowerCase() ?? ``;
430
433
  // Detect by filename extension
431
434
  if (lower_name.endsWith(`.bxsf`) || lower_name.endsWith(`.bxsf.gz`)) {
432
435
  try {
@@ -48,6 +48,7 @@ export interface BandGridData {
48
48
  n_bands: number;
49
49
  n_spins: number;
50
50
  origin?: Vec3;
51
+ periodic?: boolean;
51
52
  }
52
53
  export interface FermiSliceData {
53
54
  isolines: Isoline[];
@@ -3,7 +3,7 @@
3
3
  import { is_color, pick_contrast_color } from '../colors'
4
4
  import { format_num } from '../labels'
5
5
  import type { AxisConfig } from '../plot'
6
- import ColorBar from '../plot/ColorBar.svelte'
6
+ import ColorBar from '../plot/core/components/ColorBar.svelte'
7
7
  import { make_change_detector } from '../utils'
8
8
  import * as d3_sc from 'd3-scale-chromatic'
9
9
  import { type ComponentProps, onDestroy, onMount, type Snippet } from 'svelte'
@@ -334,7 +334,7 @@
334
334
  }
335
335
 
336
336
  function get_quantile(sorted_values: number[], quantile: number): number {
337
- if (!sorted_values.length) return 0
337
+ if (sorted_values.length === 0) return 0
338
338
  const clipped_quantile = Math.max(0, Math.min(1, quantile))
339
339
  const float_idx = (sorted_values.length - 1) * clipped_quantile
340
340
  const low_idx = Math.floor(float_idx)
@@ -358,18 +358,22 @@
358
358
  return numeric_values
359
359
  })
360
360
 
361
- // Single-pass min/max to avoid spreading large arrays into Math.min/max
362
- let [auto_min, auto_max] = $derived.by(() => {
363
- let [min, max] = [Infinity, -Infinity]
361
+ // Single-pass min/max to avoid spreading large arrays into Math.min/max. min_pos is
362
+ // the log-mode lower bound when the domain min is <= 0 (the old Number.MIN_VALUE
363
+ // floor gave log_min ~ -744, squashing all colors to the top)
364
+ let [auto_min, auto_max, min_pos] = $derived.by(() => {
365
+ let [min, max, pos] = [Infinity, -Infinity, Infinity]
364
366
  for (const value of valid_numeric_values) {
365
367
  if (value < min) min = value
366
368
  if (value > max) max = value
369
+ if (value > 0 && value < pos) pos = value
367
370
  }
368
- return min <= max ? [min, max] as const : [0, 1] as const
371
+ const min_pos_val = Number.isFinite(pos) ? pos : null
372
+ return min <= max ? [min, max, min_pos_val] as const : [0, 1, min_pos_val] as const
369
373
  })
370
374
 
371
375
  let [robust_min, robust_max] = $derived.by(() => {
372
- if (!valid_numeric_values.length) return [0, 1] as const
376
+ if (valid_numeric_values.length === 0) return [0, 1] as const
373
377
  const sorted_values = valid_numeric_values.toSorted((value_a, value_b) =>
374
378
  value_a - value_b
375
379
  )
@@ -418,7 +422,7 @@
418
422
  const lower_bound = Math.min(cs_min, cs_max)
419
423
  const upper_bound = Math.max(cs_min, cs_max)
420
424
  if (upper_bound <= 0) return missing_color || null
421
- const safe_lower_bound = Math.max(lower_bound, Number.MIN_VALUE)
425
+ const safe_lower_bound = lower_bound > 0 ? lower_bound : (min_pos ?? upper_bound)
422
426
  const safe_value = Math.max(val, safe_lower_bound)
423
427
  const log_min = Math.log(safe_lower_bound)
424
428
  const log_max = Math.log(upper_bound)
@@ -460,7 +464,7 @@
460
464
  return colors
461
465
  })
462
466
 
463
- const to_contrast_colors = (bg_values: Array<string | null>): Array<string | null> =>
467
+ const to_contrast_colors = (bg_values: (string | null)[]): (string | null)[] =>
464
468
  bg_values.map((bg_color) =>
465
469
  bg_color ? pick_contrast_color({ bg_color }) : null
466
470
  )
@@ -481,16 +485,14 @@
481
485
  bg_flat[get_flat_idx(x_idx, y_idx)]
482
486
 
483
487
  // === Cell context builder (only called for clicks, not per-hover) ===
484
- function build_cell_context(x_idx: number, y_idx: number): CellContext {
485
- return {
486
- x_item: x_items[x_idx],
487
- y_item: y_items[y_idx],
488
- x_idx,
489
- y_idx,
490
- value: get_value(x_idx, y_idx),
491
- bg_color: get_bg(x_idx, y_idx),
492
- }
493
- }
488
+ const build_cell_context = (x_idx: number, y_idx: number): CellContext => ({
489
+ x_item: x_items[x_idx],
490
+ y_item: y_items[y_idx],
491
+ x_idx,
492
+ y_idx,
493
+ value: get_value(x_idx, y_idx),
494
+ bg_color: get_bg(x_idx, y_idx),
495
+ })
494
496
 
495
497
  // === Fully imperative hover management ===
496
498
  // ZERO $state writes during mouseover — all DOM updates are direct.
@@ -777,7 +779,7 @@
777
779
  cell_pos_key(pos.x_idx, pos.y_idx) === clicked_key
778
780
  )
779
781
  const toggle_mode = selection_mode === `multi` && (event.metaKey || event.ctrlKey)
780
- if (existing_idx >= 0 && toggle_mode) next_cells.splice(existing_idx, 1)
782
+ if (existing_idx !== -1 && toggle_mode) next_cells.splice(existing_idx, 1)
781
783
  else if (selection_mode === `multi` && toggle_mode) next_cells.push(clicked_cell)
782
784
  else next_cells.splice(0, next_cells.length, clicked_cell)
783
785
  selected_cells = next_cells
@@ -1012,7 +1014,7 @@
1012
1014
  }
1013
1015
 
1014
1016
  function compute_summary(summary_values: number[]): number | null {
1015
- if (!summary_values.length) return null
1017
+ if (summary_values.length === 0) return null
1016
1018
  if (summary_fn) return summary_fn(summary_values)
1017
1019
  const total = summary_values.reduce((sum, value) => sum + value, 0)
1018
1020
  return total / summary_values.length
@@ -40,7 +40,7 @@ function escape_csv_field(value) {
40
40
  return `"${field.replaceAll(`"`, `""`)}"`;
41
41
  }
42
42
  export function rows_to_csv(rows) {
43
- if (!rows.length)
43
+ if (rows.length === 0)
44
44
  return ``;
45
45
  const headers = Object.keys(rows[0]);
46
46
  const lines = [