matterviz 0.4.1 → 0.4.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (499) hide show
  1. package/dist/EmptyState.svelte +10 -4
  2. package/dist/FilePicker.svelte +48 -60
  3. package/dist/Icon.svelte +7 -4
  4. package/dist/MillerIndexInput.svelte +2 -2
  5. package/dist/api/optimade.js +10 -7
  6. package/dist/app.css +68 -0
  7. package/dist/brillouin/BrillouinZone.svelte +90 -91
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +5 -7
  9. package/dist/brillouin/BrillouinZoneControls.svelte +3 -6
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +18 -14
  11. package/dist/brillouin/BrillouinZoneInfoPane.svelte +6 -10
  12. package/dist/brillouin/BrillouinZoneScene.svelte +46 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  14. package/dist/brillouin/compute.js +10 -16
  15. package/dist/brillouin/geometry.js +2 -2
  16. package/dist/chempot-diagram/ChemPotDiagram.svelte +48 -50
  17. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +61 -169
  18. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +1 -1
  19. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +559 -755
  20. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +1 -1
  21. package/dist/chempot-diagram/async-compute.svelte.js +13 -14
  22. package/dist/chempot-diagram/color.d.ts +21 -1
  23. package/dist/chempot-diagram/color.js +70 -1
  24. package/dist/chempot-diagram/compute.d.ts +7 -0
  25. package/dist/chempot-diagram/compute.js +85 -26
  26. package/dist/chempot-diagram/controls-state.svelte.js +1 -1
  27. package/dist/chempot-diagram/export.js +1 -6
  28. package/dist/chempot-diagram/temperature.js +9 -10
  29. package/dist/colors/index.d.ts +0 -4
  30. package/dist/colors/index.js +19 -20
  31. package/dist/composition/BarChart.svelte +30 -26
  32. package/dist/composition/BubbleChart.svelte +17 -17
  33. package/dist/composition/Composition.svelte +10 -19
  34. package/dist/composition/Formula.svelte +20 -27
  35. package/dist/composition/FormulaFilter.svelte +115 -184
  36. package/dist/composition/PieChart.svelte +55 -41
  37. package/dist/composition/format.js +7 -9
  38. package/dist/composition/index.d.ts +2 -0
  39. package/dist/composition/index.js +14 -0
  40. package/dist/composition/parse.d.ts +2 -2
  41. package/dist/composition/parse.js +61 -115
  42. package/dist/constants.d.ts +0 -1
  43. package/dist/constants.js +17 -26
  44. package/dist/convex-hull/ConvexHull.svelte +12 -15
  45. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -1
  46. package/dist/convex-hull/ConvexHull2D.svelte +93 -94
  47. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  48. package/dist/convex-hull/ConvexHull3D.svelte +127 -186
  49. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  50. package/dist/convex-hull/ConvexHull4D.svelte +131 -180
  51. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  52. package/dist/convex-hull/ConvexHullChrome.svelte +36 -40
  53. package/dist/convex-hull/ConvexHullControls.svelte +46 -48
  54. package/dist/convex-hull/ConvexHullStats.svelte +193 -195
  55. package/dist/convex-hull/ConvexHullTooltip.svelte +5 -12
  56. package/dist/convex-hull/GasPressureControls.svelte +5 -12
  57. package/dist/convex-hull/StructurePopup.svelte +18 -22
  58. package/dist/convex-hull/StructurePopup.svelte.d.ts +2 -0
  59. package/dist/convex-hull/TemperatureSlider.svelte +4 -10
  60. package/dist/convex-hull/canvas-interactions.svelte.js +2 -1
  61. package/dist/convex-hull/gas-thermodynamics.js +21 -53
  62. package/dist/convex-hull/helpers.d.ts +8 -10
  63. package/dist/convex-hull/helpers.js +37 -43
  64. package/dist/convex-hull/hull-state.svelte.d.ts +1 -1
  65. package/dist/convex-hull/thermodynamics.js +37 -44
  66. package/dist/coordination/CoordinationBarPlot.svelte +49 -53
  67. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  68. package/dist/coordination/calc-coordination.d.ts +1 -1
  69. package/dist/coordination/calc-coordination.js +28 -25
  70. package/dist/element/BohrAtom.svelte +5 -9
  71. package/dist/element/ElementHeading.svelte +4 -1
  72. package/dist/element/ElementPhoto.svelte +11 -9
  73. package/dist/element/ElementStats.svelte +12 -10
  74. package/dist/element/ElementTile.svelte +44 -67
  75. package/dist/element/Nucleus.svelte +4 -2
  76. package/dist/element/data.d.ts +3 -2
  77. package/dist/element/data.js +5 -1
  78. package/dist/element/helpers.d.ts +4 -0
  79. package/dist/element/helpers.js +18 -0
  80. package/dist/element/index.d.ts +2 -5
  81. package/dist/element/index.js +4 -19
  82. package/dist/feedback/DragOverlay.svelte +5 -5
  83. package/dist/feedback/DragOverlay.svelte.d.ts +2 -2
  84. package/dist/feedback/StatusMessage.svelte +7 -4
  85. package/dist/fermi-surface/FermiSlice.svelte +21 -18
  86. package/dist/fermi-surface/FermiSurface.svelte +35 -44
  87. package/dist/fermi-surface/FermiSurface.svelte.d.ts +7 -13
  88. package/dist/fermi-surface/FermiSurfaceControls.svelte +6 -20
  89. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  90. package/dist/fermi-surface/FermiSurfaceScene.svelte +64 -136
  91. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  92. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +9 -6
  93. package/dist/fermi-surface/compute.js +25 -58
  94. package/dist/fermi-surface/parse.js +54 -88
  95. package/dist/file-viewer/JsonBrowser.svelte +1043 -0
  96. package/dist/file-viewer/JsonBrowser.svelte.d.ts +9 -0
  97. package/dist/file-viewer/PlotPanel.svelte +350 -0
  98. package/dist/file-viewer/PlotPanel.svelte.d.ts +9 -0
  99. package/dist/file-viewer/TrajectoryWithDos.svelte +30 -0
  100. package/dist/file-viewer/TrajectoryWithDos.svelte.d.ts +10 -0
  101. package/dist/file-viewer/detect.d.ts +11 -0
  102. package/dist/file-viewer/detect.js +381 -0
  103. package/dist/file-viewer/eligibility.d.ts +4 -0
  104. package/dist/file-viewer/eligibility.js +53 -0
  105. package/dist/file-viewer/host-protocol.d.ts +50 -0
  106. package/dist/file-viewer/host-transfer.d.ts +25 -0
  107. package/dist/file-viewer/host-transfer.js +42 -0
  108. package/dist/file-viewer/index.d.ts +5 -0
  109. package/dist/file-viewer/index.js +5 -0
  110. package/dist/file-viewer/main.d.ts +44 -0
  111. package/dist/file-viewer/main.js +535 -0
  112. package/dist/file-viewer/parse.d.ts +9 -0
  113. package/dist/file-viewer/parse.js +170 -0
  114. package/dist/file-viewer/plot-utils.d.ts +24 -0
  115. package/dist/file-viewer/plot-utils.js +191 -0
  116. package/dist/file-viewer/types.d.ts +4 -0
  117. package/dist/file-viewer/types.js +5 -0
  118. package/dist/heatmap-matrix/HeatmapMatrix.svelte +153 -219
  119. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +2 -2
  120. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +9 -7
  121. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +1 -1
  122. package/dist/heatmap-matrix/index.d.ts +5 -0
  123. package/dist/icons.d.ts +4 -0
  124. package/dist/icons.js +4 -0
  125. package/dist/index.d.ts +2 -2
  126. package/dist/index.js +1 -1
  127. package/dist/io/ExportPane.svelte +11 -7
  128. package/dist/io/decompress.d.ts +4 -1
  129. package/dist/io/decompress.js +24 -36
  130. package/dist/io/export.d.ts +11 -4
  131. package/dist/io/export.js +75 -19
  132. package/dist/io/fetch.d.ts +0 -3
  133. package/dist/io/fetch.js +0 -11
  134. package/dist/io/file-drop.js +60 -35
  135. package/dist/io/index.d.ts +0 -1
  136. package/dist/io/index.js +2 -9
  137. package/dist/io/is-binary.d.ts +9 -0
  138. package/dist/io/is-binary.js +45 -1
  139. package/dist/io/url-drop.d.ts +2 -0
  140. package/dist/io/url-drop.js +40 -40
  141. package/dist/isosurface/Isosurface.svelte +700 -215
  142. package/dist/isosurface/Isosurface.svelte.d.ts +7 -1
  143. package/dist/isosurface/IsosurfaceControls.svelte +590 -116
  144. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +1 -1
  145. package/dist/isosurface/VolumeSlice.svelte +224 -0
  146. package/dist/isosurface/VolumeSlice.svelte.d.ts +28 -0
  147. package/dist/isosurface/coloring.d.ts +20 -0
  148. package/dist/isosurface/coloring.js +118 -0
  149. package/dist/isosurface/geometry-worker-types.d.ts +38 -0
  150. package/dist/isosurface/geometry.worker.d.ts +1 -0
  151. package/dist/isosurface/geometry.worker.js +59 -0
  152. package/dist/isosurface/grid.d.ts +10 -0
  153. package/dist/isosurface/grid.js +31 -0
  154. package/dist/isosurface/index.d.ts +4 -0
  155. package/dist/isosurface/index.js +4 -0
  156. package/dist/isosurface/parse-vaspwave.d.ts +3 -0
  157. package/dist/isosurface/parse-vaspwave.js +138 -0
  158. package/dist/isosurface/parse.js +6 -6
  159. package/dist/isosurface/profile.d.ts +12 -0
  160. package/dist/isosurface/profile.js +19 -0
  161. package/dist/isosurface/sampling.d.ts +34 -0
  162. package/dist/isosurface/sampling.js +408 -0
  163. package/dist/isosurface/slice-rendering.d.ts +13 -0
  164. package/dist/isosurface/slice-rendering.js +79 -0
  165. package/dist/isosurface/slice.d.ts +22 -2
  166. package/dist/isosurface/slice.js +200 -116
  167. package/dist/isosurface/types.d.ts +24 -1
  168. package/dist/isosurface/types.js +120 -8
  169. package/dist/json-path.d.ts +4 -0
  170. package/dist/json-path.js +89 -0
  171. package/dist/labels.d.ts +6 -2
  172. package/dist/labels.js +44 -14
  173. package/dist/layout/FullscreenButton.svelte +2 -1
  174. package/dist/layout/FullscreenToggle.svelte +10 -4
  175. package/dist/layout/InfoCard.svelte +8 -21
  176. package/dist/layout/InfoTag.svelte +1 -3
  177. package/dist/layout/NumberRangeInput.svelte +46 -0
  178. package/dist/layout/NumberRangeInput.svelte.d.ts +12 -0
  179. package/dist/layout/PropertyFilter.svelte +2 -6
  180. package/dist/layout/SettingsSection.svelte +57 -62
  181. package/dist/layout/SettingsSection.svelte.d.ts +6 -7
  182. package/dist/layout/SubpageGrid.svelte +3 -1
  183. package/dist/layout/ViewerChrome.svelte +16 -11
  184. package/dist/layout/ViewerChrome.svelte.d.ts +2 -1
  185. package/dist/layout/fullscreen.js +3 -5
  186. package/dist/layout/fullscreen.svelte.js +1 -2
  187. package/dist/layout/index.d.ts +1 -0
  188. package/dist/layout/index.js +1 -0
  189. package/dist/layout/json-tree/JsonNode.svelte +22 -59
  190. package/dist/layout/json-tree/JsonTree.svelte +101 -172
  191. package/dist/layout/json-tree/JsonValue.svelte +9 -32
  192. package/dist/layout/json-tree/utils.d.ts +0 -3
  193. package/dist/layout/json-tree/utils.js +50 -188
  194. package/dist/marching-cubes.d.ts +8 -1
  195. package/dist/marching-cubes.js +115 -48
  196. package/dist/math.d.ts +5 -2
  197. package/dist/math.js +48 -38
  198. package/dist/overlays/ContextMenu.svelte +19 -34
  199. package/dist/overlays/CopyButton.svelte +11 -5
  200. package/dist/overlays/DragControlTab.svelte +6 -1
  201. package/dist/overlays/DraggablePane.svelte +110 -74
  202. package/dist/overlays/DraggablePane.svelte.d.ts +2 -1
  203. package/dist/overlays/GlassChip.svelte +32 -0
  204. package/dist/overlays/GlassChip.svelte.d.ts +8 -0
  205. package/dist/overlays/InfoPaneCards.svelte +11 -23
  206. package/dist/overlays/index.d.ts +7 -0
  207. package/dist/overlays/index.js +26 -0
  208. package/dist/overlays/portal.d.ts +2 -0
  209. package/dist/overlays/portal.js +14 -0
  210. package/dist/periodic-table/PeriodicTable.svelte +113 -145
  211. package/dist/periodic-table/PeriodicTable.svelte.d.ts +5 -3
  212. package/dist/periodic-table/PeriodicTableControls.svelte +37 -115
  213. package/dist/periodic-table/TableInset.svelte +9 -4
  214. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +68 -105
  215. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -8
  216. package/dist/phase-diagram/PhaseDiagramControls.svelte +70 -94
  217. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +1 -1
  218. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +2 -1
  219. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +12 -12
  220. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +54 -58
  221. package/dist/phase-diagram/TdbInfoPanel.svelte +21 -15
  222. package/dist/phase-diagram/build-diagram.js +4 -9
  223. package/dist/phase-diagram/diagram-input.d.ts +1 -2
  224. package/dist/phase-diagram/parse.js +15 -15
  225. package/dist/phase-diagram/svg-to-diagram.js +28 -27
  226. package/dist/phase-diagram/utils.js +2 -3
  227. package/dist/plot/bar/BarPlot.svelte +461 -426
  228. package/dist/plot/bar/BarPlot.svelte.d.ts +2 -0
  229. package/dist/plot/bar/BarPlotControls.svelte +1 -3
  230. package/dist/plot/bar/BarPlotControls.svelte.d.ts +4 -6
  231. package/dist/plot/bar/SpacegroupBarPlot.svelte +46 -77
  232. package/dist/plot/bar/data.d.ts +5 -4
  233. package/dist/plot/bar/data.js +2 -1
  234. package/dist/plot/box/BoxPlot.svelte +322 -226
  235. package/dist/plot/box/BoxPlot.svelte.d.ts +2 -0
  236. package/dist/plot/box/Violin.svelte.d.ts +1 -0
  237. package/dist/plot/box/box-plot.js +1 -1
  238. package/dist/plot/core/auto-place.d.ts +1 -1
  239. package/dist/plot/core/auto-place.js +2 -2
  240. package/dist/plot/core/axis-utils.d.ts +12 -7
  241. package/dist/plot/core/axis-utils.js +48 -48
  242. package/dist/plot/core/components/AxisLabel.svelte +82 -20
  243. package/dist/plot/core/components/AxisLabel.svelte.d.ts +1 -0
  244. package/dist/plot/core/components/ColorBar.svelte +101 -106
  245. package/dist/plot/core/components/ColorScaleSelect.svelte +1 -1
  246. package/dist/plot/core/components/FillArea.svelte +10 -17
  247. package/dist/plot/core/components/HierarchyControls.svelte +249 -0
  248. package/dist/plot/{sunburst/SunburstControls.svelte.d.ts → core/components/HierarchyControls.svelte.d.ts} +12 -8
  249. package/dist/plot/core/components/InteractiveAxisLabel.svelte +1 -1
  250. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +1 -1
  251. package/dist/plot/core/components/Line.svelte +18 -9
  252. package/dist/plot/core/components/Line.svelte.d.ts +2 -0
  253. package/dist/plot/core/components/PlotAxis.svelte +40 -17
  254. package/dist/plot/core/components/PlotControls.svelte +65 -41
  255. package/dist/plot/core/components/PlotLegend.svelte +31 -35
  256. package/dist/plot/core/components/PlotMarginals.svelte +616 -0
  257. package/dist/plot/core/components/PlotMarginals.svelte.d.ts +15 -0
  258. package/dist/plot/core/components/PlotTooltip.svelte +1 -1
  259. package/dist/plot/core/components/PortalSelect.svelte +4 -8
  260. package/dist/plot/core/components/ReferenceLine.svelte +27 -24
  261. package/dist/plot/core/components/ReferenceLine3D.svelte +54 -57
  262. package/dist/plot/core/components/ReferencePlane.svelte +7 -8
  263. package/dist/plot/core/components/ZeroLines.svelte +4 -8
  264. package/dist/plot/core/components/ZoomRect.svelte +1 -2
  265. package/dist/plot/core/components/index.d.ts +1 -0
  266. package/dist/plot/core/components/index.js +1 -0
  267. package/dist/plot/core/data-cleaning-signal.d.ts +46 -0
  268. package/dist/plot/core/data-cleaning-signal.js +467 -0
  269. package/dist/plot/core/data-cleaning.d.ts +2 -42
  270. package/dist/plot/core/data-cleaning.js +27 -474
  271. package/dist/plot/core/data-transform.d.ts +1 -2
  272. package/dist/plot/core/data-transform.js +9 -15
  273. package/dist/plot/core/fill-utils.d.ts +3 -1
  274. package/dist/plot/core/fill-utils.js +28 -6
  275. package/dist/plot/core/index.d.ts +1 -0
  276. package/dist/plot/core/index.js +1 -0
  277. package/dist/plot/core/interactions.js +0 -2
  278. package/dist/plot/core/layout.d.ts +15 -6
  279. package/dist/plot/core/layout.js +57 -38
  280. package/dist/plot/core/marginals.d.ts +170 -0
  281. package/dist/plot/core/marginals.js +436 -0
  282. package/dist/plot/core/pan-zoom.svelte.d.ts +2 -4
  283. package/dist/plot/core/pan-zoom.svelte.js +34 -17
  284. package/dist/plot/core/placed-tween.svelte.d.ts +3 -0
  285. package/dist/plot/core/placed-tween.svelte.js +68 -21
  286. package/dist/plot/core/reference-line.js +1 -1
  287. package/dist/plot/core/scales.d.ts +23 -0
  288. package/dist/plot/core/scales.js +39 -13
  289. package/dist/plot/core/svg.js +0 -1
  290. package/dist/plot/core/types/fills.d.ts +101 -0
  291. package/dist/plot/core/types/fills.js +15 -0
  292. package/dist/plot/core/types/plot-3d.d.ts +87 -0
  293. package/dist/plot/core/types/plot-3d.js +4 -0
  294. package/dist/plot/core/types/reference-lines.d.ts +140 -0
  295. package/dist/plot/core/types/reference-lines.js +9 -0
  296. package/dist/plot/core/types.d.ts +29 -324
  297. package/dist/plot/core/types.js +23 -20
  298. package/dist/plot/core/utils/hierarchy-chart.d.ts +52 -0
  299. package/dist/plot/core/utils/hierarchy-chart.js +191 -0
  300. package/dist/plot/core/utils/hierarchy-labels.d.ts +20 -0
  301. package/dist/plot/core/utils/hierarchy-labels.js +100 -0
  302. package/dist/plot/core/utils/label-placement.js +2 -2
  303. package/dist/plot/histogram/Histogram.svelte +314 -340
  304. package/dist/plot/histogram/Histogram.svelte.d.ts +7 -7
  305. package/dist/plot/histogram/HistogramControls.svelte +30 -28
  306. package/dist/plot/histogram/histogram.d.ts +31 -0
  307. package/dist/plot/histogram/histogram.js +70 -0
  308. package/dist/plot/histogram/index.d.ts +1 -0
  309. package/dist/plot/histogram/index.js +1 -0
  310. package/dist/plot/index.d.ts +1 -0
  311. package/dist/plot/index.js +1 -0
  312. package/dist/plot/sankey/Sankey.svelte +78 -69
  313. package/dist/plot/sankey/Sankey.svelte.d.ts +2 -2
  314. package/dist/plot/sankey/SankeyControls.svelte +22 -16
  315. package/dist/plot/sankey/sankey.js +13 -9
  316. package/dist/plot/scatter/BinnedScatterPlot.svelte +311 -141
  317. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +7 -0
  318. package/dist/plot/scatter/ElementScatter.svelte +4 -1
  319. package/dist/plot/scatter/ScatterPlot.svelte +517 -410
  320. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +2 -0
  321. package/dist/plot/scatter/ScatterPlotControls.svelte +18 -19
  322. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +1 -1
  323. package/dist/plot/scatter/ScatterPoint.svelte +16 -9
  324. package/dist/plot/scatter/adaptive-density.d.ts +1 -1
  325. package/dist/plot/scatter/adaptive-density.js +36 -20
  326. package/dist/plot/scatter/binned-scatter-types.d.ts +3 -2
  327. package/dist/plot/scatter/binned-scatter-types.js +6 -1
  328. package/dist/plot/scatter/scatter-data.d.ts +1 -1
  329. package/dist/plot/scatter/scatter-data.js +8 -7
  330. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +25 -34
  331. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +2 -2
  332. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +8 -5
  333. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +113 -116
  334. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +2 -2
  335. package/dist/plot/scatter-3d/Surface3D.svelte +4 -13
  336. package/dist/plot/sunburst/Sunburst.svelte +269 -347
  337. package/dist/plot/sunburst/Sunburst.svelte.d.ts +2 -2
  338. package/dist/plot/sunburst/index.d.ts +1 -1
  339. package/dist/plot/sunburst/index.js +2 -1
  340. package/dist/plot/sunburst/render.d.ts +2 -2
  341. package/dist/plot/sunburst/render.js +47 -22
  342. package/dist/plot/sunburst/sunburst.d.ts +5 -1
  343. package/dist/plot/sunburst/sunburst.js +10 -3
  344. package/dist/plot/treemap/Treemap.svelte +1022 -0
  345. package/dist/plot/treemap/Treemap.svelte.d.ts +90 -0
  346. package/dist/plot/treemap/index.d.ts +4 -0
  347. package/dist/plot/treemap/index.js +4 -0
  348. package/dist/plot/treemap/labels.d.ts +38 -0
  349. package/dist/plot/treemap/labels.js +80 -0
  350. package/dist/plot/treemap/treemap.d.ts +28 -0
  351. package/dist/plot/treemap/treemap.js +102 -0
  352. package/dist/rdf/RdfPlot.svelte +37 -59
  353. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  354. package/dist/rdf/calc-rdf.js +63 -52
  355. package/dist/rdf/index.d.ts +0 -1
  356. package/dist/sanitize.js +85 -27
  357. package/dist/scene/SceneCamera.svelte +1 -1
  358. package/dist/scene/SceneCamera.svelte.d.ts +1 -1
  359. package/dist/scene/bind-renderer.svelte.js +14 -6
  360. package/dist/scene/index.d.ts +1 -2
  361. package/dist/scene/index.js +1 -1
  362. package/dist/scene/{props.js → props.svelte.js} +15 -1
  363. package/dist/settings.d.ts +19 -9
  364. package/dist/settings.js +229 -525
  365. package/dist/spectral/Bands.svelte +207 -221
  366. package/dist/spectral/BandsAndDos.svelte +11 -9
  367. package/dist/spectral/BrillouinBandsDos.svelte +19 -42
  368. package/dist/spectral/Dos.svelte +92 -93
  369. package/dist/spectral/helpers.d.ts +3 -3
  370. package/dist/spectral/helpers.js +65 -140
  371. package/dist/state.svelte.js +5 -18
  372. package/dist/structure/Arrow.svelte +5 -18
  373. package/dist/structure/ArrowInstances.svelte +160 -0
  374. package/dist/structure/ArrowInstances.svelte.d.ts +16 -0
  375. package/dist/structure/AtomLegend.svelte +120 -85
  376. package/dist/structure/AtomLegend.svelte.d.ts +2 -3
  377. package/dist/structure/Bond.svelte +31 -23
  378. package/dist/structure/CanvasTooltip.svelte +15 -3
  379. package/dist/structure/CellSelect.svelte +45 -35
  380. package/dist/structure/Cylinder.svelte +24 -40
  381. package/dist/structure/InstancedAtoms.svelte +114 -0
  382. package/dist/structure/InstancedAtoms.svelte.d.ts +15 -0
  383. package/dist/structure/Lattice.svelte +85 -149
  384. package/dist/structure/SiteLabels.svelte +122 -0
  385. package/dist/structure/SiteLabels.svelte.d.ts +18 -0
  386. package/dist/structure/Structure.svelte +636 -504
  387. package/dist/structure/Structure.svelte.d.ts +4 -2
  388. package/dist/structure/StructureCarousel.svelte +637 -0
  389. package/dist/structure/StructureCarousel.svelte.d.ts +19 -0
  390. package/dist/structure/StructureControls.svelte +165 -425
  391. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  392. package/dist/structure/StructureExportPane.svelte +17 -21
  393. package/dist/structure/StructureInfoPane.svelte +128 -133
  394. package/dist/structure/StructureInfoPane.svelte.d.ts +1 -1
  395. package/dist/structure/StructureScene.svelte +535 -578
  396. package/dist/structure/StructureScene.svelte.d.ts +6 -2
  397. package/dist/structure/StructureViewport.svelte +451 -0
  398. package/dist/structure/StructureViewport.svelte.d.ts +65 -0
  399. package/dist/structure/atom-label-placement.d.ts +16 -12
  400. package/dist/structure/atom-label-placement.js +70 -37
  401. package/dist/structure/atom-properties.d.ts +2 -0
  402. package/dist/structure/atom-properties.js +105 -38
  403. package/dist/structure/bond-order-perception.js +3 -8
  404. package/dist/structure/bonding.d.ts +9 -3
  405. package/dist/structure/bonding.js +95 -46
  406. package/dist/structure/edit-history.d.ts +6 -0
  407. package/dist/structure/edit-history.js +27 -0
  408. package/dist/structure/export.d.ts +1 -0
  409. package/dist/structure/export.js +89 -105
  410. package/dist/structure/format-detect.d.ts +1 -0
  411. package/dist/structure/format-detect.js +20 -0
  412. package/dist/structure/geometry.d.ts +9 -0
  413. package/dist/structure/geometry.js +27 -0
  414. package/dist/structure/index.d.ts +16 -1
  415. package/dist/structure/index.js +15 -10
  416. package/dist/structure/measure.d.ts +1 -1
  417. package/dist/structure/measure.js +6 -12
  418. package/dist/structure/parse.d.ts +2 -1
  419. package/dist/structure/parse.js +272 -313
  420. package/dist/structure/partial-occupancy.js +10 -5
  421. package/dist/structure/pbc.js +85 -107
  422. package/dist/structure/polyhedra.d.ts +0 -1
  423. package/dist/structure/polyhedra.js +7 -21
  424. package/dist/structure/prop-groups.d.ts +85 -0
  425. package/dist/structure/prop-groups.js +18 -0
  426. package/dist/structure/supercell.d.ts +1 -2
  427. package/dist/structure/supercell.js +7 -13
  428. package/dist/symmetry/SymmetryElements.svelte +11 -15
  429. package/dist/symmetry/SymmetryStats.svelte +55 -71
  430. package/dist/symmetry/WyckoffTable.svelte +10 -28
  431. package/dist/symmetry/cell-transform.js +6 -14
  432. package/dist/symmetry/index.d.ts +1 -0
  433. package/dist/symmetry/index.js +13 -10
  434. package/dist/symmetry/spacegroups.js +3 -2
  435. package/dist/table/HeatmapTable.svelte +1142 -447
  436. package/dist/table/HeatmapTable.svelte.d.ts +12 -2
  437. package/dist/table/ToggleMenu.svelte +168 -53
  438. package/dist/table/ToggleMenu.svelte.d.ts +1 -1
  439. package/dist/table/index.d.ts +21 -6
  440. package/dist/table/index.js +34 -21
  441. package/dist/theme/ThemeControl.svelte +16 -8
  442. package/dist/theme/embedded.d.ts +18 -0
  443. package/dist/theme/embedded.js +206 -0
  444. package/dist/theme/index.d.ts +5 -5
  445. package/dist/theme/index.js +5 -12
  446. package/dist/theme/themes.mjs +44 -66
  447. package/dist/tooltip/KCoords.svelte +4 -1
  448. package/dist/tooltip/TooltipContent.svelte +3 -6
  449. package/dist/tooltip/TooltipContent.svelte.d.ts +1 -1
  450. package/dist/tooltip/index.d.ts +8 -1
  451. package/dist/trajectory/Trajectory.svelte +613 -386
  452. package/dist/trajectory/Trajectory.svelte.d.ts +1 -1
  453. package/dist/trajectory/TrajectoryError.svelte +12 -74
  454. package/dist/trajectory/TrajectoryExportPane.svelte +14 -32
  455. package/dist/trajectory/TrajectoryInfoPane.svelte +127 -164
  456. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +2 -1
  457. package/dist/trajectory/extract.js +61 -49
  458. package/dist/trajectory/format-detect.d.ts +2 -0
  459. package/dist/trajectory/format-detect.js +17 -13
  460. package/dist/trajectory/frame-reader.d.ts +2 -0
  461. package/dist/trajectory/frame-reader.js +35 -32
  462. package/dist/trajectory/helpers.d.ts +2 -0
  463. package/dist/trajectory/helpers.js +34 -56
  464. package/dist/trajectory/index.d.ts +1 -0
  465. package/dist/trajectory/index.js +5 -8
  466. package/dist/trajectory/parse/ase.js +1 -1
  467. package/dist/trajectory/parse/h5-utils.d.ts +13 -0
  468. package/dist/trajectory/parse/h5-utils.js +109 -0
  469. package/dist/trajectory/parse/hdf5.d.ts +1 -1
  470. package/dist/trajectory/parse/hdf5.js +116 -106
  471. package/dist/trajectory/parse/index.d.ts +6 -6
  472. package/dist/trajectory/parse/index.js +25 -33
  473. package/dist/trajectory/parse/lammps.js +8 -12
  474. package/dist/trajectory/parse/vasp.js +10 -7
  475. package/dist/trajectory/parse/vaspout-electronic.d.ts +13 -0
  476. package/dist/trajectory/parse/vaspout-electronic.js +207 -0
  477. package/dist/trajectory/parse/vaspout-h5.d.ts +4 -0
  478. package/dist/trajectory/parse/vaspout-h5.js +281 -0
  479. package/dist/trajectory/parse/xyz.js +59 -9
  480. package/dist/trajectory/plotting.d.ts +8 -9
  481. package/dist/trajectory/plotting.js +113 -64
  482. package/dist/utils.d.ts +3 -0
  483. package/dist/utils.js +7 -0
  484. package/dist/xrd/XrdPlot.svelte +79 -118
  485. package/dist/xrd/broadening.js +2 -1
  486. package/dist/xrd/calc-xrd.js +24 -62
  487. package/dist/xrd/parse.d.ts +0 -1
  488. package/dist/xrd/parse.js +69 -95
  489. package/package.json +94 -34
  490. package/readme.md +6 -5
  491. package/dist/api/mp.d.ts +0 -6
  492. package/dist/api/mp.js +0 -22
  493. package/dist/plot/sunburst/SunburstControls.svelte +0 -200
  494. package/dist/scene/types.d.ts +0 -26
  495. package/dist/tooltip/types.d.ts +0 -8
  496. package/dist/trajectory/constants.d.ts +0 -6
  497. package/dist/trajectory/constants.js +0 -11
  498. /package/dist/{scene/types.js → file-viewer/host-protocol.js} +0 -0
  499. /package/dist/{tooltip/types.js → isosurface/geometry-worker-types.js} +0 -0
