matterviz 0.3.7 → 0.4.1

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 (486) 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 +76 -148
  6. package/dist/brillouin/BrillouinZone.svelte.d.ts +6 -14
  7. package/dist/brillouin/BrillouinZoneExportPane.svelte +43 -96
  8. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneInfoPane.svelte +9 -32
  10. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +2 -3
  11. package/dist/brillouin/BrillouinZoneScene.svelte +97 -205
  12. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +4 -23
  13. package/dist/brillouin/BrillouinZoneTooltip.svelte +16 -25
  14. package/dist/brillouin/ReciprocalVectors.svelte +39 -0
  15. package/dist/brillouin/ReciprocalVectors.svelte.d.ts +9 -0
  16. package/dist/brillouin/compute.d.ts +2 -0
  17. package/dist/brillouin/compute.js +89 -90
  18. package/dist/brillouin/geometry.d.ts +8 -0
  19. package/dist/brillouin/geometry.js +57 -0
  20. package/dist/brillouin/index.d.ts +2 -0
  21. package/dist/brillouin/index.js +2 -0
  22. package/dist/brillouin/types.d.ts +2 -2
  23. package/dist/chempot-diagram/ChemPotDiagram.svelte +14 -13
  24. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +1 -1
  25. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +109 -203
  26. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +4 -1
  27. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +180 -470
  28. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +7 -1
  29. package/dist/chempot-diagram/async-compute.svelte.js +3 -1
  30. package/dist/chempot-diagram/chempot-worker.js +2 -1
  31. package/dist/chempot-diagram/color.d.ts +3 -6
  32. package/dist/chempot-diagram/color.js +5 -5
  33. package/dist/chempot-diagram/compute.d.ts +4 -4
  34. package/dist/chempot-diagram/compute.js +20 -20
  35. package/dist/chempot-diagram/controls-state.svelte.d.ts +10 -0
  36. package/dist/chempot-diagram/controls-state.svelte.js +42 -0
  37. package/dist/chempot-diagram/export.d.ts +47 -0
  38. package/dist/chempot-diagram/export.js +133 -0
  39. package/dist/chempot-diagram/index.d.ts +1 -0
  40. package/dist/chempot-diagram/index.js +1 -0
  41. package/dist/chempot-diagram/pointer.d.ts +0 -10
  42. package/dist/chempot-diagram/pointer.js +4 -4
  43. package/dist/chempot-diagram/types.d.ts +3 -3
  44. package/dist/colors/index.js +8 -7
  45. package/dist/composition/FormulaFilter.svelte +18 -11
  46. package/dist/composition/PieChart.svelte +11 -10
  47. package/dist/composition/chem-sys.d.ts +8 -0
  48. package/dist/composition/chem-sys.js +86 -0
  49. package/dist/composition/format.js +7 -4
  50. package/dist/composition/index.d.ts +1 -0
  51. package/dist/composition/index.js +1 -0
  52. package/dist/composition/parse.d.ts +0 -1
  53. package/dist/composition/parse.js +41 -31
  54. package/dist/controls.d.ts +1 -0
  55. package/dist/controls.js +0 -1
  56. package/dist/convex-hull/ConvexHull.svelte +8 -10
  57. package/dist/convex-hull/ConvexHull.svelte.d.ts +1 -4
  58. package/dist/convex-hull/ConvexHull2D.svelte +106 -185
  59. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +1 -1
  60. package/dist/convex-hull/ConvexHull3D.svelte +179 -683
  61. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +1 -1
  62. package/dist/convex-hull/ConvexHull4D.svelte +183 -687
  63. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +1 -1
  64. package/dist/convex-hull/ConvexHullChrome.svelte +268 -0
  65. package/dist/convex-hull/ConvexHullChrome.svelte.d.ts +30 -0
  66. package/dist/convex-hull/ConvexHullControls.svelte +88 -7
  67. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +7 -6
  68. package/dist/convex-hull/ConvexHullInfoPane.svelte +18 -5
  69. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +6 -5
  70. package/dist/convex-hull/ConvexHullStats.svelte +36 -175
  71. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +3 -1
  72. package/dist/convex-hull/ConvexHullTooltip.svelte +11 -2
  73. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +2 -1
  74. package/dist/convex-hull/GasPressureControls.svelte +4 -4
  75. package/dist/convex-hull/TemperatureSlider.svelte +2 -2
  76. package/dist/convex-hull/barycentric-coords.d.ts +2 -4
  77. package/dist/convex-hull/barycentric-coords.js +6 -33
  78. package/dist/convex-hull/canvas-interactions.svelte.d.ts +79 -0
  79. package/dist/convex-hull/canvas-interactions.svelte.js +278 -0
  80. package/dist/convex-hull/demo-temperature.d.ts +1 -1
  81. package/dist/convex-hull/demo-temperature.js +20 -22
  82. package/dist/convex-hull/gas-thermodynamics.d.ts +2 -2
  83. package/dist/convex-hull/gas-thermodynamics.js +22 -30
  84. package/dist/convex-hull/helpers.d.ts +42 -7
  85. package/dist/convex-hull/helpers.js +171 -78
  86. package/dist/convex-hull/hull-state.svelte.d.ts +44 -0
  87. package/dist/convex-hull/hull-state.svelte.js +124 -0
  88. package/dist/convex-hull/index.d.ts +10 -8
  89. package/dist/convex-hull/index.js +7 -2
  90. package/dist/convex-hull/thermodynamics.js +136 -960
  91. package/dist/convex-hull/types.d.ts +13 -5
  92. package/dist/convex-hull/types.js +12 -0
  93. package/dist/coordination/CoordinationBarPlot.svelte +27 -34
  94. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +1 -1
  95. package/dist/element/BohrAtom.svelte +2 -1
  96. package/dist/element/index.d.ts +4 -0
  97. package/dist/element/index.js +18 -0
  98. package/dist/feedback/DragOverlay.svelte +3 -1
  99. package/dist/feedback/DragOverlay.svelte.d.ts +1 -0
  100. package/dist/feedback/StatusMessage.svelte +13 -3
  101. package/dist/fermi-surface/FermiSlice.svelte +13 -5
  102. package/dist/fermi-surface/FermiSurface.svelte +78 -151
  103. package/dist/fermi-surface/FermiSurface.svelte.d.ts +5 -14
  104. package/dist/fermi-surface/FermiSurfaceControls.svelte +1 -1
  105. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +1 -1
  106. package/dist/fermi-surface/FermiSurfaceScene.svelte +72 -221
  107. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +3 -23
  108. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +8 -34
  109. package/dist/fermi-surface/compute.js +67 -66
  110. package/dist/fermi-surface/export.js +6 -16
  111. package/dist/fermi-surface/index.d.ts +0 -1
  112. package/dist/fermi-surface/index.js +0 -1
  113. package/dist/fermi-surface/parse.d.ts +1 -1
  114. package/dist/fermi-surface/parse.js +71 -79
  115. package/dist/fermi-surface/types.d.ts +3 -2
  116. package/dist/heatmap-matrix/HeatmapMatrix.svelte +69 -52
  117. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +4 -3
  118. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +3 -2
  119. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +5 -5
  120. package/dist/heatmap-matrix/index.d.ts +3 -2
  121. package/dist/heatmap-matrix/index.js +1 -1
  122. package/dist/index.d.ts +1 -0
  123. package/dist/index.js +1 -0
  124. package/dist/io/ExportPane.svelte +166 -0
  125. package/dist/io/ExportPane.svelte.d.ts +17 -0
  126. package/dist/io/decompress.js +5 -4
  127. package/dist/io/export.d.ts +9 -5
  128. package/dist/io/export.js +77 -51
  129. package/dist/io/fetch.d.ts +2 -1
  130. package/dist/io/fetch.js +5 -1
  131. package/dist/io/file-drop.d.ts +8 -1
  132. package/dist/io/file-drop.js +48 -36
  133. package/dist/io/index.d.ts +2 -0
  134. package/dist/io/index.js +10 -0
  135. package/dist/io/types.d.ts +13 -0
  136. package/dist/io/url-drop.js +64 -33
  137. package/dist/isosurface/parse.js +52 -51
  138. package/dist/isosurface/slice.js +5 -4
  139. package/dist/isosurface/types.js +1 -1
  140. package/dist/keyboard.d.ts +3 -0
  141. package/dist/keyboard.js +23 -0
  142. package/dist/labels.d.ts +1 -1
  143. package/dist/labels.js +9 -8
  144. package/dist/layout/FullscreenButton.svelte +33 -0
  145. package/dist/layout/FullscreenButton.svelte.d.ts +10 -0
  146. package/dist/layout/FullscreenToggle.svelte +8 -14
  147. package/dist/layout/PropertyFilter.svelte +3 -2
  148. package/dist/layout/SettingsSection.svelte +1 -1
  149. package/dist/layout/ViewerChrome.svelte +116 -0
  150. package/dist/layout/ViewerChrome.svelte.d.ts +17 -0
  151. package/dist/layout/fullscreen.d.ts +4 -0
  152. package/dist/layout/fullscreen.svelte.d.ts +8 -0
  153. package/dist/layout/fullscreen.svelte.js +37 -0
  154. package/dist/layout/index.d.ts +3 -0
  155. package/dist/layout/index.js +3 -0
  156. package/dist/layout/json-tree/JsonNode.svelte +1 -1
  157. package/dist/layout/json-tree/JsonTree.svelte +2 -2
  158. package/dist/layout/json-tree/utils.js +5 -4
  159. package/dist/marching-cubes.js +8 -13
  160. package/dist/math.d.ts +12 -4
  161. package/dist/math.js +42 -30
  162. package/dist/overlays/DraggablePane.svelte +4 -4
  163. package/dist/overlays/index.d.ts +4 -0
  164. package/dist/periodic-table/PeriodicTable.svelte +27 -15
  165. package/dist/periodic-table/PropertySelect.svelte +1 -0
  166. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +9 -3
  167. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +1 -1
  168. package/dist/phase-diagram/PhaseDiagramControls.svelte +3 -2
  169. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +4 -3
  170. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +4 -2
  171. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +2 -3
  172. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +47 -132
  173. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +3 -4
  174. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +1 -1
  175. package/dist/phase-diagram/build-diagram.js +2 -2
  176. package/dist/phase-diagram/colors.js +1 -1
  177. package/dist/phase-diagram/parse.d.ts +2 -1
  178. package/dist/phase-diagram/parse.js +6 -5
  179. package/dist/phase-diagram/types.d.ts +1 -1
  180. package/dist/phase-diagram/utils.d.ts +3 -3
  181. package/dist/phase-diagram/utils.js +8 -12
  182. package/dist/plot/{BarPlot.svelte → bar/BarPlot.svelte} +246 -841
  183. package/dist/plot/{BarPlot.svelte.d.ts → bar/BarPlot.svelte.d.ts} +8 -16
  184. package/dist/plot/{BarPlotControls.svelte → bar/BarPlotControls.svelte} +6 -5
  185. package/dist/plot/{BarPlotControls.svelte.d.ts → bar/BarPlotControls.svelte.d.ts} +3 -3
  186. package/dist/plot/{SpacegroupBarPlot.svelte → bar/SpacegroupBarPlot.svelte} +8 -7
  187. package/dist/plot/{SpacegroupBarPlot.svelte.d.ts → bar/SpacegroupBarPlot.svelte.d.ts} +1 -1
  188. package/dist/plot/bar/data.d.ts +40 -0
  189. package/dist/plot/bar/data.js +154 -0
  190. package/dist/plot/bar/geometry.d.ts +39 -0
  191. package/dist/plot/bar/geometry.js +60 -0
  192. package/dist/plot/bar/index.d.ts +3 -0
  193. package/dist/plot/bar/index.js +3 -0
  194. package/dist/plot/box/BoxPlot.svelte +1292 -0
  195. package/dist/plot/box/BoxPlot.svelte.d.ts +95 -0
  196. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  197. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  198. package/dist/plot/box/Violin.svelte +14 -0
  199. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  200. package/dist/plot/box/box-plot.d.ts +56 -0
  201. package/dist/plot/box/box-plot.js +129 -0
  202. package/dist/plot/box/index.d.ts +5 -0
  203. package/dist/plot/box/index.js +5 -0
  204. package/dist/plot/box/kde.d.ts +17 -0
  205. package/dist/plot/box/kde.js +160 -0
  206. package/dist/plot/box/quantile.d.ts +3 -0
  207. package/dist/plot/box/quantile.js +53 -0
  208. package/dist/plot/{auto-place.d.ts → core/auto-place.d.ts} +1 -1
  209. package/dist/plot/{auto-place.js → core/auto-place.js} +6 -3
  210. package/dist/plot/core/axis-utils.d.ts +46 -0
  211. package/dist/plot/core/axis-utils.js +110 -0
  212. package/dist/plot/{AxisLabel.svelte → core/components/AxisLabel.svelte} +2 -2
  213. package/dist/plot/{AxisLabel.svelte.d.ts → core/components/AxisLabel.svelte.d.ts} +1 -1
  214. package/dist/plot/{ColorBar.svelte → core/components/ColorBar.svelte} +41 -38
  215. package/dist/plot/{ColorBar.svelte.d.ts → core/components/ColorBar.svelte.d.ts} +7 -6
  216. package/dist/plot/{ColorScaleSelect.svelte → core/components/ColorScaleSelect.svelte} +4 -3
  217. package/dist/plot/{ColorScaleSelect.svelte.d.ts → core/components/ColorScaleSelect.svelte.d.ts} +2 -2
  218. package/dist/plot/core/components/ControlPane.svelte +46 -0
  219. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  220. package/dist/plot/{FillArea.svelte → core/components/FillArea.svelte} +17 -6
  221. package/dist/plot/{FillArea.svelte.d.ts → core/components/FillArea.svelte.d.ts} +1 -1
  222. package/dist/plot/{InteractiveAxisLabel.svelte → core/components/InteractiveAxisLabel.svelte} +3 -3
  223. package/dist/plot/{InteractiveAxisLabel.svelte.d.ts → core/components/InteractiveAxisLabel.svelte.d.ts} +2 -2
  224. package/dist/plot/{Line.svelte → core/components/Line.svelte} +33 -15
  225. package/dist/plot/{Line.svelte.d.ts → core/components/Line.svelte.d.ts} +3 -2
  226. package/dist/plot/{PlotAxis.svelte → core/components/PlotAxis.svelte} +9 -6
  227. package/dist/plot/{PlotAxis.svelte.d.ts → core/components/PlotAxis.svelte.d.ts} +5 -3
  228. package/dist/plot/{PlotControls.svelte → core/components/PlotControls.svelte} +17 -29
  229. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  230. package/dist/plot/{PlotLegend.svelte → core/components/PlotLegend.svelte} +21 -10
  231. package/dist/plot/{PlotLegend.svelte.d.ts → core/components/PlotLegend.svelte.d.ts} +3 -2
  232. package/dist/plot/{PlotTooltip.svelte → core/components/PlotTooltip.svelte} +17 -1
  233. package/dist/plot/{PlotTooltip.svelte.d.ts → core/components/PlotTooltip.svelte.d.ts} +8 -0
  234. package/dist/plot/{PortalSelect.svelte → core/components/PortalSelect.svelte} +11 -7
  235. package/dist/plot/{ReferenceLine.svelte → core/components/ReferenceLine.svelte} +3 -3
  236. package/dist/plot/{ReferenceLine.svelte.d.ts → core/components/ReferenceLine.svelte.d.ts} +1 -1
  237. package/dist/plot/{ReferenceLine3D.svelte → core/components/ReferenceLine3D.svelte} +5 -5
  238. package/dist/plot/{ReferenceLine3D.svelte.d.ts → core/components/ReferenceLine3D.svelte.d.ts} +5 -5
  239. package/dist/plot/{ReferencePlane.svelte → core/components/ReferencePlane.svelte} +8 -8
  240. package/dist/plot/{ReferencePlane.svelte.d.ts → core/components/ReferencePlane.svelte.d.ts} +5 -5
  241. package/dist/plot/{ZeroLines.svelte → core/components/ZeroLines.svelte} +3 -3
  242. package/dist/plot/{ZeroLines.svelte.d.ts → core/components/ZeroLines.svelte.d.ts} +3 -3
  243. package/dist/plot/{ZoomRect.svelte → core/components/ZoomRect.svelte} +1 -1
  244. package/dist/plot/{ZoomRect.svelte.d.ts → core/components/ZoomRect.svelte.d.ts} +1 -1
  245. package/dist/plot/core/components/index.d.ts +17 -0
  246. package/dist/plot/core/components/index.js +17 -0
  247. package/dist/plot/{data-cleaning.d.ts → core/data-cleaning.d.ts} +71 -1
  248. package/dist/plot/{data-cleaning.js → core/data-cleaning.js} +21 -23
  249. package/dist/plot/{data-transform.d.ts → core/data-transform.d.ts} +2 -2
  250. package/dist/plot/{data-transform.js → core/data-transform.js} +3 -3
  251. package/dist/plot/core/fill-utils.d.ts +34 -0
  252. package/dist/plot/core/fill-utils.js +391 -0
  253. package/dist/plot/core/index.d.ts +10 -0
  254. package/dist/plot/core/index.js +11 -0
  255. package/dist/plot/core/interactions.d.ts +39 -0
  256. package/dist/plot/core/interactions.js +209 -0
  257. package/dist/plot/{layout.d.ts → core/layout.d.ts} +1 -0
  258. package/dist/plot/{layout.js → core/layout.js} +16 -8
  259. package/dist/plot/core/pan-zoom.svelte.d.ts +35 -0
  260. package/dist/plot/core/pan-zoom.svelte.js +221 -0
  261. package/dist/plot/core/placed-tween.svelte.d.ts +21 -0
  262. package/dist/plot/core/placed-tween.svelte.js +68 -0
  263. package/dist/plot/{reference-line.d.ts → core/reference-line.d.ts} +11 -11
  264. package/dist/plot/{reference-line.js → core/reference-line.js} +29 -42
  265. package/dist/plot/core/scales.d.ts +40 -0
  266. package/dist/plot/{scales.js → core/scales.js} +94 -93
  267. package/dist/plot/core/svg.d.ts +3 -0
  268. package/dist/plot/core/svg.js +41 -0
  269. package/dist/plot/{types.d.ts → core/types.d.ts} +36 -85
  270. package/dist/plot/{types.js → core/types.js} +1 -1
  271. package/dist/plot/{utils → core/utils}/label-placement.d.ts +3 -3
  272. package/dist/plot/{utils → core/utils}/label-placement.js +3 -3
  273. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  274. package/dist/plot/{utils → core/utils}/series-visibility.js +29 -2
  275. package/dist/plot/core/utils.d.ts +12 -0
  276. package/dist/plot/core/utils.js +27 -0
  277. package/dist/plot/{Histogram.svelte → histogram/Histogram.svelte} +174 -551
  278. package/dist/plot/{Histogram.svelte.d.ts → histogram/Histogram.svelte.d.ts} +2 -2
  279. package/dist/plot/{HistogramControls.svelte → histogram/HistogramControls.svelte} +6 -6
  280. package/dist/plot/{HistogramControls.svelte.d.ts → histogram/HistogramControls.svelte.d.ts} +4 -4
  281. package/dist/plot/histogram/index.d.ts +2 -0
  282. package/dist/plot/histogram/index.js +2 -0
  283. package/dist/plot/index.d.ts +8 -41
  284. package/dist/plot/index.js +10 -39
  285. package/dist/plot/sankey/Sankey.svelte +697 -0
  286. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  287. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  288. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  289. package/dist/plot/sankey/index.d.ts +4 -0
  290. package/dist/plot/sankey/index.js +3 -0
  291. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  292. package/dist/plot/sankey/sankey-types.js +4 -0
  293. package/dist/plot/sankey/sankey.d.ts +52 -0
  294. package/dist/plot/sankey/sankey.js +189 -0
  295. package/dist/plot/{BinnedScatterPlot.svelte → scatter/BinnedScatterPlot.svelte} +64 -64
  296. package/dist/plot/{BinnedScatterPlot.svelte.d.ts → scatter/BinnedScatterPlot.svelte.d.ts} +6 -6
  297. package/dist/plot/{ElementScatter.svelte → scatter/ElementScatter.svelte} +6 -6
  298. package/dist/plot/{ElementScatter.svelte.d.ts → scatter/ElementScatter.svelte.d.ts} +2 -2
  299. package/dist/plot/{ScatterPlot.svelte → scatter/ScatterPlot.svelte} +297 -1008
  300. package/dist/plot/{ScatterPlot.svelte.d.ts → scatter/ScatterPlot.svelte.d.ts} +10 -18
  301. package/dist/plot/{ScatterPlotControls.svelte → scatter/ScatterPlotControls.svelte} +6 -5
  302. package/dist/plot/{ScatterPlotControls.svelte.d.ts → scatter/ScatterPlotControls.svelte.d.ts} +2 -2
  303. package/dist/plot/{ScatterPoint.svelte → scatter/ScatterPoint.svelte} +7 -7
  304. package/dist/plot/{ScatterPoint.svelte.d.ts → scatter/ScatterPoint.svelte.d.ts} +3 -3
  305. package/dist/plot/{adaptive-density.d.ts → scatter/adaptive-density.d.ts} +14 -4
  306. package/dist/plot/{adaptive-density.js → scatter/adaptive-density.js} +46 -20
  307. package/dist/plot/{binned-scatter-types.d.ts → scatter/binned-scatter-types.d.ts} +5 -12
  308. package/dist/plot/scatter/index.d.ts +7 -0
  309. package/dist/plot/scatter/index.js +5 -0
  310. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  311. package/dist/plot/scatter/scatter-data.js +212 -0
  312. package/dist/plot/{ScatterPlot3D.svelte → scatter-3d/ScatterPlot3D.svelte} +25 -34
  313. package/dist/plot/{ScatterPlot3D.svelte.d.ts → scatter-3d/ScatterPlot3D.svelte.d.ts} +9 -17
  314. package/dist/plot/{ScatterPlot3DControls.svelte → scatter-3d/ScatterPlot3DControls.svelte} +14 -14
  315. package/dist/plot/{ScatterPlot3DControls.svelte.d.ts → scatter-3d/ScatterPlot3DControls.svelte.d.ts} +6 -6
  316. package/dist/plot/{ScatterPlot3DScene.svelte → scatter-3d/ScatterPlot3DScene.svelte} +129 -128
  317. package/dist/plot/{ScatterPlot3DScene.svelte.d.ts → scatter-3d/ScatterPlot3DScene.svelte.d.ts} +6 -15
  318. package/dist/plot/{Surface3D.svelte → scatter-3d/Surface3D.svelte} +7 -6
  319. package/dist/plot/{Surface3D.svelte.d.ts → scatter-3d/Surface3D.svelte.d.ts} +5 -4
  320. package/dist/plot/scatter-3d/index.d.ts +4 -0
  321. package/dist/plot/scatter-3d/index.js +4 -0
  322. package/dist/plot/sunburst/Sunburst.svelte +1041 -0
  323. package/dist/plot/sunburst/Sunburst.svelte.d.ts +97 -0
  324. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  325. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  326. package/dist/plot/sunburst/index.d.ts +4 -0
  327. package/dist/plot/sunburst/index.js +4 -0
  328. package/dist/plot/sunburst/render.d.ts +34 -0
  329. package/dist/plot/sunburst/render.js +122 -0
  330. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  331. package/dist/plot/sunburst/sunburst.js +269 -0
  332. package/dist/rdf/RdfPlot.svelte +2 -1
  333. package/dist/rdf/RdfPlot.svelte.d.ts +1 -1
  334. package/dist/rdf/calc-rdf.js +11 -24
  335. package/dist/sanitize.js +14 -3
  336. package/dist/scene/SceneCamera.svelte +62 -0
  337. package/dist/scene/SceneCamera.svelte.d.ts +19 -0
  338. package/dist/scene/bind-renderer.svelte.d.ts +2 -0
  339. package/dist/scene/bind-renderer.svelte.js +14 -0
  340. package/dist/scene/index.d.ts +4 -0
  341. package/dist/scene/index.js +5 -0
  342. package/dist/scene/props.js +52 -0
  343. package/dist/scene/types.d.ts +26 -0
  344. package/dist/scene/types.js +1 -0
  345. package/dist/settings.d.ts +79 -3
  346. package/dist/settings.js +321 -1
  347. package/dist/spectral/Bands.svelte +47 -36
  348. package/dist/spectral/Bands.svelte.d.ts +6 -6
  349. package/dist/spectral/BandsAndDos.svelte +23 -25
  350. package/dist/spectral/BrillouinBandsDos.svelte +42 -30
  351. package/dist/spectral/Dos.svelte +15 -23
  352. package/dist/spectral/Dos.svelte.d.ts +4 -3
  353. package/dist/spectral/helpers.d.ts +8 -6
  354. package/dist/spectral/helpers.js +137 -65
  355. package/dist/state.svelte.d.ts +0 -7
  356. package/dist/state.svelte.js +0 -6
  357. package/dist/structure/Arrow.svelte +2 -4
  358. package/dist/structure/AtomLegend.svelte +8 -9
  359. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  360. package/dist/structure/CanvasTooltip.svelte +1 -0
  361. package/dist/structure/CellSelect.svelte +12 -5
  362. package/dist/structure/CellSelect.svelte.d.ts +2 -1
  363. package/dist/structure/Cylinder.svelte +12 -8
  364. package/dist/structure/Cylinder.svelte.d.ts +4 -1
  365. package/dist/structure/Lattice.svelte +2 -2
  366. package/dist/structure/Structure.svelte +365 -423
  367. package/dist/structure/Structure.svelte.d.ts +5 -15
  368. package/dist/structure/StructureControls.svelte +217 -2
  369. package/dist/structure/StructureControls.svelte.d.ts +5 -3
  370. package/dist/structure/StructureExportPane.svelte +54 -156
  371. package/dist/structure/StructureExportPane.svelte.d.ts +4 -5
  372. package/dist/structure/StructureInfoPane.svelte +10 -9
  373. package/dist/structure/StructureInfoPane.svelte.d.ts +5 -5
  374. package/dist/structure/StructureScene.svelte +376 -208
  375. package/dist/structure/StructureScene.svelte.d.ts +22 -20
  376. package/dist/structure/{label-placement.d.ts → atom-label-placement.d.ts} +3 -3
  377. package/dist/structure/{label-placement.js → atom-label-placement.js} +15 -5
  378. package/dist/structure/atom-properties.d.ts +1 -1
  379. package/dist/structure/atom-properties.js +17 -22
  380. package/dist/structure/bond-order-perception.js +3 -5
  381. package/dist/structure/bonding.d.ts +4 -0
  382. package/dist/structure/bonding.js +134 -63
  383. package/dist/structure/export.d.ts +24 -4
  384. package/dist/structure/export.js +89 -143
  385. package/dist/structure/index.d.ts +4 -4
  386. package/dist/structure/index.js +3 -3
  387. package/dist/structure/measure.d.ts +3 -2
  388. package/dist/structure/measure.js +6 -5
  389. package/dist/structure/parse.d.ts +3 -2
  390. package/dist/structure/parse.js +419 -438
  391. package/dist/structure/partial-occupancy.d.ts +0 -1
  392. package/dist/structure/partial-occupancy.js +1 -1
  393. package/dist/structure/pbc.d.ts +1 -1
  394. package/dist/structure/pbc.js +190 -13
  395. package/dist/structure/polyhedra.d.ts +41 -0
  396. package/dist/structure/polyhedra.js +602 -0
  397. package/dist/structure/site.d.ts +4 -0
  398. package/dist/structure/site.js +1 -0
  399. package/dist/structure/supercell.js +3 -2
  400. package/dist/structure/validation.js +5 -6
  401. package/dist/symmetry/SymmetryElementControls.svelte +69 -0
  402. package/dist/symmetry/SymmetryElementControls.svelte.d.ts +9 -0
  403. package/dist/symmetry/SymmetryElements.svelte +354 -0
  404. package/dist/symmetry/SymmetryElements.svelte.d.ts +24 -0
  405. package/dist/symmetry/SymmetryStats.svelte +113 -8
  406. package/dist/symmetry/WyckoffTable.svelte +68 -7
  407. package/dist/symmetry/WyckoffTable.svelte.d.ts +3 -0
  408. package/dist/symmetry/cell-transform.js +7 -14
  409. package/dist/symmetry/index.d.ts +14 -4
  410. package/dist/symmetry/index.js +291 -72
  411. package/dist/symmetry/spacegroups.d.ts +12 -1
  412. package/dist/symmetry/spacegroups.js +63 -14
  413. package/dist/symmetry/symmetry-elements.d.ts +33 -0
  414. package/dist/symmetry/symmetry-elements.js +521 -0
  415. package/dist/symmetry/wyckoff-db.d.ts +9 -0
  416. package/dist/symmetry/wyckoff-db.js +87 -0
  417. package/dist/table/HeatmapTable.svelte +66 -25
  418. package/dist/table/HeatmapTable.svelte.d.ts +1 -1
  419. package/dist/table/index.d.ts +1 -3
  420. package/dist/table/index.js +1 -1
  421. package/dist/theme/index.js +8 -8
  422. package/dist/tooltip/KCoords.svelte +45 -0
  423. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  424. package/dist/tooltip/index.d.ts +1 -0
  425. package/dist/tooltip/index.js +1 -0
  426. package/dist/trajectory/Trajectory.svelte +123 -100
  427. package/dist/trajectory/Trajectory.svelte.d.ts +11 -22
  428. package/dist/trajectory/TrajectoryExportPane.svelte +17 -25
  429. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +4 -5
  430. package/dist/trajectory/TrajectoryInfoPane.svelte +5 -3
  431. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +3 -2
  432. package/dist/trajectory/constants.js +6 -2
  433. package/dist/trajectory/extract.js +17 -37
  434. package/dist/trajectory/format-detect.d.ts +1 -1
  435. package/dist/trajectory/format-detect.js +27 -19
  436. package/dist/trajectory/frame-reader.d.ts +0 -1
  437. package/dist/trajectory/frame-reader.js +63 -162
  438. package/dist/trajectory/helpers.d.ts +10 -2
  439. package/dist/trajectory/helpers.js +56 -36
  440. package/dist/trajectory/index.js +1 -1
  441. package/dist/trajectory/parse/ase.d.ts +9 -1
  442. package/dist/trajectory/parse/ase.js +47 -32
  443. package/dist/trajectory/parse/diagnostics.d.ts +3 -0
  444. package/dist/trajectory/parse/diagnostics.js +14 -0
  445. package/dist/trajectory/parse/hdf5.js +1 -1
  446. package/dist/trajectory/parse/index.d.ts +1 -1
  447. package/dist/trajectory/parse/index.js +65 -105
  448. package/dist/trajectory/parse/lammps.d.ts +0 -2
  449. package/dist/trajectory/parse/lammps.js +8 -6
  450. package/dist/trajectory/parse/pymatgen.d.ts +2 -0
  451. package/dist/trajectory/parse/pymatgen.js +74 -0
  452. package/dist/trajectory/parse/vasp.js +38 -18
  453. package/dist/trajectory/parse/xyz.d.ts +13 -1
  454. package/dist/trajectory/parse/xyz.js +102 -94
  455. package/dist/trajectory/plotting.d.ts +1 -2
  456. package/dist/trajectory/plotting.js +16 -113
  457. package/dist/utils.d.ts +2 -0
  458. package/dist/utils.js +7 -5
  459. package/dist/xrd/XrdPlot.svelte +16 -30
  460. package/dist/xrd/broadening.d.ts +2 -1
  461. package/dist/xrd/calc-xrd.js +18 -20
  462. package/dist/xrd/index.d.ts +2 -2
  463. package/dist/xrd/parse.js +2 -2
  464. package/package.json +43 -26
  465. package/dist/element/data.json +0 -11864
  466. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  467. package/dist/fermi-surface/marching-cubes.js +0 -2
  468. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  469. package/dist/plot/axis-utils.d.ts +0 -19
  470. package/dist/plot/axis-utils.js +0 -78
  471. package/dist/plot/defaults.d.ts +0 -19
  472. package/dist/plot/defaults.js +0 -9
  473. package/dist/plot/fill-utils.d.ts +0 -46
  474. package/dist/plot/fill-utils.js +0 -322
  475. package/dist/plot/hover-lock.svelte.d.ts +0 -14
  476. package/dist/plot/hover-lock.svelte.js +0 -46
  477. package/dist/plot/interactions.d.ts +0 -12
  478. package/dist/plot/interactions.js +0 -101
  479. package/dist/plot/scales.d.ts +0 -48
  480. package/dist/plot/svg.d.ts +0 -1
  481. package/dist/plot/svg.js +0 -11
  482. package/dist/plot/utils/series-visibility.d.ts +0 -15
  483. package/dist/plot/utils.d.ts +0 -1
  484. package/dist/plot/utils.js +0 -14
  485. /package/dist/plot/{PortalSelect.svelte.d.ts → core/components/PortalSelect.svelte.d.ts} +0 -0
  486. /package/dist/plot/{binned-scatter-types.js → scatter/binned-scatter-types.js} +0 -0
