matterviz 0.3.6 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (926) hide show
  1. package/dist/EmptyState.svelte.d.ts +9 -0
  2. package/dist/FilePicker.svelte +360 -0
  3. package/dist/FilePicker.svelte.d.ts +17 -0
  4. package/dist/Icon.svelte +44 -0
  5. package/dist/Icon.svelte.d.ts +13 -0
  6. package/dist/MillerIndexInput.svelte +66 -0
  7. package/dist/MillerIndexInput.svelte.d.ts +7 -0
  8. package/dist/api/mp.d.ts +6 -0
  9. package/dist/api/mp.js +22 -0
  10. package/dist/api/optimade.d.ts +45 -0
  11. package/dist/api/optimade.js +141 -0
  12. package/dist/app.css +244 -0
  13. package/dist/brillouin/BrillouinZone.svelte +554 -0
  14. package/dist/brillouin/BrillouinZone.svelte.d.ts +84 -0
  15. package/dist/brillouin/BrillouinZoneControls.svelte +144 -0
  16. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +17 -0
  17. package/dist/brillouin/BrillouinZoneExportPane.svelte +146 -0
  18. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +15 -0
  19. package/dist/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  20. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +13 -0
  21. package/dist/brillouin/BrillouinZoneScene.svelte +522 -0
  22. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +49 -0
  23. package/dist/brillouin/BrillouinZoneTooltip.svelte +83 -0
  24. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +8 -0
  25. package/dist/brillouin/compute.d.ts +17 -0
  26. package/dist/brillouin/compute.js +422 -0
  27. package/dist/brillouin/index.d.ts +8 -0
  28. package/dist/brillouin/index.js +7 -0
  29. package/dist/brillouin/types.d.ts +43 -0
  30. package/dist/brillouin/types.js +1 -0
  31. package/dist/chempot-diagram/ChemPotDiagram.svelte +328 -0
  32. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  33. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +843 -0
  34. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  35. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3191 -0
  36. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  37. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  38. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  39. package/dist/chempot-diagram/async-compute.svelte.js +80 -0
  40. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  41. package/dist/chempot-diagram/chempot-worker.js +12 -0
  42. package/dist/chempot-diagram/color.d.ts +10 -0
  43. package/dist/chempot-diagram/color.js +32 -0
  44. package/dist/chempot-diagram/compute.d.ts +48 -0
  45. package/dist/chempot-diagram/compute.js +804 -0
  46. package/dist/chempot-diagram/index.d.ts +6 -0
  47. package/dist/chempot-diagram/index.js +6 -0
  48. package/dist/chempot-diagram/pointer.d.ts +16 -0
  49. package/dist/chempot-diagram/pointer.js +40 -0
  50. package/dist/chempot-diagram/temperature.d.ts +15 -0
  51. package/dist/chempot-diagram/temperature.js +34 -0
  52. package/dist/chempot-diagram/types.d.ts +81 -0
  53. package/dist/chempot-diagram/types.js +28 -0
  54. package/dist/colors/index.d.ts +47 -0
  55. package/dist/colors/index.js +204 -0
  56. package/dist/composition/BarChart.svelte +297 -0
  57. package/dist/composition/BarChart.svelte.d.ts +39 -0
  58. package/dist/composition/BubbleChart.svelte +218 -0
  59. package/dist/composition/BubbleChart.svelte.d.ts +28 -0
  60. package/dist/composition/Composition.svelte +165 -0
  61. package/dist/composition/Composition.svelte.d.ts +15 -0
  62. package/dist/composition/Formula.svelte +268 -0
  63. package/dist/composition/Formula.svelte.d.ts +19 -0
  64. package/dist/composition/FormulaFilter.svelte +1263 -0
  65. package/dist/composition/FormulaFilter.svelte.d.ts +51 -0
  66. package/dist/composition/PieChart.svelte +324 -0
  67. package/dist/composition/PieChart.svelte.d.ts +37 -0
  68. package/dist/composition/chem-sys.d.ts +8 -0
  69. package/dist/composition/chem-sys.js +85 -0
  70. package/dist/composition/format.d.ts +15 -0
  71. package/dist/composition/format.js +111 -0
  72. package/dist/composition/index.d.ts +21 -0
  73. package/dist/composition/index.js +15 -0
  74. package/dist/composition/parse.d.ts +56 -0
  75. package/dist/composition/parse.js +486 -0
  76. package/dist/constants.d.ts +29 -0
  77. package/dist/constants.js +99 -0
  78. package/dist/controls.d.ts +14 -0
  79. package/dist/controls.js +30 -0
  80. package/dist/convex-hull/ConvexHull.svelte +157 -0
  81. package/dist/convex-hull/ConvexHull.svelte.d.ts +13 -0
  82. package/dist/convex-hull/ConvexHull2D.svelte +827 -0
  83. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +11 -0
  84. package/dist/convex-hull/ConvexHull3D.svelte +1801 -0
  85. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +8 -0
  86. package/dist/convex-hull/ConvexHull4D.svelte +1394 -0
  87. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +8 -0
  88. package/dist/convex-hull/ConvexHullControls.svelte +535 -0
  89. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +48 -0
  90. package/dist/convex-hull/ConvexHullInfoPane.svelte +125 -0
  91. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +20 -0
  92. package/dist/convex-hull/ConvexHullStats.svelte +929 -0
  93. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +17 -0
  94. package/dist/convex-hull/ConvexHullTooltip.svelte +131 -0
  95. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +33 -0
  96. package/dist/convex-hull/GasPressureControls.svelte +247 -0
  97. package/dist/convex-hull/GasPressureControls.svelte.d.ts +11 -0
  98. package/dist/convex-hull/StructurePopup.svelte +151 -0
  99. package/dist/convex-hull/StructurePopup.svelte.d.ts +18 -0
  100. package/dist/convex-hull/TemperatureSlider.svelte +140 -0
  101. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +8 -0
  102. package/dist/convex-hull/barycentric-coords.d.ts +18 -0
  103. package/dist/convex-hull/barycentric-coords.js +182 -0
  104. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  105. package/dist/convex-hull/demo-temperature.js +38 -0
  106. package/dist/convex-hull/gas-thermodynamics.d.ts +16 -0
  107. package/dist/convex-hull/gas-thermodynamics.js +306 -0
  108. package/dist/convex-hull/helpers.d.ts +117 -0
  109. package/dist/convex-hull/helpers.js +718 -0
  110. package/dist/convex-hull/index.d.ts +119 -0
  111. package/dist/convex-hull/index.js +58 -0
  112. package/dist/convex-hull/thermodynamics.d.ts +67 -0
  113. package/dist/convex-hull/thermodynamics.js +1757 -0
  114. package/dist/convex-hull/types.d.ts +162 -0
  115. package/dist/convex-hull/types.js +36 -0
  116. package/dist/coordination/CoordinationBarPlot.svelte +311 -0
  117. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +30 -0
  118. package/dist/coordination/calc-coordination.d.ts +15 -0
  119. package/dist/coordination/calc-coordination.js +63 -0
  120. package/dist/coordination/index.d.ts +8 -0
  121. package/dist/coordination/index.js +7 -0
  122. package/dist/effects.svelte.d.ts +12 -0
  123. package/dist/effects.svelte.js +37 -0
  124. package/dist/element/BohrAtom.svelte.d.ts +20 -0
  125. package/dist/element/ElementHeading.svelte +26 -0
  126. package/dist/element/ElementHeading.svelte.d.ts +8 -0
  127. package/dist/element/ElementPhoto.svelte +57 -0
  128. package/dist/element/ElementPhoto.svelte.d.ts +9 -0
  129. package/dist/element/ElementStats.svelte +80 -0
  130. package/dist/element/ElementStats.svelte.d.ts +8 -0
  131. package/dist/element/ElementTile.svelte +484 -0
  132. package/dist/element/ElementTile.svelte.d.ts +29 -0
  133. package/dist/element/Nucleus.svelte.d.ts +17 -0
  134. package/dist/element/data.d.ts +2 -0
  135. package/dist/element/data.js +2 -0
  136. package/dist/element/index.d.ts +8 -0
  137. package/dist/element/index.js +7 -0
  138. package/dist/element/types.d.ts +57 -0
  139. package/dist/element/types.js +1 -0
  140. package/dist/feedback/ClickFeedback.svelte +58 -0
  141. package/dist/feedback/ClickFeedback.svelte.d.ts +12 -0
  142. package/dist/feedback/DragOverlay.svelte +42 -0
  143. package/dist/feedback/DragOverlay.svelte.d.ts +7 -0
  144. package/dist/feedback/Spinner.svelte.d.ts +7 -0
  145. package/dist/feedback/StatusMessage.svelte.d.ts +9 -0
  146. package/dist/feedback/index.d.ts +4 -0
  147. package/dist/feedback/index.js +4 -0
  148. package/dist/fermi-surface/FermiSlice.svelte +197 -0
  149. package/dist/fermi-surface/FermiSlice.svelte.d.ts +24 -0
  150. package/dist/fermi-surface/FermiSurface.svelte +606 -0
  151. package/dist/fermi-surface/FermiSurface.svelte.d.ts +83 -0
  152. package/dist/fermi-surface/FermiSurfaceControls.svelte +448 -0
  153. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +35 -0
  154. package/dist/fermi-surface/FermiSurfaceScene.svelte +797 -0
  155. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +50 -0
  156. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +85 -0
  157. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +8 -0
  158. package/dist/fermi-surface/compute.d.ts +5 -0
  159. package/dist/fermi-surface/compute.js +538 -0
  160. package/dist/fermi-surface/constants.d.ts +9 -0
  161. package/dist/fermi-surface/constants.js +27 -0
  162. package/dist/fermi-surface/export.d.ts +5 -0
  163. package/dist/fermi-surface/export.js +51 -0
  164. package/dist/fermi-surface/index.d.ts +12 -0
  165. package/dist/fermi-surface/index.js +13 -0
  166. package/dist/fermi-surface/marching-cubes.d.ts +2 -0
  167. package/dist/fermi-surface/marching-cubes.js +2 -0
  168. package/dist/fermi-surface/parse.d.ts +2 -0
  169. package/dist/fermi-surface/parse.js +494 -0
  170. package/dist/fermi-surface/symmetry.d.ts +3 -0
  171. package/dist/fermi-surface/symmetry.js +46 -0
  172. package/dist/fermi-surface/types.d.ts +111 -0
  173. package/dist/fermi-surface/types.js +4 -0
  174. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1547 -0
  175. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  176. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  177. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  178. package/dist/heatmap-matrix/index.d.ts +53 -0
  179. package/dist/heatmap-matrix/index.js +100 -0
  180. package/dist/heatmap-matrix/shared.d.ts +2 -0
  181. package/dist/heatmap-matrix/shared.js +4 -0
  182. package/dist/icons.d.ts +569 -0
  183. package/dist/icons.js +648 -0
  184. package/dist/index.d.ts +39 -0
  185. package/dist/index.js +39 -0
  186. package/dist/io/decompress.d.ts +11 -0
  187. package/dist/io/decompress.js +76 -0
  188. package/dist/io/export.d.ts +16 -0
  189. package/dist/io/export.js +338 -0
  190. package/dist/io/fetch.d.ts +5 -0
  191. package/dist/io/fetch.js +43 -0
  192. package/dist/io/file-drop.d.ts +7 -0
  193. package/dist/io/file-drop.js +42 -0
  194. package/dist/io/index.d.ts +7 -0
  195. package/dist/io/index.js +6 -0
  196. package/dist/io/is-binary.d.ts +1 -0
  197. package/dist/io/is-binary.js +20 -0
  198. package/dist/io/types.d.ts +8 -0
  199. package/dist/io/types.js +1 -0
  200. package/dist/io/url-drop.d.ts +2 -0
  201. package/dist/io/url-drop.js +154 -0
  202. package/dist/isosurface/Isosurface.svelte +285 -0
  203. package/dist/isosurface/Isosurface.svelte.d.ts +8 -0
  204. package/dist/isosurface/IsosurfaceControls.svelte +277 -0
  205. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +9 -0
  206. package/dist/isosurface/index.d.ts +5 -0
  207. package/dist/isosurface/index.js +6 -0
  208. package/dist/isosurface/parse.d.ts +6 -0
  209. package/dist/isosurface/parse.js +552 -0
  210. package/dist/isosurface/slice.d.ts +11 -0
  211. package/dist/isosurface/slice.js +141 -0
  212. package/dist/isosurface/types.d.ts +56 -0
  213. package/dist/isosurface/types.js +227 -0
  214. package/dist/keyboard.d.ts +3 -0
  215. package/dist/keyboard.js +23 -0
  216. package/dist/labels.d.ts +53 -0
  217. package/dist/labels.js +278 -0
  218. package/dist/layout/FullscreenToggle.svelte +50 -0
  219. package/dist/layout/FullscreenToggle.svelte.d.ts +7 -0
  220. package/dist/layout/InfoCard.svelte +120 -0
  221. package/dist/layout/InfoCard.svelte.d.ts +21 -0
  222. package/dist/layout/InfoTag.svelte +185 -0
  223. package/dist/layout/InfoTag.svelte.d.ts +19 -0
  224. package/dist/layout/PropertyFilter.svelte +247 -0
  225. package/dist/layout/PropertyFilter.svelte.d.ts +24 -0
  226. package/dist/layout/SettingsSection.svelte +148 -0
  227. package/dist/layout/SettingsSection.svelte.d.ts +17 -0
  228. package/dist/layout/SubpageGrid.svelte +82 -0
  229. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  230. package/dist/layout/fullscreen.d.ts +9 -0
  231. package/dist/layout/fullscreen.js +53 -0
  232. package/dist/layout/index.d.ts +10 -0
  233. package/dist/layout/index.js +8 -0
  234. package/dist/layout/json-tree/JsonNode.svelte +548 -0
  235. package/dist/layout/json-tree/JsonNode.svelte.d.ts +11 -0
  236. package/dist/layout/json-tree/JsonTree.svelte +1230 -0
  237. package/dist/layout/json-tree/JsonTree.svelte.d.ts +6 -0
  238. package/dist/layout/json-tree/JsonValue.svelte.d.ts +9 -0
  239. package/dist/layout/json-tree/index.d.ts +3 -0
  240. package/dist/layout/json-tree/index.js +3 -0
  241. package/dist/layout/json-tree/types.d.ts +74 -0
  242. package/dist/layout/json-tree/types.js +2 -0
  243. package/dist/layout/json-tree/utils.d.ts +29 -0
  244. package/dist/layout/json-tree/utils.js +642 -0
  245. package/dist/marching-cubes.d.ts +14 -0
  246. package/dist/marching-cubes.js +535 -0
  247. package/dist/math.d.ts +105 -0
  248. package/dist/math.js +920 -0
  249. package/dist/overlays/ContextMenu.svelte +162 -0
  250. package/dist/overlays/ContextMenu.svelte.d.ts +25 -0
  251. package/dist/overlays/CopyButton.svelte +45 -0
  252. package/dist/overlays/CopyButton.svelte.d.ts +8 -0
  253. package/dist/overlays/DragControlTab.svelte +98 -0
  254. package/dist/overlays/DragControlTab.svelte.d.ts +8 -0
  255. package/dist/overlays/DraggablePane.svelte +487 -0
  256. package/dist/overlays/DraggablePane.svelte.d.ts +36 -0
  257. package/dist/overlays/InfoPaneCards.svelte +149 -0
  258. package/dist/overlays/InfoPaneCards.svelte.d.ts +22 -0
  259. package/dist/overlays/index.d.ts +3 -0
  260. package/dist/overlays/index.js +3 -0
  261. package/dist/periodic-table/PeriodicTable.svelte +480 -0
  262. package/dist/periodic-table/PeriodicTable.svelte.d.ts +55 -0
  263. package/dist/periodic-table/PeriodicTableControls.svelte +557 -0
  264. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +24 -0
  265. package/dist/periodic-table/PropertySelect.svelte +38 -0
  266. package/dist/periodic-table/PropertySelect.svelte.d.ts +13 -0
  267. package/dist/periodic-table/TableInset.svelte.d.ts +9 -0
  268. package/dist/periodic-table/index.d.ts +10 -0
  269. package/dist/periodic-table/index.js +4 -0
  270. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1092 -0
  271. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +44 -0
  272. package/dist/phase-diagram/PhaseDiagramControls.svelte +444 -0
  273. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +30 -0
  274. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +127 -0
  275. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  276. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  277. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +19 -0
  278. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  279. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +16 -0
  280. package/dist/phase-diagram/TdbInfoPanel.svelte +203 -0
  281. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +12 -0
  282. package/dist/phase-diagram/build-diagram.d.ts +11 -0
  283. package/dist/phase-diagram/build-diagram.js +160 -0
  284. package/dist/phase-diagram/colors.d.ts +35 -0
  285. package/dist/phase-diagram/colors.js +51 -0
  286. package/dist/phase-diagram/diagram-input.d.ts +29 -0
  287. package/dist/phase-diagram/diagram-input.js +3 -0
  288. package/dist/phase-diagram/index.d.ts +13 -0
  289. package/dist/phase-diagram/index.js +11 -0
  290. package/dist/phase-diagram/parse.d.ts +55 -0
  291. package/dist/phase-diagram/parse.js +273 -0
  292. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  293. package/dist/phase-diagram/svg-to-diagram.js +867 -0
  294. package/dist/phase-diagram/types.d.ts +93 -0
  295. package/dist/phase-diagram/types.js +1 -0
  296. package/dist/phase-diagram/utils.d.ts +118 -0
  297. package/dist/phase-diagram/utils.js +600 -0
  298. package/dist/plot/bar/BarPlot.svelte +1755 -0
  299. package/dist/plot/bar/BarPlot.svelte.d.ts +84 -0
  300. package/dist/plot/bar/BarPlotControls.svelte +67 -0
  301. package/dist/plot/bar/BarPlotControls.svelte.d.ts +18 -0
  302. package/dist/plot/bar/SpacegroupBarPlot.svelte +293 -0
  303. package/dist/plot/bar/SpacegroupBarPlot.svelte.d.ts +9 -0
  304. package/dist/plot/bar/data.d.ts +40 -0
  305. package/dist/plot/bar/data.js +154 -0
  306. package/dist/plot/bar/geometry.d.ts +39 -0
  307. package/dist/plot/bar/geometry.js +60 -0
  308. package/dist/plot/bar/index.d.ts +3 -0
  309. package/dist/plot/bar/index.js +3 -0
  310. package/dist/plot/box/BoxPlot.svelte +1462 -0
  311. package/dist/plot/box/BoxPlot.svelte.d.ts +94 -0
  312. package/dist/plot/box/BoxPlotControls.svelte +109 -0
  313. package/dist/plot/box/BoxPlotControls.svelte.d.ts +19 -0
  314. package/dist/plot/box/Violin.svelte +14 -0
  315. package/dist/plot/box/Violin.svelte.d.ts +70 -0
  316. package/dist/plot/box/box-plot.d.ts +55 -0
  317. package/dist/plot/box/box-plot.js +126 -0
  318. package/dist/plot/box/index.d.ts +5 -0
  319. package/dist/plot/box/index.js +5 -0
  320. package/dist/plot/box/kde.d.ts +16 -0
  321. package/dist/plot/box/kde.js +160 -0
  322. package/dist/plot/box/quantile.d.ts +3 -0
  323. package/dist/plot/box/quantile.js +53 -0
  324. package/dist/plot/core/auto-place.d.ts +43 -0
  325. package/dist/plot/core/auto-place.js +122 -0
  326. package/dist/plot/core/axis-utils.d.ts +46 -0
  327. package/dist/plot/core/axis-utils.js +110 -0
  328. package/dist/plot/core/components/AxisLabel.svelte +51 -0
  329. package/dist/plot/core/components/AxisLabel.svelte.d.ts +16 -0
  330. package/dist/plot/core/components/ColorBar.svelte +724 -0
  331. package/dist/plot/core/components/ColorBar.svelte.d.ts +31 -0
  332. package/dist/plot/core/components/ColorScaleSelect.svelte +55 -0
  333. package/dist/plot/core/components/ColorScaleSelect.svelte.d.ts +15 -0
  334. package/dist/plot/core/components/ControlPane.svelte +46 -0
  335. package/dist/plot/core/components/ControlPane.svelte.d.ts +13 -0
  336. package/dist/plot/core/components/FillArea.svelte +234 -0
  337. package/dist/plot/core/components/FillArea.svelte.d.ts +21 -0
  338. package/dist/plot/core/components/InteractiveAxisLabel.svelte +96 -0
  339. package/dist/plot/core/components/InteractiveAxisLabel.svelte.d.ts +14 -0
  340. package/dist/plot/core/components/Line.svelte +101 -0
  341. package/dist/plot/core/components/Line.svelte.d.ts +15 -0
  342. package/dist/plot/core/components/PlotAxis.svelte +171 -0
  343. package/dist/plot/core/components/PlotAxis.svelte.d.ts +25 -0
  344. package/dist/plot/core/components/PlotControls.svelte +525 -0
  345. package/dist/plot/core/components/PlotControls.svelte.d.ts +4 -0
  346. package/dist/plot/core/components/PlotLegend.svelte +580 -0
  347. package/dist/plot/core/components/PlotLegend.svelte.d.ts +30 -0
  348. package/dist/plot/core/components/PlotTooltip.svelte +83 -0
  349. package/dist/plot/core/components/PlotTooltip.svelte.d.ts +25 -0
  350. package/dist/plot/core/components/PortalSelect.svelte +257 -0
  351. package/dist/plot/core/components/PortalSelect.svelte.d.ts +16 -0
  352. package/dist/plot/core/components/ReferenceLine.svelte +204 -0
  353. package/dist/plot/core/components/ReferenceLine.svelte.d.ts +20 -0
  354. package/dist/plot/core/components/ReferenceLine3D.svelte +156 -0
  355. package/dist/plot/core/components/ReferenceLine3D.svelte.d.ts +14 -0
  356. package/dist/plot/core/components/ReferencePlane.svelte +175 -0
  357. package/dist/plot/core/components/ReferencePlane.svelte.d.ts +14 -0
  358. package/dist/plot/core/components/ZeroLines.svelte +97 -0
  359. package/dist/plot/core/components/ZeroLines.svelte.d.ts +33 -0
  360. package/dist/plot/core/components/ZoomRect.svelte +23 -0
  361. package/dist/plot/core/components/ZoomRect.svelte.d.ts +8 -0
  362. package/dist/plot/core/components/index.d.ts +17 -0
  363. package/dist/plot/core/components/index.js +17 -0
  364. package/dist/plot/core/data-cleaning.d.ts +107 -0
  365. package/dist/plot/core/data-cleaning.js +853 -0
  366. package/dist/plot/core/data-transform.d.ts +16 -0
  367. package/dist/plot/core/data-transform.js +45 -0
  368. package/dist/plot/core/fill-utils.d.ts +33 -0
  369. package/dist/plot/core/fill-utils.js +388 -0
  370. package/dist/plot/core/hover-lock.svelte.d.ts +14 -0
  371. package/dist/plot/core/hover-lock.svelte.js +45 -0
  372. package/dist/plot/core/index.d.ts +10 -0
  373. package/dist/plot/core/index.js +11 -0
  374. package/dist/plot/core/interactions.d.ts +35 -0
  375. package/dist/plot/core/interactions.js +195 -0
  376. package/dist/plot/core/layout.d.ts +79 -0
  377. package/dist/plot/core/layout.js +281 -0
  378. package/dist/plot/core/reference-line.d.ts +60 -0
  379. package/dist/plot/core/reference-line.js +301 -0
  380. package/dist/plot/core/scales.d.ts +48 -0
  381. package/dist/plot/core/scales.js +480 -0
  382. package/dist/plot/core/svg.d.ts +2 -0
  383. package/dist/plot/core/svg.js +41 -0
  384. package/dist/plot/core/types.d.ts +771 -0
  385. package/dist/plot/core/types.js +99 -0
  386. package/dist/plot/core/utils/label-placement.d.ts +68 -0
  387. package/dist/plot/core/utils/label-placement.js +326 -0
  388. package/dist/plot/core/utils/series-visibility.d.ts +26 -0
  389. package/dist/plot/core/utils/series-visibility.js +112 -0
  390. package/dist/plot/core/utils.d.ts +11 -0
  391. package/dist/plot/core/utils.js +27 -0
  392. package/dist/plot/histogram/Histogram.svelte +1418 -0
  393. package/dist/plot/histogram/Histogram.svelte.d.ts +50 -0
  394. package/dist/plot/histogram/HistogramControls.svelte +212 -0
  395. package/dist/plot/histogram/HistogramControls.svelte.d.ts +22 -0
  396. package/dist/plot/histogram/index.d.ts +2 -0
  397. package/dist/plot/histogram/index.js +2 -0
  398. package/dist/plot/index.d.ts +8 -0
  399. package/dist/plot/index.js +10 -0
  400. package/dist/plot/sankey/Sankey.svelte +700 -0
  401. package/dist/plot/sankey/Sankey.svelte.d.ts +74 -0
  402. package/dist/plot/sankey/SankeyControls.svelte +98 -0
  403. package/dist/plot/sankey/SankeyControls.svelte.d.ts +19 -0
  404. package/dist/plot/sankey/index.d.ts +4 -0
  405. package/dist/plot/sankey/index.js +3 -0
  406. package/dist/plot/sankey/sankey-types.d.ts +42 -0
  407. package/dist/plot/sankey/sankey-types.js +4 -0
  408. package/dist/plot/sankey/sankey.d.ts +52 -0
  409. package/dist/plot/sankey/sankey.js +187 -0
  410. package/dist/plot/scatter/BinnedScatterPlot.svelte +1116 -0
  411. package/dist/plot/scatter/BinnedScatterPlot.svelte.d.ts +66 -0
  412. package/dist/plot/scatter/ElementScatter.svelte +63 -0
  413. package/dist/plot/scatter/ElementScatter.svelte.d.ts +14 -0
  414. package/dist/plot/scatter/ScatterPlot.svelte +2357 -0
  415. package/dist/plot/scatter/ScatterPlot.svelte.d.ts +96 -0
  416. package/dist/plot/scatter/ScatterPlotControls.svelte +307 -0
  417. package/dist/plot/scatter/ScatterPlotControls.svelte.d.ts +17 -0
  418. package/dist/plot/scatter/ScatterPoint.svelte +182 -0
  419. package/dist/plot/scatter/ScatterPoint.svelte.d.ts +22 -0
  420. package/dist/plot/scatter/adaptive-density.d.ts +79 -0
  421. package/dist/plot/scatter/adaptive-density.js +217 -0
  422. package/dist/plot/scatter/binned-scatter-types.d.ts +59 -0
  423. package/dist/plot/scatter/binned-scatter-types.js +1 -0
  424. package/dist/plot/scatter/index.d.ts +7 -0
  425. package/dist/plot/scatter/index.js +5 -0
  426. package/dist/plot/scatter/scatter-data.d.ts +19 -0
  427. package/dist/plot/scatter/scatter-data.js +212 -0
  428. package/dist/plot/scatter-3d/ScatterPlot3D.svelte +531 -0
  429. package/dist/plot/scatter-3d/ScatterPlot3D.svelte.d.ts +95 -0
  430. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte +438 -0
  431. package/dist/plot/scatter-3d/ScatterPlot3DControls.svelte.d.ts +20 -0
  432. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte +912 -0
  433. package/dist/plot/scatter-3d/ScatterPlot3DScene.svelte.d.ts +74 -0
  434. package/dist/plot/scatter-3d/Surface3D.svelte +197 -0
  435. package/dist/plot/scatter-3d/Surface3D.svelte.d.ts +13 -0
  436. package/dist/plot/scatter-3d/index.d.ts +4 -0
  437. package/dist/plot/scatter-3d/index.js +4 -0
  438. package/dist/plot/sunburst/Sunburst.svelte +1045 -0
  439. package/dist/plot/sunburst/Sunburst.svelte.d.ts +96 -0
  440. package/dist/plot/sunburst/SunburstControls.svelte +200 -0
  441. package/dist/plot/sunburst/SunburstControls.svelte.d.ts +26 -0
  442. package/dist/plot/sunburst/index.d.ts +4 -0
  443. package/dist/plot/sunburst/index.js +4 -0
  444. package/dist/plot/sunburst/render.d.ts +34 -0
  445. package/dist/plot/sunburst/render.js +122 -0
  446. package/dist/plot/sunburst/sunburst.d.ts +62 -0
  447. package/dist/plot/sunburst/sunburst.js +266 -0
  448. package/dist/rdf/RdfPlot.svelte +248 -0
  449. package/dist/rdf/RdfPlot.svelte.d.ts +27 -0
  450. package/dist/rdf/calc-rdf.d.ts +4 -0
  451. package/dist/rdf/calc-rdf.js +98 -0
  452. package/dist/rdf/index.d.ts +23 -0
  453. package/dist/rdf/index.js +2 -0
  454. package/dist/sanitize.d.ts +6 -0
  455. package/dist/sanitize.js +116 -0
  456. package/dist/settings.d.ts +319 -0
  457. package/dist/settings.js +1394 -0
  458. package/dist/spectral/Bands.svelte +1050 -0
  459. package/dist/spectral/Bands.svelte.d.ts +39 -0
  460. package/dist/spectral/BandsAndDos.svelte +134 -0
  461. package/dist/spectral/BandsAndDos.svelte.d.ts +18 -0
  462. package/dist/spectral/BrillouinBandsDos.svelte +264 -0
  463. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +20 -0
  464. package/dist/spectral/Dos.svelte +688 -0
  465. package/dist/spectral/Dos.svelte.d.ts +29 -0
  466. package/dist/spectral/helpers.d.ts +121 -0
  467. package/dist/spectral/helpers.js +1098 -0
  468. package/dist/spectral/index.d.ts +6 -0
  469. package/dist/spectral/index.js +6 -0
  470. package/dist/spectral/types.d.ts +84 -0
  471. package/dist/spectral/types.js +2 -0
  472. package/dist/state.svelte.d.ts +25 -0
  473. package/dist/state.svelte.js +45 -0
  474. package/dist/structure/Arrow.svelte +72 -0
  475. package/dist/structure/Arrow.svelte.d.ts +15 -0
  476. package/dist/structure/AtomLegend.svelte +814 -0
  477. package/dist/structure/AtomLegend.svelte.d.ts +35 -0
  478. package/dist/structure/Bond.svelte +140 -0
  479. package/dist/structure/Bond.svelte.d.ts +9 -0
  480. package/dist/structure/CanvasTooltip.svelte +33 -0
  481. package/dist/structure/CanvasTooltip.svelte.d.ts +12 -0
  482. package/dist/structure/CellSelect.svelte +348 -0
  483. package/dist/structure/CellSelect.svelte.d.ts +13 -0
  484. package/dist/structure/Cylinder.svelte +49 -0
  485. package/dist/structure/Cylinder.svelte.d.ts +13 -0
  486. package/dist/structure/Lattice.svelte +196 -0
  487. package/dist/structure/Lattice.svelte.d.ts +17 -0
  488. package/dist/structure/Structure.svelte +2254 -0
  489. package/dist/structure/Structure.svelte.d.ts +89 -0
  490. package/dist/structure/StructureControls.svelte +1273 -0
  491. package/dist/structure/StructureControls.svelte.d.ts +31 -0
  492. package/dist/structure/StructureExportPane.svelte +252 -0
  493. package/dist/structure/StructureExportPane.svelte.d.ts +17 -0
  494. package/dist/structure/StructureInfoPane.svelte +736 -0
  495. package/dist/structure/StructureInfoPane.svelte.d.ts +19 -0
  496. package/dist/structure/StructureScene.svelte +2256 -0
  497. package/dist/structure/StructureScene.svelte.d.ts +111 -0
  498. package/dist/structure/atom-properties.d.ts +37 -0
  499. package/dist/structure/atom-properties.js +200 -0
  500. package/dist/structure/bond-order-perception.d.ts +13 -0
  501. package/dist/structure/bond-order-perception.js +384 -0
  502. package/dist/structure/bonding.d.ts +69 -0
  503. package/dist/structure/bonding.js +724 -0
  504. package/dist/structure/export.d.ts +20 -0
  505. package/dist/structure/export.js +731 -0
  506. package/dist/structure/index.d.ts +124 -0
  507. package/dist/structure/index.js +167 -0
  508. package/dist/structure/label-placement.d.ts +14 -0
  509. package/dist/structure/label-placement.js +72 -0
  510. package/dist/structure/measure.d.ts +7 -0
  511. package/dist/structure/measure.js +30 -0
  512. package/dist/structure/parse.d.ts +66 -0
  513. package/dist/structure/parse.js +1410 -0
  514. package/dist/structure/partial-occupancy.d.ts +25 -0
  515. package/dist/structure/partial-occupancy.js +99 -0
  516. package/dist/structure/pbc.d.ts +9 -0
  517. package/dist/structure/pbc.js +127 -0
  518. package/dist/structure/supercell.d.ts +8 -0
  519. package/dist/structure/supercell.js +170 -0
  520. package/dist/structure/validation.d.ts +2 -0
  521. package/dist/structure/validation.js +10 -0
  522. package/dist/symmetry/SymmetryStats.svelte +226 -0
  523. package/dist/symmetry/SymmetryStats.svelte.d.ts +21 -0
  524. package/dist/symmetry/WyckoffTable.svelte +120 -0
  525. package/dist/symmetry/WyckoffTable.svelte.d.ts +11 -0
  526. package/dist/symmetry/cell-transform.d.ts +12 -0
  527. package/dist/symmetry/cell-transform.js +91 -0
  528. package/dist/symmetry/index.d.ts +43 -0
  529. package/dist/symmetry/index.js +226 -0
  530. package/dist/symmetry/spacegroups.d.ts +16 -0
  531. package/dist/symmetry/spacegroups.js +429 -0
  532. package/dist/table/HeatmapTable.svelte +1885 -0
  533. package/dist/table/HeatmapTable.svelte.d.ts +49 -0
  534. package/dist/table/ToggleMenu.svelte +385 -0
  535. package/dist/table/ToggleMenu.svelte.d.ts +11 -0
  536. package/dist/table/index.d.ts +72 -0
  537. package/dist/table/index.js +38 -0
  538. package/dist/theme/ThemeControl.svelte +53 -0
  539. package/dist/theme/ThemeControl.svelte.d.ts +9 -0
  540. package/dist/theme/index.d.ts +29 -0
  541. package/dist/theme/index.js +79 -0
  542. package/dist/time.d.ts +4 -0
  543. package/dist/time.js +70 -0
  544. package/dist/tooltip/KCoords.svelte +45 -0
  545. package/dist/tooltip/KCoords.svelte.d.ts +8 -0
  546. package/dist/tooltip/TooltipContent.svelte +58 -0
  547. package/dist/tooltip/TooltipContent.svelte.d.ts +31 -0
  548. package/dist/tooltip/index.d.ts +3 -0
  549. package/dist/tooltip/index.js +2 -0
  550. package/dist/tooltip/types.d.ts +8 -0
  551. package/dist/tooltip/types.js +1 -0
  552. package/dist/trajectory/Trajectory.svelte +1571 -0
  553. package/dist/trajectory/Trajectory.svelte.d.ts +78 -0
  554. package/dist/trajectory/TrajectoryError.svelte +128 -0
  555. package/dist/trajectory/TrajectoryError.svelte.d.ts +13 -0
  556. package/dist/trajectory/TrajectoryExportPane.svelte +358 -0
  557. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +17 -0
  558. package/dist/trajectory/TrajectoryInfoPane.svelte +314 -0
  559. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +17 -0
  560. package/dist/trajectory/constants.d.ts +6 -0
  561. package/dist/trajectory/constants.js +7 -0
  562. package/dist/trajectory/extract.d.ts +5 -0
  563. package/dist/trajectory/extract.js +162 -0
  564. package/dist/trajectory/format-detect.d.ts +10 -0
  565. package/dist/trajectory/format-detect.js +90 -0
  566. package/dist/trajectory/frame-reader.d.ts +17 -0
  567. package/dist/trajectory/frame-reader.js +299 -0
  568. package/dist/trajectory/helpers.d.ts +15 -0
  569. package/dist/trajectory/helpers.js +164 -0
  570. package/dist/trajectory/index.d.ts +63 -0
  571. package/dist/trajectory/index.js +126 -0
  572. package/dist/trajectory/parse/ase.d.ts +2 -0
  573. package/dist/trajectory/parse/ase.js +73 -0
  574. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  575. package/dist/trajectory/parse/hdf5.js +127 -0
  576. package/dist/trajectory/parse/index.d.ts +12 -0
  577. package/dist/trajectory/parse/index.js +306 -0
  578. package/dist/trajectory/parse/lammps.d.ts +5 -0
  579. package/dist/trajectory/parse/lammps.js +179 -0
  580. package/dist/trajectory/parse/vasp.d.ts +2 -0
  581. package/dist/trajectory/parse/vasp.js +87 -0
  582. package/dist/trajectory/parse/xyz.d.ts +26 -0
  583. package/dist/trajectory/parse/xyz.js +123 -0
  584. package/dist/trajectory/plotting.d.ts +28 -0
  585. package/dist/trajectory/plotting.js +423 -0
  586. package/dist/trajectory/types.d.ts +11 -0
  587. package/dist/trajectory/types.js +1 -0
  588. package/dist/utils.d.ts +7 -0
  589. package/dist/utils.js +47 -0
  590. package/dist/xrd/XrdPlot.svelte +616 -0
  591. package/dist/xrd/XrdPlot.svelte.d.ts +28 -0
  592. package/dist/xrd/broadening.d.ts +20 -0
  593. package/dist/xrd/broadening.js +97 -0
  594. package/dist/xrd/calc-xrd.d.ts +37 -0
  595. package/dist/xrd/calc-xrd.js +339 -0
  596. package/dist/xrd/index.d.ts +37 -0
  597. package/dist/xrd/index.js +4 -0
  598. package/dist/xrd/parse.d.ts +13 -0
  599. package/dist/xrd/parse.js +749 -0
  600. package/license +1 -1
  601. package/package.json +237 -1458
  602. package/readme.md +98 -171
  603. package/.vscode/launch.json +0 -13
  604. package/.vscodeignore +0 -7
  605. package/dist/assets/STLExporter-BpTH3YHE.js +0 -8
  606. package/dist/assets/browser-DdDecX_W.js +0 -1
  607. package/dist/assets/export-qgn-H9y6.js +0 -2
  608. package/dist/assets/main-DiKYzti2.css +0 -1
  609. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  610. package/dist/extension.js +0 -31293
  611. package/dist/src/lib/FilePicker.svelte +0 -360
  612. package/dist/src/lib/Icon.svelte +0 -41
  613. package/dist/src/lib/MillerIndexInput.svelte +0 -66
  614. package/dist/src/lib/api/mp.ts +0 -26
  615. package/dist/src/lib/api/optimade.ts +0 -204
  616. package/dist/src/lib/app.css +0 -247
  617. package/dist/src/lib/brillouin/BrillouinZone.svelte +0 -549
  618. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +0 -144
  619. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +0 -146
  620. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  621. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +0 -476
  622. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +0 -92
  623. package/dist/src/lib/brillouin/compute.ts +0 -529
  624. package/dist/src/lib/brillouin/index.ts +0 -8
  625. package/dist/src/lib/brillouin/types.ts +0 -51
  626. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +0 -327
  627. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +0 -846
  628. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +0 -3193
  629. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +0 -94
  630. package/dist/src/lib/chempot-diagram/chempot-worker.ts +0 -11
  631. package/dist/src/lib/chempot-diagram/color.ts +0 -42
  632. package/dist/src/lib/chempot-diagram/compute.ts +0 -1014
  633. package/dist/src/lib/chempot-diagram/index.ts +0 -6
  634. package/dist/src/lib/chempot-diagram/pointer.ts +0 -56
  635. package/dist/src/lib/chempot-diagram/temperature.ts +0 -77
  636. package/dist/src/lib/chempot-diagram/types.ts +0 -130
  637. package/dist/src/lib/colors/index.ts +0 -249
  638. package/dist/src/lib/composition/BarChart.svelte +0 -297
  639. package/dist/src/lib/composition/BubbleChart.svelte +0 -218
  640. package/dist/src/lib/composition/Composition.svelte +0 -165
  641. package/dist/src/lib/composition/Formula.svelte +0 -268
  642. package/dist/src/lib/composition/FormulaFilter.svelte +0 -1257
  643. package/dist/src/lib/composition/PieChart.svelte +0 -323
  644. package/dist/src/lib/composition/format.ts +0 -155
  645. package/dist/src/lib/composition/index.ts +0 -37
  646. package/dist/src/lib/composition/parse.ts +0 -605
  647. package/dist/src/lib/constants.ts +0 -134
  648. package/dist/src/lib/controls.ts +0 -42
  649. package/dist/src/lib/convex-hull/ConvexHull.svelte +0 -157
  650. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +0 -825
  651. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +0 -1801
  652. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +0 -1398
  653. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +0 -535
  654. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +0 -125
  655. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +0 -929
  656. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +0 -131
  657. package/dist/src/lib/convex-hull/GasPressureControls.svelte +0 -247
  658. package/dist/src/lib/convex-hull/StructurePopup.svelte +0 -151
  659. package/dist/src/lib/convex-hull/TemperatureSlider.svelte +0 -140
  660. package/dist/src/lib/convex-hull/barycentric-coords.ts +0 -246
  661. package/dist/src/lib/convex-hull/demo-temperature.ts +0 -63
  662. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +0 -405
  663. package/dist/src/lib/convex-hull/helpers.ts +0 -932
  664. package/dist/src/lib/convex-hull/index.ts +0 -202
  665. package/dist/src/lib/convex-hull/thermodynamics.ts +0 -2192
  666. package/dist/src/lib/convex-hull/types.ts +0 -267
  667. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +0 -311
  668. package/dist/src/lib/coordination/calc-coordination.ts +0 -93
  669. package/dist/src/lib/coordination/index.ts +0 -9
  670. package/dist/src/lib/effects.svelte.ts +0 -48
  671. package/dist/src/lib/element/ElementHeading.svelte +0 -26
  672. package/dist/src/lib/element/ElementPhoto.svelte +0 -57
  673. package/dist/src/lib/element/ElementStats.svelte +0 -80
  674. package/dist/src/lib/element/ElementTile.svelte +0 -484
  675. package/dist/src/lib/element/data.ts +0 -14
  676. package/dist/src/lib/element/index.ts +0 -8
  677. package/dist/src/lib/element/types.ts +0 -62
  678. package/dist/src/lib/feedback/ClickFeedback.svelte +0 -58
  679. package/dist/src/lib/feedback/DragOverlay.svelte +0 -42
  680. package/dist/src/lib/feedback/index.ts +0 -4
  681. package/dist/src/lib/fermi-surface/FermiSlice.svelte +0 -189
  682. package/dist/src/lib/fermi-surface/FermiSurface.svelte +0 -600
  683. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +0 -448
  684. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +0 -794
  685. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  686. package/dist/src/lib/fermi-surface/compute.ts +0 -728
  687. package/dist/src/lib/fermi-surface/constants.ts +0 -32
  688. package/dist/src/lib/fermi-surface/export.ts +0 -64
  689. package/dist/src/lib/fermi-surface/index.ts +0 -14
  690. package/dist/src/lib/fermi-surface/marching-cubes.ts +0 -3
  691. package/dist/src/lib/fermi-surface/parse.ts +0 -574
  692. package/dist/src/lib/fermi-surface/symmetry.ts +0 -56
  693. package/dist/src/lib/fermi-surface/types.ts +0 -159
  694. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +0 -1545
  695. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  696. package/dist/src/lib/heatmap-matrix/index.ts +0 -167
  697. package/dist/src/lib/heatmap-matrix/shared.ts +0 -7
  698. package/dist/src/lib/icons.ts +0 -650
  699. package/dist/src/lib/index.ts +0 -61
  700. package/dist/src/lib/io/decompress.ts +0 -92
  701. package/dist/src/lib/io/export.ts +0 -385
  702. package/dist/src/lib/io/fetch.ts +0 -46
  703. package/dist/src/lib/io/file-drop.ts +0 -51
  704. package/dist/src/lib/io/index.ts +0 -7
  705. package/dist/src/lib/io/is-binary.ts +0 -24
  706. package/dist/src/lib/io/types.ts +0 -8
  707. package/dist/src/lib/io/url-drop.ts +0 -141
  708. package/dist/src/lib/isosurface/Isosurface.svelte +0 -285
  709. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +0 -277
  710. package/dist/src/lib/isosurface/index.ts +0 -7
  711. package/dist/src/lib/isosurface/parse.ts +0 -656
  712. package/dist/src/lib/isosurface/slice.ts +0 -175
  713. package/dist/src/lib/isosurface/types.ts +0 -309
  714. package/dist/src/lib/labels.ts +0 -320
  715. package/dist/src/lib/layout/FullscreenToggle.svelte +0 -50
  716. package/dist/src/lib/layout/InfoCard.svelte +0 -120
  717. package/dist/src/lib/layout/InfoTag.svelte +0 -185
  718. package/dist/src/lib/layout/PropertyFilter.svelte +0 -246
  719. package/dist/src/lib/layout/SettingsSection.svelte +0 -148
  720. package/dist/src/lib/layout/SubpageGrid.svelte +0 -82
  721. package/dist/src/lib/layout/fullscreen.ts +0 -65
  722. package/dist/src/lib/layout/index.ts +0 -11
  723. package/dist/src/lib/layout/json-tree/JsonNode.svelte +0 -548
  724. package/dist/src/lib/layout/json-tree/JsonTree.svelte +0 -1230
  725. package/dist/src/lib/layout/json-tree/index.ts +0 -3
  726. package/dist/src/lib/layout/json-tree/types.ts +0 -126
  727. package/dist/src/lib/layout/json-tree/utils.ts +0 -682
  728. package/dist/src/lib/marching-cubes.ts +0 -614
  729. package/dist/src/lib/math.ts +0 -1081
  730. package/dist/src/lib/overlays/ContextMenu.svelte +0 -162
  731. package/dist/src/lib/overlays/CopyButton.svelte +0 -45
  732. package/dist/src/lib/overlays/DragControlTab.svelte +0 -98
  733. package/dist/src/lib/overlays/DraggablePane.svelte +0 -487
  734. package/dist/src/lib/overlays/InfoPaneCards.svelte +0 -149
  735. package/dist/src/lib/overlays/index.ts +0 -3
  736. package/dist/src/lib/periodic-table/PeriodicTable.svelte +0 -469
  737. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +0 -557
  738. package/dist/src/lib/periodic-table/PropertySelect.svelte +0 -37
  739. package/dist/src/lib/periodic-table/index.ts +0 -12
  740. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1086
  741. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +0 -444
  742. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  743. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +0 -184
  744. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +0 -391
  745. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +0 -203
  746. package/dist/src/lib/phase-diagram/build-diagram.ts +0 -186
  747. package/dist/src/lib/phase-diagram/colors.ts +0 -58
  748. package/dist/src/lib/phase-diagram/diagram-input.ts +0 -40
  749. package/dist/src/lib/phase-diagram/index.ts +0 -13
  750. package/dist/src/lib/phase-diagram/parse.ts +0 -348
  751. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +0 -1023
  752. package/dist/src/lib/phase-diagram/types.ts +0 -144
  753. package/dist/src/lib/phase-diagram/utils.ts +0 -775
  754. package/dist/src/lib/plot/AxisLabel.svelte +0 -51
  755. package/dist/src/lib/plot/BarPlot.svelte +0 -2113
  756. package/dist/src/lib/plot/BarPlotControls.svelte +0 -66
  757. package/dist/src/lib/plot/BinnedScatterPlot.svelte +0 -1114
  758. package/dist/src/lib/plot/ColorBar.svelte +0 -721
  759. package/dist/src/lib/plot/ColorScaleSelect.svelte +0 -54
  760. package/dist/src/lib/plot/ElementScatter.svelte +0 -63
  761. package/dist/src/lib/plot/FillArea.svelte +0 -223
  762. package/dist/src/lib/plot/Histogram.svelte +0 -1558
  763. package/dist/src/lib/plot/HistogramControls.svelte +0 -212
  764. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +0 -96
  765. package/dist/src/lib/plot/Line.svelte +0 -84
  766. package/dist/src/lib/plot/PlotAxis.svelte +0 -169
  767. package/dist/src/lib/plot/PlotControls.svelte +0 -537
  768. package/dist/src/lib/plot/PlotLegend.svelte +0 -569
  769. package/dist/src/lib/plot/PlotTooltip.svelte +0 -67
  770. package/dist/src/lib/plot/PortalSelect.svelte +0 -253
  771. package/dist/src/lib/plot/ReferenceLine.svelte +0 -204
  772. package/dist/src/lib/plot/ReferenceLine3D.svelte +0 -156
  773. package/dist/src/lib/plot/ReferencePlane.svelte +0 -175
  774. package/dist/src/lib/plot/ScatterPlot.svelte +0 -2778
  775. package/dist/src/lib/plot/ScatterPlot3D.svelte +0 -529
  776. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +0 -437
  777. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +0 -912
  778. package/dist/src/lib/plot/ScatterPlotControls.svelte +0 -306
  779. package/dist/src/lib/plot/ScatterPoint.svelte +0 -182
  780. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +0 -293
  781. package/dist/src/lib/plot/Surface3D.svelte +0 -197
  782. package/dist/src/lib/plot/ZeroLines.svelte +0 -97
  783. package/dist/src/lib/plot/ZoomRect.svelte +0 -23
  784. package/dist/src/lib/plot/adaptive-density.ts +0 -316
  785. package/dist/src/lib/plot/auto-place.ts +0 -184
  786. package/dist/src/lib/plot/axis-utils.ts +0 -122
  787. package/dist/src/lib/plot/binned-scatter-types.ts +0 -83
  788. package/dist/src/lib/plot/data-cleaning.ts +0 -1069
  789. package/dist/src/lib/plot/data-transform.ts +0 -69
  790. package/dist/src/lib/plot/defaults.ts +0 -9
  791. package/dist/src/lib/plot/fill-utils.ts +0 -494
  792. package/dist/src/lib/plot/hover-lock.svelte.ts +0 -60
  793. package/dist/src/lib/plot/index.ts +0 -53
  794. package/dist/src/lib/plot/interactions.ts +0 -119
  795. package/dist/src/lib/plot/layout.ts +0 -425
  796. package/dist/src/lib/plot/reference-line.ts +0 -426
  797. package/dist/src/lib/plot/scales.ts +0 -654
  798. package/dist/src/lib/plot/svg.ts +0 -23
  799. package/dist/src/lib/plot/types.ts +0 -1144
  800. package/dist/src/lib/plot/utils/label-placement.ts +0 -541
  801. package/dist/src/lib/plot/utils/series-visibility.ts +0 -140
  802. package/dist/src/lib/plot/utils.ts +0 -11
  803. package/dist/src/lib/rdf/RdfPlot.svelte +0 -247
  804. package/dist/src/lib/rdf/calc-rdf.ts +0 -167
  805. package/dist/src/lib/rdf/index.ts +0 -27
  806. package/dist/src/lib/sanitize.ts +0 -126
  807. package/dist/src/lib/settings.ts +0 -1479
  808. package/dist/src/lib/spectral/Bands.svelte +0 -1040
  809. package/dist/src/lib/spectral/BandsAndDos.svelte +0 -134
  810. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +0 -252
  811. package/dist/src/lib/spectral/Dos.svelte +0 -697
  812. package/dist/src/lib/spectral/helpers.ts +0 -1381
  813. package/dist/src/lib/spectral/index.ts +0 -8
  814. package/dist/src/lib/spectral/types.ts +0 -112
  815. package/dist/src/lib/state.svelte.ts +0 -64
  816. package/dist/src/lib/structure/Arrow.svelte +0 -72
  817. package/dist/src/lib/structure/AtomLegend.svelte +0 -815
  818. package/dist/src/lib/structure/Bond.svelte +0 -140
  819. package/dist/src/lib/structure/CanvasTooltip.svelte +0 -33
  820. package/dist/src/lib/structure/CellSelect.svelte +0 -349
  821. package/dist/src/lib/structure/Cylinder.svelte +0 -45
  822. package/dist/src/lib/structure/Lattice.svelte +0 -196
  823. package/dist/src/lib/structure/Structure.svelte +0 -2248
  824. package/dist/src/lib/structure/StructureControls.svelte +0 -1273
  825. package/dist/src/lib/structure/StructureExportPane.svelte +0 -252
  826. package/dist/src/lib/structure/StructureInfoPane.svelte +0 -737
  827. package/dist/src/lib/structure/StructureScene.svelte +0 -2255
  828. package/dist/src/lib/structure/atom-properties.ts +0 -316
  829. package/dist/src/lib/structure/bond-order-perception.ts +0 -447
  830. package/dist/src/lib/structure/bonding.ts +0 -944
  831. package/dist/src/lib/structure/export.ts +0 -861
  832. package/dist/src/lib/structure/index.ts +0 -291
  833. package/dist/src/lib/structure/label-placement.ts +0 -130
  834. package/dist/src/lib/structure/measure.ts +0 -45
  835. package/dist/src/lib/structure/parse.ts +0 -1705
  836. package/dist/src/lib/structure/partial-occupancy.ts +0 -183
  837. package/dist/src/lib/structure/pbc.ts +0 -164
  838. package/dist/src/lib/structure/supercell.ts +0 -226
  839. package/dist/src/lib/structure/validation.ts +0 -11
  840. package/dist/src/lib/symmetry/SymmetryStats.svelte +0 -226
  841. package/dist/src/lib/symmetry/WyckoffTable.svelte +0 -120
  842. package/dist/src/lib/symmetry/cell-transform.ts +0 -118
  843. package/dist/src/lib/symmetry/index.ts +0 -348
  844. package/dist/src/lib/symmetry/spacegroups.ts +0 -404
  845. package/dist/src/lib/table/HeatmapTable.svelte +0 -1833
  846. package/dist/src/lib/table/ToggleMenu.svelte +0 -385
  847. package/dist/src/lib/table/index.ts +0 -139
  848. package/dist/src/lib/theme/ThemeControl.svelte +0 -53
  849. package/dist/src/lib/theme/index.ts +0 -107
  850. package/dist/src/lib/time.ts +0 -71
  851. package/dist/src/lib/tooltip/TooltipContent.svelte +0 -58
  852. package/dist/src/lib/tooltip/index.ts +0 -2
  853. package/dist/src/lib/tooltip/types.ts +0 -13
  854. package/dist/src/lib/trajectory/Trajectory.svelte +0 -1545
  855. package/dist/src/lib/trajectory/TrajectoryError.svelte +0 -128
  856. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +0 -357
  857. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +0 -313
  858. package/dist/src/lib/trajectory/constants.ts +0 -7
  859. package/dist/src/lib/trajectory/extract.ts +0 -196
  860. package/dist/src/lib/trajectory/format-detect.ts +0 -96
  861. package/dist/src/lib/trajectory/frame-reader.ts +0 -456
  862. package/dist/src/lib/trajectory/helpers.ts +0 -217
  863. package/dist/src/lib/trajectory/index.ts +0 -218
  864. package/dist/src/lib/trajectory/parse/ase.ts +0 -109
  865. package/dist/src/lib/trajectory/parse/hdf5.ts +0 -173
  866. package/dist/src/lib/trajectory/parse/index.ts +0 -411
  867. package/dist/src/lib/trajectory/parse/lammps.ts +0 -215
  868. package/dist/src/lib/trajectory/parse/vasp.ts +0 -102
  869. package/dist/src/lib/trajectory/parse/xyz.ts +0 -143
  870. package/dist/src/lib/trajectory/plotting.ts +0 -599
  871. package/dist/src/lib/trajectory/types.ts +0 -13
  872. package/dist/src/lib/utils.ts +0 -56
  873. package/dist/src/lib/xrd/XrdPlot.svelte +0 -615
  874. package/dist/src/lib/xrd/broadening.ts +0 -130
  875. package/dist/src/lib/xrd/calc-xrd.ts +0 -397
  876. package/dist/src/lib/xrd/index.ts +0 -38
  877. package/dist/src/lib/xrd/parse.ts +0 -858
  878. package/dist/webview.js +0 -29421
  879. package/icon.png +0 -0
  880. package/matterviz-0.3.2.vsix +0 -0
  881. package/matterviz-0.3.4.vsix +0 -0
  882. package/matterviz-0.3.5.vsix +0 -0
  883. package/scripts/sync-config.ts +0 -101
  884. package/src/declarations.d.ts +0 -2
  885. package/src/extension.ts +0 -972
  886. package/src/node-io.ts +0 -65
  887. package/src/types.ts +0 -17
  888. package/src/webview/JsonBrowser.svelte +0 -1079
  889. package/src/webview/PlotPanel.svelte +0 -346
  890. package/src/webview/detect.ts +0 -444
  891. package/src/webview/main.ts +0 -764
  892. package/src/webview/plot-utils.ts +0 -250
  893. package/test-fixtures/all-viz-types.json.gz +0 -0
  894. package/test-fixtures/plot-demo-data.json.gz +0 -0
  895. package/tests/detect.test.ts +0 -604
  896. package/tests/extension.test.ts +0 -2041
  897. package/tests/node-io.test.ts +0 -39
  898. package/tests/plot-utils.test.ts +0 -302
  899. package/tests/vite-plugin-json-gz.test.ts +0 -114
  900. package/tests/vscode-mock.ts +0 -18
  901. package/tests/webview.test.ts +0 -231
  902. package/tsconfig.json +0 -20
  903. package/vite-plugin-json-gz.ts +0 -29
  904. package/vite.config.ts +0 -34
  905. package/vite.extension.config.ts +0 -34
  906. /package/dist/{src/lib/EmptyState.svelte → EmptyState.svelte} +0 -0
  907. /package/dist/{src/lib/chempot-diagram → chempot-diagram}/ChemPotScene3D.svelte +0 -0
  908. /package/dist/{src/lib/colors → colors}/alloy-colors.json +0 -0
  909. /package/dist/{src/lib/colors → colors}/dark-mode-colors.json +0 -0
  910. /package/dist/{src/lib/colors → colors}/jmol-colors.json +0 -0
  911. /package/dist/{src/lib/colors → colors}/muted-colors.json +0 -0
  912. /package/dist/{src/lib/colors → colors}/pastel-colors.json +0 -0
  913. /package/dist/{src/lib/colors → colors}/vesta-colors.json +0 -0
  914. /package/dist/{src/lib/element → element}/BohrAtom.svelte +0 -0
  915. /package/dist/{src/lib/element → element}/Nucleus.svelte +0 -0
  916. /package/dist/{src/lib/element → element}/data.json +0 -0
  917. /package/dist/{src/lib/element → element}/data.json.gz +0 -0
  918. /package/dist/{src/lib/element → element}/data.json.gz.d.ts +0 -0
  919. /package/dist/{src/lib/element → element}/data.schema.json +0 -0
  920. /package/dist/{src/lib/element-image-urls.json → element-image-urls.json} +0 -0
  921. /package/dist/{src/lib/feedback → feedback}/Spinner.svelte +0 -0
  922. /package/dist/{src/lib/feedback → feedback}/StatusMessage.svelte +0 -0
  923. /package/dist/{src/lib/layout → layout}/json-tree/JsonValue.svelte +0 -0
  924. /package/dist/{src/lib/periodic-table → periodic-table}/TableInset.svelte +0 -0
  925. /package/dist/{src/lib/theme → theme}/themes.mjs +0 -0
  926. /package/dist/{src/lib/xrd → xrd}/atomic_scattering_params.json +0 -0