@@ -0,0 +1,436 @@
1
+ // Shared marginal-distribution model for all 2D plots. Pure and unit-tested: types,
2
+ // shorthand resolution, pad reservation, strip geometry, and the curve math (histogram /
3
+ // kde / cdf / rug). The PlotMarginals.svelte renderer consumes these; each plot only adapts
4
+ // its data to MarginalSeriesInput and folds reserve_marginal_pad into its `pad`.
5
+ import { sorted_range } from './interactions';
6
+ import { get_scale_type_name } from './types';
7
+ import { gaussian_kde } from '../box/kde';
8
+ import { bin } from 'd3-array';
9
+ export const MARGINAL_SIDES = [`top`, `bottom`, `left`, `right`];
10
+ // Top/bottom strips run along the x (horizontal) positional axis; left/right run along y
11
+ const is_x_side = (side) => side === `top` || side === `bottom`;
12
+ // Build a MarginalAxis from a host plot's scale fn + current range, reading scale_type/format/label
13
+ // off the plot's AxisConfig (DRYs the per-axis object every host plot passes to PlotMarginals; the
14
+ // renderer defaults a missing scale_type to `linear`). `tick_label` maps a position to a label.
15
+ export const marginal_axis = (scale, range, axis, tick_label) => ({
16
+ scale,
17
+ range,
18
+ scale_type: axis.scale_type,
19
+ format: axis.format,
20
+ label: axis.label,
21
+ tick_label,
22
+ });
23
+ // Pixel tolerance for rug-tick hit-testing (a tick farther than this from the pointer is a miss)
24
+ export const MARGINAL_HIT_TOLERANCE_PX = 10;
25
+ // Pure hit-test: given a strip's render context and a pointer position in wrapper px, return the
26
+ // nearest datum as a MarginalHover (or null for a miss). ctx.curves is kind-homogeneous, so we
27
+ // branch once on the first curve's kind, matching only along the shared positional axis. Non-finite
28
+ // data is skipped (consistent with the renderer) so custom reduce/data curves can't yield ghost hits.
29
+ export function marginal_hit(ctx, px, py) {
30
+ const { side, curves, positional_scale, value_scale, baseline, config, scale_type } = ctx;
31
+ const is_x = is_x_side(side);
32
+ const pointer_pos = is_x ? px : py; // along the shared positional axis
33
+ const pointer_cross = is_x ? py : px; // across the strip thickness (the value direction)
34
+ const kind = curves[0]?.curve.kind;
35
+ if (!kind)
36
+ return null;
37
+ const contains_cross = (value_px) => Number.isFinite(value_px) &&
38
+ pointer_cross >= Math.min(baseline, value_px) &&
39
+ pointer_cross <= Math.max(baseline, value_px);
40
+ const hover = (curve, extra) => ({
41
+ side,
42
+ x: px,
43
+ y: py,
44
+ color: config.color ?? curve.color,
45
+ label: curve.label,
46
+ kind,
47
+ config,
48
+ scale_type,
49
+ format: ctx.format,
50
+ pos_label: ctx.tick_label?.(extra.pos),
51
+ axis_title: ctx.axis_title,
52
+ ...extra,
53
+ });
54
+ if (kind === `bars`) {
55
+ // Among bins whose rendered rect contains the pointer, pick the largest-value (tallest) bar.
56
+ // Baseline-anchored bars nest, so the tallest containing bar wins render-order independently.
57
+ let best = null;
58
+ for (const series_curve of curves) {
59
+ if (series_curve.curve.kind !== `bars`)
60
+ continue;
61
+ for (const bar of series_curve.curve.bins) {
62
+ if (!Number.isFinite(bar.value) || bar.value <= 0)
63
+ continue; // finite positive only (matches renderer)
64
+ const edge_a = positional_scale(bar.pos0);
65
+ const edge_b = positional_scale(bar.pos1);
66
+ if (!Number.isFinite(edge_a) || !Number.isFinite(edge_b))
67
+ continue;
68
+ if (pointer_pos < Math.min(edge_a, edge_b) || pointer_pos > Math.max(edge_a, edge_b)) {
69
+ continue;
70
+ }
71
+ if (!contains_cross(value_scale(bar.value)))
72
+ continue;
73
+ if (!best || bar.value > best.bar.value)
74
+ best = { curve: series_curve, bar };
75
+ }
76
+ }
77
+ if (!best)
78
+ return null;
79
+ const { bar } = best;
80
+ return hover(best.curve, {
81
+ pos: (bar.pos0 + bar.pos1) / 2,
82
+ pos0: bar.pos0,
83
+ pos1: bar.pos1,
84
+ value: bar.value,
85
+ });
86
+ }
87
+ if (kind === `line`) {
88
+ let chosen = null;
89
+ let best_extent = -1;
90
+ for (const series_curve of curves) {
91
+ if (series_curve.curve.kind !== `line`)
92
+ continue;
93
+ const pts = [];
94
+ let min_pos = Infinity;
95
+ let max_pos = -Infinity;
96
+ for (const pt of series_curve.curve.points) {
97
+ const px_pos = positional_scale(pt.pos);
98
+ const px_val = value_scale(pt.value);
99
+ if (!Number.isFinite(px_pos) || !Number.isFinite(px_val))
100
+ continue;
101
+ pts.push({ curve: series_curve, pos: pt.pos, value: pt.value, px_pos, px_val });
102
+ min_pos = Math.min(min_pos, px_pos);
103
+ max_pos = Math.max(max_pos, px_pos);
104
+ }
105
+ if (pts.length < 2)
106
+ continue; // renderer skips line/area paths without two finite points
107
+ if (pointer_pos < min_pos || pointer_pos > max_pos)
108
+ continue;
109
+ let near = null;
110
+ let near_dist = Infinity;
111
+ for (const pt of pts) {
112
+ const pos_dist = Math.abs(pt.px_pos - pointer_pos);
113
+ if (pos_dist < near_dist) {
114
+ near_dist = pos_dist;
115
+ near = pt;
116
+ }
117
+ }
118
+ if (!near || !contains_cross(near.px_val))
119
+ continue;
120
+ const extent = Math.abs(near.px_val - baseline);
121
+ if (extent > best_extent)
122
+ [best_extent, chosen] = [extent, near];
123
+ }
124
+ return chosen ? hover(chosen.curve, { pos: chosen.pos, value: chosen.value }) : null;
125
+ }
126
+ // rug: nearest tick along the positional axis, within a pixel tolerance (no value/cross axis)
127
+ let best = null;
128
+ for (const series_curve of curves) {
129
+ if (series_curve.curve.kind !== `rug`)
130
+ continue;
131
+ for (const pos of series_curve.curve.positions) {
132
+ const px_pos = positional_scale(pos);
133
+ if (!Number.isFinite(px_pos))
134
+ continue;
135
+ const dist = Math.abs(px_pos - pointer_pos);
136
+ if (dist < (best?.dist ?? Infinity))
137
+ best = { curve: series_curve, pos, dist };
138
+ }
139
+ }
140
+ if (!best || best.dist > MARGINAL_HIT_TOLERANCE_PX)
141
+ return null;
142
+ return hover(best.curve, { pos: best.pos });
143
+ }
144
+ // Co-located defaults (mirrors REF_LINE_STYLE_DEFAULTS in types.ts). Deliberately NOT part of
145
+ // settings.ts DEFAULTS to avoid pulling marginals into the settings-UI JSON schema.
146
+ export const MARGINAL_DEFAULTS = {
147
+ type: `histogram`,
148
+ size: 64,
149
+ gap: 6,
150
+ placement: `auto`,
151
+ per_series: true,
152
+ bins: 60,
153
+ bandwidth: `silverman`,
154
+ stroke_width: 1.5,
155
+ opacity: 1,
156
+ value_axis: true,
157
+ };
158
+ // Normalize a single side's shorthand to a MarginalConfig, `false` (explicit disable), or
159
+ // undefined (not specified -> fall back to default)
160
+ const to_config = (input) => {
161
+ if (input === undefined)
162
+ return undefined;
163
+ if (input === false)
164
+ return false;
165
+ if (input === true)
166
+ return {};
167
+ if (typeof input === `string`)
168
+ return { type: input };
169
+ return input;
170
+ };
171
+ // Merge a user side-input over the plot's default side-input into a resolved config (or null)
172
+ const resolve_side = (user_input, default_input) => {
173
+ const user = to_config(user_input);
174
+ if (user === false)
175
+ return null; // explicit disable wins over any default
176
+ const base = to_config(default_input);
177
+ const base_cfg = base === false ? undefined : base;
178
+ if (user === undefined && base_cfg === undefined)
179
+ return null; // side inactive
180
+ return { ...MARGINAL_DEFAULTS, ...base_cfg, ...user };
181
+ };
182
+ // Expand the `marginals` prop into a per-side resolved config, merging with the plot's
183
+ // `default_sides` (the sensible defaults a given plot enables when `marginals` is `true`).
184
+ // - `true`: enable exactly the plot's default sides
185
+ // - a type string: that type on the plot's default sides (or top+right if none), inheriting
186
+ // each default side's config (e.g. shared bins)
187
+ // - a per-side map: enable ONLY the sides the user lists (default sides do not auto-activate),
188
+ // merging the plot's per-side default config under the user's
189
+ export function normalize_marginals(prop, default_sides = {}) {
190
+ const result = { top: null, bottom: null, left: null, right: null };
191
+ if (prop == null || prop === false)
192
+ return result;
193
+ if (prop === true) {
194
+ for (const side of MARGINAL_SIDES)
195
+ result[side] = resolve_side(undefined, default_sides[side]);
196
+ return result;
197
+ }
198
+ if (typeof prop === `string`) {
199
+ const sides = Object.keys(default_sides).length > 0 ? default_sides : { top: true, right: true };
200
+ for (const side of MARGINAL_SIDES) {
201
+ if (!(side in sides))
202
+ continue;
203
+ result[side] = resolve_side(prop, default_sides[side]);
204
+ }
205
+ return result;
206
+ }
207
+ // Explicit per-side map: only sides the user names become active
208
+ for (const side of MARGINAL_SIDES) {
209
+ if (prop[side] === undefined)
210
+ continue;
211
+ result[side] = resolve_side(prop[side], default_sides[side]);
212
+ }
213
+ return result;
214
+ }
215
+ // Padding (px) each plot must add to its `pad` to make room for active marginal strips
216
+ export function reserve_marginal_pad(resolved) {
217
+ const reserve = (cfg) => (cfg ? cfg.size + cfg.gap : 0);
218
+ return {
219
+ t: reserve(resolved.top),
220
+ b: reserve(resolved.bottom),
221
+ l: reserve(resolved.left),
222
+ r: reserve(resolved.right),
223
+ };
224
+ }
225
+ // Sum two padding objects (used to fold marginal reservation into the decoration pad)
226
+ export const add_sides = (a, b) => ({
227
+ t: a.t + b.t,
228
+ b: a.b + b.b,
229
+ l: a.l + b.l,
230
+ r: a.r + b.r,
231
+ });
232
+ // Default axis a side binds to when `config.axis` is unset
233
+ export const default_axis_for_side = (side) => is_x_side(side) ? `x1` : `y1`;
234
+ // Which sides carry an axis (drives `auto` placement). Bottom/left hold the primary x/y axes and
235
+ // are always present; top/right only when the plot shows a secondary axis there.
236
+ export const marginal_axis_presence = (top, right) => ({ top, bottom: true, left: true, right });
237
+ // Whether the strip should hug the plot edge (`flush`) vs sit beyond the ticks (`outer`)
238
+ const is_flush = (placement, has_axis) => placement === `flush` || (placement === `auto` && !has_axis);
239
+ // Pixel rect of a marginal strip. The cross dimension spans the plot area (so it aligns with
240
+ // the shared positional scale); the thickness is `config.size`, positioned per placement.
241
+ export function marginal_strip_rect(side, pad, width, height, config, has_axis) {
242
+ const { size, gap } = config;
243
+ const flush = is_flush(config.placement, has_axis);
244
+ const is_x = is_x_side(side);
245
+ const grows_negative = side === `top` || side === `left`;
246
+ // thickness-axis position of the strip's near edge: flush sits a gap from the plot, outer at
247
+ // the container edge (top/left strips go before the plot, bottom/right strips after it)
248
+ const plot_near = is_x ? pad.t : pad.l;
249
+ const plot_far = is_x ? height - pad.b : width - pad.r;
250
+ const container_far = is_x ? height : width;
251
+ const thick = flush
252
+ ? grows_negative
253
+ ? plot_near - gap - size
254
+ : plot_far + gap
255
+ : grows_negative
256
+ ? 0
257
+ : container_far - size;
258
+ // cross axis spans the plot area so the strip aligns with the shared positional scale
259
+ const cross_min = is_x ? pad.l : pad.t;
260
+ const cross = Math.max(0, (is_x ? width - pad.r : height - pad.b) - cross_min);
261
+ return is_x
262
+ ? { x: cross_min, y: thick, width: cross, height: size }
263
+ : { x: thick, y: cross_min, width: size, height: cross };
264
+ }
265
+ // Linear value scale across a strip's thickness, growing away from the plot. `domain` is the
266
+ // marginal value range (typically [0, max]); `baseline` is the plot-facing value=domain[0] edge.
267
+ export function marginal_value_scale(side, rect, domain) {
268
+ const [lo, hi] = domain;
269
+ const span = hi - lo || 1;
270
+ const is_x = is_x_side(side);
271
+ const thickness = is_x ? rect.height : rect.width;
272
+ const near = is_x ? rect.y : rect.x; // strip edge at the smaller pixel coordinate
273
+ // top/left strips grow toward smaller pixel coords; their baseline (value=lo, plot-facing) sits
274
+ // at the far edge, and value increases in the negative pixel direction
275
+ const grows_negative = side === `top` || side === `left`;
276
+ const baseline = grows_negative ? near + thickness : near;
277
+ const sign = grows_negative ? -1 : 1;
278
+ return { scale: (val) => baseline + sign * ((val - lo) / span) * thickness, baseline };
279
+ }
280
+ // Drop non-finite positions (and matching weights), restrict to the current positional range
281
+ // so every marginal type tracks zoom/pan consistently (histogram already clips via bin domain),
282
+ // and drop non-positive positions on a log axis.
283
+ const clean_pairs = (positions, weights, positional_range, scale_type) => {
284
+ const [lo, hi] = positional_range; // ascending (canonicalized by compute_marginal_curve)
285
+ const require_positive = get_scale_type_name(scale_type) === `log`;
286
+ const out_pos = [];
287
+ const out_wts = weights ? [] : undefined;
288
+ for (let idx = 0; idx < positions.length; idx++) {
289
+ const pos = positions[idx];
290
+ if (!Number.isFinite(pos) || pos < lo || pos > hi)
291
+ continue;
292
+ if (require_positive && pos <= 0)
293
+ continue;
294
+ if (weights && out_wts) {
295
+ const weight = weights[idx];
296
+ // skip non-finite and negative weights: a negative makes a weighted CDF non-monotone and
297
+ // skews histogram normalization. zero is kept (it contributes nothing and the renderer
298
+ // already drops zero-value bars, so skipping it would only needlessly drop rug/kde positions)
299
+ if (!Number.isFinite(weight) || weight < 0)
300
+ continue;
301
+ out_wts.push(weight);
302
+ }
303
+ out_pos.push(pos);
304
+ }
305
+ return { positions: out_pos, weights: out_wts };
306
+ };
307
+ function compute_histogram(positions, weights, config, positional_range) {
308
+ const indices = positions.map((_, idx) => idx);
309
+ const binner = bin()
310
+ .domain(positional_range)
311
+ .thresholds(config.bins)
312
+ .value((idx) => positions[idx]);
313
+ const binned = binner(indices);
314
+ let max = 0;
315
+ const bins = binned.map((items) => {
316
+ const value = weights ? items.reduce((sum, idx) => sum + weights[idx], 0) : items.length;
317
+ if (value > max)
318
+ max = value;
319
+ return { pos0: items.x0 ?? 0, pos1: items.x1 ?? 0, value };
320
+ });
321
+ // count: raw; probability: value/total; density: value/(total*bin_width)
322
+ if (config.normalize && config.normalize !== `count`) {
323
+ const grand = bins.reduce((sum, item) => sum + item.value, 0) || 1;
324
+ max = 0;
325
+ for (const item of bins) {
326
+ const width = item.pos1 - item.pos0;
327
+ item.value =
328
+ config.normalize === `density`
329
+ ? item.value / (grand * (width || 1))
330
+ : item.value / grand;
331
+ if (item.value > max)
332
+ max = item.value;
333
+ }
334
+ }
335
+ return { kind: `bars`, bins, max };
336
+ }
337
+ function compute_cdf(positions, weights) {
338
+ const order = positions.map((_, idx) => idx).sort((a, b) => positions[a] - positions[b]);
339
+ const total = weights ? weights.reduce((sum, weight) => sum + weight, 0) : positions.length;
340
+ const points = [];
341
+ let cum = 0;
342
+ for (const idx of order) {
343
+ cum += weights ? weights[idx] : 1;
344
+ const pos = positions[idx];
345
+ const value = total > 0 ? cum / total : 0;
346
+ // collapse ties so positions stay strictly increasing (keeps monotone curves well-behaved)
347
+ const last = points[points.length - 1];
348
+ if (last?.pos === pos)
349
+ last.value = value;
350
+ else
351
+ points.push({ pos, value });
352
+ }
353
+ return { kind: `line`, points, max: 1 };
354
+ }
355
+ // Smallest strictly-positive value (Infinity if none): repairs a degenerate log lower bound (<= 0)
356
+ // so kde grids / histogram bins don't dip to non-renderable positions
357
+ const smallest_positive = (vals) => vals.reduce((min, val) => (val > 0 && val < min ? val : min), Infinity);
358
+ function compute_kde(positions, config, positional_range, scale_type) {
359
+ // The grid spans the current positional range, so on a normal log axis (range[0] > 0) no
360
+ // clamping is needed. Only repair a degenerate log range whose lower bound is <= 0 (would
361
+ // otherwise emit grid points at <= 0 -> NaN pixels) by clamping to the smallest positive sample.
362
+ let clip;
363
+ if (get_scale_type_name(scale_type) === `log` && positional_range[0] <= 0) {
364
+ const min_pos = smallest_positive(positions);
365
+ if (Number.isFinite(min_pos))
366
+ clip = [min_pos, null];
367
+ }
368
+ const kde = gaussian_kde(positions, {
369
+ bandwidth: config.bandwidth,
370
+ n_points: 100,
371
+ range: positional_range,
372
+ clip,
373
+ max_samples: 5000,
374
+ });
375
+ let max = 0;
376
+ for (const density of kde.density)
377
+ if (density > max)
378
+ max = density;
379
+ const points = kde.grid.map((pos, idx) => ({ pos, value: kde.density[idx] }));
380
+ return { kind: `line`, points, max };
381
+ }
382
+ // Summarize 1-D values into a renderable curve per the marginal type. Filters non-finite
383
+ // inputs and returns an empty curve for empty input (so nothing renders).
384
+ export function compute_marginal_curve(positions, weights, config, positional_range, scale_type) {
385
+ // Canonicalize to an ascending range so a reversed (inverted-axis) range doesn't crash
386
+ // d3.bin (negative-length bin array) or empty the kde grid
387
+ const range = sorted_range(positional_range[0], positional_range[1]);
388
+ const { positions: pos, weights: wts } = clean_pairs(positions, weights, range, scale_type);
389
+ // rug returns the raw positions (empty or not); other types short-circuit on empty input
390
+ if (config.type === `rug`)
391
+ return { kind: `rug`, positions: pos };
392
+ if (pos.length === 0) {
393
+ return config.type === `histogram`
394
+ ? { kind: `bars`, bins: [], max: 0 }
395
+ : { kind: `line`, points: [], max: 0 };
396
+ }
397
+ if (config.type === `histogram`) {
398
+ // on a degenerate log axis (lower bound <= 0) bin over the smallest positive sample instead, so
399
+ // bins aren't spread below the smallest renderable position (mirrors compute_kde's clip)
400
+ const hist_range = get_scale_type_name(scale_type) === `log` && range[0] <= 0
401
+ ? [smallest_positive(pos), range[1]]
402
+ : range;
403
+ return compute_histogram(pos, wts, config, hist_range);
404
+ }
405
+ if (config.type === `cdf`)
406
+ return compute_cdf(pos, wts);
407
+ return compute_kde(pos, config, range, scale_type);
408
+ }
409
+ // Max value across a set of curves (for a shared per-side value scale)
410
+ export const curves_max = (curves) => curves.reduce((max, curve) => (curve.kind === `rug` ? max : Math.max(max, curve.max)), 0);
411
+ // Value-axis title for a strip: explicit `config.label` wins, else auto per type (histogram uses
412
+ // its normalization). `rug` has no value axis so returns an empty string.
413
+ export const default_marginal_label = (config) => {
414
+ if (config.label != null)
415
+ return config.label;
416
+ if (config.type === `cdf`)
417
+ return `CDF`;
418
+ if (config.type === `kde`)
419
+ return `density`;
420
+ if (config.type === `histogram`)
421
+ return config.normalize ?? `count`;
422
+ return ``;
423
+ };
424
+ // d3-format spec for the strip's value-axis tick labels, picked to suit each type's value units
425
+ export const marginal_value_format = (config) => {
426
+ if (config.type === `cdf`)
427
+ return `.0%`;
428
+ if (config.type === `histogram`) {
429
+ if (config.normalize === `probability`)
430
+ return `.0%`;
431
+ if (config.normalize === `density`)
432
+ return `.2~g`;
433
+ return `.3~s`;
434
+ }
435
+ return `.2~g`; // kde density
436
+ };
@@ -1,13 +1,11 @@
1
1
  import type { Point2D, Vec2 } from '../../math';
