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,1755 @@
1
+ <script
2
+ lang="ts"
3
+ generics="Metadata extends Record<string, unknown> = Record<string, unknown>"
4
+ >
5
+ import type { D3ColorSchemeName, D3InterpolateName } from '../../colors'
6
+ import { format_value } from '../../labels'
7
+ import { sanitize_html } from '../../sanitize'
8
+ import { FullscreenToggle, set_fullscreen_bg } from '../../layout'
9
+ import type { Point2D, Vec2 } from '../../math'
10
+ import type {
11
+ AxisLoadError,
12
+ BarHandlerProps,
13
+ BarMode,
14
+ BarSeries,
15
+ BarStyle,
16
+ BasePlotProps,
17
+ DataLoaderFn,
18
+ InitialRanges,
19
+ InternalPoint,
20
+ LegendConfig,
21
+ LegendItem,
22
+ LineStyle,
23
+ Orientation,
24
+ PanConfig,
25
+ PlotConfig,
26
+ RefLine,
27
+ RefLineEvent,
28
+ ScaleType,
29
+ UserContentProps,
30
+ } from '..'
31
+ import {
32
+ BarPlotControls,
33
+ compute_element_placement,
34
+ PlotAxis,
35
+ PlotLegend,
36
+ ReferenceLine,
37
+ ScatterPoint,
38
+ } from '..'
39
+ import type { AxisChangeState } from '../core/axis-utils'
40
+ import { create_axis_loader } from '../core/axis-utils'
41
+ import {
42
+ create_dimension_tracker,
43
+ create_hover_lock,
44
+ } from '../core/hover-lock.svelte'
45
+ import { create_legend_visibility } from '../core/utils/series-visibility'
46
+ import {
47
+ axis_ranges_equal,
48
+ get_relative_coords,
49
+ MIN_TOUCH_DISTANCE_PIXELS,
50
+ pan_range_by_pixels,
51
+ PINCH_ZOOM_THRESHOLD,
52
+ remove_drag_listeners,
53
+ resolve_axis_ranges,
54
+ sorted_range,
55
+ to_epoch_num,
56
+ zoom_range_by_factor,
57
+ } from '../core/interactions'
58
+ import type { IndexedRefLine } from '../core/reference-line'
59
+ import { group_ref_lines_by_z, index_ref_lines } from '../core/reference-line'
60
+ import {
61
+ create_color_scale,
62
+ create_scale,
63
+ create_size_scale,
64
+ generate_ticks,
65
+ get_tick_label,
66
+ } from '../core/scales'
67
+ import { DEFAULT_MARKERS } from '../core/types'
68
+ import { DEFAULTS } from '../../settings'
69
+ import { extent } from 'd3-array'
70
+ import type { Snippet } from 'svelte'
71
+ import { onDestroy, untrack } from 'svelte'
72
+ import type { HTMLAttributes } from 'svelte/elements'
73
+ import { Tween, type TweenOptions } from 'svelte/motion'
74
+ import {
75
+ build_obstacles_norm,
76
+ clip_bar,
77
+ has_explicit_position,
78
+ measured_footprint,
79
+ place_decorations,
80
+ } from '../core/auto-place'
81
+ import {
82
+ calc_auto_padding,
83
+ filter_padding,
84
+ LABEL_GAP_DEFAULT,
85
+ y2_axis_label_x,
86
+ measure_max_tick_width,
87
+ } from '../core/layout'
88
+ import PlotTooltip from '../core/components/PlotTooltip.svelte'
89
+ import { bar_path } from '../core/svg'
90
+ import { unique_id } from '../core/utils'
91
+ import ZeroLines from '../core/components/ZeroLines.svelte'
92
+ import ZoomRect from '../core/components/ZoomRect.svelte'
93
+ import {
94
+ compute_bar_auto_ranges,
95
+ compute_group_info,
96
+ compute_stacked_offsets,
97
+ normalize_categorical,
98
+ } from './data'
99
+ import { compute_bar_rect, compute_line_points } from './geometry'
100
+ import type { LineSeriesPoint as BarLineSeriesPoint } from './geometry'
101
+
102
+ // Handler props for line marker events (extends BarHandlerProps with point-specific data)
103
+ interface LineMarkerHandlerProps extends BarHandlerProps<Metadata> {
104
+ point: InternalPoint<Metadata>
105
+ }
106
+
107
+ // Extended point type with computed screen coordinates (used internally for rendering)
108
+ type LineSeriesPoint = BarLineSeriesPoint<Metadata>
109
+
110
+ let {
111
+ series = $bindable([]),
112
+ orientation = $bindable(`vertical`),
113
+ mode = $bindable(`overlay`),
114
+ x_axis = $bindable({}),
115
+ x2_axis: x2_axis_prop = $bindable({}),
116
+ y_axis = $bindable({}),
117
+ y2_axis: y2_axis_prop = $bindable({}),
118
+ display = $bindable(DEFAULTS.bar.display),
119
+ range_padding = 0.05,
120
+ padding = { t: 20, b: 60, l: 60, r: 20 },
121
+ legend = {},
122
+ show_legend,
123
+ bar = {},
124
+ line = {},
125
+ tooltip,
126
+ user_content,
127
+ hovered = $bindable(false),
128
+ change = () => {},
129
+ on_bar_click,
130
+ on_bar_hover,
131
+ // Line marker props (matching ScatterPlot)
132
+ color_scale = {
133
+ type: `linear`,
134
+ scheme: `interpolateViridis`,
135
+ value_range: undefined,
136
+ },
137
+ size_scale = { type: `linear`, radius_range: [2, 10], value_range: undefined },
138
+ point_tween,
139
+ on_point_click,
140
+ on_point_hover,
141
+ ref_lines = $bindable([]),
142
+ on_ref_line_click,
143
+ on_ref_line_hover,
144
+ show_controls = $bindable(true),
145
+ controls_open = $bindable(false),
146
+ controls_toggle_props,
147
+ controls_pane_props,
148
+ fullscreen = $bindable(false),
149
+ fullscreen_toggle = true,
150
+ children,
151
+ header_controls,
152
+ controls_extra,
153
+ data_loader,
154
+ on_axis_change,
155
+ on_error,
156
+ pan = {},
157
+ ...rest
158
+ }: HTMLAttributes<HTMLDivElement> & BasePlotProps & PlotConfig & {
159
+ series?: BarSeries<Metadata>[]
160
+ // Component-specific props
161
+ orientation?: Orientation
162
+ mode?: BarMode
163
+ legend?: LegendConfig | null
164
+ show_legend?: boolean
165
+ bar?: BarStyle
166
+ line?: LineStyle
167
+ tooltip?: Snippet<[BarHandlerProps<Metadata>]>
168
+ user_content?: Snippet<[UserContentProps]>
169
+ header_controls?: Snippet<
170
+ [{ height: number; width: number; fullscreen: boolean }]
171
+ >
172
+ controls_extra?: Snippet<
173
+ [{ orientation: Orientation; mode: BarMode } & Required<PlotConfig>]
174
+ >
175
+ change?: (data: BarHandlerProps<Metadata> | null) => void
176
+ on_bar_click?: (
177
+ data: BarHandlerProps<Metadata> & { event: MouseEvent | KeyboardEvent },
178
+ ) => void
179
+ on_bar_hover?: (
180
+ data:
181
+ | (BarHandlerProps<Metadata> & {
182
+ event: MouseEvent | FocusEvent | KeyboardEvent
183
+ })
184
+ | null,
185
+ ) => void
186
+ // Line marker props (matching ScatterPlot)
187
+ // Note: For line series with markers, BOTH on_bar_* AND on_point_* events fire.
188
+ // Use on_point_* for marker-specific data (includes `point` with InternalPoint details)
189
+ // or on_bar_* for backward compatibility with bar-style event handling.
190
+ color_scale?: {
191
+ type?: ScaleType
192
+ scheme?: D3ColorSchemeName | D3InterpolateName
193
+ value_range?: [number, number]
194
+ } | D3InterpolateName
195
+ size_scale?: {
196
+ type?: ScaleType
197
+ radius_range?: [number, number]
198
+ value_range?: [number, number]
199
+ }
200
+ point_tween?: TweenOptions<Point2D>
201
+ on_point_click?: (
202
+ data: LineMarkerHandlerProps & { event: MouseEvent | KeyboardEvent },
203
+ ) => void
204
+ on_point_hover?: (
205
+ data:
206
+ | (LineMarkerHandlerProps & {
207
+ event: MouseEvent | FocusEvent | KeyboardEvent
208
+ })
209
+ | null,
210
+ ) => void
211
+ ref_lines?: RefLine[]
212
+ on_ref_line_click?: (event: RefLineEvent) => void
213
+ on_ref_line_hover?: (event: RefLineEvent | null) => void
214
+ // Interactive axis props
215
+ data_loader?: DataLoaderFn<Metadata, BarSeries<Metadata>>
216
+ on_axis_change?: (
217
+ axis: `x` | `x2` | `y` | `y2`,
218
+ key: string,
219
+ new_series: BarSeries<Metadata>[],
220
+ ) => void
221
+ on_error?: (error: AxisLoadError) => void
222
+ pan?: PanConfig
223
+ } = $props()
224
+
225
+ // Initialize bar, line, y2_axis with defaults - using $derived for reactivity
226
+ let bar_state = $derived({ ...DEFAULTS.bar.bar, ...bar })
227
+ let line_state = $derived({ ...DEFAULTS.bar.line, ...line })
228
+ // Merge secondary-axis defaults as deriveds instead of assigning back into the
229
+ // $bindable props (which would push library defaults into the parent's bound state)
230
+ let y2_axis = $derived({
231
+ format: ``,
232
+ scale_type: `linear`,
233
+ ticks: 5,
234
+ label_shift: { x: 0, y: 0 }, // y2 title stays vertically centered (x pos set by y2_axis_label_x)
235
+ tick: { label: { shift: { x: 0, y: 0 } } }, // base offset handled in rendering
236
+ range: [null, null],
237
+ ...y2_axis_prop,
238
+ } as typeof y2_axis_prop)
239
+ let x2_axis = $derived({
240
+ format: ``,
241
+ scale_type: `linear`,
242
+ ticks: 5,
243
+ label_shift: { x: 0, y: 40 },
244
+ tick: { label: { shift: { x: 0, y: 0 } } },
245
+ range: [null, null],
246
+ ...x2_axis_prop,
247
+ } as typeof x2_axis_prop)
248
+
249
+ let [width, height] = $state([0, 0])
250
+ let wrapper: HTMLDivElement | undefined = $state()
251
+ let svg_element: SVGElement | null = $state(null)
252
+ const clip_path_id = unique_id(`chart-clip`) // stable, collision-resistant (see unique_id)
253
+
254
+ // Reference line hover state
255
+ let hovered_ref_line_idx = $state<number | null>(null)
256
+
257
+ // Interactive axis loading state
258
+ let axis_loading = $state<`x` | `x2` | `y` | `y2` | null>(null)
259
+
260
+ // Compute ref_lines with index and group by z-index (using shared utilities)
261
+ let indexed_ref_lines = $derived(index_ref_lines(ref_lines))
262
+ let ref_lines_by_z = $derived(group_ref_lines_by_z(indexed_ref_lines))
263
+
264
+ // === Categorical Normalization (string x values -> integer indices, see ./data) ===
265
+ let cat_norm = $derived(normalize_categorical(series, x_axis.categories))
266
+ let category_list = $derived(cat_norm.category_list)
267
+ let internal_series = $derived(cat_norm.internal_series)
268
+
269
+ let category_indices = $derived(
270
+ category_list.length > 0 ? category_list.map((_, idx) => idx) : null,
271
+ )
272
+
273
+ // Thin categorical tick labels + grid lines when many categories would overlap.
274
+ // Bars still render for every category (this only reduces drawn ticks/labels/grid).
275
+ let cat_tick_indices = $derived.by<number[]>(() => {
276
+ if (!category_indices) return []
277
+ const axis_px = (orientation === `horizontal` ? height : width) || 0
278
+ const max_ticks = Math.max(1, Math.floor(axis_px / 28)) // ~28px per category label
279
+ const step = Math.ceil(category_indices.length / max_ticks)
280
+ return step <= 1
281
+ ? category_indices
282
+ : category_indices.filter((_, idx) => idx % step === 0)
283
+ })
284
+
285
+ // Compute auto ranges from visible series
286
+ let visible_series = $derived(
287
+ internal_series.filter((srs) => srs?.visible ?? true),
288
+ )
289
+
290
+ // Separate series by y-axis
291
+ let y1_series = $derived(
292
+ visible_series.filter((srs) => (srs.y_axis ?? `y1`) === `y1`),
293
+ )
294
+ let y2_series = $derived(
295
+ visible_series.filter((srs) => srs.y_axis === `y2`),
296
+ )
297
+ let x2_series = $derived(
298
+ visible_series.filter((srs) => srs.x_axis === `x2`),
299
+ )
300
+
301
+ let auto_ranges = $derived(compute_bar_auto_ranges({
302
+ visible_series,
303
+ y1_series,
304
+ y2_series,
305
+ x2_series,
306
+ mode,
307
+ orientation,
308
+ range_padding,
309
+ category_count: category_list.length,
310
+ x_range: x_axis.range ?? [null, null],
311
+ x_scale_type: x_axis.scale_type ?? `linear`,
312
+ x_is_time: x_axis.format?.startsWith(`%`) || false,
313
+ x2_range: x2_axis.range ?? [null, null],
314
+ x2_scale_type: x2_axis.scale_type ?? `linear`,
315
+ x2_is_time: x2_axis.format?.startsWith(`%`) || false,
316
+ y_range: y_axis.range ?? [null, null],
317
+ y_scale_type: y_axis.scale_type ?? `linear`,
318
+ y2_range: y2_axis.range ?? [null, null],
319
+ y2_scale_type: y2_axis.scale_type ?? `linear`,
320
+ }))
321
+
322
+ // Initialize and current ranges
323
+ let ranges = $state<{
324
+ initial: { x: Vec2; x2: Vec2; y: Vec2; y2: Vec2 }
325
+ current: { x: Vec2; x2: Vec2; y: Vec2; y2: Vec2 }
326
+ }>({
327
+ initial: { x: [0, 1], x2: [0, 1], y: [0, 1], y2: [0, 1] },
328
+ current: { x: [0, 1], x2: [0, 1], y: [0, 1], y2: [0, 1] },
329
+ })
330
+
331
+ $effect(() => { // handle x_axis.range / x2_axis.range / y_axis.range / y2_axis.range changes
332
+ // resolve_axis_ranges returns null for transient non-finite bounds (skip: writing
333
+ // NaN breaks scales and, since NaN !== NaN, loops the effect)
334
+ const next = resolve_axis_ranges({ x: x_axis, x2: x2_axis, y: y_axis, y2: y2_axis }, auto_ranges)
335
+ if (!next) return
336
+ // Only update if the initial (data-driven) ranges changed, not when user pans.
337
+ // untrack the read of `ranges` so the assignment below can't re-trigger this effect
338
+ // (reading + writing the same state otherwise causes effect_update_depth_exceeded).
339
+ const init = untrack(() => ranges.initial)
340
+ if (!axis_ranges_equal(init, next)) {
341
+ ranges = { initial: { ...next }, current: { ...next } }
342
+ }
343
+ })
344
+
345
+ // Layout: dynamic padding based on tick label widths
346
+ const default_padding = { t: 20, b: 60, l: 60, r: 20 }
347
+ // base_pad reserves space for tick labels/axis titles; pad (below) adds decoration reservations
348
+ let base_pad = $derived(filter_padding(padding, default_padding))
349
+
350
+ // Update padding when format or ticks change
351
+ $effect(() => {
352
+ const new_pad = width && height && ticks.y.length > 0
353
+ ? calc_auto_padding({
354
+ padding,
355
+ default_padding,
356
+ x2_axis: { ...x2_axis, tick_values: ticks.x2 },
357
+ y_axis: { ...y_axis, tick_values: ticks.y },
358
+ y2_axis: { ...y2_axis, tick_values: ticks.y2 },
359
+ })
360
+ : filter_padding(padding, default_padding)
361
+ // Expand right padding if y2 ticks are shown (only for vertical orientation)
362
+ if (
363
+ width && height && y2_series.length > 0 && ticks.y2.length > 0 &&
364
+ orientation === `vertical`
365
+ ) {
366
+ // Need space for: tick shift + tick width + gap (30px) + label space (20px if present)
367
+ // When ticks are inside, they don't contribute to padding
368
+ const inside = y2_axis.tick?.label?.inside ?? false
369
+ const tick_shift = inside ? 0 : (y2_axis.tick?.label?.shift?.x ?? 0) + 8
370
+ const tick_width_contribution = inside ? 0 : tick_label_widths.y2_max
371
+ const label_space = y2_axis.label ? 20 : 0
372
+ new_pad.r = Math.max(
373
+ new_pad.r,
374
+ tick_shift + tick_width_contribution + 30 + label_space,
375
+ )
376
+ }
377
+ // Expand top padding if x2 ticks are shown (only for vertical orientation)
378
+ if (
379
+ width && height && x2_series.length > 0 && ticks.x2.length > 0 &&
380
+ orientation === `vertical`
381
+ ) {
382
+ const inside = x2_axis.tick?.label?.inside ?? false
383
+ const tick_shift = inside ? 0 : Math.abs(x2_axis.tick?.label?.shift?.y ?? 0) + 5
384
+ const tick_height = inside ? 0 : 16
385
+ const label_space = x2_axis.label ? 20 : 0
386
+ new_pad.t = Math.max(new_pad.t, tick_shift + tick_height + 30 + label_space)
387
+ }
388
+
389
+ // Only update if padding actually changed (prevents infinite loop)
390
+ if (
391
+ base_pad.t !== new_pad.t || base_pad.b !== new_pad.b ||
392
+ base_pad.l !== new_pad.l || base_pad.r !== new_pad.r
393
+ ) base_pad = new_pad
394
+ })
395
+
396
+ let legend_element = $state<HTMLDivElement | undefined>()
397
+ const legend_footprint = $derived(measured_footprint(legend_element, { width: 120, height: 60 }))
398
+ const legend_has_explicit_pos = $derived(has_explicit_position(legend?.style))
399
+
400
+ // Obstacle field in normalized [0,1] plot coords (y=0 at top). Each bar is modeled as a segment
401
+ // from baseline to its tip so the legend can't hide inside a tall bar. Built from internal_series
402
+ // (pad-independent) + ranges so the crowding decision can't see its own reservation.
403
+ const obstacles_norm = $derived.by(() => {
404
+ if (!width || !height || visible_series.length === 0) return []
405
+ const base_w = width - base_pad.l - base_pad.r
406
+ const base_h = height - base_pad.t - base_pad.b
407
+ if (base_w <= 0 || base_h <= 0) return []
408
+ const bars: { points: { x: number; y: number }[]; draws_line: boolean }[] = []
409
+ const vertical = orientation === `vertical`
410
+ internal_series.forEach((srs, series_idx) => {
411
+ if (!(srs?.visible ?? true)) return
412
+ const is_line = srs.render_mode === `line`
413
+ const series_offsets = stacked_offsets[series_idx] ?? []
414
+ const [ax0, ax1] = srs.x_axis === `x2` ? ranges.current.x2 : ranges.current.x
415
+ const [vy0, vy1] = srs.y_axis === `y2` ? ranges.current.y2 : ranges.current.y
416
+ const [cy0, cy1] = ranges.current.y
417
+ const x_span = ax1 - ax0
418
+ const y_span = vy1 - vy0
419
+ const cy_span = cy1 - cy0
420
+ if (!(x_span > 0) || !((vertical ? y_span : cy_span) > 0)) return
421
+ srs.x.forEach((x_val, bar_idx) => {
422
+ const base = !is_line && mode === `stacked` ? (series_offsets[bar_idx] ?? 0) : 0
423
+ const value = base + srs.y[bar_idx]
424
+ // vertical: category on x, value rises on y (inverted). horizontal: category on y, value on x
425
+ const seg = vertical
426
+ ? clip_bar(true, (x_val - ax0) / x_span, 1 - (value - vy0) / y_span, 1 - (base - vy0) / y_span)
427
+ : clip_bar(false, 1 - (x_val - cy0) / cy_span, (value - ax0) / x_span, (base - ax0) / x_span)
428
+ if (seg) bars.push(seg)
429
+ })
430
+ })
431
+ return build_obstacles_norm(bars, base_w, base_h)
432
+ })
433
+
434
+ // Move the legend to the bottom margin when no interior spot avoids the bars
435
+ const decor = $derived.by(() =>
436
+ place_decorations({
437
+ base_pad,
438
+ width,
439
+ height,
440
+ obstacles_norm,
441
+ // gate on legend_element (the render signal) not legend_data, whose entries can read pad
442
+ legend: legend != null &&
443
+ (show_legend !== undefined ? show_legend : series.length > 1) &&
444
+ legend_element != null && !legend_has_explicit_pos
445
+ ? { footprint: legend_footprint, clearance: legend?.axis_clearance }
446
+ : null,
447
+ })
448
+ )
449
+ const pad = $derived(decor.pad)
450
+ const legend_auto_outside = $derived(decor.legend_outside)
451
+ const legend_outside_x = $derived(decor.legend_pos.x)
452
+ const legend_outside_y = $derived(decor.legend_pos.y)
453
+ const chart_width = $derived(Math.max(1, width - pad.l - pad.r))
454
+ const chart_height = $derived(Math.max(1, height - pad.t - pad.b))
455
+
456
+ // Scales
457
+ let scales = $derived({
458
+ x: create_scale(x_axis.scale_type ?? `linear`, ranges.current.x, [
459
+ pad.l,
460
+ width - pad.r,
461
+ ]),
462
+ x2: create_scale(x2_axis.scale_type ?? `linear`, ranges.current.x2, [
463
+ pad.l,
464
+ width - pad.r,
465
+ ]),
466
+ y: create_scale(y_axis.scale_type ?? `linear`, ranges.current.y, [
467
+ height - pad.b,
468
+ pad.t,
469
+ ]),
470
+ y2: create_scale(y2_axis.scale_type ?? `linear`, ranges.current.y2, [
471
+ height - pad.b,
472
+ pad.t,
473
+ ]),
474
+ })
475
+
476
+ // Compute plot center for point tweening origin
477
+ let plot_center_x = $derived(pad.l + (width - pad.r - pad.l) / 2)
478
+ let plot_center_y = $derived(pad.t + (height - pad.b - pad.t) / 2)
479
+
480
+ // Compute color values from line series for color scaling (filter to numbers only)
481
+ let all_color_values = $derived(
482
+ visible_series
483
+ .filter((srs: BarSeries<Metadata>) => srs.render_mode === `line`)
484
+ .flatMap((srs: BarSeries<Metadata>) =>
485
+ (srs.color_values ?? []).filter(
486
+ (val): val is number => typeof val === `number`,
487
+ )
488
+ ),
489
+ )
490
+
491
+ // Create auto color range (safely handle empty arrays or undefined extent results)
492
+ let auto_color_range: [number, number] = $derived.by(() => {
493
+ if (all_color_values.length === 0) return [0, 1]
494
+ const [min_val, max_val] = extent(all_color_values)
495
+ return [min_val ?? 0, max_val ?? 1]
496
+ })
497
+
498
+ // All size values from line series (for size scale, filter to numbers only)
499
+ let all_size_values = $derived(
500
+ visible_series
501
+ .filter((srs: BarSeries<Metadata>) => srs.render_mode === `line`)
502
+ .flatMap((srs: BarSeries<Metadata>) =>
503
+ [...(srs.size_values ?? [])].filter(
504
+ (val): val is number => typeof val === `number`,
505
+ )
506
+ ),
507
+ )
508
+
509
+ // Color scale function (using shared utility)
510
+ let color_scale_fn = $derived(create_color_scale(color_scale, auto_color_range))
511
+
512
+ // Size scale function (using shared utility)
513
+ let size_scale_fn = $derived(create_size_scale(size_scale, all_size_values))
514
+
515
+ // Auto-generate tick labels for categorical data (unless user provides explicit ticks)
516
+ // In vertical mode categories are on x-axis; in horizontal mode on y-axis
517
+ let cat_axis = $derived(orientation === `horizontal` ? `y` : `x`)
518
+ let effective_cat_ticks = $derived.by(() => {
519
+ if (category_list.length === 0) return undefined
520
+ // Only respect user ticks when they're a Record (custom label mapping),
521
+ // not a number (tick count) or array (tick positions)
522
+ const user_ticks = cat_axis === `x` ? x_axis.ticks : y_axis.ticks
523
+ if (
524
+ user_ticks != null && typeof user_ticks === `object` &&
525
+ !Array.isArray(user_ticks)
526
+ ) return user_ticks
527
+ return Object.fromEntries(
528
+ category_list.map((cat, idx) => [idx, cat]),
529
+ ) as Record<number, string>
530
+ })
531
+
532
+ // Ticks
533
+ let ticks = $derived({
534
+ x: width && height
535
+ ? (category_indices && cat_axis === `x` ? cat_tick_indices : generate_ticks(
536
+ ranges.current.x,
537
+ x_axis.scale_type ?? `linear`,
538
+ x_axis.ticks,
539
+ scales.x,
540
+ { default_count: 8 },
541
+ ))
542
+ : [],
543
+ y: width && height
544
+ ? (category_indices && cat_axis === `y` ? cat_tick_indices : generate_ticks(
545
+ ranges.current.y,
546
+ y_axis.scale_type ?? `linear`,
547
+ y_axis.ticks,
548
+ scales.y,
549
+ { default_count: 6 },
550
+ ))
551
+ : [],
552
+ y2: width && height && y2_series.length > 0 && orientation === `vertical`
553
+ ? generate_ticks(
554
+ ranges.current.y2,
555
+ y2_axis.scale_type ?? `linear`,
556
+ y2_axis.ticks,
557
+ scales.y2,
558
+ {
559
+ default_count: 6,
560
+ },
561
+ )
562
+ : [],
563
+ x2: width && height && x2_series.length > 0 && orientation === `vertical`
564
+ ? generate_ticks(
565
+ ranges.current.x2,
566
+ x2_axis.scale_type ?? `linear`,
567
+ x2_axis.ticks,
568
+ scales.x2,
569
+ {
570
+ default_count: 8,
571
+ },
572
+ )
573
+ : [],
574
+ })
575
+
576
+ // Cache measured tick-label widths so expensive canvas text measurement
577
+ // only runs when ticks/format change, not on every template rerender.
578
+ let tick_label_widths = $derived({
579
+ y_max: measure_max_tick_width(ticks.y, y_axis.format ?? ``),
580
+ y2_max: measure_max_tick_width(ticks.y2, y2_axis.format ?? ``),
581
+ x2_max: measure_max_tick_width(ticks.x2, x2_axis.format ?? ``),
582
+ })
583
+
584
+ // Zoom drag state
585
+ let drag_state = $state<{
586
+ start: { x: number; y: number } | null
587
+ current: { x: number; y: number } | null
588
+ bounds: DOMRect | null
589
+ }>({ start: null, current: null, bounds: null })
590
+
591
+ // Pan state
592
+ let is_focused = $state(false)
593
+ let shift_held = $state(false)
594
+ let pan_drag_state = $state<
595
+ InitialRanges & { start: { x: number; y: number } } | null
596
+ >(null)
597
+ let touch_state = $state<
598
+ InitialRanges & { start_touches: { x: number; y: number }[] } | null
599
+ >(null)
600
+ const on_window_mouse_move = (evt: MouseEvent) => {
601
+ if (!drag_state.start || !drag_state.bounds) return
602
+ drag_state.current = {
603
+ x: evt.clientX - drag_state.bounds.left,
604
+ y: evt.clientY - drag_state.bounds.top,
605
+ }
606
+ }
607
+ const on_window_mouse_up = () => {
608
+ if (drag_state.start && drag_state.current) {
609
+ const x1_raw = scales.x.invert(drag_state.start.x) as number | Date
610
+ const x2_raw = scales.x.invert(drag_state.current.x) as number | Date
611
+ const y1 = scales.y.invert(drag_state.start.y)
612
+ const y2 = scales.y.invert(drag_state.current.y)
613
+ const y2_1 = scales.y2.invert(drag_state.start.y)
614
+ const y2_2 = scales.y2.invert(drag_state.current.y)
615
+ const x2a_1_raw = scales.x2.invert(drag_state.start.x) as number | Date
616
+ const x2a_2_raw = scales.x2.invert(drag_state.current.x) as number | Date
617
+ const dx = Math.abs(drag_state.start.x - drag_state.current.x)
618
+ const dy = Math.abs(drag_state.start.y - drag_state.current.y)
619
+
620
+ // Same scale inverts both coords, so each pair is all-number or all-Date
621
+ const [xr1, xr2] = [to_epoch_num(x1_raw), to_epoch_num(x2_raw)]
622
+ const [x2r1, x2r2] = [to_epoch_num(x2a_1_raw), to_epoch_num(x2a_2_raw)]
623
+
624
+ if (dx > 5 && dy > 5 && Number.isFinite(xr1) && Number.isFinite(xr2)) {
625
+ // Update axis ranges to trigger reactivity and prevent effect from overriding
626
+ x_axis = { ...x_axis, range: sorted_range(xr1, xr2) }
627
+ if (x2_series.length > 0 && Number.isFinite(x2r1) && Number.isFinite(x2r2)) {
628
+ x2_axis_prop = { ...x2_axis_prop, range: sorted_range(x2r1, x2r2) }
629
+ }
630
+ y_axis = { ...y_axis, range: sorted_range(y1, y2) }
631
+ // gate on y2 series presence (like x2): the y2 scale is a [0, 1] sentinel
632
+ // otherwise, so inverting would store a phantom range in the bindable prop
633
+ if (y2_series.length > 0) {
634
+ y2_axis_prop = { ...y2_axis_prop, range: sorted_range(y2_1, y2_2) }
635
+ }
636
+ }
637
+ }
638
+ drag_state = { start: null, current: null, bounds: null }
639
+ window.removeEventListener(`mousemove`, on_window_mouse_move)
640
+ window.removeEventListener(`mouseup`, on_window_mouse_up)
641
+ document.body.style.cursor = `default`
642
+ }
643
+
644
+ // Pan/zoom all four axes from an interaction-start snapshot, each in its own
645
+ // scale's transform space (log axes pan by a constant factor, linear by a shift)
646
+ const pan_all_axes = (init: InitialRanges, dx_px: number, dy_px: number) => {
647
+ ranges.current.x = pan_range_by_pixels(init.initial_x_range, dx_px, chart_width, x_axis.scale_type)
648
+ ranges.current.x2 = pan_range_by_pixels(init.initial_x2_range, dx_px, chart_width, x2_axis.scale_type)
649
+ ranges.current.y = pan_range_by_pixels(init.initial_y_range, dy_px, chart_height, y_axis.scale_type)
650
+ ranges.current.y2 = pan_range_by_pixels(init.initial_y2_range, dy_px, chart_height, y2_axis.scale_type)
651
+ }
652
+ const zoom_all_axes = (init: InitialRanges, factor: number) => {
653
+ ranges.current.x = zoom_range_by_factor(init.initial_x_range, factor, x_axis.scale_type)
654
+ ranges.current.x2 = zoom_range_by_factor(init.initial_x2_range, factor, x2_axis.scale_type)
655
+ ranges.current.y = zoom_range_by_factor(init.initial_y_range, factor, y_axis.scale_type)
656
+ ranges.current.y2 = zoom_range_by_factor(init.initial_y2_range, factor, y2_axis.scale_type)
657
+ }
658
+
659
+ // Pan drag handler (drag direction inverted on x for natural pan feel)
660
+ const on_pan_move = (evt: MouseEvent) => {
661
+ if (!pan_drag_state) return
662
+ const sensitivity = pan?.drag_sensitivity ?? 1
663
+ pan_all_axes(
664
+ pan_drag_state,
665
+ -(evt.clientX - pan_drag_state.start.x) * sensitivity,
666
+ (evt.clientY - pan_drag_state.start.y) * sensitivity,
667
+ )
668
+ }
669
+
670
+ const on_pan_end = () => {
671
+ pan_drag_state = null
672
+ document.body.style.cursor = ``
673
+ window.removeEventListener(`mousemove`, on_pan_move)
674
+ window.removeEventListener(`mouseup`, on_pan_end)
675
+ }
676
+
677
+ // Tear down any window listeners + cursor override if the component unmounts mid-drag
678
+ // (mouseup/panend would otherwise never fire, leaking listeners and a stuck cursor).
679
+ // onDestroy also runs during SSR teardown, where window/document don't exist.
680
+ onDestroy(() => {
681
+ remove_drag_listeners([on_window_mouse_move, on_pan_move], [on_window_mouse_up, on_pan_end])
682
+ drag_state = { start: null, current: null, bounds: null }
683
+ pan_drag_state = null
684
+ })
685
+
686
+ function handle_mouse_down(evt: MouseEvent) {
687
+ const coords = get_relative_coords(evt)
688
+ if (!coords || !svg_element) return
689
+
690
+ // Check if pan is enabled and shift is held for pan mode
691
+ const pan_enabled = pan?.enabled !== false
692
+ if (pan_enabled && evt.shiftKey) {
693
+ evt.preventDefault()
694
+ pan_drag_state = {
695
+ start: { x: evt.clientX, y: evt.clientY },
696
+ initial_x_range: [...ranges.current.x] as [number, number],
697
+ initial_x2_range: [...ranges.current.x2] as [number, number],
698
+ initial_y_range: [...ranges.current.y] as [number, number],
699
+ initial_y2_range: [...ranges.current.y2] as [number, number],
700
+ }
701
+ document.body.style.cursor = `grabbing`
702
+ window.addEventListener(`mousemove`, on_pan_move)
703
+ window.addEventListener(`mouseup`, on_pan_end)
704
+ return
705
+ }
706
+
707
+ drag_state = {
708
+ start: coords,
709
+ current: coords,
710
+ bounds: svg_element.getBoundingClientRect(),
711
+ }
712
+ window.addEventListener(`mousemove`, on_window_mouse_move)
713
+ window.addEventListener(`mouseup`, on_window_mouse_up)
714
+ evt.preventDefault()
715
+ }
716
+
717
+ // Wheel handler for pan (requires focus and shift)
718
+ function handle_wheel(evt: WheelEvent) {
719
+ const pan_enabled = pan?.enabled !== false
720
+ // Only capture wheel when focused AND Shift is held
721
+ // Use shift_held state (tracked via keydown/keyup) for compatibility with synthetic events
722
+ if (!pan_enabled || !is_focused || !shift_held) return
723
+
724
+ evt.preventDefault()
725
+
726
+ const sensitivity = pan?.wheel_sensitivity ?? 1
727
+
728
+ // Pan along the dominant wheel direction
729
+ if (Math.abs(evt.deltaX) > Math.abs(evt.deltaY)) {
730
+ const dx = evt.deltaX * sensitivity
731
+ ranges.current.x = pan_range_by_pixels(ranges.current.x, dx, chart_width, x_axis.scale_type)
732
+ ranges.current.x2 = pan_range_by_pixels(ranges.current.x2, dx, chart_width, x2_axis.scale_type)
733
+ } else {
734
+ const dy = evt.deltaY * sensitivity
735
+ ranges.current.y = pan_range_by_pixels(ranges.current.y, dy, chart_height, y_axis.scale_type)
736
+ ranges.current.y2 = pan_range_by_pixels(ranges.current.y2, dy, chart_height, y2_axis.scale_type)
737
+ }
738
+ }
739
+
740
+ // Touch handlers for pinch-zoom and two-finger pan
741
+ function handle_touch_start(evt: TouchEvent) {
742
+ const touch_enabled = pan?.enabled !== false && pan?.touch_enabled !== false
743
+ if (!touch_enabled || evt.touches.length !== 2) return
744
+
745
+ evt.preventDefault()
746
+ const touches = Array.from(evt.touches)
747
+ touch_state = {
748
+ start_touches: touches.map((touch) => ({ x: touch.clientX, y: touch.clientY })),
749
+ initial_x_range: [...ranges.current.x] as [number, number],
750
+ initial_x2_range: [...ranges.current.x2] as [number, number],
751
+ initial_y_range: [...ranges.current.y] as [number, number],
752
+ initial_y2_range: [...ranges.current.y2] as [number, number],
753
+ }
754
+ }
755
+
756
+ function handle_touch_move(evt: TouchEvent) {
757
+ if (!touch_state || evt.touches.length !== 2) return
758
+ evt.preventDefault()
759
+
760
+ const [t1, t2] = Array.from(evt.touches)
761
+ const [s1, s2] = touch_state.start_touches
762
+
763
+ // Calculate center movement for pan
764
+ const start_center = { x: (s1.x + s2.x) / 2, y: (s1.y + s2.y) / 2 }
765
+ const curr_center = {
766
+ x: (t1.clientX + t2.clientX) / 2,
767
+ y: (t1.clientY + t2.clientY) / 2,
768
+ }
769
+ const dx = curr_center.x - start_center.x
770
+ const dy = curr_center.y - start_center.y
771
+
772
+ // Calculate pinch scale (curr/start so spread = zoom out, pinch = zoom in)
773
+ const start_dist = Math.hypot(s2.x - s1.x, s2.y - s1.y)
774
+ // ignore near-coincident touches so curr_dist / start_dist can't blow up the scale
775
+ if (start_dist < MIN_TOUCH_DISTANCE_PIXELS) return
776
+ const curr_dist = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY)
777
+ const scale = curr_dist / start_dist
778
+
779
+ // If scale changed significantly, treat as pinch-zoom
780
+ // Also guard against scale being too small to avoid division by zero
781
+ // Pinch zoom about the view center (spread = zoom in, pinch = zoom out)
782
+ if (Math.abs(scale - 1) > PINCH_ZOOM_THRESHOLD && scale > Number.EPSILON) {
783
+ zoom_all_axes(touch_state, scale)
784
+ } else pan_all_axes(touch_state, -dx, dy)
785
+ }
786
+
787
+ function handle_touch_end() {
788
+ touch_state = null
789
+ }
790
+
791
+ // Legend data and handlers
792
+ let legend_data = $derived.by<LegendItem[]>(() =>
793
+ series.map((srs: BarSeries<Metadata>, idx: number) => {
794
+ const is_line = srs.render_mode === `line`
795
+ const series_markers = srs.markers ?? DEFAULT_MARKERS
796
+ const has_line = series_markers === `line` || series_markers === `line+points`
797
+ const has_points = series_markers === `points` ||
798
+ series_markers === `line+points`
799
+ const series_color = srs.color ?? (is_line ? line_state.color : bar_state.color)
800
+
801
+ // Get point style for symbol color (handle array or single object)
802
+ const first_point_style = Array.isArray(srs.point_style)
803
+ ? srs.point_style[0]
804
+ : srs.point_style
805
+ const first_color_value = srs.color_values?.[0]
806
+ const point_color = first_color_value != null
807
+ ? color_scale_fn(first_color_value)
808
+ : first_point_style?.fill ?? series_color
809
+
810
+ if (is_line) {
811
+ // Line series: show line and/or symbol based on markers
812
+ return {
813
+ series_idx: idx,
814
+ label: srs.label ?? `Series ${idx + 1}`,
815
+ visible: srs.visible ?? true,
816
+ legend_group: srs.legend_group,
817
+ display_style: {
818
+ ...(has_line
819
+ ? {
820
+ line_color: series_color,
821
+ line_dash: srs.line_style?.line_dash,
822
+ }
823
+ : {}),
824
+ ...(has_points
825
+ ? {
826
+ symbol_type: first_point_style?.symbol_type ??
827
+ DEFAULTS.scatter.symbol_type,
828
+ symbol_color: point_color,
829
+ }
830
+ : {}),
831
+ },
832
+ }
833
+ }
834
+ // Bar series: show square symbol
835
+ return {
836
+ series_idx: idx,
837
+ label: srs.label ?? `Series ${idx + 1}`,
838
+ visible: srs.visible ?? true,
839
+ legend_group: srs.legend_group,
840
+ display_style: {
841
+ symbol_type: `Square` as const,
842
+ symbol_color: series_color,
843
+ },
844
+ }
845
+ })
846
+ )
847
+
848
+ const legend_vis = create_legend_visibility(() => series, (next) => (series = next))
849
+
850
+ // Collect bar and line positions for legend placement
851
+ let bar_points_for_placement = $derived.by(() => {
852
+ if (!width || !height || visible_series.length === 0) return []
853
+
854
+ return internal_series.flatMap((srs, series_idx) => {
855
+ if (!(srs?.visible ?? true)) return []
856
+ const is_line = srs.render_mode === `line`
857
+ const series_offsets = stacked_offsets[series_idx] ?? []
858
+ const use_y2 = srs.y_axis === `y2`
859
+ const y_scale = use_y2 ? scales.y2 : scales.y
860
+ const use_x2_pl = srs.x_axis === `x2`
861
+ const x_scale_pl = use_x2_pl ? scales.x2 : scales.x
862
+ return srs.x
863
+ .map((x_val, bar_idx) => {
864
+ const y_val = srs.y[bar_idx]
865
+ const base = !is_line && mode === `stacked`
866
+ ? (series_offsets[bar_idx] ?? 0)
867
+ : 0
868
+ const [bar_x, bar_y] = orientation === `vertical`
869
+ ? [x_scale_pl(x_val), y_scale(base + y_val)]
870
+ : [x_scale_pl(base + y_val), scales.y(x_val)]
871
+ return { x: bar_x, y: bar_y }
872
+ })
873
+ .filter(({ x, y }) => isFinite(x) && isFinite(y))
874
+ })
875
+ })
876
+
877
+ // Legend placement stability state (legend_element declared above for the auto-place block)
878
+ let hovered_legend_series_idx = $state<number | null>(null)
879
+ const legend_hover = create_hover_lock()
880
+ const dim_tracker = create_dimension_tracker()
881
+ let has_initial_legend_placement = $state(false)
882
+
883
+ // Clear pending hover lock timeout on unmount
884
+ $effect(() => () => legend_hover.cleanup())
885
+
886
+ // Calculate best legend placement using continuous grid sampling
887
+ let legend_placement = $derived.by(() => {
888
+ const should_show = show_legend !== undefined ? show_legend : series.length > 1
889
+ if (!should_show || !width || !height) return null
890
+
891
+ const result = compute_element_placement({
892
+ plot_bounds: { x: pad.l, y: pad.t, width: chart_width, height: chart_height },
893
+ element: legend_element,
894
+ element_size: { width: 120, height: 60 }, // fallback before first render
895
+ axis_clearance: legend?.axis_clearance,
896
+ exclude_rects: [],
897
+ points: bar_points_for_placement,
898
+ })
899
+
900
+ return result
901
+ })
902
+
903
+ // Tweened legend coordinates for smooth animation - create once, update target via effect
904
+ // untrack() explicitly captures initial tween config (intentional - config set once at mount)
905
+ const tweened_legend_coords = new Tween(
906
+ { x: 0, y: 0 },
907
+ untrack(() => ({ duration: 400, ...legend?.tween })),
908
+ )
909
+
910
+ // Update legend position with stability checks
911
+ $effect(() => {
912
+ if (!width || !height || !legend_placement) return
913
+
914
+ // Track dimensions for resize detection
915
+ const dims_changed = dim_tracker.has_changed(width, height)
916
+ if (dims_changed) dim_tracker.update(width, height)
917
+
918
+ const is_responsive = legend?.responsive ?? false
919
+ // Only update if: resize occurred, OR (not hover-locked AND (responsive OR not yet initially placed))
920
+ const should_update = dims_changed || (!legend_hover.is_locked.current &&
921
+ (is_responsive || !has_initial_legend_placement))
922
+
923
+ if (should_update) {
924
+ tweened_legend_coords.set(
925
+ { x: legend_placement.x, y: legend_placement.y },
926
+ // Skip animation on initial placement to avoid jump from (0, 0)
927
+ has_initial_legend_placement ? undefined : { duration: 0 },
928
+ )
929
+ // Only lock position after we have actual measured size
930
+ if (legend_element) {
931
+ has_initial_legend_placement = true
932
+ }
933
+ }
934
+ })
935
+
936
+ // Tooltip state
937
+ let hover_info = $state<BarHandlerProps<Metadata> | null>(null)
938
+
939
+ function get_bar_data(
940
+ series_idx: number,
941
+ bar_idx: number,
942
+ color: string,
943
+ ): BarHandlerProps<Metadata> {
944
+ const srs = internal_series[series_idx]
945
+ const [x, y] = [srs.x[bar_idx], srs.y[bar_idx]]
946
+ const [orient_x, orient_y] = orientation === `horizontal` ? [y, x] : [x, y]
947
+ const metadata = Array.isArray(srs.metadata)
948
+ ? srs.metadata[bar_idx]
949
+ : srs.metadata
950
+ const label = srs.labels?.[bar_idx] ?? null
951
+ const active_y_axis = srs.y_axis ?? `y1`
952
+ const active_x_axis = srs.x_axis ?? `x1`
953
+ const category_label = category_list[x]
954
+ const coords = {
955
+ x,
956
+ y,
957
+ orient_x,
958
+ orient_y,
959
+ x_axis: active_x_axis === `x2` ? x2_axis : x_axis,
960
+ x2_axis,
961
+ y_axis: active_y_axis === `y2` ? y2_axis : y_axis,
962
+ y2_axis,
963
+ }
964
+ return {
965
+ ...coords,
966
+ metadata,
967
+ color,
968
+ label,
969
+ series_idx,
970
+ bar_idx,
971
+ active_y_axis,
972
+ active_x_axis,
973
+ category_label,
974
+ }
975
+ }
976
+
977
+ // Find the point closest to the cursor on a polyline overlay (O(n) scan).
978
+ function find_closest_point(
979
+ evt: MouseEvent,
980
+ points: LineSeriesPoint[],
981
+ ): LineSeriesPoint | null {
982
+ const target = evt.target
983
+ if (!(target instanceof Element)) return null
984
+ const svg_el = target.closest(`svg`)
985
+ if (!svg_el) return null
986
+ const rect = svg_el.getBoundingClientRect()
987
+ const mx = evt.clientX - rect.left
988
+ const my = evt.clientY - rect.top
989
+ let best: LineSeriesPoint | null = null
990
+ let best_dist = Infinity
991
+ for (const pt of points) {
992
+ const dist = (pt.x - mx) ** 2 + (pt.y - my) ** 2
993
+ if (dist < best_dist) {
994
+ best_dist = dist
995
+ best = pt
996
+ }
997
+ }
998
+ return best
999
+ }
1000
+
1001
+ const line_point_fill = (pt: LineSeriesPoint, series_color: string): string =>
1002
+ pt.color_value != null
1003
+ ? color_scale_fn(pt.color_value)
1004
+ : pt.point_style?.fill ?? series_color
1005
+
1006
+ const handle_bar_hover =
1007
+ (series_idx: number, bar_idx: number, color: string) => (event: MouseEvent) => {
1008
+ hovered = true
1009
+ hover_info = get_bar_data(series_idx, bar_idx, color)
1010
+ change(hover_info)
1011
+ on_bar_hover?.({ ...hover_info, event })
1012
+ }
1013
+
1014
+ // Stack offsets (only for bar series in stacked mode, grouped by y-axis)
1015
+ let stacked_offsets = $derived(compute_stacked_offsets(internal_series, mode))
1016
+
1017
+ // Calculate group positions for grouped mode (side-by-side bars)
1018
+ let group_info = $derived(compute_group_info(internal_series, mode))
1019
+
1020
+ // Set theme-aware background when entering fullscreen
1021
+ $effect(() => {
1022
+ set_fullscreen_bg(wrapper, fullscreen, `--barplot-fullscreen-bg`)
1023
+ })
1024
+
1025
+ // State accessors for shared axis change handler
1026
+ const axis_state: AxisChangeState<BarSeries<Metadata>> = {
1027
+ get_axis: (axis) => {
1028
+ if (axis === `x`) return x_axis
1029
+ if (axis === `x2`) return x2_axis
1030
+ if (axis === `y`) return y_axis
1031
+ return y2_axis
1032
+ },
1033
+ set_axis: (axis, config) => {
1034
+ // Spread into existing state to preserve merged type structure
1035
+ if (axis === `x`) x_axis = { ...x_axis, ...config }
1036
+ else if (axis === `x2`) x2_axis_prop = { ...x2_axis_prop, ...config }
1037
+ else if (axis === `y`) y_axis = { ...y_axis, ...config }
1038
+ else y2_axis_prop = { ...y2_axis_prop, ...config }
1039
+ },
1040
+ get_series: () => series,
1041
+ set_series: (new_series) => (series = new_series),
1042
+ get_loading: () => axis_loading,
1043
+ set_loading: (axis) => (axis_loading = axis),
1044
+ }
1045
+
1046
+ // Shared handler + one-shot auto-load bound to this component's state
1047
+ const { handle_axis_change, try_auto_load } = create_axis_loader(
1048
+ axis_state,
1049
+ () => ({ data_loader, on_axis_change, on_error }),
1050
+ )
1051
+ $effect(try_auto_load)
1052
+ </script>
1053
+
1054
+ {#snippet ref_lines_layer(lines: IndexedRefLine[])}
1055
+ {#each lines as line (line.id ?? line.idx)}
1056
+ <ReferenceLine
1057
+ ref_line={line}
1058
+ line_idx={line.idx}
1059
+ x_min={line.x_axis === `x2` ? ranges.current.x2[0] : ranges.current.x[0]}
1060
+ x_max={line.x_axis === `x2` ? ranges.current.x2[1] : ranges.current.x[1]}
1061
+ y_min={line.y_axis === `y2` ? ranges.current.y2[0] : ranges.current.y[0]}
1062
+ y_max={line.y_axis === `y2` ? ranges.current.y2[1] : ranges.current.y[1]}
1063
+ x_scale={scales.x}
1064
+ x2_scale={scales.x2}
1065
+ y_scale={scales.y}
1066
+ y2_scale={scales.y2}
1067
+ {clip_path_id}
1068
+ hovered_line_idx={hovered_ref_line_idx}
1069
+ on_click={(event: RefLineEvent) => {
1070
+ line.on_click?.(event)
1071
+ on_ref_line_click?.(event)
1072
+ }}
1073
+ on_hover={(event: RefLineEvent | null) => {
1074
+ hovered_ref_line_idx = event?.line_idx ?? null
1075
+ line.on_hover?.(event)
1076
+ on_ref_line_hover?.(event)
1077
+ }}
1078
+ />
1079
+ {/each}
1080
+ {/snippet}
1081
+
1082
+ <svelte:window
1083
+ onkeydown={(evt) => {
1084
+ if (evt.key === `Escape` && fullscreen) {
1085
+ evt.preventDefault()
1086
+ fullscreen = false
1087
+ }
1088
+ if (evt.key === `Shift`) shift_held = true
1089
+ }}
1090
+ onkeyup={(evt) => {
1091
+ if (evt.key === `Shift`) shift_held = false
1092
+ }}
1093
+ />
1094
+
1095
+ <div
1096
+ bind:this={wrapper}
1097
+ bind:clientWidth={width}
1098
+ bind:clientHeight={height}
1099
+ {...rest}
1100
+ class="bar-plot {rest.class ?? ``}"
1101
+ class:fullscreen
1102
+ >
1103
+ {#if width && height}
1104
+ <div class="header-controls">
1105
+ {@render header_controls?.({ height, width, fullscreen })}
1106
+ {#if fullscreen_toggle}
1107
+ <FullscreenToggle bind:fullscreen />
1108
+ {/if}
1109
+ </div>
1110
+ <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
1111
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
1112
+ <svg
1113
+ bind:this={svg_element}
1114
+ role="application"
1115
+ aria-label={rest[`aria-label`] ??
1116
+ ([x_axis.label, y_axis.label].filter(Boolean).join(` vs `) || `Bar chart`)}
1117
+ tabindex="0"
1118
+ onfocusin={() => (is_focused = true)}
1119
+ onfocusout={() => (is_focused = false)}
1120
+ onmousedown={handle_mouse_down}
1121
+ ondblclick={() => {
1122
+ // Reset zoom to initial ranges (undo any pan/zoom)
1123
+ ranges.current.x = [...ranges.initial.x] as [number, number]
1124
+ ranges.current.x2 = [...ranges.initial.x2] as [number, number]
1125
+ ranges.current.y = [...ranges.initial.y] as [number, number]
1126
+ ranges.current.y2 = [...ranges.initial.y2] as [number, number]
1127
+ // Also reset axis props so future data changes recalculate auto ranges
1128
+ x_axis = { ...x_axis, range: [null, null] }
1129
+ x2_axis_prop = { ...x2_axis_prop, range: [null, null] }
1130
+ y_axis = { ...y_axis, range: [null, null] }
1131
+ y2_axis_prop = { ...y2_axis_prop, range: [null, null] }
1132
+ }}
1133
+ onmouseleave={() => {
1134
+ hovered = false
1135
+ hover_info = null
1136
+ change(null)
1137
+ on_bar_hover?.(null)
1138
+ }}
1139
+ onwheel={handle_wheel}
1140
+ ontouchstart={handle_touch_start}
1141
+ ontouchmove={handle_touch_move}
1142
+ ontouchend={handle_touch_end}
1143
+ ontouchcancel={handle_touch_end}
1144
+ style:cursor={pan_drag_state
1145
+ ? `grabbing`
1146
+ : shift_held && pan?.enabled !== false
1147
+ ? `grab`
1148
+ : `crosshair`}
1149
+ >
1150
+ <ZoomRect start={drag_state.start} current={drag_state.current} />
1151
+
1152
+ <!-- User content (custom overlays, reference lines, etc.) -->
1153
+ {@render user_content?.({
1154
+ height,
1155
+ width,
1156
+ x_scale_fn: scales.x,
1157
+ x2_scale_fn: scales.x2,
1158
+ y_scale_fn: scales.y,
1159
+ y2_scale_fn: scales.y2,
1160
+ pad,
1161
+ x_range: ranges.current.x,
1162
+ x2_range: ranges.current.x2,
1163
+ y_range: ranges.current.y,
1164
+ y2_range: ranges.current.y2,
1165
+ fullscreen,
1166
+ })}
1167
+
1168
+ <!-- Reference lines: below grid (rendered before axes which contain grid lines) -->
1169
+ {@render ref_lines_layer(ref_lines_by_z.below_grid)}
1170
+
1171
+ <!-- X-axis -->
1172
+ <PlotAxis
1173
+ side="x"
1174
+ ticks={ticks.x as number[]}
1175
+ place={scales.x}
1176
+ axis={x_axis}
1177
+ domain={ranges.current.x as Vec2}
1178
+ {pad}
1179
+ {width}
1180
+ {height}
1181
+ show_grid={display.x_grid}
1182
+ tick_label={(tick) =>
1183
+ get_tick_label(tick, cat_axis === `x` ? effective_cat_ticks : x_axis.ticks)}
1184
+ label_x={pad.l + chart_width / 2 + (x_axis.label_shift?.x ?? 0)}
1185
+ label_y={height - pad.b / 3 + (x_axis.label_shift?.y ?? 0)}
1186
+ axis_loading={axis_loading === `x`}
1187
+ on_axis_change={(key) => handle_axis_change(`x`, key)}
1188
+ />
1189
+
1190
+ <!-- X2-axis (Top) -->
1191
+ <!-- Note: x2 axis is only supported for vertical orientation -->
1192
+ {#if x2_series.length > 0 && orientation === `vertical`}
1193
+ <PlotAxis
1194
+ side="x2"
1195
+ ticks={ticks.x2 as number[]}
1196
+ place={scales.x2}
1197
+ axis={x2_axis}
1198
+ domain={ranges.current.x2 as Vec2}
1199
+ {pad}
1200
+ {width}
1201
+ {height}
1202
+ show_grid={display.x2_grid}
1203
+ tick_label={(tick) => get_tick_label(tick, x2_axis.ticks)}
1204
+ label_x={pad.l + chart_width / 2 + (x2_axis.label_shift?.x ?? 0)}
1205
+ label_y={Math.max(12, pad.t - (x2_axis.label_shift?.y ?? 40))}
1206
+ axis_loading={axis_loading === `x2`}
1207
+ on_axis_change={(key) => handle_axis_change(`x2`, key)}
1208
+ />
1209
+ {/if}
1210
+
1211
+ <!-- Y-axis -->
1212
+ <PlotAxis
1213
+ side="y"
1214
+ ticks={ticks.y as number[]}
1215
+ place={scales.y}
1216
+ axis={y_axis}
1217
+ domain={ranges.current.y as Vec2}
1218
+ {pad}
1219
+ {width}
1220
+ {height}
1221
+ show_grid={display.y_grid}
1222
+ tick_label={(tick) =>
1223
+ get_tick_label(tick, cat_axis === `y` ? effective_cat_ticks : y_axis.ticks)}
1224
+ label_x={Math.max(
1225
+ 12,
1226
+ pad.l - (y_axis.tick?.label?.inside ? 0 : tick_label_widths.y_max) -
1227
+ LABEL_GAP_DEFAULT,
1228
+ ) + (y_axis.label_shift?.x ?? 0)}
1229
+ label_y={pad.t + chart_height / 2 + (y_axis.label_shift?.y ?? 0)}
1230
+ axis_loading={axis_loading === `y`}
1231
+ on_axis_change={(key) => handle_axis_change(`y`, key)}
1232
+ />
1233
+
1234
+ <!-- Y2-axis (Right) -->
1235
+ <!-- Note: y2 axis is only supported for vertical orientation. Implementing x2 for horizontal mode requires additional complexity. -->
1236
+ {#if y2_series.length > 0 && orientation === `vertical`}
1237
+ <PlotAxis
1238
+ side="y2"
1239
+ ticks={ticks.y2 as number[]}
1240
+ place={scales.y2}
1241
+ axis={y2_axis}
1242
+ domain={ranges.current.y2 as Vec2}
1243
+ {pad}
1244
+ {width}
1245
+ {height}
1246
+ show_grid={display.y2_grid}
1247
+ tick_label={(tick) => get_tick_label(tick, y2_axis.ticks)}
1248
+ label_x={y2_axis_label_x(y2_axis, width, pad.r, tick_label_widths.y2_max)}
1249
+ label_y={pad.t + chart_height / 2 + (y2_axis.label_shift?.y ?? 0)}
1250
+ axis_loading={axis_loading === `y2`}
1251
+ on_axis_change={(key) => handle_axis_change(`y2`, key)}
1252
+ />
1253
+ {/if}
1254
+
1255
+ <!-- Define clip path for chart area -->
1256
+ <defs>
1257
+ <clipPath id={clip_path_id}>
1258
+ <rect x={pad.l} y={pad.t} width={chart_width} height={chart_height} />
1259
+ </clipPath>
1260
+ </defs>
1261
+
1262
+ <!-- Chart content is clipped in two groups so reference lines can interleave
1263
+ at their z positions while staying outside the chart clip: each line still
1264
+ self-clips to the plot area inside ReferenceLine, only its annotation text
1265
+ is allowed to overflow the plot edges. -->
1266
+ <g clip-path="url(#{clip_path_id})">
1267
+ <ZeroLines
1268
+ {display}
1269
+ x_scale_fn={scales.x}
1270
+ x2_scale_fn={scales.x2}
1271
+ y_scale_fn={scales.y}
1272
+ y2_scale_fn={scales.y2}
1273
+ x_range={ranges.current.x}
1274
+ x2_range={ranges.current.x2}
1275
+ y_range={ranges.current.y}
1276
+ y2_range={ranges.current.y2}
1277
+ x_scale_type={x_axis.scale_type}
1278
+ x2_scale_type={x2_axis.scale_type}
1279
+ y_scale_type={y_axis.scale_type}
1280
+ y2_scale_type={y2_axis.scale_type}
1281
+ x_is_time={x_axis.format?.startsWith(`%`) ?? false}
1282
+ x2_is_time={x2_axis.format?.startsWith(`%`) ?? false}
1283
+ has_x2={x2_series.length > 0}
1284
+ has_y2={y2_series.length > 0}
1285
+ {width}
1286
+ {height}
1287
+ {pad}
1288
+ />
1289
+ </g>
1290
+
1291
+ {@render ref_lines_layer(ref_lines_by_z.below_lines)}
1292
+
1293
+ <!-- Bars and Lines -->
1294
+ <g clip-path="url(#{clip_path_id})">
1295
+ {#each internal_series as srs, series_idx (srs?.id ?? series_idx)}
1296
+ {#if srs?.visible ?? true}
1297
+ {@const is_line = srs.render_mode === `line`}
1298
+ <g
1299
+ class={is_line ? `line-series` : `bar-series`}
1300
+ data-series-idx={series_idx}
1301
+ opacity={hovered_legend_series_idx !== null &&
1302
+ hovered_legend_series_idx !== series_idx
1303
+ ? 0.25
1304
+ : 1}
1305
+ >
1306
+ {#if is_line}
1307
+ <!-- Render as line -->
1308
+ {@const color = srs.color ?? line_state.color ?? `steelblue`}
1309
+ {@const stroke_width = srs.line_style?.stroke_width ?? line_state.width ?? 2}
1310
+ {@const line_dash = srs.line_style?.line_dash ?? `none`}
1311
+ {@const use_y2 = srs.y_axis === `y2`}
1312
+ {@const y_scale = use_y2 ? scales.y2 : scales.y}
1313
+ {@const use_x2 = srs.x_axis === `x2`}
1314
+ {@const x_scale = use_x2 ? scales.x2 : scales.x}
1315
+ {@const series_markers = srs.markers ?? DEFAULT_MARKERS}
1316
+ {@const show_line = series_markers === `line` ||
1317
+ series_markers === `line+points`}
1318
+ {@const show_points = series_markers === `points` ||
1319
+ series_markers === `line+points`}
1320
+ {@const points = compute_line_points({
1321
+ series: srs,
1322
+ series_idx,
1323
+ orientation,
1324
+ x_scale,
1325
+ y_scale,
1326
+ cat_y_scale: scales.y,
1327
+ })}
1328
+ {@const polyline_str = show_line && points.length > 1
1329
+ ? points.map((pt) => `${pt.x},${pt.y}`).join(` `)
1330
+ : ``}
1331
+ {#if polyline_str}
1332
+ <polyline
1333
+ points={polyline_str}
1334
+ fill="none"
1335
+ stroke={color}
1336
+ stroke-width={stroke_width}
1337
+ stroke-dasharray={line_dash}
1338
+ stroke-linejoin="round"
1339
+ stroke-linecap="round"
1340
+ />
1341
+ {/if}
1342
+ {#if polyline_str && !show_points && (on_bar_hover || on_bar_click)}
1343
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
1344
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
1345
+ <polyline
1346
+ points={polyline_str}
1347
+ fill="none"
1348
+ stroke="transparent"
1349
+ stroke-width={Math.max(10, stroke_width * 3)}
1350
+ stroke-linejoin="round"
1351
+ stroke-linecap="round"
1352
+ style:cursor={on_bar_click ? `pointer` : undefined}
1353
+ onmousemove={(evt) => {
1354
+ const pt = find_closest_point(evt, points)
1355
+ if (!pt) return
1356
+ hovered = true
1357
+ const fill = line_point_fill(pt, color)
1358
+ hover_info = get_bar_data(series_idx, pt.idx, fill)
1359
+ change(hover_info)
1360
+ on_bar_hover?.({ ...hover_info!, event: evt })
1361
+ }}
1362
+ onmouseleave={() => {
1363
+ change(null)
1364
+ hover_info = null
1365
+ on_bar_hover?.(null)
1366
+ }}
1367
+ onclick={(evt) => {
1368
+ const pt = find_closest_point(evt, points)
1369
+ if (!pt) return
1370
+ const fill = line_point_fill(pt, color)
1371
+ const bar_data = get_bar_data(series_idx, pt.idx, fill)
1372
+ on_bar_click?.({ ...bar_data, event: evt })
1373
+ }}
1374
+ />
1375
+ {/if}
1376
+ {#if show_points}
1377
+ {@const clickable = on_bar_click || on_point_click}
1378
+ {@const get_pt = (evt: Event) => {
1379
+ const attr = evt.target instanceof Element
1380
+ ? evt.target.closest(`[data-bar-idx]`)?.getAttribute(
1381
+ `data-bar-idx`,
1382
+ )
1383
+ : null
1384
+ return points.find((pt) => pt.idx === parseInt(attr ?? ``, 10))
1385
+ }}
1386
+ {@const set_hover = (
1387
+ pt: LineSeriesPoint | null,
1388
+ evt: MouseEvent | FocusEvent,
1389
+ ) => {
1390
+ if (pt) {
1391
+ hovered = true
1392
+ const fill = line_point_fill(pt, color)
1393
+ hover_info = get_bar_data(series_idx, pt.idx, fill)
1394
+ change(hover_info)
1395
+ } else {
1396
+ change(null)
1397
+ hover_info = null
1398
+ }
1399
+ on_bar_hover?.(pt ? { ...hover_info!, event: evt } : null)
1400
+ on_point_hover?.(
1401
+ pt ? { ...hover_info!, event: evt, point: pt } : null,
1402
+ )
1403
+ }}
1404
+ {@const do_click = (
1405
+ pt: LineSeriesPoint,
1406
+ evt: MouseEvent | KeyboardEvent,
1407
+ ) => {
1408
+ const fill = line_point_fill(pt, color)
1409
+ const bar_data = get_bar_data(series_idx, pt.idx, fill)
1410
+ on_bar_click?.({ ...bar_data, event: evt })
1411
+ on_point_click?.({ ...bar_data, event: evt, point: pt })
1412
+ }}
1413
+ {@const leaving = (evt: MouseEvent | FocusEvent) =>
1414
+ (evt.relatedTarget instanceof Element
1415
+ ? evt.relatedTarget.closest(`.line-points`)
1416
+ : null) !== evt.currentTarget}
1417
+ <!-- svelte-ignore a11y_no_noninteractive_element_interactions, a11y_mouse_events_have_key_events -->
1418
+ <g
1419
+ class="line-points"
1420
+ role="group"
1421
+ onmouseover={(evt) => {
1422
+ const pt = get_pt(evt)
1423
+ if (pt) set_hover(pt, evt)
1424
+ }}
1425
+ onfocusin={(evt) => {
1426
+ const pt = get_pt(evt)
1427
+ if (pt) set_hover(pt, evt)
1428
+ }}
1429
+ onmouseout={(evt) => {
1430
+ if (leaving(evt)) set_hover(null, evt)
1431
+ }}
1432
+ onfocusout={(evt) => {
1433
+ if (leaving(evt)) set_hover(null, evt)
1434
+ }}
1435
+ onclick={(evt) => {
1436
+ const pt = get_pt(evt)
1437
+ if (pt && clickable) do_click(pt, evt)
1438
+ }}
1439
+ onkeydown={(evt) => {
1440
+ const pt = get_pt(evt)
1441
+ if (pt && clickable && (evt.key === `Enter` || evt.key === ` `)) {
1442
+ evt.preventDefault()
1443
+ do_click(pt, evt)
1444
+ }
1445
+ }}
1446
+ >
1447
+ {#each points as pt (pt.idx)}
1448
+ {@const sty = pt.point_style}
1449
+ {@const fl = line_point_fill(pt, color)}
1450
+ {@const rad = pt.size_value != null
1451
+ ? size_scale_fn(pt.size_value)
1452
+ : sty?.radius ?? 4}
1453
+ {@const hov = hover_info?.series_idx === series_idx &&
1454
+ hover_info?.bar_idx === pt.idx}
1455
+ <ScatterPoint
1456
+ x={pt.x}
1457
+ y={pt.y}
1458
+ is_hovered={hov}
1459
+ {point_tween}
1460
+ style={{
1461
+ ...sty,
1462
+ radius: rad,
1463
+ fill: fl,
1464
+ stroke: sty?.stroke ?? `transparent`,
1465
+ stroke_width: sty?.stroke_width ?? 1,
1466
+ fill_opacity: sty?.fill_opacity ?? 1,
1467
+ stroke_opacity: sty?.stroke_opacity ?? 1,
1468
+ cursor: clickable ? `pointer` : undefined,
1469
+ }}
1470
+ hover={pt.point_hover ?? {}}
1471
+ label={pt.point_label ?? {}}
1472
+ offset={pt.point_offset ?? { x: 0, y: 0 }}
1473
+ origin={{ x: plot_center_x, y: plot_center_y }}
1474
+ --point-fill-color={fl}
1475
+ data-bar-idx={pt.idx}
1476
+ tabindex={clickable ? (hov ? 0 : -1) : undefined}
1477
+ />
1478
+ {/each}
1479
+ </g>
1480
+ {/if}
1481
+ {:else}
1482
+ <!-- Render as bars -->
1483
+ {#each srs.x as x_val, bar_idx (bar_idx)}
1484
+ {@const y_val = srs.y[bar_idx]}
1485
+ {@const base = mode === `stacked`
1486
+ ? (stacked_offsets[series_idx]?.[bar_idx] ?? 0)
1487
+ : 0}
1488
+ {@const color = srs.color ?? bar_state.color ?? `steelblue`}
1489
+ {@const bar_width_val = Array.isArray(srs.bar_width)
1490
+ ? (srs.bar_width[bar_idx] ?? 0.5)
1491
+ : (srs.bar_width ?? 0.5)}
1492
+ {@const is_vertical = orientation === `vertical`}
1493
+ {@const x_scale_bar = srs.x_axis === `x2` ? scales.x2 : scales.x}
1494
+ {@const [cat_scale, val_scale] = is_vertical
1495
+ ? [x_scale_bar, srs.y_axis === `y2` ? scales.y2 : scales.y]
1496
+ : [scales.y, x_scale_bar]}
1497
+ {@const { c0, c1, v0, v1, rect_x, rect_y, rect_w, rect_h } =
1498
+ compute_bar_rect({
1499
+ cat_val: x_val,
1500
+ val: y_val,
1501
+ base,
1502
+ bar_width_val,
1503
+ series_idx,
1504
+ mode,
1505
+ orientation,
1506
+ group_info,
1507
+ cat_scale,
1508
+ val_scale,
1509
+ })}
1510
+ {#if (is_vertical ? rect_h : rect_w) > 0}
1511
+ <path
1512
+ d={bar_path(
1513
+ rect_x,
1514
+ rect_y,
1515
+ rect_w,
1516
+ rect_h,
1517
+ Math.min(bar_state.border_radius ?? 0, rect_w / 2, rect_h / 2),
1518
+ is_vertical,
1519
+ )}
1520
+ fill={color}
1521
+ opacity={mode === `overlay` ? bar_state.opacity : 1}
1522
+ stroke={bar_state.stroke_color}
1523
+ stroke-opacity={bar_state.stroke_opacity}
1524
+ stroke-width={bar_state.stroke_width}
1525
+ role="button"
1526
+ tabindex="0"
1527
+ aria-label={`bar ${bar_idx + 1} of ${srs.label ?? `series`}`}
1528
+ style:cursor={on_bar_click ? `pointer` : undefined}
1529
+ onmousemove={handle_bar_hover(series_idx, bar_idx, color)}
1530
+ onmouseleave={() => {
1531
+ hover_info = null
1532
+ change(null)
1533
+ on_bar_hover?.(null)
1534
+ }}
1535
+ onclick={(evt) =>
1536
+ on_bar_click?.({
1537
+ ...get_bar_data(series_idx, bar_idx, color),
1538
+ event: evt,
1539
+ })}
1540
+ onkeydown={(evt) => {
1541
+ if (evt.key === `Enter` || evt.key === ` `) {
1542
+ evt.preventDefault()
1543
+ on_bar_click?.({
1544
+ ...get_bar_data(series_idx, bar_idx, color),
1545
+ event: evt,
1546
+ })
1547
+ }
1548
+ }}
1549
+ />
1550
+ {#if srs.labels?.[bar_idx]}
1551
+ <text
1552
+ x={is_vertical ? (c0 + c1) / 2 : Math.max(v0, v1) + 4}
1553
+ y={is_vertical ? Math.max(0, Math.min(v0, v1) - 6) : (c0 + c1) / 2}
1554
+ text-anchor={is_vertical ? `middle` : undefined}
1555
+ dominant-baseline={is_vertical ? undefined : `central`}
1556
+ class="bar-label"
1557
+ >
1558
+ {srs.labels[bar_idx]}
1559
+ </text>
1560
+ {/if}
1561
+ {/if}
1562
+ {/each}
1563
+ {/if}
1564
+ </g>
1565
+ {/if}
1566
+ {/each}
1567
+ </g>
1568
+
1569
+ {@render ref_lines_layer(ref_lines_by_z.below_points)}
1570
+ {@render ref_lines_layer(ref_lines_by_z.above_all)}
1571
+ </svg>
1572
+
1573
+ <!-- Legend -->
1574
+ {#if legend && (show_legend !== undefined ? show_legend : series.length > 1)}
1575
+ {@const legend_left = legend_auto_outside
1576
+ ? legend_outside_x
1577
+ : legend_placement
1578
+ ? tweened_legend_coords.current.x
1579
+ : pad.l + 10}
1580
+ {@const legend_top = legend_auto_outside
1581
+ ? legend_outside_y
1582
+ : legend_placement
1583
+ ? tweened_legend_coords.current.y
1584
+ : pad.t + 10}
1585
+ <PlotLegend
1586
+ bind:root_element={legend_element}
1587
+ {...legend}
1588
+ series_data={legend_data}
1589
+ on_toggle={legend?.on_toggle ?? legend_vis.on_toggle}
1590
+ on_group_toggle={legend?.on_group_toggle ?? legend_vis.on_group_toggle}
1591
+ on_double_click={legend?.on_double_click ?? legend_vis.on_double_click}
1592
+ on_hover_change={legend_hover.set_locked}
1593
+ on_item_hover={(item) =>
1594
+ (hovered_legend_series_idx = item != null && item.series_idx >= 0
1595
+ ? item.series_idx
1596
+ : null)}
1597
+ active_series_idx={hover_info?.series_idx ?? hovered_legend_series_idx}
1598
+ style={`
1599
+ position: absolute;
1600
+ left: ${legend_left}px;
1601
+ top: ${legend_top}px;
1602
+ pointer-events: auto;
1603
+ ${legend?.style || ``}
1604
+ `}
1605
+ />
1606
+ {/if}
1607
+
1608
+ {#if hover_info && hovered}
1609
+ {@const cx = (hover_info.active_x_axis === `x2` ? scales.x2 : scales.x)(
1610
+ hover_info.orient_x,
1611
+ )}
1612
+ {@const cy = (hover_info.active_y_axis === `y2` ? scales.y2 : scales.y)(
1613
+ hover_info.orient_y,
1614
+ )}
1615
+ <PlotTooltip
1616
+ x={cx}
1617
+ y={cy}
1618
+ offset={{ x: 10, y: 5 }}
1619
+ constrain_to={{ width, height }}
1620
+ fallback_size={{ width: 140, height: 50 }}
1621
+ bg_color={hover_info.color}
1622
+ >
1623
+ {#if tooltip}
1624
+ {@render tooltip({ ...hover_info, fullscreen })}
1625
+ {:else}
1626
+ {@const series_label = series[hover_info.series_idx]?.label}
1627
+ {#if series.length > 1 && series_label}
1628
+ <div><strong>{series_label}</strong></div>
1629
+ {/if}
1630
+ <div>
1631
+ {@html sanitize_html(hover_info.x_axis.label || `x`)}: {
1632
+ (cat_axis === `x` ? hover_info.category_label : undefined) ??
1633
+ format_value(hover_info.orient_x, hover_info.x_axis.format || `.3~s`)
1634
+ }
1635
+ </div>
1636
+ <div>
1637
+ {@html sanitize_html(hover_info.y_axis.label || `y`)}: {
1638
+ (cat_axis === `y` ? hover_info.category_label : undefined) ??
1639
+ format_value(hover_info.orient_y, hover_info.y_axis.format || `.3~s`)
1640
+ }
1641
+ </div>
1642
+ {/if}
1643
+ </PlotTooltip>
1644
+ {/if}
1645
+
1646
+ {#if show_controls}
1647
+ <BarPlotControls
1648
+ toggle_props={{
1649
+ ...controls_toggle_props,
1650
+ style: `--ctrl-btn-right: var(--fullscreen-btn-offset, 30px); ${
1651
+ controls_toggle_props?.style ?? ``
1652
+ }`,
1653
+ }}
1654
+ pane_props={controls_pane_props}
1655
+ bind:show_controls
1656
+ bind:controls_open
1657
+ bind:orientation
1658
+ bind:mode
1659
+ bind:x_axis
1660
+ bind:x2_axis={x2_axis_prop}
1661
+ bind:y_axis
1662
+ bind:y2_axis={y2_axis_prop}
1663
+ bind:display
1664
+ auto_x_range={auto_ranges.x as Vec2}
1665
+ auto_x2_range={auto_ranges.x2 as Vec2}
1666
+ auto_y_range={auto_ranges.y as Vec2}
1667
+ auto_y2_range={auto_ranges.y2 as Vec2}
1668
+ has_x2_points={x2_series.length > 0}
1669
+ has_y2_points={y2_series.length > 0}
1670
+ children={controls_extra}
1671
+ />
1672
+ {/if}
1673
+ {/if}
1674
+
1675
+ <!-- User-provided children (e.g. for custom absolutely-positioned overlays) -->
1676
+ {@render children?.({ height, width, fullscreen })}
1677
+ </div>
1678
+
1679
+ <style>
1680
+ .bar-plot {
1681
+ position: relative;
1682
+ width: 100%;
1683
+ height: var(--barplot-height, auto);
1684
+ min-height: var(--barplot-min-height, 300px);
1685
+ container-type: size;
1686
+ z-index: var(--barplot-z-index, auto);
1687
+ border-radius: var(--barplot-border-radius, var(--border-radius, 3pt));
1688
+ flex: var(--barplot-flex, 1);
1689
+ display: var(--barplot-display, flex);
1690
+ flex-direction: column;
1691
+ background: var(--barplot-bg, var(--plot-bg));
1692
+ }
1693
+ .bar-plot.fullscreen {
1694
+ position: fixed;
1695
+ top: 0;
1696
+ left: 0;
1697
+ width: 100vw !important;
1698
+ height: 100vh !important;
1699
+ /* Must be higher than Structure.svelte's --struct-buttons-z-index. */
1700
+ z-index: var(--barplot-fullscreen-z-index, var(--z-index-overlay-nav, 100000001));
1701
+ margin: 0;
1702
+ border-radius: 0;
1703
+ background: var(--barplot-fullscreen-bg, var(--barplot-bg, var(--plot-bg)));
1704
+ max-height: none !important;
1705
+ overflow: hidden;
1706
+ /* border-top (not padding-top): bind:clientHeight includes padding but excludes
1707
+ borders - padding made the chart overflow + clip its bottom 2em (x-axis title) */
1708
+ border-top: var(--plot-fullscreen-padding-top, 2em) solid
1709
+ var(--barplot-fullscreen-bg, var(--barplot-bg, var(--plot-bg, transparent)));
1710
+ box-sizing: border-box;
1711
+ }
1712
+ .header-controls {
1713
+ position: absolute;
1714
+ top: var(--ctrl-btn-top, 5pt);
1715
+ right: var(--fullscreen-btn-right, 4px);
1716
+ z-index: var(--fullscreen-btn-z-index, 10);
1717
+ display: flex;
1718
+ align-items: center;
1719
+ gap: 8px;
1720
+ }
1721
+ .header-controls :global(.fullscreen-toggle) {
1722
+ position: static; /* Override absolute positioning since container handles it */
1723
+ opacity: 1; /* Always visible when inside header-controls, container controls visibility */
1724
+ }
1725
+ /* Hide controls and fullscreen toggles by default, show on hover */
1726
+ .bar-plot :global(.pane-toggle),
1727
+ .bar-plot .header-controls {
1728
+ opacity: 0;
1729
+ transition: opacity 0.2s, background-color 0.2s;
1730
+ }
1731
+ .bar-plot:hover :global(.pane-toggle),
1732
+ .bar-plot:hover .header-controls,
1733
+ .bar-plot :global(.pane-toggle:focus-visible),
1734
+ .bar-plot :global(.pane-toggle[aria-expanded='true']),
1735
+ .bar-plot .header-controls:focus-within {
1736
+ opacity: 1;
1737
+ }
1738
+ svg {
1739
+ width: var(--barplot-svg-width, 100%);
1740
+ height: var(--barplot-svg-height, 100%);
1741
+ flex: var(--barplot-svg-flex, 1);
1742
+ overflow: var(--barplot-svg-overflow, visible);
1743
+ fill: var(--text-color);
1744
+ font-weight: var(--scatter-font-weight);
1745
+ font-size: var(--scatter-font-size);
1746
+ }
1747
+ .bar-plot.dragover {
1748
+ border: var(--barplot-dragover-border, var(--dragover-border));
1749
+ background-color: var(--barplot-dragover-bg, var(--dragover-bg));
1750
+ }
1751
+ .bar-label {
1752
+ fill: var(--text-color);
1753
+ font-size: 11px;
1754
+ }
1755
+ </style>