@@ -0,0 +1,1418 @@
1
+ <script lang="ts">
2
+ import { format_value } from '../../labels'
3
+ import { FullscreenToggle, set_fullscreen_bg } from '../../layout'
4
+ import type {
5
+ AxisLoadError,
6
+ BarStyle,
7
+ DataLoaderFn,
8
+ HistogramHandlerProps,
9
+ PanConfig,
10
+ RefLine,
11
+ RefLineEvent,
12
+ } from '..'
13
+ import {
14
+ compute_element_placement,
15
+ HistogramControls,
16
+ PlotAxis,
17
+ PlotLegend,
18
+ ReferenceLine,
19
+ } from '..'
20
+ import type { AxisChangeState } from '../core/axis-utils'
21
+ import { AXIS_DEFAULTS, create_axis_loader } from '../core/axis-utils'
22
+ import { extract_series_color, prepare_legend_data } from '../core/data-transform'
23
+ import {
24
+ create_dimension_tracker,
25
+ create_hover_lock,
26
+ } from '../core/hover-lock.svelte'
27
+ import { create_legend_visibility } from '../core/utils/series-visibility'
28
+ import {
29
+ get_relative_coords,
30
+ MIN_TOUCH_DISTANCE_PIXELS,
31
+ pan_range_by_pixels,
32
+ PINCH_ZOOM_THRESHOLD,
33
+ remove_drag_listeners,
34
+ resolve_axis_ranges,
35
+ sorted_range,
36
+ vec2_equal,
37
+ zoom_range_by_factor,
38
+ } from '../core/interactions'
39
+ import {
40
+ calc_auto_padding,
41
+ filter_padding,
42
+ LABEL_GAP_DEFAULT,
43
+ y2_axis_label_x,
44
+ measure_max_tick_width,
45
+ } from '../core/layout'
46
+ import {
47
+ build_obstacles_norm,
48
+ clip_bar,
49
+ has_explicit_position,
50
+ measured_footprint,
51
+ place_decorations,
52
+ } from '../core/auto-place'
53
+ import type { IndexedRefLine } from '../core/reference-line'
54
+ import { group_ref_lines_by_z, index_ref_lines } from '../core/reference-line'
55
+ import {
56
+ create_scale,
57
+ generate_ticks,
58
+ get_nice_data_range,
59
+ get_tick_label,
60
+ } from '../core/scales'
61
+ import type {
62
+ BasePlotProps,
63
+ DataSeries,
64
+ InitialRanges,
65
+ LegendConfig,
66
+ PlotConfig,
67
+ ScaleType,
68
+ } from '../core/types'
69
+ import { get_scale_type_name } from '../core/types'
70
+ import ZeroLines from '../core/components/ZeroLines.svelte'
71
+ import ZoomRect from '../core/components/ZoomRect.svelte'
72
+ import { DEFAULTS } from '../../settings'
73
+ import { bin, max } from 'd3-array'
74
+ import type { Snippet } from 'svelte'
75
+ import { onDestroy, untrack } from 'svelte'
76
+ import type { HTMLAttributes } from 'svelte/elements'
77
+ import { Tween } from 'svelte/motion'
78
+ import type { Vec2 } from '../../math'
79
+ import PlotTooltip from '../core/components/PlotTooltip.svelte'
80
+ import { bar_path } from '../core/svg'
81
+ import { unique_id } from '../core/utils'
82
+
83
+ let {
84
+ series = $bindable([]),
85
+ x_axis: x_axis_init = {},
86
+ x2_axis: x2_axis_init = {},
87
+ y_axis: y_axis_init = {},
88
+ y2_axis: y2_axis_init = {},
89
+ display: display_init = DEFAULTS.histogram.display,
90
+ range_padding = 0.05,
91
+ padding = { t: 20, b: 60, l: 60, r: 20 },
92
+ bins = $bindable(100),
93
+ show_legend = $bindable(true),
94
+ legend = {},
95
+ bar: bar_init = {},
96
+ selected_property = $bindable(``),
97
+ mode = $bindable(`single`),
98
+ tooltip,
99
+ hovered = $bindable(false),
100
+ change = () => {},
101
+ on_bar_click,
102
+ on_bar_hover,
103
+ ref_lines = $bindable([]),
104
+ on_ref_line_click,
105
+ on_ref_line_hover,
106
+ show_controls = $bindable(true),
107
+ controls_open = $bindable(false),
108
+ on_series_toggle = () => {},
109
+ controls_toggle_props,
110
+ controls_pane_props,
111
+ fullscreen = $bindable(false),
112
+ fullscreen_toggle = true,
113
+ children,
114
+ header_controls,
115
+ controls_extra,
116
+ data_loader,
117
+ on_axis_change,
118
+ on_error,
119
+ pan = {},
120
+ ...rest
121
+ }: HTMLAttributes<HTMLDivElement> & BasePlotProps & PlotConfig & {
122
+ series: DataSeries[]
123
+ // Component-specific props
124
+ bins?: number
125
+ show_legend?: boolean
126
+ legend?: LegendConfig | null
127
+ bar?: BarStyle
128
+ selected_property?: string
129
+ mode?: `single` | `overlay`
130
+ tooltip?: Snippet<[HistogramHandlerProps]>
131
+ header_controls?: Snippet<
132
+ [{ height: number; width: number; fullscreen: boolean }]
133
+ >
134
+ controls_extra?: Snippet<[Required<PlotConfig>]>
135
+ change?: (data: { value: number; count: number; property: string } | null) => void
136
+ on_bar_click?: (
137
+ data: {
138
+ value: number
139
+ count: number
140
+ property: string
141
+ event: MouseEvent | KeyboardEvent
142
+ },
143
+ ) => void
144
+ on_bar_hover?: (
145
+ data:
146
+ | { value: number; count: number; property: string; event: MouseEvent }
147
+ | null,
148
+ ) => void
149
+ ref_lines?: RefLine[]
150
+ on_ref_line_click?: (event: RefLineEvent) => void
151
+ on_ref_line_hover?: (event: RefLineEvent | null) => void
152
+ on_series_toggle?: (series_idx: number) => void
153
+ // Interactive axis props
154
+ data_loader?: DataLoaderFn
155
+ on_axis_change?: (
156
+ axis: `x` | `x2` | `y` | `y2`,
157
+ key: string,
158
+ new_series: DataSeries[],
159
+ ) => void
160
+ on_error?: (error: AxisLoadError) => void
161
+ pan?: PanConfig
162
+ } = $props()
163
+
164
+ // Local state for controls (initialized from props, owned by this component)
165
+ // Include key AXIS_DEFAULTS props (range, ticks, scale_type) that PlotControls needs
166
+ // Using $state because these have bindings in HistogramControls/PlotControls
167
+ // untrack() explicitly captures initial prop values (intentional - props provide initial config)
168
+ const { format: _, ...axis_state_defaults } = AXIS_DEFAULTS // Exclude format (has component-specific default)
169
+ let bar = $state(untrack(() => ({ ...DEFAULTS.histogram.bar, ...bar_init })))
170
+ let x_axis = $state(untrack(() => ({ ...axis_state_defaults, ...x_axis_init })))
171
+ // x2-axis needs different default label_shift for top-side positioning
172
+ let x2_axis = $state(untrack(() => ({
173
+ ...axis_state_defaults,
174
+ label_shift: { x: 0, y: 40 },
175
+ ...x2_axis_init,
176
+ })))
177
+ let y_axis = $state(untrack(() => ({ ...axis_state_defaults, ...y_axis_init })))
178
+ // y2 title stays vertically centered; its x position is computed by y2_axis_label_x
179
+ let y2_axis = $state(untrack(() => ({
180
+ ...axis_state_defaults,
181
+ label_shift: { x: 0, y: 0 },
182
+ ...y2_axis_init,
183
+ })))
184
+ let display = $state(
185
+ untrack(() => ({ ...DEFAULTS.histogram.display, ...display_init })),
186
+ )
187
+
188
+ // Merge component-specific defaults with local state (format comes from here, not AXIS_DEFAULTS)
189
+ const final_x_axis = $derived({ label: `Value`, format: `.2~s`, ...x_axis })
190
+ const final_x2_axis = $derived({ label: `Value`, format: `.2~s`, ...x2_axis })
191
+ const final_y_axis = $derived({ label: `Count`, format: `d`, ...y_axis })
192
+ const final_bar = $derived({ ...DEFAULTS.histogram.bar, ...bar })
193
+ const final_y2_axis = $derived({ label: `Count`, format: `d`, ...y2_axis })
194
+
195
+ // Core state
196
+ let [width, height] = $state([0, 0])
197
+ let wrapper: HTMLDivElement | undefined = $state()
198
+ let svg_element: SVGElement | null = $state(null)
199
+ const clip_path_id = unique_id(`histogram-clip`) // stable, collision-resistant (see unique_id)
200
+ let hover_info = $state<HistogramHandlerProps | null>(null)
201
+
202
+ // Reference line hover state
203
+ let hovered_ref_line_idx = $state<number | null>(null)
204
+
205
+ // Interactive axis loading state
206
+ let axis_loading = $state<`x` | `x2` | `y` | `y2` | null>(null)
207
+
208
+ // Compute ref_lines with index and group by z-index (using shared utilities)
209
+ let indexed_ref_lines = $derived(index_ref_lines(ref_lines))
210
+ let ref_lines_by_z = $derived(group_ref_lines_by_z(indexed_ref_lines))
211
+ let drag_state = $state<{
212
+ start: { x: number; y: number } | null
213
+ current: { x: number; y: number } | null
214
+ bounds: DOMRect | null
215
+ }>({ start: null, current: null, bounds: null })
216
+
217
+ // Pan state
218
+ let is_focused = $state(false)
219
+ let shift_held = $state(false)
220
+ let pan_drag_state = $state<
221
+ InitialRanges & { start: { x: number; y: number } } | null
222
+ >(null)
223
+ let touch_state = $state<
224
+ InitialRanges & { start_touches: { x: number; y: number }[] } | null
225
+ >(null)
226
+
227
+ // Legend placement stability state
228
+ let legend_element = $state<HTMLDivElement | undefined>()
229
+ let hovered_legend_series_idx = $state<number | null>(null)
230
+ const legend_hover = create_hover_lock()
231
+ const dim_tracker = create_dimension_tracker()
232
+ let has_initial_legend_placement = $state(false)
233
+
234
+ // Clear pending hover lock timeout on unmount
235
+ $effect(() => () => legend_hover.cleanup())
236
+
237
+ // Derived data
238
+ type IndexedSeries = { series_data: DataSeries; series_idx: number }
239
+ let visible_series_labels = $derived(
240
+ series
241
+ .filter((series_data) => series_data.visible ?? true)
242
+ .map((series_data) => series_data.label)
243
+ .filter((label): label is string => typeof label === `string` && label.length > 0),
244
+ )
245
+ $effect(() => {
246
+ if (mode !== `single`) return
247
+ if (selected_property && visible_series_labels.includes(selected_property)) return
248
+ selected_property = visible_series_labels[0] ?? ``
249
+ })
250
+ let selected_series_entries = $derived<IndexedSeries[]>(
251
+ series
252
+ .map((series_data: DataSeries, series_idx: number) => ({ series_data, series_idx }))
253
+ .filter(({ series_data }) =>
254
+ (series_data.visible ?? true) &&
255
+ (mode !== `single` || !selected_property || series_data.label === selected_property)
256
+ ),
257
+ )
258
+ let selected_series = $derived(
259
+ selected_series_entries.map(({ series_data }) => series_data),
260
+ )
261
+
262
+ // Separate series by y-axis
263
+ let y1_series = $derived(
264
+ selected_series.filter((srs: DataSeries) => (srs.y_axis ?? `y1`) === `y1`),
265
+ )
266
+ let y2_series = $derived(
267
+ selected_series.filter((srs: DataSeries) => srs.y_axis === `y2`),
268
+ )
269
+ let x2_series = $derived(
270
+ selected_series.filter((srs: DataSeries) => srs.x_axis === `x2`),
271
+ )
272
+
273
+ let auto_ranges = $derived.by(() => {
274
+ // Only x1 series contribute to the x1 auto-range (x2 series get their own domain below)
275
+ const x1_values = selected_series.flatMap((srs) => srs.x_axis === `x2` ? [] : srs.y)
276
+ const auto_x = get_nice_data_range(
277
+ x1_values.map((val) => ({ x: val, y: 0 })),
278
+ ({ x }) => x,
279
+ final_x_axis.range ?? [null, null],
280
+ final_x_axis.scale_type ?? `linear`,
281
+ range_padding,
282
+ false,
283
+ )
284
+
285
+ const x2_values = x2_series.flatMap((srs: DataSeries) => srs.y)
286
+ const auto_x2 = x2_values.length > 0
287
+ ? get_nice_data_range(
288
+ x2_values.map((val) => ({ x: val, y: 0 })),
289
+ ({ x }) => x,
290
+ final_x2_axis.range ?? [null, null],
291
+ final_x2_axis.scale_type ?? `linear`,
292
+ range_padding,
293
+ false,
294
+ )
295
+ : [0, 1] as Vec2
296
+
297
+ // Calculate y-range for a specific set of series
298
+ const calc_y_range = (
299
+ series_list: typeof selected_series,
300
+ y_limit: [number | null, number | null],
301
+ scale_type: ScaleType,
302
+ ): Vec2 => {
303
+ const type_name = get_scale_type_name(scale_type)
304
+ if (series_list.length === 0) {
305
+ const fallback = type_name === `log` ? 1 : 0
306
+ return [fallback, 1]
307
+ }
308
+ // Bin each series over the domain of the x-axis it renders on (d3 bin() drops
309
+ // out-of-domain values, so binning x2 series over the x1 domain skews max_count)
310
+ const max_count = Math.max(
311
+ 0,
312
+ ...series_list.map((srs: DataSeries) => {
313
+ const hist = bin().domain(srs.x_axis === `x2` ? auto_x2 : auto_x).thresholds(bins)
314
+ return max(hist(srs.y), (data) => data.length) || 0
315
+ }),
316
+ )
317
+
318
+ // If there's effectively no data, avoid log-range issues (counts can't be <= 0 on log)
319
+ if (max_count <= 0) {
320
+ const fallback = type_name === `log` ? 1 : 0
321
+ return [fallback, 1]
322
+ }
323
+
324
+ const [y0, y1] = get_nice_data_range(
325
+ [{ x: 0, y: 0 }, { x: max_count, y: 0 }],
326
+ ({ x }) => x,
327
+ y_limit,
328
+ scale_type,
329
+ range_padding,
330
+ false,
331
+ )
332
+ // For log scale, minimum must be >= 1 (count can't be 0 on log)
333
+ // For linear/arcsinh, start from 0
334
+ const y_min = type_name === `log` ? Math.max(1, y0) : Math.max(0, y0)
335
+ return [y_min, y1]
336
+ }
337
+
338
+ const y1_range = calc_y_range(
339
+ y1_series,
340
+ final_y_axis.range ?? [null, null],
341
+ final_y_axis.scale_type ?? `linear`,
342
+ )
343
+ const y2_auto_range = calc_y_range(
344
+ y2_series,
345
+ final_y2_axis.range ?? [null, null],
346
+ final_y2_axis.scale_type ?? `linear`,
347
+ )
348
+
349
+ return { x: auto_x, x2: auto_x2, y: y1_range, y2: y2_auto_range }
350
+ })
351
+
352
+ // Initialize ranges
353
+ let ranges = $state({
354
+ initial: {
355
+ x: [0, 1] as Vec2,
356
+ x2: [0, 1] as Vec2,
357
+ y: [0, 1] as Vec2,
358
+ y2: [0, 1] as Vec2,
359
+ },
360
+ current: {
361
+ x: [0, 1] as Vec2,
362
+ x2: [0, 1] as Vec2,
363
+ y: [0, 1] as Vec2,
364
+ y2: [0, 1] as Vec2,
365
+ },
366
+ })
367
+
368
+ $effect(() => {
369
+ // Supports one-sided range pinning (null bounds fall back to auto); returns null
370
+ // for transient non-finite bounds (skip: writing NaN breaks scales and loops here)
371
+ const next = resolve_axis_ranges(
372
+ { x: final_x_axis, x2: final_x2_axis, y: final_y_axis, y2: final_y2_axis },
373
+ auto_ranges,
374
+ )
375
+ if (!next) return
376
+ // Update only changed axes (preserving each unchanged axis's panned current view).
377
+ // untrack the reads of `ranges` so the writes below can't re-trigger this effect
378
+ // (reading + writing the same state otherwise causes effect_update_depth_exceeded).
379
+ const init = untrack(() => ranges.initial)
380
+ if (!vec2_equal(init.x, next.x)) [ranges.initial.x, ranges.current.x] = [next.x, next.x]
381
+ if (!vec2_equal(init.x2, next.x2)) [ranges.initial.x2, ranges.current.x2] = [next.x2, next.x2]
382
+ if (!vec2_equal(init.y, next.y)) [ranges.initial.y, ranges.current.y] = [next.y, next.y]
383
+ if (!vec2_equal(init.y2, next.y2)) [ranges.initial.y2, ranges.current.y2] = [next.y2, next.y2]
384
+ })
385
+
386
+ // Layout: dynamic padding based on tick label widths
387
+ const default_padding = { t: 20, b: 60, l: 60, r: 20 }
388
+ // base_pad reserves space for tick labels/axis titles; pad (below) adds decoration reservations
389
+ let base_pad = $derived(filter_padding(padding, default_padding))
390
+
391
+ // Update padding based on tick label widths (untrack breaks circular dependency)
392
+ $effect(() => {
393
+ const current_ticks_x2 = untrack(() => ticks.x2)
394
+ const current_ticks_y = untrack(() => ticks.y)
395
+ const current_ticks_y2 = untrack(() => ticks.y2)
396
+
397
+ const new_pad = width && height && current_ticks_y.length > 0
398
+ ? calc_auto_padding({
399
+ padding,
400
+ default_padding,
401
+ x2_axis: { ...final_x2_axis, tick_values: current_ticks_x2 },
402
+ y_axis: { ...final_y_axis, tick_values: current_ticks_y },
403
+ y2_axis: { ...final_y2_axis, tick_values: current_ticks_y2 },
404
+ })
405
+ : filter_padding(padding, default_padding)
406
+
407
+ // Add y2 axis label space (calc_auto_padding only accounts for tick labels)
408
+ if (
409
+ width && height && y2_series.length > 0 && current_ticks_y2.length > 0 &&
410
+ final_y2_axis.label
411
+ ) {
412
+ const inside = final_y2_axis.tick?.label?.inside ?? false
413
+ // When ticks are inside, they don't contribute to padding
414
+ const tick_shift = inside ? 0 : (final_y2_axis.tick?.label?.shift?.x ?? 0) + 8
415
+ const tick_width_contribution = inside ? 0 : tick_label_widths.y2_max
416
+ const label_thickness = Math.round(12 * 1.2)
417
+ new_pad.r = Math.max(
418
+ new_pad.r,
419
+ tick_width_contribution + LABEL_GAP_DEFAULT + tick_shift + label_thickness,
420
+ )
421
+ }
422
+
423
+ // Add x2 axis label space (mirroring y2 logic for top padding)
424
+ if (
425
+ width && height && x2_series.length > 0 && current_ticks_x2.length > 0 &&
426
+ final_x2_axis.label
427
+ ) {
428
+ const inside = final_x2_axis.tick?.label?.inside ?? false
429
+ const tick_shift = inside
430
+ ? 0
431
+ : Math.abs(final_x2_axis.tick?.label?.shift?.y ?? 0) + 8
432
+ const label_thickness = Math.round(12 * 1.2)
433
+ new_pad.t = Math.max(
434
+ new_pad.t,
435
+ tick_shift + LABEL_GAP_DEFAULT + label_thickness,
436
+ )
437
+ }
438
+
439
+ // Only update if padding actually changed
440
+ if (
441
+ base_pad.t !== new_pad.t || base_pad.b !== new_pad.b ||
442
+ base_pad.l !== new_pad.l || base_pad.r !== new_pad.r
443
+ ) base_pad = new_pad
444
+ })
445
+
446
+ const legend_footprint = $derived(measured_footprint(legend_element, { width: 120, height: 60 }))
447
+ const legend_has_explicit_pos = $derived(has_explicit_position(legend?.style))
448
+
449
+ // Obstacle field in normalized [0,1] plot coords (y=0 at top). Each filled bar is modeled as a
450
+ // vertical segment (top -> baseline) so the legend can't hide inside a tall bar. Built from
451
+ // histogram_bins (pad-independent) + ranges so the crowding decision can't see its own reservation.
452
+ const obstacles_norm = $derived.by(() => {
453
+ if (!width || !height || histogram_bins.length === 0) return []
454
+ const base_w = width - base_pad.l - base_pad.r
455
+ const base_h = height - base_pad.t - base_pad.b
456
+ if (base_w <= 0 || base_h <= 0) return []
457
+ const bars: { points: { x: number; y: number }[]; draws_line: boolean }[] = []
458
+ for (const hist of histogram_bins) {
459
+ const [rx0, rx1] = hist.x_axis === `x2` ? ranges.current.x2 : ranges.current.x
460
+ const [ry0, ry1] = hist.y_axis === `y2` ? ranges.current.y2 : ranges.current.y
461
+ const x_span = rx1 - rx0
462
+ const y_span = ry1 - ry0
463
+ if (!(x_span > 0) || !(y_span > 0)) continue
464
+ for (const series_bin of hist.bins) {
465
+ if (series_bin.length <= 0) continue
466
+ const x_norm = (((series_bin.x0 ?? 0) + (series_bin.x1 ?? 0)) / 2 - rx0) / x_span
467
+ const top = 1 - (series_bin.length - ry0) / y_span
468
+ const baseline = 1 + ry0 / y_span // normalized y of count=0 (bar foot)
469
+ const seg = clip_bar(true, x_norm, top, baseline)
470
+ if (seg) bars.push(seg)
471
+ }
472
+ }
473
+ return build_obstacles_norm(bars, base_w, base_h)
474
+ })
475
+
476
+ // Move the legend to the bottom margin when no interior spot avoids the bars
477
+ const decor = $derived.by(() =>
478
+ place_decorations({
479
+ base_pad,
480
+ width,
481
+ height,
482
+ obstacles_norm,
483
+ // gate on legend_element (the render signal) not legend_data, whose entries can read pad
484
+ legend: show_legend && legend != null && series.length > 1 &&
485
+ legend_element != null && !legend_has_explicit_pos
486
+ ? { footprint: legend_footprint, clearance: legend?.axis_clearance }
487
+ : null,
488
+ })
489
+ )
490
+ const pad = $derived(decor.pad)
491
+ const legend_auto_outside = $derived(decor.legend_outside)
492
+ const legend_outside_x = $derived(decor.legend_pos.x)
493
+ const legend_outside_y = $derived(decor.legend_pos.y)
494
+
495
+ // Scales and data
496
+ let scales = $derived({
497
+ x: create_scale(
498
+ final_x_axis.scale_type ?? `linear`,
499
+ ranges.current.x,
500
+ [pad.l, width - pad.r],
501
+ ),
502
+ x2: create_scale(
503
+ final_x2_axis.scale_type ?? `linear`,
504
+ ranges.current.x2,
505
+ [pad.l, width - pad.r],
506
+ ),
507
+ y: create_scale(
508
+ final_y_axis.scale_type ?? `linear`,
509
+ ranges.current.y,
510
+ [height - pad.b, pad.t],
511
+ ),
512
+ y2: create_scale(
513
+ final_y2_axis.scale_type ?? `linear`,
514
+ ranges.current.y2,
515
+ [height - pad.b, pad.t],
516
+ ),
517
+ })
518
+
519
+ // Pad-independent binning (no pixel scales) so the auto-place obstacle field can reuse it
520
+ let histogram_bins = $derived.by(() => {
521
+ if (selected_series.length === 0 || !width || !height) return []
522
+ const hist_generator = bin()
523
+ .domain([ranges.current.x[0], ranges.current.x[1]])
524
+ .thresholds(bins)
525
+ const x2_hist_generator = x2_series.length > 0
526
+ ? bin().domain([ranges.current.x2[0], ranges.current.x2[1]]).thresholds(bins)
527
+ : null
528
+ return selected_series_entries.map(({ series_data, series_idx }) => {
529
+ const use_x2 = series_data.x_axis === `x2`
530
+ const active_hist = use_x2 && x2_hist_generator ? x2_hist_generator : hist_generator
531
+ const bins_arr = active_hist(series_data.y)
532
+ return {
533
+ id: series_data.id ?? series_idx,
534
+ series_idx,
535
+ label: series_data.label || `Series ${series_idx + 1}`,
536
+ color: selected_series.length === 1
537
+ ? final_bar.color
538
+ : extract_series_color(series_data),
539
+ bins: bins_arr,
540
+ max_count: max(bins_arr, (data) => data.length) || 0,
541
+ x_axis: series_data.x_axis,
542
+ y_axis: series_data.y_axis,
543
+ }
544
+ })
545
+ })
546
+ // Render-time data adds the pixel scales (pad-dependent)
547
+ let histogram_data = $derived(
548
+ histogram_bins.map((hist) => ({
549
+ ...hist,
550
+ x_scale: hist.x_axis === `x2` ? scales.x2 : scales.x,
551
+ y_scale: hist.y_axis === `y2` ? scales.y2 : scales.y,
552
+ })),
553
+ )
554
+
555
+ let ticks = $derived({
556
+ x: width && height
557
+ ? generate_ticks(
558
+ ranges.current.x,
559
+ final_x_axis.scale_type ?? `linear`,
560
+ final_x_axis.ticks,
561
+ scales.x,
562
+ { default_count: 8 },
563
+ )
564
+ : [],
565
+ x2: width && height && x2_series.length > 0
566
+ ? generate_ticks(
567
+ ranges.current.x2,
568
+ final_x2_axis.scale_type ?? `linear`,
569
+ final_x2_axis.ticks,
570
+ scales.x2,
571
+ { default_count: 8 },
572
+ )
573
+ : [],
574
+ y: width && height
575
+ ? generate_ticks(
576
+ ranges.current.y,
577
+ final_y_axis.scale_type ?? `linear`,
578
+ final_y_axis.ticks,
579
+ scales.y,
580
+ { default_count: 6 },
581
+ )
582
+ : [],
583
+ y2: width && height && y2_series.length > 0
584
+ ? generate_ticks(
585
+ ranges.current.y2,
586
+ final_y2_axis.scale_type ?? `linear`,
587
+ final_y2_axis.ticks,
588
+ scales.y2,
589
+ { default_count: 6 },
590
+ )
591
+ : [],
592
+ })
593
+
594
+ // Cache measured tick-label widths so expensive text measurement only runs
595
+ // when tick values/format change, not on every template rerender.
596
+ let tick_label_widths = $derived({
597
+ x2_max: measure_max_tick_width(ticks.x2, final_x2_axis.format ?? ``),
598
+ y_max: measure_max_tick_width(ticks.y, final_y_axis.format ?? ``),
599
+ y2_max: measure_max_tick_width(ticks.y2, final_y2_axis.format ?? ``),
600
+ })
601
+
602
+ let legend_data = $derived(prepare_legend_data(series))
603
+
604
+ // Collect histogram bar positions for legend placement
605
+ let hist_points_for_placement = $derived.by(() => {
606
+ if (!width || !height || histogram_data.length === 0) return []
607
+
608
+ const points: { x: number; y: number }[] = []
609
+
610
+ for (const { bins: series_bins, x_scale, y_scale } of histogram_data) {
611
+ for (const series_bin of series_bins) {
612
+ if (series_bin.length > 0) {
613
+ const bar_x = x_scale(((series_bin.x0 ?? 0) + (series_bin.x1 ?? 0)) / 2)
614
+ const bar_y = y_scale(series_bin.length)
615
+ if (isFinite(bar_x) && isFinite(bar_y)) {
616
+ // Add multiple points for taller bars to increase their weight
617
+ // Cap to prevent O(N·count/10) blow-ups for large counts
618
+ const weight = Math.min(20, Math.ceil(series_bin.length / 10))
619
+ for (let idx = 0; idx < weight; idx++) points.push({ x: bar_x, y: bar_y })
620
+ }
621
+ }
622
+ }
623
+ }
624
+ return points
625
+ })
626
+
627
+ // Calculate best legend placement using continuous grid sampling
628
+ let legend_placement = $derived.by(() => {
629
+ const should_place = show_legend && legend != null && series.length > 1
630
+ if (!should_place || !width || !height) return null
631
+
632
+ const plot_width = width - pad.l - pad.r
633
+ const plot_height = height - pad.t - pad.b
634
+
635
+ const result = compute_element_placement({
636
+ plot_bounds: { x: pad.l, y: pad.t, width: plot_width, height: plot_height },
637
+ element: legend_element,
638
+ element_size: { width: 120, height: 60 }, // fallback before first render
639
+ axis_clearance: legend?.axis_clearance,
640
+ exclude_rects: [],
641
+ points: hist_points_for_placement,
642
+ })
643
+
644
+ return result
645
+ })
646
+
647
+ // Tweened legend coordinates for smooth animation - create once, update target via effect
648
+ // untrack() explicitly captures initial tween config (intentional - config set once at mount)
649
+ const tweened_legend_coords = new Tween(
650
+ { x: 0, y: 0 },
651
+ untrack(() => ({ duration: 400, ...legend?.tween })),
652
+ )
653
+
654
+ // Update legend position with stability checks
655
+ $effect(() => {
656
+ if (!width || !height || !legend_placement) return
657
+
658
+ // Track dimensions for resize detection
659
+ const dims_changed = dim_tracker.has_changed(width, height)
660
+ if (dims_changed) dim_tracker.update(width, height)
661
+
662
+ // Only update if: resize occurred, OR (not hover-locked AND (responsive OR not yet initially placed))
663
+ const is_responsive = legend?.responsive ?? false
664
+ const should_update = dims_changed || (!legend_hover.is_locked.current &&
665
+ (is_responsive || !has_initial_legend_placement))
666
+
667
+ if (should_update) {
668
+ tweened_legend_coords.set(
669
+ { x: legend_placement.x, y: legend_placement.y },
670
+ // Skip animation on initial placement to avoid jump from (0, 0)
671
+ has_initial_legend_placement ? undefined : { duration: 0 },
672
+ )
673
+ // Only lock position after we have actual measured size
674
+ if (legend_element) {
675
+ has_initial_legend_placement = true
676
+ }
677
+ }
678
+ })
679
+
680
+ // Event handlers
681
+ const handle_zoom = () => {
682
+ if (!drag_state.start || !drag_state.current) return
683
+ const start_x = scales.x.invert(drag_state.start.x)
684
+ const end_x = scales.x.invert(drag_state.current.x)
685
+ const start_x2 = scales.x2.invert(drag_state.start.x)
686
+ const end_x2 = scales.x2.invert(drag_state.current.x)
687
+ const start_y = scales.y.invert(drag_state.start.y)
688
+ const end_y = scales.y.invert(drag_state.current.y)
689
+ const start_y2 = scales.y2.invert(drag_state.start.y)
690
+ const end_y2 = scales.y2.invert(drag_state.current.y)
691
+
692
+ if (typeof start_x === `number` && typeof end_x === `number`) {
693
+ const dx = Math.abs(drag_state.start.x - drag_state.current.x)
694
+ const dy = Math.abs(drag_state.start.y - drag_state.current.y)
695
+ if (dx > 5 && dy > 5) {
696
+ // Update axis ranges to trigger reactivity and prevent effect from overriding
697
+ x_axis = { ...x_axis, range: sorted_range(start_x, end_x) }
698
+ if (x2_series.length > 0) {
699
+ x2_axis = { ...x2_axis, range: sorted_range(start_x2, end_x2) }
700
+ }
701
+ y_axis = { ...y_axis, range: sorted_range(start_y, end_y) }
702
+ // gate on y2 series presence (like x2): the y2 scale is a [0, 1] sentinel
703
+ // otherwise, so inverting would store a phantom range in the bindable prop
704
+ if (y2_series.length > 0) {
705
+ y2_axis = { ...y2_axis, range: sorted_range(start_y2, end_y2) }
706
+ }
707
+ }
708
+ }
709
+ }
710
+
711
+ const on_window_mouse_move = (evt: MouseEvent) => {
712
+ if (!drag_state.start || !drag_state.bounds) return
713
+ drag_state.current = {
714
+ x: evt.clientX - drag_state.bounds.left,
715
+ y: evt.clientY - drag_state.bounds.top,
716
+ }
717
+ }
718
+
719
+ const on_window_mouse_up = () => {
720
+ handle_zoom()
721
+ drag_state = { start: null, current: null, bounds: null }
722
+ window.removeEventListener(`mousemove`, on_window_mouse_move)
723
+ window.removeEventListener(`mouseup`, on_window_mouse_up)
724
+ document.body.style.cursor = `default`
725
+ }
726
+
727
+ // Pan/zoom all four axes from an interaction-start snapshot, each in its own
728
+ // scale's transform space (log axes pan by a constant factor, linear by a shift).
729
+ // Plot dims clamped to 1px so degenerate containers can't produce Infinity deltas.
730
+ const pan_all_axes = (init: InitialRanges, dx_px: number, dy_px: number) => {
731
+ const plot_width = Math.max(1, width - pad.l - pad.r)
732
+ const plot_height = Math.max(1, height - pad.t - pad.b)
733
+ ranges.current.x = pan_range_by_pixels(init.initial_x_range, dx_px, plot_width, final_x_axis.scale_type)
734
+ ranges.current.x2 = pan_range_by_pixels(init.initial_x2_range, dx_px, plot_width, final_x2_axis.scale_type)
735
+ ranges.current.y = pan_range_by_pixels(init.initial_y_range, dy_px, plot_height, final_y_axis.scale_type)
736
+ ranges.current.y2 = pan_range_by_pixels(init.initial_y2_range, dy_px, plot_height, final_y2_axis.scale_type)
737
+ }
738
+ const zoom_all_axes = (init: InitialRanges, factor: number) => {
739
+ ranges.current.x = zoom_range_by_factor(init.initial_x_range, factor, final_x_axis.scale_type)
740
+ ranges.current.x2 = zoom_range_by_factor(init.initial_x2_range, factor, final_x2_axis.scale_type)
741
+ ranges.current.y = zoom_range_by_factor(init.initial_y_range, factor, final_y_axis.scale_type)
742
+ ranges.current.y2 = zoom_range_by_factor(init.initial_y2_range, factor, final_y2_axis.scale_type)
743
+ }
744
+
745
+ // Pan drag handler (drag direction inverted on x for natural pan feel)
746
+ const on_pan_move = (evt: MouseEvent) => {
747
+ if (!pan_drag_state) return
748
+ const sensitivity = pan?.drag_sensitivity ?? 1
749
+ pan_all_axes(
750
+ pan_drag_state,
751
+ -(evt.clientX - pan_drag_state.start.x) * sensitivity,
752
+ (evt.clientY - pan_drag_state.start.y) * sensitivity,
753
+ )
754
+ }
755
+
756
+ const on_pan_end = () => {
757
+ pan_drag_state = null
758
+ document.body.style.cursor = ``
759
+ window.removeEventListener(`mousemove`, on_pan_move)
760
+ window.removeEventListener(`mouseup`, on_pan_end)
761
+ }
762
+
763
+ // Tear down any window listeners + cursor override if the component unmounts mid-drag
764
+ // (mouseup/panend would otherwise never fire, leaking listeners and a stuck cursor).
765
+ // onDestroy also runs during SSR teardown, where window/document don't exist.
766
+ onDestroy(() => {
767
+ remove_drag_listeners([on_window_mouse_move, on_pan_move], [on_window_mouse_up, on_pan_end])
768
+ drag_state = { start: null, current: null, bounds: null }
769
+ pan_drag_state = null
770
+ })
771
+
772
+ function handle_mouse_down(evt: MouseEvent) {
773
+ const coords = get_relative_coords(evt)
774
+ if (!coords || !svg_element) return
775
+
776
+ // Check if pan is enabled and shift is held for pan mode
777
+ const pan_enabled = pan?.enabled !== false
778
+ if (pan_enabled && evt.shiftKey) {
779
+ evt.preventDefault()
780
+ pan_drag_state = {
781
+ start: { x: evt.clientX, y: evt.clientY },
782
+ initial_x_range: [...ranges.current.x] as [number, number],
783
+ initial_x2_range: [...ranges.current.x2] as [number, number],
784
+ initial_y_range: [...ranges.current.y] as [number, number],
785
+ initial_y2_range: [...ranges.current.y2] as [number, number],
786
+ }
787
+ document.body.style.cursor = `grabbing`
788
+ window.addEventListener(`mousemove`, on_pan_move)
789
+ window.addEventListener(`mouseup`, on_pan_end)
790
+ return
791
+ }
792
+
793
+ drag_state = {
794
+ start: coords,
795
+ current: coords,
796
+ bounds: svg_element.getBoundingClientRect(),
797
+ }
798
+ window.addEventListener(`mousemove`, on_window_mouse_move)
799
+ window.addEventListener(`mouseup`, on_window_mouse_up)
800
+ evt.preventDefault()
801
+ }
802
+
803
+ // Wheel handler for pan (requires focus and shift)
804
+ function handle_wheel(evt: WheelEvent) {
805
+ const pan_enabled = pan?.enabled !== false
806
+ // Only capture wheel when focused AND Shift is held
807
+ // Use shift_held state (tracked via keydown/keyup) for compatibility with synthetic events
808
+ if (!pan_enabled || !is_focused || !shift_held) return
809
+
810
+ evt.preventDefault()
811
+
812
+ // Clamp to at least 1 to avoid Infinity deltas when padding equals container size
813
+ const plot_width = Math.max(1, width - pad.l - pad.r)
814
+ const plot_height = Math.max(1, height - pad.t - pad.b)
815
+ const sensitivity = pan?.wheel_sensitivity ?? 1
816
+
817
+ // Pan along the dominant wheel direction
818
+ if (Math.abs(evt.deltaX) > Math.abs(evt.deltaY)) {
819
+ const dx = evt.deltaX * sensitivity
820
+ ranges.current.x = pan_range_by_pixels(ranges.current.x, dx, plot_width, final_x_axis.scale_type)
821
+ ranges.current.x2 = pan_range_by_pixels(ranges.current.x2, dx, plot_width, final_x2_axis.scale_type)
822
+ } else {
823
+ const dy = evt.deltaY * sensitivity
824
+ ranges.current.y = pan_range_by_pixels(ranges.current.y, dy, plot_height, final_y_axis.scale_type)
825
+ ranges.current.y2 = pan_range_by_pixels(ranges.current.y2, dy, plot_height, final_y2_axis.scale_type)
826
+ }
827
+ }
828
+
829
+ // Touch handlers for pinch-zoom and two-finger pan
830
+ function handle_touch_start(evt: TouchEvent) {
831
+ const touch_enabled = pan?.enabled !== false && pan?.touch_enabled !== false
832
+ if (!touch_enabled || evt.touches.length !== 2) return
833
+
834
+ evt.preventDefault()
835
+ const touches = Array.from(evt.touches)
836
+ touch_state = {
837
+ start_touches: touches.map((touch) => ({ x: touch.clientX, y: touch.clientY })),
838
+ initial_x_range: [...ranges.current.x] as [number, number],
839
+ initial_x2_range: [...ranges.current.x2] as [number, number],
840
+ initial_y_range: [...ranges.current.y] as [number, number],
841
+ initial_y2_range: [...ranges.current.y2] as [number, number],
842
+ }
843
+ }
844
+
845
+ function handle_touch_move(evt: TouchEvent) {
846
+ if (!touch_state || evt.touches.length !== 2) return
847
+ evt.preventDefault()
848
+
849
+ const [t1, t2] = Array.from(evt.touches)
850
+ const [s1, s2] = touch_state.start_touches
851
+
852
+ // Calculate center movement for pan
853
+ const start_center = { x: (s1.x + s2.x) / 2, y: (s1.y + s2.y) / 2 }
854
+ const curr_center = {
855
+ x: (t1.clientX + t2.clientX) / 2,
856
+ y: (t1.clientY + t2.clientY) / 2,
857
+ }
858
+ const dx = curr_center.x - start_center.x
859
+ const dy = curr_center.y - start_center.y
860
+
861
+ // Calculate pinch scale (curr/start so spread = zoom out, pinch = zoom in)
862
+ const start_dist = Math.hypot(s2.x - s1.x, s2.y - s1.y)
863
+ // ignore near-coincident touches so curr_dist / start_dist can't blow up the scale
864
+ if (start_dist < MIN_TOUCH_DISTANCE_PIXELS) return
865
+ const curr_dist = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY)
866
+ const scale = curr_dist / start_dist
867
+
868
+ // Pinch zoom about the view center (spread = zoom in, pinch = zoom out)
869
+ if (Math.abs(scale - 1) > PINCH_ZOOM_THRESHOLD && scale > Number.EPSILON) {
870
+ zoom_all_axes(touch_state, scale)
871
+ } else pan_all_axes(touch_state, -dx, dy)
872
+ }
873
+
874
+ function handle_touch_end() {
875
+ touch_state = null
876
+ }
877
+
878
+ function handle_double_click() {
879
+ // Reset zoom to initial ranges (undo any pan/zoom)
880
+ ranges.current.x = [...ranges.initial.x] as [number, number]
881
+ ranges.current.x2 = [...ranges.initial.x2] as [number, number]
882
+ ranges.current.y = [...ranges.initial.y] as [number, number]
883
+ ranges.current.y2 = [...ranges.initial.y2] as [number, number]
884
+ // Also reset axis props so future data changes recalculate auto ranges
885
+ x_axis = { ...x_axis, range: [null, null] }
886
+ x2_axis = { ...x2_axis, range: [null, null] }
887
+ y_axis = { ...y_axis, range: [null, null] }
888
+ y2_axis = { ...y2_axis, range: [null, null] }
889
+ }
890
+
891
+ function handle_mouse_move(
892
+ evt: MouseEvent,
893
+ value: number,
894
+ count: number,
895
+ property: string,
896
+ active_y_axis: `y1` | `y2` = `y1`,
897
+ series_idx: number = 0,
898
+ active_x_axis: `x1` | `x2` = `x1`,
899
+ ) {
900
+ hovered = true
901
+ hover_info = {
902
+ value,
903
+ count,
904
+ property,
905
+ active_y_axis,
906
+ active_x_axis,
907
+ x: value,
908
+ y: count,
909
+ series_idx,
910
+ metadata: null,
911
+ label: property,
912
+ x_axis: active_x_axis === `x2` ? x2_axis : x_axis,
913
+ x2_axis,
914
+ y_axis: active_y_axis === `y2` ? y2_axis : y_axis,
915
+ y2_axis,
916
+ }
917
+ change({ value, count, property })
918
+ on_bar_hover?.({ value, count, property, event: evt })
919
+ }
920
+
921
+ const legend_vis = create_legend_visibility(() => series, (next) => (series = next))
922
+
923
+ // Set theme-aware background when entering fullscreen
924
+ $effect(() => {
925
+ set_fullscreen_bg(wrapper, fullscreen, `--histogram-fullscreen-bg`)
926
+ })
927
+
928
+ // State accessors for shared axis change handler
929
+ const axis_state: AxisChangeState<DataSeries> = {
930
+ get_axis: (axis) => {
931
+ if (axis === `x`) return x_axis
932
+ if (axis === `x2`) return x2_axis
933
+ if (axis === `y`) return y_axis
934
+ return y2_axis
935
+ },
936
+ set_axis: (axis, config) => {
937
+ // Spread into existing state to preserve merged type structure
938
+ if (axis === `x`) x_axis = { ...x_axis, ...config }
939
+ else if (axis === `x2`) x2_axis = { ...x2_axis, ...config }
940
+ else if (axis === `y`) y_axis = { ...y_axis, ...config }
941
+ else y2_axis = { ...y2_axis, ...config }
942
+ },
943
+ get_series: () => series,
944
+ set_series: (new_series) => (series = new_series),
945
+ get_loading: () => axis_loading,
946
+ set_loading: (axis) => (axis_loading = axis),
947
+ }
948
+
949
+ // Shared handler + one-shot auto-load bound to this component's state
950
+ const { handle_axis_change, try_auto_load } = create_axis_loader(
951
+ axis_state,
952
+ () => ({ data_loader, on_axis_change, on_error }),
953
+ )
954
+ $effect(try_auto_load)
955
+ </script>
956
+
957
+ {#snippet ref_lines_layer(lines: IndexedRefLine[])}
958
+ {#each lines as line (line.id ?? line.idx)}
959
+ <ReferenceLine
960
+ ref_line={line}
961
+ line_idx={line.idx}
962
+ x_min={line.x_axis === `x2` ? ranges.current.x2[0] : ranges.current.x[0]}
963
+ x_max={line.x_axis === `x2` ? ranges.current.x2[1] : ranges.current.x[1]}
964
+ y_min={line.y_axis === `y2` ? ranges.current.y2[0] : ranges.current.y[0]}
965
+ y_max={line.y_axis === `y2` ? ranges.current.y2[1] : ranges.current.y[1]}
966
+ x_scale={scales.x}
967
+ x2_scale={scales.x2}
968
+ y_scale={scales.y}
969
+ y2_scale={scales.y2}
970
+ {clip_path_id}
971
+ hovered_line_idx={hovered_ref_line_idx}
972
+ on_click={(event: RefLineEvent) => {
973
+ line.on_click?.(event)
974
+ on_ref_line_click?.(event)
975
+ }}
976
+ on_hover={(event: RefLineEvent | null) => {
977
+ hovered_ref_line_idx = event?.line_idx ?? null
978
+ line.on_hover?.(event)
979
+ on_ref_line_hover?.(event)
980
+ }}
981
+ />
982
+ {/each}
983
+ {/snippet}
984
+
985
+ <svelte:window
986
+ onkeydown={(evt) => {
987
+ if (evt.key === `Escape` && fullscreen) {
988
+ evt.preventDefault()
989
+ fullscreen = false
990
+ }
991
+ if (evt.key === `Shift`) shift_held = true
992
+ }}
993
+ onkeyup={(evt) => {
994
+ if (evt.key === `Shift`) shift_held = false
995
+ }}
996
+ />
997
+
998
+ <div
999
+ class="histogram"
1000
+ bind:this={wrapper}
1001
+ bind:clientWidth={width}
1002
+ bind:clientHeight={height}
1003
+ {...rest}
1004
+ class:fullscreen
1005
+ >
1006
+ {#if width && height}
1007
+ <div class="header-controls">
1008
+ {@render header_controls?.({ height, width, fullscreen })}
1009
+ {#if fullscreen_toggle}
1010
+ <FullscreenToggle bind:fullscreen />
1011
+ {/if}
1012
+ </div>
1013
+ {/if}
1014
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
1015
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
1016
+ <svg
1017
+ bind:this={svg_element}
1018
+ role="application"
1019
+ aria-label={rest[`aria-label`] ??
1020
+ ([final_x_axis.label, final_y_axis.label].filter(Boolean).join(` vs `) ||
1021
+ `Histogram`)}
1022
+ tabindex="0"
1023
+ onfocusin={() => (is_focused = true)}
1024
+ onfocusout={() => (is_focused = false)}
1025
+ onmouseenter={() => (hovered = true)}
1026
+ onmousedown={handle_mouse_down}
1027
+ onmouseleave={() => {
1028
+ hovered = false
1029
+ hover_info = null
1030
+ on_bar_hover?.(null)
1031
+ }}
1032
+ ondblclick={handle_double_click}
1033
+ onwheel={handle_wheel}
1034
+ ontouchstart={handle_touch_start}
1035
+ ontouchmove={handle_touch_move}
1036
+ ontouchend={handle_touch_end}
1037
+ ontouchcancel={handle_touch_end}
1038
+ style:cursor={pan_drag_state
1039
+ ? `grabbing`
1040
+ : shift_held && pan?.enabled !== false
1041
+ ? `grab`
1042
+ : `crosshair`}
1043
+ onkeydown={(event) => {
1044
+ if (event.key === `Escape` && drag_state.start) {
1045
+ drag_state = { start: null, current: null, bounds: null }
1046
+ }
1047
+ if ([`Enter`, ` `].includes(event.key)) {
1048
+ event.preventDefault()
1049
+ handle_double_click()
1050
+ }
1051
+ }}
1052
+ >
1053
+ <!-- Define clip path for chart area -->
1054
+ <defs>
1055
+ <clipPath id={clip_path_id}>
1056
+ <rect
1057
+ x={pad.l}
1058
+ y={pad.t}
1059
+ width={width - pad.l - pad.r}
1060
+ height={height - pad.t - pad.b}
1061
+ />
1062
+ </clipPath>
1063
+ </defs>
1064
+
1065
+ <!-- Reference lines: below grid (must render first to appear behind grid) -->
1066
+ {@render ref_lines_layer(ref_lines_by_z.below_grid)}
1067
+
1068
+ <ZoomRect start={drag_state.start} current={drag_state.current} />
1069
+
1070
+ <ZeroLines
1071
+ {display}
1072
+ x_scale_fn={scales.x}
1073
+ x2_scale_fn={scales.x2}
1074
+ y_scale_fn={scales.y}
1075
+ y2_scale_fn={scales.y2}
1076
+ x_range={ranges.current.x}
1077
+ x2_range={ranges.current.x2}
1078
+ y_range={ranges.current.y}
1079
+ y2_range={ranges.current.y2}
1080
+ x_scale_type={final_x_axis.scale_type}
1081
+ x2_scale_type={final_x2_axis.scale_type}
1082
+ y_scale_type={final_y_axis.scale_type}
1083
+ y2_scale_type={final_y2_axis.scale_type}
1084
+ has_x2={x2_series.length > 0}
1085
+ has_y2={y2_series.length > 0}
1086
+ {width}
1087
+ {height}
1088
+ {pad}
1089
+ />
1090
+
1091
+ <!-- Reference lines: below lines -->
1092
+ {@render ref_lines_layer(ref_lines_by_z.below_lines)}
1093
+
1094
+ <!-- Reference lines: below points -->
1095
+ {@render ref_lines_layer(ref_lines_by_z.below_points)}
1096
+
1097
+ <!-- X-axis -->
1098
+ <PlotAxis
1099
+ side="x"
1100
+ ticks={ticks.x as number[]}
1101
+ place={scales.x}
1102
+ axis={final_x_axis}
1103
+ domain={ranges.current.x as Vec2}
1104
+ {pad}
1105
+ {width}
1106
+ {height}
1107
+ show_grid={display.x_grid}
1108
+ tick_label={(tick) => get_tick_label(tick, final_x_axis.ticks)}
1109
+ label_x={(pad.l + width - pad.r) / 2 + (final_x_axis.label_shift?.x ?? 0)}
1110
+ label_y={height - 10 + (final_x_axis.label_shift?.y ?? 0)}
1111
+ axis_loading={axis_loading === `x`}
1112
+ on_axis_change={(key) => handle_axis_change(`x`, key)}
1113
+ />
1114
+
1115
+ <!-- X2-axis (Top) -->
1116
+ {#if x2_series.length > 0}
1117
+ <PlotAxis
1118
+ side="x2"
1119
+ ticks={ticks.x2 as number[]}
1120
+ place={scales.x2}
1121
+ axis={final_x2_axis}
1122
+ domain={ranges.current.x2 as Vec2}
1123
+ {pad}
1124
+ {width}
1125
+ {height}
1126
+ show_grid={display.x2_grid}
1127
+ tick_label={(tick) => get_tick_label(tick, final_x2_axis.ticks)}
1128
+ label_x={(pad.l + width - pad.r) / 2 + (final_x2_axis.label_shift?.x ?? 0)}
1129
+ label_y={Math.max(12, pad.t - (final_x2_axis.label_shift?.y ?? 40))}
1130
+ axis_loading={axis_loading === `x2`}
1131
+ on_axis_change={(key) => handle_axis_change(`x2`, key)}
1132
+ />
1133
+ {/if}
1134
+
1135
+ <!-- Y-axis -->
1136
+ <PlotAxis
1137
+ side="y"
1138
+ ticks={ticks.y as number[]}
1139
+ place={scales.y}
1140
+ axis={final_y_axis}
1141
+ domain={ranges.current.y as Vec2}
1142
+ {pad}
1143
+ {width}
1144
+ {height}
1145
+ show_grid={display.y_grid}
1146
+ tick_label={(tick) => get_tick_label(tick, final_y_axis.ticks)}
1147
+ label_x={Math.max(
1148
+ 12,
1149
+ pad.l - (final_y_axis.tick?.label?.inside ? 0 : tick_label_widths.y_max) -
1150
+ LABEL_GAP_DEFAULT,
1151
+ ) + (final_y_axis.label_shift?.x ?? 0)}
1152
+ label_y={pad.t + (height - pad.t - pad.b) / 2 + (final_y_axis.label_shift?.y ?? 0)}
1153
+ axis_loading={axis_loading === `y`}
1154
+ on_axis_change={(key) => handle_axis_change(`y`, key)}
1155
+ />
1156
+
1157
+ <!-- Y2-axis (Right) -->
1158
+ {#if y2_series.length > 0}
1159
+ <PlotAxis
1160
+ side="y2"
1161
+ ticks={ticks.y2 as number[]}
1162
+ place={scales.y2}
1163
+ axis={final_y2_axis}
1164
+ domain={ranges.current.y2 as Vec2}
1165
+ {pad}
1166
+ {width}
1167
+ {height}
1168
+ show_grid={display.y2_grid}
1169
+ tick_label={(tick) => get_tick_label(tick, final_y2_axis.ticks)}
1170
+ label_x={y2_axis_label_x(final_y2_axis, width, pad.r, tick_label_widths.y2_max)}
1171
+ label_y={pad.t + (height - pad.t - pad.b) / 2 + (final_y2_axis.label_shift?.y ?? 0)}
1172
+ axis_loading={axis_loading === `y2`}
1173
+ on_axis_change={(key) => handle_axis_change(`y2`, key)}
1174
+ />
1175
+ {/if}
1176
+
1177
+ <!-- Histogram bars (rendered after axes so bars appear above grid lines) -->
1178
+ {#each histogram_data as
1179
+ { id, bins, color, label, x_scale, y_scale, x_axis: srs_x_axis, y_axis, series_idx },
1180
+ idx
1181
+ (id ?? idx)
1182
+ }
1183
+ <g
1184
+ class="histogram-series"
1185
+ data-series-idx={series_idx}
1186
+ clip-path="url(#{clip_path_id})"
1187
+ opacity={hovered_legend_series_idx !== null &&
1188
+ hovered_legend_series_idx !== series_idx
1189
+ ? 0.25
1190
+ : 1}
1191
+ >
1192
+ {#each bins as bin, bin_idx (bin_idx)}
1193
+ {@const bar_x = x_scale(bin.x0!)}
1194
+ {@const bar_width = Math.max(1, Math.abs(x_scale(bin.x1!) - bar_x))}
1195
+ {@const bar_height = Math.max(0, (height - pad.b) - y_scale(bin.length))}
1196
+ {@const bar_y = y_scale(bin.length)}
1197
+ {@const value = (bin.x0! + bin.x1!) / 2}
1198
+ {#if bar_height > 0}
1199
+ <path
1200
+ d={bar_path(
1201
+ bar_x,
1202
+ bar_y,
1203
+ bar_width,
1204
+ bar_height,
1205
+ Math.min(final_bar.border_radius ?? 0, bar_width / 2, bar_height / 2),
1206
+ )}
1207
+ fill={color}
1208
+ opacity={final_bar.opacity}
1209
+ stroke={final_bar.stroke_color}
1210
+ stroke-opacity={final_bar.stroke_opacity}
1211
+ stroke-width={final_bar.stroke_width}
1212
+ role="button"
1213
+ tabindex="0"
1214
+ onmousemove={(evt) =>
1215
+ handle_mouse_move(
1216
+ evt,
1217
+ value,
1218
+ bin.length,
1219
+ label,
1220
+ (y_axis ?? `y1`) as `y1` | `y2`,
1221
+ series_idx,
1222
+ (srs_x_axis ?? `x1`) as `x1` | `x2`,
1223
+ )}
1224
+ onmouseleave={() => {
1225
+ hover_info = null
1226
+ change(null)
1227
+ on_bar_hover?.(null)
1228
+ }}
1229
+ onclick={(event) =>
1230
+ on_bar_click?.({ value, count: bin.length, property: label, event })}
1231
+ onkeydown={(event: KeyboardEvent) => {
1232
+ if ([`Enter`, ` `].includes(event.key)) {
1233
+ event.preventDefault()
1234
+ on_bar_click?.({ value, count: bin.length, property: label, event })
1235
+ }
1236
+ }}
1237
+ style:cursor={on_bar_click ? `pointer` : undefined}
1238
+ />
1239
+ {/if}
1240
+ {/each}
1241
+ </g>
1242
+ {/each}
1243
+
1244
+ <!-- Reference lines: above all -->
1245
+ {@render ref_lines_layer(ref_lines_by_z.above_all)}
1246
+ </svg>
1247
+
1248
+ <!-- Tooltip (outside SVG for proper HTML rendering) -->
1249
+ {#if hover_info}
1250
+ {@const { value, count, property, active_y_axis, active_x_axis } = hover_info}
1251
+ {@const tooltip_x = (active_x_axis === `x2` ? scales.x2 : scales.x)(value)}
1252
+ {@const tooltip_y = (active_y_axis === `y2` ? scales.y2 : scales.y)(count)}
1253
+ <PlotTooltip
1254
+ x={tooltip_x}
1255
+ y={tooltip_y}
1256
+ offset={{ x: 5, y: -10 }}
1257
+ constrain_to={{ width, height }}
1258
+ fallback_size={{ width: 120, height: mode === `overlay` ? 60 : 40 }}
1259
+ >
1260
+ {#if tooltip}
1261
+ {@render tooltip({ ...hover_info, fullscreen })}
1262
+ {:else}
1263
+ <div>Value: {format_value(value, hover_info.x_axis.format || `.3~s`)}</div>
1264
+ <div>Count: {format_value(count, hover_info.y_axis.format || `.3~s`)}</div>
1265
+ {#if mode === `overlay`}<div>{property}</div>{/if}
1266
+ {/if}
1267
+ </PlotTooltip>
1268
+ {/if}
1269
+
1270
+ {#if show_controls}
1271
+ <HistogramControls
1272
+ toggle_props={{
1273
+ ...controls_toggle_props,
1274
+ style: `--ctrl-btn-right: var(--fullscreen-btn-offset, 30px); ${
1275
+ controls_toggle_props?.style ?? ``
1276
+ }`,
1277
+ }}
1278
+ pane_props={controls_pane_props}
1279
+ bind:show_controls
1280
+ bind:controls_open
1281
+ bind:bins
1282
+ bind:mode
1283
+ bind:show_legend
1284
+ bind:selected_property
1285
+ bind:display
1286
+ bind:bar
1287
+ bind:x_axis
1288
+ bind:x2_axis
1289
+ bind:y_axis
1290
+ bind:y2_axis
1291
+ auto_x_range={auto_ranges.x}
1292
+ auto_x2_range={auto_ranges.x2}
1293
+ auto_y_range={auto_ranges.y}
1294
+ auto_y2_range={auto_ranges.y2}
1295
+ {series}
1296
+ has_x2_points={x2_series.length > 0}
1297
+ has_y2_points={y2_series.length > 0}
1298
+ children={controls_extra}
1299
+ />
1300
+ {/if}
1301
+
1302
+ {#if show_legend && legend != null && series.length > 1}
1303
+ {@const legend_left = legend_auto_outside
1304
+ ? legend_outside_x
1305
+ : legend_placement
1306
+ ? tweened_legend_coords.current.x
1307
+ : pad.l + 10}
1308
+ {@const legend_top = legend_auto_outside
1309
+ ? legend_outside_y
1310
+ : legend_placement
1311
+ ? tweened_legend_coords.current.y
1312
+ : pad.t + 10}
1313
+ <PlotLegend
1314
+ bind:root_element={legend_element}
1315
+ {...legend}
1316
+ series_data={legend_data}
1317
+ on_toggle={legend?.on_toggle ?? ((series_idx: number) => {
1318
+ if (series_idx < 0 || series_idx >= series.length) return
1319
+ legend_vis.on_toggle(series_idx)
1320
+ on_series_toggle(series_idx)
1321
+ })}
1322
+ on_double_click={legend?.on_double_click ?? legend_vis.on_double_click}
1323
+ on_hover_change={legend_hover.set_locked}
1324
+ on_item_hover={(item) =>
1325
+ (hovered_legend_series_idx = item != null && item.series_idx >= 0
1326
+ ? item.series_idx
1327
+ : null)}
1328
+ active_series_idx={hover_info?.series_idx ?? hovered_legend_series_idx}
1329
+ style={`
1330
+ position: absolute;
1331
+ left: ${legend_left}px;
1332
+ top: ${legend_top}px;
1333
+ pointer-events: auto;
1334
+ ${legend?.style || ``}
1335
+ `}
1336
+ />
1337
+ {/if}
1338
+
1339
+ <!-- User-provided children (e.g. for custom absolutely-positioned overlays) -->
1340
+ {@render children?.({ height, width, fullscreen })}
1341
+ </div>
1342
+
1343
+ <style>
1344
+ .histogram {
1345
+ position: relative;
1346
+ width: var(--histogram-width, 100%);
1347
+ height: var(--histogram-height, auto);
1348
+ min-height: var(--histogram-min-height, 300px);
1349
+ container-type: size; /* enable cqh for panes if explicit height is set */
1350
+ z-index: var(--histogram-z-index, auto);
1351
+ flex: var(--histogram-flex, 1);
1352
+ display: var(--histogram-display, flex);
1353
+ flex-direction: column;
1354
+ background: var(--histogram-bg, var(--plot-bg));
1355
+ border-radius: var(--histogram-border-radius, var(--border-radius, 3pt));
1356
+ }
1357
+ .histogram.fullscreen {
1358
+ position: fixed;
1359
+ top: 0;
1360
+ left: 0;
1361
+ width: 100vw !important;
1362
+ height: 100vh !important;
1363
+ /* Must be higher than Structure.svelte's --struct-buttons-z-index. */
1364
+ z-index: var(--histogram-fullscreen-z-index, var(--z-index-overlay-nav, 100000001));
1365
+ margin: 0;
1366
+ border-radius: 0;
1367
+ background: var(--histogram-fullscreen-bg, var(--histogram-bg, var(--plot-bg)));
1368
+ max-height: none !important;
1369
+ overflow: hidden;
1370
+ /* border-top (not padding-top): bind:clientHeight includes padding but excludes
1371
+ borders - padding made the chart overflow + clip its bottom 2em (x-axis title) */
1372
+ border-top: var(--plot-fullscreen-padding-top, 2em) solid
1373
+ var(--histogram-fullscreen-bg, var(--histogram-bg, var(--plot-bg, transparent)));
1374
+ box-sizing: border-box;
1375
+ }
1376
+ .header-controls {
1377
+ position: absolute;
1378
+ top: var(--ctrl-btn-top, 5pt);
1379
+ right: var(--fullscreen-btn-right, 4px);
1380
+ z-index: var(--fullscreen-btn-z-index, 10);
1381
+ display: flex;
1382
+ align-items: center;
1383
+ gap: 8px;
1384
+ }
1385
+ .header-controls :global(.fullscreen-toggle) {
1386
+ position: static; /* Override absolute positioning since container handles it */
1387
+ opacity: 1; /* Always visible when inside header-controls, container controls visibility */
1388
+ }
1389
+ /* Hide controls and fullscreen toggles by default, show on hover */
1390
+ .histogram :global(.pane-toggle),
1391
+ .histogram .header-controls {
1392
+ opacity: 0;
1393
+ transition: opacity 0.2s, background-color 0.2s;
1394
+ }
1395
+ .histogram:hover :global(.pane-toggle),
1396
+ .histogram:hover .header-controls,
1397
+ .histogram :global(.pane-toggle:focus-visible),
1398
+ .histogram :global(.pane-toggle[aria-expanded='true']),
1399
+ .histogram .header-controls:focus-within {
1400
+ opacity: 1;
1401
+ }
1402
+ svg {
1403
+ width: var(--histogram-svg-width, 100%);
1404
+ height: var(--histogram-svg-height, 100%);
1405
+ max-height: var(--histogram-svg-max-height, 100%);
1406
+ flex: var(--histogram-svg-flex, 1);
1407
+ overflow: var(--histogram-svg-overflow, visible);
1408
+ fill: var(--text-color);
1409
+ font-weight: var(--histogram-font-weight);
1410
+ font-size: var(--histogram-font-size);
1411
+ }
1412
+ .histogram-series path {
1413
+ transition: opacity 0.2s ease;
1414
+ }
1415
+ .histogram-series path:hover {
1416
+ opacity: 1 !important;
1417
+ }
1418
+ </style>