2
+ import { type Rect } from './layout';
2
3
  import type { AxisRanges, PanConfig, ScaleType } from './types';
3
4
  type Axis = `x` | `x2` | `y` | `y2`;
4
5
  export interface PanZoomOptions {
5
6
  ranges: () => AxisRanges;
6
7
  scale_type: (axis: Axis) => ScaleType | undefined;
7
- plot_dims: () => {
8
- width: number;
9
- height: number;
10
- };
8
+ plot_bounds: () => Rect;
11
9
  pan: () => PanConfig | undefined;
12
10
  set_range: (axis: Axis, range: Vec2) => void;
13
11
  svg: () => SVGElement | null;
@@ -3,17 +3,18 @@
3
3
  // per-component policy (which axis props to write on rect-zoom, reset semantics)
4
4
  // stays in the component via the on_rect_zoom/on_reset/set_range callbacks.
5
5
  import { MIN_TOUCH_DISTANCE_PIXELS, pan_range_by_pixels, PINCH_ZOOM_THRESHOLD, remove_drag_listeners, snapshot_ranges, zoom_range_by_factor, } from './interactions';
6
+ import { point_in_rect } from './layout';
6
7
  const AXES = [`x`, `x2`, `y`, `y2`];
7
8
  export function create_pan_zoom(opts) {
8
9
  // Rect-zoom drag state
9
- let drag_state = $state({ start: null, current: null, bounds: null });
10
+ let drag_state = $state(null);
10
11
  // Pan state
11
12
  let is_focused = $state(false);
12
13
  let shift_held = $state(false);
13
14
  let pan_drag_state = $state(null);
14
15
  let touch_state = $state(null);
15
16
  const cancel_rect_drag = () => {
16
- drag_state = { start: null, current: null, bounds: null };
17
+ drag_state = null;
17
18
  if (typeof window !== `undefined`) {
18
19
  window.removeEventListener(`mousemove`, on_window_mouse_move);
19
20
  window.removeEventListener(`mouseup`, on_window_mouse_up);
@@ -21,7 +22,7 @@ export function create_pan_zoom(opts) {
21
22
  }
22
23
  };
23
24
  const on_window_mouse_move = (evt) => {
24
- if (!drag_state.start || !drag_state.bounds)
25
+ if (!drag_state)
25
26
  return;
26
27
  const coords = {
27
28
  x: evt.clientX - drag_state.bounds.left,
@@ -35,7 +36,7 @@ export function create_pan_zoom(opts) {
35
36
  opts.on_drag_move?.(coords, inside_svg);
36
37
  };
37
38
  const on_window_mouse_up = () => {
38
- if (drag_state.start && drag_state.current) {
39
+ if (drag_state) {
39
40
  // Ignore minuscule drag rects (e.g. accidental clicks)
40
41
  const dx = Math.abs(drag_state.start.x - drag_state.current.x);
41
42
  const dy = Math.abs(drag_state.start.y - drag_state.current.y);
@@ -47,7 +48,7 @@ export function create_pan_zoom(opts) {
47
48
  // Pan/zoom all four axes from an interaction-start snapshot, each in its own
48
49
  // scale's transform space (log axes pan by a constant factor, linear by a shift)
49
50
  const pan_all_axes = (init, dx_px, dy_px) => {
50
- const dims = opts.plot_dims();
51
+ const dims = opts.plot_bounds();
51
52
  for (const axis of AXES) {
52
53
  const horizontal = axis === `x` || axis === `x2`;
53
54
  opts.set_range(axis, pan_range_by_pixels(init[`initial_${axis}_range`], horizontal ? dx_px : dy_px, horizontal ? dims.width : dims.height, opts.scale_type(axis)));
@@ -72,9 +73,17 @@ export function create_pan_zoom(opts) {
72
73
  window.removeEventListener(`mouseup`, on_pan_end);
73
74
  };
74
75
  const on_mouse_down = (evt) => {
76
+ if (evt.button !== 0)
77
+ return;
75
78
  const svg = opts.svg();
76
79
  if (!svg)
77
80
  return;
81
+ // The SVG also contains axes, tick labels, and titles. Only the padded data
82
+ // rectangle may start a drag interaction.
83
+ const svg_bounds = svg.getBoundingClientRect();
84
+ const coords = { x: evt.clientX - svg_bounds.left, y: evt.clientY - svg_bounds.top };
85
+ if (!point_in_rect(coords, opts.plot_bounds()))
86
+ return;
78
87
  // Shift+drag pans (when enabled); plain drag draws the zoom rect
79
88
  const pan_enabled = opts.pan()?.enabled !== false;
80
89
  if (pan_enabled && evt.shiftKey) {
@@ -89,9 +98,7 @@ export function create_pan_zoom(opts) {
89
98
  return;
90
99
  }
91
100
  // Cache bounds at drag start so window mousemove can compute relative coords
92
- const bounds = svg.getBoundingClientRect();
93
- const coords = { x: evt.clientX - bounds.left, y: evt.clientY - bounds.top };
94
- drag_state = { start: coords, current: coords, bounds };
101
+ drag_state = { start: coords, current: coords, bounds: svg_bounds };
95
102
  window.addEventListener(`mousemove`, on_window_mouse_move);
96
103
  window.addEventListener(`mouseup`, on_window_mouse_up);
97
104
  document.body.style.cursor = `crosshair`;
@@ -104,7 +111,7 @@ export function create_pan_zoom(opts) {
104
111
  if (pan_cfg?.enabled === false || !is_focused || !shift_held)
105
112
  return;
106
113
  evt.preventDefault();
107
- const dims = opts.plot_dims();
114
+ const dims = opts.plot_bounds();
108
115
  const sensitivity = pan_cfg?.wheel_sensitivity ?? 1;
109
116
  const ranges = opts.ranges();
110
117
  // Pan along the dominant wheel direction
@@ -125,12 +132,22 @@ export function create_pan_zoom(opts) {
125
132
  const touch_enabled = pan_cfg?.enabled !== false && pan_cfg?.touch_enabled !== false;
126
133
  if (!touch_enabled || evt.touches.length !== 2)
127
134
  return;
135
+ const svg_bounds = opts.svg()?.getBoundingClientRect();
136
+ if (!svg_bounds)
137
+ return;
138
+ const plot_bounds = opts.plot_bounds();
139
+ const start_touches = Array.from(evt.touches).map((touch) => ({
140
+ x: touch.clientX,
141
+ y: touch.clientY,
142
+ }));
143
+ // Every contact must start in the data rectangle; touching an axis or label
144
+ // must not arm a gesture that later moves into the plot.
145
+ const starts_outside_plot = start_touches.some((touch) => !point_in_rect({ x: touch.x - svg_bounds.left, y: touch.y - svg_bounds.top }, plot_bounds));
146
+ if (starts_outside_plot)
147
+ return;
128
148
  evt.preventDefault();
129
149
  touch_state = {
130
- start_touches: Array.from(evt.touches).map((touch) => ({
131
- x: touch.clientX,
132
- y: touch.clientY,
133
- })),
150
+ start_touches,
134
151
  ...snapshot_ranges(opts.ranges()),
135
152
  };
136
153
  };
@@ -168,7 +185,7 @@ export function create_pan_zoom(opts) {
168
185
  const on_key_down = (evt) => {
169
186
  if (evt.target !== evt.currentTarget)
170
187
  return;
171
- if (evt.key === `Escape` && drag_state.start)
188
+ if (evt.key === `Escape` && drag_state)
172
189
  cancel_rect_drag();
173
190
  if ([`Enter`, ` `].includes(evt.key)) {
174
191
  evt.preventDefault();
@@ -177,10 +194,10 @@ export function create_pan_zoom(opts) {
177
194
  };
178
195
  return {
179
196
  get drag_start() {
180
- return drag_state.start;
197
+ return drag_state?.start ?? null;
181
198
  },
182
199
  get drag_current() {
183
- return drag_state.current;
200
+ return drag_state?.current ?? null;
184
201
  },
185
202
  get is_pan_dragging() {
186
203
  return pan_drag_state !== null;
@@ -213,7 +230,7 @@ export function create_pan_zoom(opts) {
213
230
  // stuck cursor). Safe during SSR teardown, where window/document don't exist.
214
231
  destroy: () => {
215
232
  remove_drag_listeners([on_window_mouse_move, on_pan_move], [on_window_mouse_up, on_pan_end]);
216
- drag_state = { start: null, current: null, bounds: null };
233
+ drag_state = null;
217
234
  pan_drag_state = null;
218
235
  touch_state = null;
219
236
  },
@@ -14,8 +14,11 @@ export declare function create_placed_tween(opts: {
14
14
  tween?: () => TweenOptions<Point> | undefined;
15
15
  suspended?: () => boolean;
16
16
  manual_position?: () => Point | null;
17
+ on_element_resize?: () => void;
18
+ placement_revision?: () => unknown;
17
19
  }): {
18
20
  coords: Tween<Point>;
21
+ placed: () => boolean;
19
22
  set_locked: (locked: boolean) => void;
20
23
  };
21
24
  export {};