@@ -0,0 +1,697 @@
1
+ <script
2
+ lang="ts"
3
+ generics="Metadata extends Record<string, unknown> = Record<string, unknown>"
4
+ >
5
+ import { format_value } from '../../labels'
6
+ import { FullscreenToggle, set_fullscreen_bg } from '../../layout'
7
+ import type {
8
+ BasePlotProps,
9
+ LegendConfig,
10
+ LegendItem,
11
+ SankeyData,
12
+ SankeyHandlerProps,
13
+ SankeyLinkColorMode,
14
+ SankeyLinkHandlerProps,
15
+ SankeyNodeAlign,
16
+ SankeyNodeHandlerProps,
17
+ SankeyOrientation,
18
+ } from '..'
19
+ import { DEFAULT_SERIES_COLORS, PlotLegend, PlotTooltip, SankeyControls } from '..'
20
+ import { closest_data_idx } from '../core/interactions'
21
+ import { compute_element_placement, constrain_tooltip_position, filter_padding } from '../core/layout'
22
+ import type { Sides } from '../core/layout'
23
+ import { compute_sankey_layout } from './sankey'
24
+ import type { PositionedLink, PositionedNode} from './sankey'
25
+ import { unique_id } from '../core/utils'
26
+ import { DEFAULTS } from '../../settings'
27
+ import { type Snippet, untrack } from 'svelte'
28
+ import type { HTMLAttributes } from 'svelte/elements'
29
+ import { SvelteSet } from 'svelte/reactivity'
30
+
31
+ const DEFAULT_PADDING: Required<Sides> = { t: 20, b: 20, l: 10, r: 10 }
32
+
33
+ let {
34
+ data = $bindable({ nodes: [], links: [] }),
35
+ orientation = $bindable(DEFAULTS.sankey.orientation),
36
+ node_width = $bindable(DEFAULTS.sankey.node_width),
37
+ node_padding = $bindable(DEFAULTS.sankey.node_padding),
38
+ node_align = $bindable(DEFAULTS.sankey.node_align),
39
+ iterations = DEFAULTS.sankey.iterations,
40
+ link_opacity = $bindable(DEFAULTS.sankey.link_opacity),
41
+ link_color_mode = `source`,
42
+ show_node_labels = $bindable(DEFAULTS.sankey.show_node_labels),
43
+ node_label,
44
+ value_format = `,`,
45
+ padding = DEFAULT_PADDING,
46
+ legend = {},
47
+ show_legend = false,
48
+ tooltip,
49
+ node_content,
50
+ link_content,
51
+ hovered = $bindable(false),
52
+ change = () => {},
53
+ on_node_click,
54
+ on_node_hover,
55
+ on_link_click,
56
+ on_link_hover,
57
+ show_controls = $bindable(true),
58
+ controls_open = $bindable(false),
59
+ controls_toggle_props,
60
+ controls_pane_props,
61
+ fullscreen = $bindable(false),
62
+ fullscreen_toggle = true,
63
+ children,
64
+ header_controls,
65
+ controls_extra,
66
+ ...rest
67
+ }: HTMLAttributes<HTMLDivElement> & Omit<BasePlotProps, `change`> & {
68
+ data?: SankeyData<Metadata>
69
+ orientation?: SankeyOrientation
70
+ node_width?: number
71
+ node_padding?: number
72
+ node_align?: SankeyNodeAlign
73
+ iterations?: number
74
+ link_opacity?: number
75
+ link_color_mode?: SankeyLinkColorMode
76
+ show_node_labels?: boolean
77
+ node_label?: (node: PositionedNode) => string
78
+ value_format?: string
79
+ padding?: Sides
80
+ legend?: LegendConfig | null
81
+ show_legend?: boolean
82
+ tooltip?: Snippet<[SankeyHandlerProps<Metadata>]>
83
+ // Fully replace the default node rect / link ribbon. NOTE: this also replaces the
84
+ // built-in hover/focus/click + tooltip wiring, so re-implement any interactivity
85
+ // you need inside the snippet.
86
+ node_content?: Snippet<[{ node: PositionedNode; color: string }]>
87
+ link_content?: Snippet<[{ link: PositionedLink; color: string }]>
88
+ change?: (data: SankeyHandlerProps<Metadata> | null) => void
89
+ on_node_click?: (
90
+ data: SankeyNodeHandlerProps<Metadata> & { event: MouseEvent | KeyboardEvent },
91
+ ) => void
92
+ on_node_hover?: (
93
+ data:
94
+ | (SankeyNodeHandlerProps<Metadata> & { event: MouseEvent | FocusEvent })
95
+ | null,
96
+ ) => void
97
+ on_link_click?: (
98
+ data: SankeyLinkHandlerProps<Metadata> & { event: MouseEvent | KeyboardEvent },
99
+ ) => void
100
+ on_link_hover?: (
101
+ data:
102
+ | (SankeyLinkHandlerProps<Metadata> & { event: MouseEvent | FocusEvent })
103
+ | null,
104
+ ) => void
105
+ header_controls?: Snippet<[{ height: number; width: number; fullscreen: boolean }]>
106
+ controls_extra?: Snippet<[{ orientation: SankeyOrientation }]>
107
+ } = $props()
108
+
109
+ let [width, height] = $state([0, 0])
110
+ let wrapper: HTMLDivElement | undefined = $state()
111
+ let svg_element: SVGSVGElement | null = $state(null)
112
+ let tooltip_el = $state<HTMLDivElement | undefined>()
113
+ // Unique per-instance prefix for gradient ids (collision-resistant, see unique_id)
114
+ const uid = unique_id(`sankey`)
115
+
116
+ let hovered_node = $state<number | null>(null)
117
+ let hovered_link = $state<number | null>(null)
118
+ let hover_info = $state<SankeyHandlerProps<Metadata> | null>(null)
119
+ let hover_pos = $state<{ x: number; y: number }>({ x: 0, y: 0 })
120
+ // Nodes muted via legend toggle (dimmed, not removed - keeps layout stable)
121
+ let muted_nodes = new SvelteSet<string | number>()
122
+
123
+ let pad = $derived(filter_padding(padding, DEFAULT_PADDING))
124
+ let inner_width = $derived(Math.max(0, width - pad.l - pad.r))
125
+ let inner_height = $derived(Math.max(0, height - pad.t - pad.b))
126
+
127
+ // Resolved node colors (per node_idx), explicit color or cycled palette
128
+ let node_colors = $derived(
129
+ data.nodes.map((node, idx) =>
130
+ node.color ?? DEFAULT_SERIES_COLORS[idx % DEFAULT_SERIES_COLORS.length]
131
+ ),
132
+ )
133
+
134
+ // Drop muted ids that no longer exist when data changes (untrack avoids a
135
+ // self-trigger loop from reading/writing muted_nodes in the same effect).
136
+ $effect(() => {
137
+ const valid = new Set(data.nodes.map((node, idx) => node.id ?? idx))
138
+ untrack(() => {
139
+ for (const id of muted_nodes) if (!valid.has(id)) muted_nodes.delete(id)
140
+ })
141
+ })
142
+
143
+ // Degrade to an empty layout (instead of crashing the host page) when the graph
144
+ // is invalid, e.g. contains a cycle. The thrown error is surfaced via console.error.
145
+ let layout = $derived.by(() => {
146
+ try {
147
+ return compute_sankey_layout(data, {
148
+ width: inner_width,
149
+ height: inner_height,
150
+ node_width,
151
+ node_padding,
152
+ node_align,
153
+ orientation,
154
+ iterations,
155
+ })
156
+ } catch (err) {
157
+ console.error(err)
158
+ return { nodes: [], links: [] }
159
+ }
160
+ })
161
+
162
+ // node_idx -> positioned node (array order is preserved by d3-sankey, but map is safer)
163
+ let node_by_idx = $derived(
164
+ new Map(layout.nodes.map((node) => [node.node_idx, node])),
165
+ )
166
+
167
+ const node_id_at = (node_idx: number): string | number =>
168
+ node_by_idx.get(node_idx)?.id ?? node_idx
169
+
170
+ // Node box center in container (pad-offset) pixel space, for tooltip + legend placement
171
+ const node_center = (node: PositionedNode): { x: number; y: number } => ({
172
+ x: pad.l + (node.x0 + node.x1) / 2,
173
+ y: pad.t + (node.y0 + node.y1) / 2,
174
+ })
175
+
176
+ // Resolve a link's ribbon color from explicit color or the active color mode
177
+ const link_color = (link: PositionedLink): string => {
178
+ if (link.color) return link.color
179
+ const src = node_colors[link.source.node_idx]
180
+ const tgt = node_colors[link.target.node_idx]
181
+ if (link_color_mode === `target`) return tgt
182
+ if (link_color_mode === `gradient`) return `url(#${uid}-grad-${link.link_idx})`
183
+ if (link_color_mode === `static`) return `var(--sankey-link-color, #888)`
184
+ return src
185
+ }
186
+
187
+ // Set of node/link indices to keep fully opaque given the current hover target
188
+ let active = $derived.by(() => {
189
+ if (hovered_node != null) {
190
+ const node = node_by_idx.get(hovered_node)
191
+ if (!node) return null
192
+ const link_set = new SvelteSet<number>()
193
+ const node_set = new SvelteSet<number>([hovered_node])
194
+ for (const link of [...(node.sourceLinks ?? []), ...(node.targetLinks ?? [])]) {
195
+ link_set.add((link as PositionedLink).link_idx)
196
+ node_set.add((link.source as PositionedNode).node_idx)
197
+ node_set.add((link.target as PositionedNode).node_idx)
198
+ }
199
+ return { links: link_set, nodes: node_set }
200
+ }
201
+ if (hovered_link != null) {
202
+ const link = layout.links[hovered_link]
203
+ if (!link) return null
204
+ return {
205
+ links: new SvelteSet([hovered_link]),
206
+ nodes: new SvelteSet([link.source.node_idx, link.target.node_idx]),
207
+ }
208
+ }
209
+ return null
210
+ })
211
+
212
+ const node_opacity = (node: PositionedNode): number => {
213
+ if (muted_nodes.has(node.id)) return 0.12
214
+ if (active && !active.nodes.has(node.node_idx)) return 0.3
215
+ return 1
216
+ }
217
+
218
+ const link_dim = (link: PositionedLink): boolean =>
219
+ muted_nodes.has(link.source.id) || muted_nodes.has(link.target.id)
220
+
221
+ const link_stroke_opacity = (link: PositionedLink): number => {
222
+ if (link_dim(link)) return link_opacity * 0.15
223
+ if (active) return active.links.has(link.link_idx) ? Math.min(1, link_opacity + 0.35) : link_opacity * 0.25
224
+ return link_opacity
225
+ }
226
+
227
+ const node_text = (node: PositionedNode): string =>
228
+ node_label?.(node) ?? node.label ?? `${node.id}`
229
+
230
+ function make_node_props(node: PositionedNode): SankeyNodeHandlerProps<Metadata> {
231
+ return {
232
+ type: `node`,
233
+ node_idx: node.node_idx,
234
+ id: node.id,
235
+ label: node.label,
236
+ value: node.value ?? 0,
237
+ color: node_colors[node.node_idx],
238
+ metadata: data.nodes[node.node_idx]?.metadata,
239
+ }
240
+ }
241
+
242
+ function make_link_props(link: PositionedLink): SankeyLinkHandlerProps<Metadata> {
243
+ return {
244
+ type: `link`,
245
+ link_idx: link.link_idx,
246
+ source_idx: link.source.node_idx,
247
+ target_idx: link.target.node_idx,
248
+ source_label: link.source.label,
249
+ target_label: link.target.label,
250
+ value: link.value,
251
+ color: link_color(link),
252
+ metadata: data.links[link.link_idx]?.metadata,
253
+ }
254
+ }
255
+
256
+ // Anchor the tooltip at the cursor (mouse hover) so it follows the pointer over wide nodes
257
+ // and long link ribbons; fall back to the element center on keyboard focus (no cursor).
258
+ function event_pos(event?: MouseEvent | FocusEvent): { x: number; y: number } | null {
259
+ if (event instanceof MouseEvent && svg_element) {
260
+ const rect = svg_element.getBoundingClientRect()
261
+ return { x: event.clientX - rect.left, y: event.clientY - rect.top }
262
+ }
263
+ return null
264
+ }
265
+
266
+ function set_node_hover(node: PositionedNode | null, event?: MouseEvent | FocusEvent) {
267
+ if (node) {
268
+ hovered = true
269
+ hovered_node = node.node_idx
270
+ hovered_link = null
271
+ hover_info = make_node_props(node)
272
+ hover_pos = event_pos(event) ?? node_center(node)
273
+ change(hover_info)
274
+ if (event) on_node_hover?.({ ...(hover_info as SankeyNodeHandlerProps<Metadata>), event })
275
+ } else {
276
+ hovered_node = null
277
+ hover_info = null
278
+ change(null)
279
+ on_node_hover?.(null)
280
+ }
281
+ }
282
+
283
+ function set_link_hover(link: PositionedLink | null, event?: MouseEvent | FocusEvent) {
284
+ if (link) {
285
+ hovered = true
286
+ hovered_link = link.link_idx
287
+ hovered_node = null
288
+ hover_info = make_link_props(link)
289
+ hover_pos = event_pos(event) ?? { x: pad.l + link.mid.x, y: pad.t + link.mid.y }
290
+ change(hover_info)
291
+ if (event) on_link_hover?.({ ...(hover_info as SankeyLinkHandlerProps<Metadata>), event })
292
+ } else {
293
+ hovered_link = null
294
+ hover_info = null
295
+ change(null)
296
+ on_link_hover?.(null)
297
+ }
298
+ }
299
+
300
+ const link_from_event = (event: Event): PositionedLink | null => {
301
+ const idx = closest_data_idx(event, `data-sankey-link-idx`, svg_element)
302
+ return idx == null ? null : layout.links[idx] ?? null
303
+ }
304
+
305
+ const node_from_event = (event: Event): PositionedNode | null => {
306
+ const idx = closest_data_idx(event, `data-sankey-node-idx`, svg_element)
307
+ return idx == null ? null : node_by_idx.get(idx) ?? null
308
+ }
309
+
310
+ function handle_link_hover_event(event: MouseEvent | FocusEvent) {
311
+ set_link_hover(link_from_event(event), event)
312
+ }
313
+
314
+ function handle_node_hover_event(event: MouseEvent | FocusEvent) {
315
+ set_node_hover(node_from_event(event), event)
316
+ }
317
+
318
+ function handle_link_click(event: MouseEvent | KeyboardEvent) {
319
+ const link = link_from_event(event)
320
+ if (link) on_link_click?.({ ...make_link_props(link), event })
321
+ }
322
+
323
+ function handle_node_click(event: MouseEvent | KeyboardEvent) {
324
+ const node = node_from_event(event)
325
+ if (node) on_node_click?.({ ...make_node_props(node), event })
326
+ }
327
+
328
+ function handle_link_keydown(event: KeyboardEvent) {
329
+ if (event.key !== `Enter` && event.key !== ` `) return
330
+ event.preventDefault()
331
+ handle_link_click(event)
332
+ }
333
+
334
+ function handle_node_keydown(event: KeyboardEvent) {
335
+ if (event.key !== `Enter` && event.key !== ` `) return
336
+ event.preventDefault()
337
+ handle_node_click(event)
338
+ }
339
+
340
+ // Legend: one item per node, toggling mutes (dims) rather than removing.
341
+ // Auto-place to avoid covering nodes (node box centers act as obstacle points).
342
+ let legend_element = $state<HTMLDivElement | undefined>()
343
+ let legend_placement = $derived.by(() => {
344
+ if (!show_legend || legend == null || data.nodes.length <= 1 || !width || !height) {
345
+ return null
346
+ }
347
+ return compute_element_placement({
348
+ plot_bounds: { x: pad.l, y: pad.t, width: inner_width, height: inner_height },
349
+ element: legend_element,
350
+ element_size: { width: 120, height: 60 },
351
+ axis_clearance: legend?.axis_clearance,
352
+ exclude_rects: [],
353
+ points: layout.nodes.map(node_center),
354
+ })
355
+ })
356
+ // Only nodes that survive the layout (orphans with no links are dropped, see
357
+ // compute_sankey_layout) - keeps the legend in sync with what's drawn.
358
+ let legend_data = $derived.by<LegendItem[]>(() =>
359
+ data.nodes
360
+ .map((node, idx) => ({ node, idx }))
361
+ .filter(({ idx }) => node_by_idx.has(idx))
362
+ .map(({ node, idx }) => ({
363
+ series_idx: idx,
364
+ label: node.label ?? `${node.id ?? idx}`,
365
+ visible: !muted_nodes.has(node.id ?? idx),
366
+ display_style: { symbol_type: `Square` as const, symbol_color: node_colors[idx] },
367
+ }))
368
+ )
369
+
370
+ function toggle_node(series_idx: number) {
371
+ const id = node_id_at(series_idx)
372
+ if (muted_nodes.has(id)) muted_nodes.delete(id)
373
+ else muted_nodes.add(id)
374
+ }
375
+
376
+ $effect(() => set_fullscreen_bg(wrapper, fullscreen, `--sankey-fullscreen-bg`))
377
+
378
+ // Node label placement: horizontal -> beside node; vertical -> above node
379
+ function label_attrs(node: PositionedNode) {
380
+ if (orientation === `vertical`) {
381
+ return {
382
+ x: (node.x0 + node.x1) / 2,
383
+ y: node.y0 - 4,
384
+ anchor: `middle` as const,
385
+ baseline: `auto` as const,
386
+ }
387
+ }
388
+ const left_half = (node.x0 + node.x1) / 2 < inner_width / 2
389
+ return {
390
+ x: left_half ? node.x1 + 6 : node.x0 - 6,
391
+ y: (node.y0 + node.y1) / 2,
392
+ anchor: (left_half ? `start` : `end`) as `start` | `end`,
393
+ baseline: `middle` as const,
394
+ }
395
+ }
396
+ </script>
397
+
398
+ <svelte:window
399
+ onkeydown={(evt) => {
400
+ if (evt.key === `Escape` && fullscreen) {
401
+ evt.preventDefault()
402
+ fullscreen = false
403
+ }
404
+ }}
405
+ />
406
+
407
+ <div
408
+ bind:this={wrapper}
409
+ bind:clientWidth={width}
410
+ bind:clientHeight={height}
411
+ {...rest}
412
+ class="sankey {rest.class ?? ``}"
413
+ class:fullscreen
414
+ >
415
+ {#if width && height}
416
+ <div class="header-controls">
417
+ {@render header_controls?.({ height, width, fullscreen })}
418
+ {#if fullscreen_toggle}
419
+ <FullscreenToggle bind:fullscreen />
420
+ {/if}
421
+ </div>
422
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
423
+ <svg
424
+ bind:this={svg_element}
425
+ role="application"
426
+ aria-label={rest[`aria-label`] ?? `Sankey diagram`}
427
+ onmouseleave={() => {
428
+ hovered = false
429
+ set_node_hover(null)
430
+ set_link_hover(null)
431
+ }}
432
+ >
433
+ {#if link_color_mode === `gradient`}
434
+ <defs>
435
+ {#each layout.links as link (link.link_idx)}
436
+ {@const src_color = node_colors[link.source.node_idx]}
437
+ {@const tgt_color = node_colors[link.target.node_idx]}
438
+ {@const vertical = orientation === `vertical`}
439
+ <linearGradient
440
+ id="{uid}-grad-{link.link_idx}"
441
+ gradientUnits="userSpaceOnUse"
442
+ x1={vertical ? link.mid.x : link.source.x1}
443
+ y1={vertical ? link.source.y1 : link.mid.y}
444
+ x2={vertical ? link.mid.x : link.target.x0}
445
+ y2={vertical ? link.target.y0 : link.mid.y}
446
+ >
447
+ <stop offset="0%" stop-color={src_color} />
448
+ <stop offset="100%" stop-color={tgt_color} />
449
+ </linearGradient>
450
+ {/each}
451
+ </defs>
452
+ {/if}
453
+
454
+ <g transform="translate({pad.l}, {pad.t})">
455
+ <!-- Links -->
456
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
457
+ <g
458
+ class="links"
459
+ fill="none"
460
+ onmousemove={handle_link_hover_event}
461
+ onmouseleave={() => set_link_hover(null)}
462
+ onfocusin={handle_link_hover_event}
463
+ onfocusout={() => set_link_hover(null)}
464
+ onclick={handle_link_click}
465
+ onkeydown={handle_link_keydown}
466
+ >
467
+ {#each layout.links as link (link.link_idx)}
468
+ {@const color = link_color(link)}
469
+ {#if link_content}
470
+ {@render link_content({ link, color })}
471
+ {:else}
472
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
473
+ <path
474
+ d={link.path}
475
+ data-sankey-link-idx={link.link_idx}
476
+ stroke={color}
477
+ stroke-width={Math.max(1, link.width)}
478
+ stroke-opacity={link_stroke_opacity(link)}
479
+ role={on_link_click ? `button` : undefined}
480
+ tabindex={on_link_click ? 0 : undefined}
481
+ aria-label={on_link_click
482
+ ? `flow ${link.source.label} to ${link.target.label}: ${link.value}`
483
+ : undefined}
484
+ style:cursor={on_link_click ? `pointer` : `default`}
485
+ />
486
+ {/if}
487
+ {/each}
488
+ </g>
489
+
490
+ <!-- Nodes -->
491
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
492
+ <g
493
+ class="nodes"
494
+ onmousemove={handle_node_hover_event}
495
+ onmouseleave={() => set_node_hover(null)}
496
+ onfocusin={handle_node_hover_event}
497
+ onfocusout={() => set_node_hover(null)}
498
+ onclick={handle_node_click}
499
+ onkeydown={handle_node_keydown}
500
+ >
501
+ {#each layout.nodes as node (node.node_idx)}
502
+ {@const color = node_colors[node.node_idx]}
503
+ <g class="node" style:opacity={node_opacity(node)}>
504
+ {#if node_content}
505
+ {@render node_content({ node, color })}
506
+ {:else}
507
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
508
+ <rect
509
+ data-sankey-node-idx={node.node_idx}
510
+ x={node.x0}
511
+ y={node.y0}
512
+ width={Math.max(0, node.x1 - node.x0)}
513
+ height={Math.max(0, node.y1 - node.y0)}
514
+ fill={color}
515
+ stroke="var(--sankey-node-stroke, rgba(0, 0, 0, 0.5))"
516
+ stroke-width="0.5"
517
+ rx="1"
518
+ role={on_node_click ? `button` : undefined}
519
+ tabindex={on_node_click ? 0 : undefined}
520
+ aria-label={on_node_click ? `${node.label ?? node.id}: ${node.value}` : undefined}
521
+ style:cursor={on_node_click ? `pointer` : `default`}
522
+ />
523
+ {/if}
524
+ {#if show_node_labels}
525
+ {@const lbl = label_attrs(node)}
526
+ <text
527
+ class="node-label"
528
+ x={lbl.x}
529
+ y={lbl.y}
530
+ text-anchor={lbl.anchor}
531
+ dominant-baseline={lbl.baseline}
532
+ >{node_text(node)}</text>
533
+ {/if}
534
+ </g>
535
+ {/each}
536
+ </g>
537
+ </g>
538
+ </svg>
539
+ {/if}
540
+
541
+ {#if hover_info}
542
+ {@const tip = constrain_tooltip_position(
543
+ hover_pos.x,
544
+ hover_pos.y,
545
+ tooltip_el?.offsetWidth ?? 140,
546
+ tooltip_el?.offsetHeight ?? 44,
547
+ width,
548
+ height,
549
+ { offset_x: 10, offset_y: 5 },
550
+ )}
551
+ <!-- Solid chip bg (PlotTooltip auto-contrasts text). Links use the source node
552
+ color so gradient/static ribbons (url(...)/var(...)) still get a readable color. -->
553
+ {@const tip_bg = hover_info.type === `node`
554
+ ? hover_info.color
555
+ : node_colors[hover_info.source_idx] ?? `rgba(0, 0, 0, 0.7)`}
556
+ <PlotTooltip
557
+ x={tip.x}
558
+ y={tip.y}
559
+ offset={{ x: 0, y: 0 }}
560
+ bg_color={tip_bg}
561
+ bind:wrapper={tooltip_el}
562
+ >
563
+ {#if tooltip}
564
+ {@render tooltip(hover_info)}
565
+ {:else if hover_info.type === `node`}
566
+ <strong>{hover_info.label ?? hover_info.id}</strong>: {
567
+ format_value(hover_info.value, value_format)
568
+ }
569
+ {:else}
570
+ {hover_info.source_label ?? hover_info.source_idx} &rarr; {
571
+ hover_info.target_label ?? hover_info.target_idx
572
+ }: {format_value(hover_info.value, value_format)}
573
+ {/if}
574
+ </PlotTooltip>
575
+ {/if}
576
+
577
+ {#if show_legend && legend != null && data.nodes.length > 1}
578
+ {@const legend_left = legend_placement?.x ?? pad.l + 10}
579
+ {@const legend_top = legend_placement?.y ?? pad.t + 10}
580
+ <PlotLegend
581
+ bind:root_element={legend_element}
582
+ {...legend}
583
+ series_data={legend_data}
584
+ on_toggle={legend?.on_toggle ?? toggle_node}
585
+ on_item_hover={(item) =>
586
+ (hovered_node = item != null && item.series_idx >= 0 ? item.series_idx : null)}
587
+ style={`position: absolute; left: ${legend_left}px; top: ${legend_top}px; pointer-events: auto; ${
588
+ legend?.style ?? ``
589
+ }`}
590
+ />
591
+ {/if}
592
+
593
+ {#if show_controls}
594
+ <SankeyControls
595
+ toggle_props={{
596
+ ...controls_toggle_props,
597
+ style: `--ctrl-btn-right: var(--fullscreen-btn-offset, 30px); ${
598
+ controls_toggle_props?.style ?? ``
599
+ }`,
600
+ }}
601
+ pane_props={controls_pane_props}
602
+ bind:show_controls
603
+ bind:controls_open
604
+ bind:orientation
605
+ bind:node_width
606
+ bind:node_padding
607
+ bind:node_align
608
+ bind:link_opacity
609
+ bind:show_node_labels
610
+ >
611
+ {@render controls_extra?.({ orientation })}
612
+ </SankeyControls>
613
+ {/if}
614
+
615
+ {@render children?.({ height, width, fullscreen })}
616
+ </div>
617
+
618
+ <style>
619
+ .sankey {
620
+ position: relative;
621
+ width: var(--sankey-width, 100%);
622
+ height: var(--sankey-height, auto);
623
+ min-height: var(--sankey-min-height, 300px);
624
+ container-type: size;
625
+ z-index: var(--sankey-z-index, auto);
626
+ flex: var(--sankey-flex, 1);
627
+ display: var(--sankey-display, flex);
628
+ flex-direction: column;
629
+ background: var(--sankey-bg, var(--plot-bg));
630
+ border-radius: var(--sankey-border-radius, var(--border-radius, 3pt));
631
+ }
632
+ .sankey.fullscreen {
633
+ position: fixed;
634
+ top: 0;
635
+ left: 0;
636
+ width: 100vw !important;
637
+ height: 100vh !important;
638
+ z-index: var(--sankey-fullscreen-z-index, var(--z-index-overlay-nav, 100000001));
639
+ margin: 0;
640
+ border-radius: 0;
641
+ background: var(--sankey-fullscreen-bg, var(--sankey-bg, var(--plot-bg)));
642
+ max-height: none !important;
643
+ overflow: hidden;
644
+ /* border-top (not padding-top): bind:clientHeight includes padding but excludes
645
+ borders - padding made the chart overflow + clip its bottom 2em (x-axis title) */
646
+ border-top: var(--plot-fullscreen-padding-top, 2em) solid
647
+ var(--sankey-fullscreen-bg, var(--sankey-bg, var(--plot-bg, transparent)));
648
+ box-sizing: border-box;
649
+ }
650
+ .header-controls {
651
+ position: absolute;
652
+ top: var(--ctrl-btn-top, 5pt);
653
+ right: var(--fullscreen-btn-right, 4px);
654
+ z-index: var(--fullscreen-btn-z-index, 10);
655
+ display: flex;
656
+ align-items: center;
657
+ gap: 8px;
658
+ }
659
+ .header-controls :global(.fullscreen-toggle) {
660
+ position: static;
661
+ opacity: 1;
662
+ }
663
+ .sankey :global(.pane-toggle),
664
+ .sankey .header-controls {
665
+ opacity: 0;
666
+ transition: opacity 0.2s, background-color 0.2s;
667
+ }
668
+ .sankey:hover :global(.pane-toggle),
669
+ .sankey:hover .header-controls,
670
+ .sankey :global(.pane-toggle:focus-visible),
671
+ .sankey :global(.pane-toggle[aria-expanded='true']),
672
+ .sankey .header-controls:focus-within {
673
+ opacity: 1;
674
+ }
675
+ svg {
676
+ width: var(--sankey-svg-width, 100%);
677
+ height: var(--sankey-svg-height, 100%);
678
+ flex: var(--sankey-svg-flex, 1);
679
+ overflow: var(--sankey-svg-overflow, visible);
680
+ fill: var(--text-color);
681
+ font-size: var(--sankey-font-size, 11px);
682
+ }
683
+ .links path {
684
+ transition: stroke-opacity 0.15s ease;
685
+ }
686
+ .node {
687
+ transition: opacity 0.15s ease;
688
+ }
689
+ .node-label {
690
+ fill: var(--text-color);
691
+ pointer-events: none;
692
+ paint-order: stroke;
693
+ stroke: var(--sankey-label-halo, var(--plot-bg, white));
694
+ stroke-width: var(--sankey-label-halo-width, 3px);
695
+ stroke-linejoin: round;
696
+ }
697
+ </style>