matterviz 0.3.5 → 0.3.6

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 (855) hide show
  1. package/.vscode/launch.json +13 -0
  2. package/.vscodeignore +7 -0
  3. package/dist/assets/STLExporter-BpTH3YHE.js +8 -0
  4. package/dist/assets/browser-DdDecX_W.js +1 -0
  5. package/dist/assets/export-qgn-H9y6.js +2 -0
  6. package/dist/assets/main-DiKYzti2.css +1 -0
  7. package/dist/assets/moyo_wasm_bg-0ocwg7xY.wasm +0 -0
  8. package/dist/extension.js +31293 -0
  9. package/dist/src/lib/FilePicker.svelte +360 -0
  10. package/dist/src/lib/MillerIndexInput.svelte +66 -0
  11. package/dist/src/lib/api/mp.ts +26 -0
  12. package/dist/src/lib/api/optimade.ts +204 -0
  13. package/dist/src/lib/brillouin/BrillouinZone.svelte +549 -0
  14. package/dist/src/lib/brillouin/BrillouinZoneControls.svelte +144 -0
  15. package/dist/src/lib/brillouin/BrillouinZoneExportPane.svelte +146 -0
  16. package/dist/src/lib/brillouin/BrillouinZoneInfoPane.svelte +146 -0
  17. package/dist/src/lib/brillouin/BrillouinZoneScene.svelte +476 -0
  18. package/dist/src/lib/brillouin/BrillouinZoneTooltip.svelte +92 -0
  19. package/dist/src/lib/brillouin/compute.ts +529 -0
  20. package/dist/src/lib/brillouin/index.ts +8 -0
  21. package/dist/src/lib/brillouin/types.ts +51 -0
  22. package/dist/src/lib/chempot-diagram/ChemPotDiagram.svelte +327 -0
  23. package/dist/src/lib/chempot-diagram/ChemPotDiagram2D.svelte +846 -0
  24. package/dist/src/lib/chempot-diagram/ChemPotDiagram3D.svelte +3193 -0
  25. package/dist/src/lib/chempot-diagram/async-compute.svelte.ts +94 -0
  26. package/dist/src/lib/chempot-diagram/chempot-worker.ts +11 -0
  27. package/dist/src/lib/chempot-diagram/color.ts +42 -0
  28. package/dist/src/lib/chempot-diagram/compute.ts +1014 -0
  29. package/dist/src/lib/chempot-diagram/index.ts +6 -0
  30. package/dist/src/lib/chempot-diagram/pointer.ts +56 -0
  31. package/dist/src/lib/chempot-diagram/temperature.ts +77 -0
  32. package/dist/src/lib/chempot-diagram/types.ts +130 -0
  33. package/dist/src/lib/colors/index.ts +249 -0
  34. package/dist/src/lib/composition/BarChart.svelte +297 -0
  35. package/dist/src/lib/composition/BubbleChart.svelte +218 -0
  36. package/dist/src/lib/composition/Composition.svelte +165 -0
  37. package/dist/src/lib/composition/Formula.svelte +268 -0
  38. package/dist/src/lib/composition/FormulaFilter.svelte +1257 -0
  39. package/dist/src/lib/composition/PieChart.svelte +323 -0
  40. package/dist/src/lib/composition/format.ts +155 -0
  41. package/dist/src/lib/composition/index.ts +37 -0
  42. package/dist/src/lib/composition/parse.ts +605 -0
  43. package/dist/src/lib/constants.ts +134 -0
  44. package/dist/src/lib/controls.ts +42 -0
  45. package/dist/src/lib/convex-hull/ConvexHull.svelte +157 -0
  46. package/dist/src/lib/convex-hull/ConvexHull2D.svelte +825 -0
  47. package/dist/src/lib/convex-hull/ConvexHull3D.svelte +1801 -0
  48. package/dist/src/lib/convex-hull/ConvexHull4D.svelte +1398 -0
  49. package/dist/src/lib/convex-hull/ConvexHullControls.svelte +535 -0
  50. package/dist/src/lib/convex-hull/ConvexHullInfoPane.svelte +125 -0
  51. package/dist/src/lib/convex-hull/ConvexHullStats.svelte +929 -0
  52. package/dist/src/lib/convex-hull/ConvexHullTooltip.svelte +131 -0
  53. package/dist/src/lib/convex-hull/GasPressureControls.svelte +247 -0
  54. package/dist/src/lib/convex-hull/StructurePopup.svelte +151 -0
  55. package/dist/src/lib/convex-hull/TemperatureSlider.svelte +140 -0
  56. package/dist/src/lib/convex-hull/barycentric-coords.ts +246 -0
  57. package/dist/src/lib/convex-hull/demo-temperature.ts +63 -0
  58. package/dist/src/lib/convex-hull/gas-thermodynamics.ts +405 -0
  59. package/dist/src/lib/convex-hull/helpers.ts +932 -0
  60. package/dist/src/lib/convex-hull/index.ts +202 -0
  61. package/dist/src/lib/convex-hull/thermodynamics.ts +2192 -0
  62. package/dist/src/lib/convex-hull/types.ts +267 -0
  63. package/dist/src/lib/coordination/CoordinationBarPlot.svelte +311 -0
  64. package/dist/src/lib/coordination/calc-coordination.ts +93 -0
  65. package/dist/src/lib/coordination/index.ts +9 -0
  66. package/dist/src/lib/effects.svelte.ts +48 -0
  67. package/dist/src/lib/element/BohrAtom.svelte +147 -0
  68. package/dist/src/lib/element/ElementHeading.svelte +26 -0
  69. package/dist/src/lib/element/ElementPhoto.svelte +57 -0
  70. package/dist/src/lib/element/ElementStats.svelte +80 -0
  71. package/dist/src/lib/element/ElementTile.svelte +484 -0
  72. package/dist/src/lib/element/data.json.gz.d.ts +4 -0
  73. package/dist/src/lib/element/data.ts +14 -0
  74. package/dist/src/lib/element/index.ts +8 -0
  75. package/dist/src/lib/element/types.ts +62 -0
  76. package/dist/src/lib/feedback/ClickFeedback.svelte +58 -0
  77. package/dist/src/lib/feedback/DragOverlay.svelte +42 -0
  78. package/dist/src/lib/feedback/index.ts +4 -0
  79. package/dist/src/lib/fermi-surface/FermiSlice.svelte +189 -0
  80. package/dist/src/lib/fermi-surface/FermiSurface.svelte +600 -0
  81. package/dist/src/lib/fermi-surface/FermiSurfaceControls.svelte +448 -0
  82. package/dist/src/lib/fermi-surface/FermiSurfaceScene.svelte +794 -0
  83. package/dist/src/lib/fermi-surface/FermiSurfaceTooltip.svelte +111 -0
  84. package/dist/src/lib/fermi-surface/compute.ts +728 -0
  85. package/dist/src/lib/fermi-surface/constants.ts +32 -0
  86. package/dist/src/lib/fermi-surface/export.ts +64 -0
  87. package/dist/src/lib/fermi-surface/index.ts +14 -0
  88. package/dist/src/lib/fermi-surface/marching-cubes.ts +3 -0
  89. package/dist/src/lib/fermi-surface/parse.ts +574 -0
  90. package/dist/src/lib/fermi-surface/symmetry.ts +56 -0
  91. package/dist/src/lib/fermi-surface/types.ts +159 -0
  92. package/dist/src/lib/heatmap-matrix/HeatmapMatrix.svelte +1545 -0
  93. package/dist/src/lib/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  94. package/dist/src/lib/heatmap-matrix/index.ts +167 -0
  95. package/dist/src/lib/heatmap-matrix/shared.ts +7 -0
  96. package/dist/src/lib/icons.ts +650 -0
  97. package/dist/src/lib/index.ts +61 -0
  98. package/dist/src/lib/io/decompress.ts +92 -0
  99. package/dist/src/lib/io/export.ts +385 -0
  100. package/dist/src/lib/io/fetch.ts +46 -0
  101. package/dist/src/lib/io/file-drop.ts +51 -0
  102. package/dist/src/lib/io/index.ts +7 -0
  103. package/dist/src/lib/io/is-binary.ts +24 -0
  104. package/dist/src/lib/io/types.ts +8 -0
  105. package/dist/src/lib/io/url-drop.ts +141 -0
  106. package/dist/src/lib/isosurface/Isosurface.svelte +285 -0
  107. package/dist/src/lib/isosurface/IsosurfaceControls.svelte +277 -0
  108. package/dist/src/lib/isosurface/index.ts +7 -0
  109. package/dist/src/lib/isosurface/parse.ts +656 -0
  110. package/dist/src/lib/isosurface/slice.ts +175 -0
  111. package/dist/src/lib/isosurface/types.ts +309 -0
  112. package/dist/src/lib/labels.ts +320 -0
  113. package/dist/src/lib/layout/FullscreenToggle.svelte +50 -0
  114. package/dist/src/lib/layout/InfoCard.svelte +120 -0
  115. package/dist/src/lib/layout/InfoTag.svelte +185 -0
  116. package/dist/src/lib/layout/PropertyFilter.svelte +246 -0
  117. package/dist/src/lib/layout/SettingsSection.svelte +148 -0
  118. package/dist/src/lib/layout/SubpageGrid.svelte +82 -0
  119. package/dist/src/lib/layout/fullscreen.ts +65 -0
  120. package/dist/src/lib/layout/index.ts +11 -0
  121. package/dist/src/lib/layout/json-tree/JsonNode.svelte +548 -0
  122. package/dist/src/lib/layout/json-tree/JsonTree.svelte +1230 -0
  123. package/dist/src/lib/layout/json-tree/JsonValue.svelte +334 -0
  124. package/dist/src/lib/layout/json-tree/index.ts +3 -0
  125. package/dist/src/lib/layout/json-tree/types.ts +126 -0
  126. package/dist/src/lib/layout/json-tree/utils.ts +682 -0
  127. package/dist/src/lib/marching-cubes.ts +614 -0
  128. package/dist/src/lib/math.ts +1081 -0
  129. package/dist/src/lib/overlays/ContextMenu.svelte +162 -0
  130. package/dist/src/lib/overlays/CopyButton.svelte +45 -0
  131. package/dist/src/lib/overlays/DragControlTab.svelte +98 -0
  132. package/dist/src/lib/overlays/DraggablePane.svelte +487 -0
  133. package/dist/src/lib/overlays/InfoPaneCards.svelte +149 -0
  134. package/dist/src/lib/overlays/index.ts +3 -0
  135. package/dist/src/lib/periodic-table/PeriodicTable.svelte +469 -0
  136. package/dist/src/lib/periodic-table/PeriodicTableControls.svelte +557 -0
  137. package/dist/src/lib/periodic-table/PropertySelect.svelte +37 -0
  138. package/dist/src/lib/periodic-table/index.ts +12 -0
  139. package/dist/src/lib/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +1086 -0
  140. package/dist/src/lib/phase-diagram/PhaseDiagramControls.svelte +444 -0
  141. package/dist/src/lib/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  142. package/dist/src/lib/phase-diagram/PhaseDiagramExportPane.svelte +184 -0
  143. package/dist/src/lib/phase-diagram/PhaseDiagramTooltip.svelte +391 -0
  144. package/dist/src/lib/phase-diagram/TdbInfoPanel.svelte +203 -0
  145. package/dist/src/lib/phase-diagram/build-diagram.ts +186 -0
  146. package/dist/src/lib/phase-diagram/colors.ts +58 -0
  147. package/dist/src/lib/phase-diagram/diagram-input.ts +40 -0
  148. package/dist/src/lib/phase-diagram/index.ts +13 -0
  149. package/dist/src/lib/phase-diagram/parse.ts +348 -0
  150. package/dist/src/lib/phase-diagram/svg-to-diagram.ts +1023 -0
  151. package/dist/src/lib/phase-diagram/types.ts +144 -0
  152. package/dist/src/lib/phase-diagram/utils.ts +775 -0
  153. package/dist/src/lib/plot/AxisLabel.svelte +51 -0
  154. package/dist/src/lib/plot/BarPlot.svelte +2113 -0
  155. package/dist/src/lib/plot/BarPlotControls.svelte +66 -0
  156. package/dist/src/lib/plot/BinnedScatterPlot.svelte +1114 -0
  157. package/dist/src/lib/plot/ColorBar.svelte +721 -0
  158. package/dist/src/lib/plot/ColorScaleSelect.svelte +54 -0
  159. package/dist/src/lib/plot/ElementScatter.svelte +63 -0
  160. package/dist/src/lib/plot/FillArea.svelte +223 -0
  161. package/dist/src/lib/plot/Histogram.svelte +1558 -0
  162. package/dist/src/lib/plot/HistogramControls.svelte +212 -0
  163. package/dist/src/lib/plot/InteractiveAxisLabel.svelte +96 -0
  164. package/dist/src/lib/plot/Line.svelte +84 -0
  165. package/dist/src/lib/plot/PlotAxis.svelte +169 -0
  166. package/dist/src/lib/plot/PlotControls.svelte +537 -0
  167. package/dist/src/lib/plot/PlotLegend.svelte +569 -0
  168. package/dist/src/lib/plot/PlotTooltip.svelte +67 -0
  169. package/dist/src/lib/plot/PortalSelect.svelte +253 -0
  170. package/dist/src/lib/plot/ReferenceLine3D.svelte +156 -0
  171. package/dist/src/lib/plot/ReferencePlane.svelte +175 -0
  172. package/dist/src/lib/plot/ScatterPlot.svelte +2778 -0
  173. package/dist/src/lib/plot/ScatterPlot3D.svelte +529 -0
  174. package/dist/src/lib/plot/ScatterPlot3DControls.svelte +437 -0
  175. package/dist/src/lib/plot/ScatterPlot3DScene.svelte +912 -0
  176. package/dist/src/lib/plot/ScatterPlotControls.svelte +306 -0
  177. package/dist/src/lib/plot/ScatterPoint.svelte +182 -0
  178. package/dist/src/lib/plot/SpacegroupBarPlot.svelte +293 -0
  179. package/dist/src/lib/plot/Surface3D.svelte +197 -0
  180. package/dist/src/lib/plot/ZeroLines.svelte +97 -0
  181. package/dist/src/lib/plot/ZoomRect.svelte +23 -0
  182. package/dist/src/lib/plot/adaptive-density.ts +316 -0
  183. package/dist/src/lib/plot/auto-place.ts +184 -0
  184. package/dist/src/lib/plot/axis-utils.ts +122 -0
  185. package/dist/src/lib/plot/binned-scatter-types.ts +83 -0
  186. package/dist/src/lib/plot/data-cleaning.ts +1069 -0
  187. package/dist/src/lib/plot/data-transform.ts +69 -0
  188. package/dist/src/lib/plot/defaults.ts +9 -0
  189. package/dist/src/lib/plot/fill-utils.ts +494 -0
  190. package/dist/src/lib/plot/hover-lock.svelte.ts +60 -0
  191. package/dist/src/lib/plot/index.ts +53 -0
  192. package/dist/src/lib/plot/interactions.ts +119 -0
  193. package/dist/src/lib/plot/layout.ts +425 -0
  194. package/dist/src/lib/plot/reference-line.ts +426 -0
  195. package/dist/src/lib/plot/scales.ts +654 -0
  196. package/dist/src/lib/plot/svg.ts +23 -0
  197. package/dist/src/lib/plot/types.ts +1144 -0
  198. package/dist/src/lib/plot/utils/label-placement.ts +541 -0
  199. package/dist/src/lib/plot/utils/series-visibility.ts +140 -0
  200. package/dist/src/lib/plot/utils.ts +11 -0
  201. package/dist/src/lib/rdf/RdfPlot.svelte +247 -0
  202. package/dist/src/lib/rdf/calc-rdf.ts +167 -0
  203. package/dist/src/lib/rdf/index.ts +27 -0
  204. package/dist/src/lib/sanitize.ts +126 -0
  205. package/dist/src/lib/settings.ts +1479 -0
  206. package/dist/src/lib/spectral/Bands.svelte +1040 -0
  207. package/dist/src/lib/spectral/BandsAndDos.svelte +134 -0
  208. package/dist/src/lib/spectral/BrillouinBandsDos.svelte +252 -0
  209. package/dist/src/lib/spectral/Dos.svelte +697 -0
  210. package/dist/src/lib/spectral/helpers.ts +1381 -0
  211. package/dist/src/lib/spectral/index.ts +8 -0
  212. package/dist/src/lib/spectral/types.ts +112 -0
  213. package/dist/src/lib/state.svelte.ts +64 -0
  214. package/dist/src/lib/structure/Arrow.svelte +72 -0
  215. package/dist/src/lib/structure/AtomLegend.svelte +815 -0
  216. package/dist/src/lib/structure/Bond.svelte +140 -0
  217. package/dist/src/lib/structure/CanvasTooltip.svelte +33 -0
  218. package/dist/src/lib/structure/CellSelect.svelte +349 -0
  219. package/dist/src/lib/structure/Cylinder.svelte +45 -0
  220. package/dist/src/lib/structure/Lattice.svelte +196 -0
  221. package/dist/src/lib/structure/Structure.svelte +2248 -0
  222. package/dist/src/lib/structure/StructureControls.svelte +1273 -0
  223. package/dist/src/lib/structure/StructureExportPane.svelte +252 -0
  224. package/dist/src/lib/structure/StructureInfoPane.svelte +737 -0
  225. package/dist/src/lib/structure/StructureScene.svelte +2255 -0
  226. package/dist/src/lib/structure/atom-properties.ts +316 -0
  227. package/dist/src/lib/structure/bond-order-perception.ts +447 -0
  228. package/dist/src/lib/structure/bonding.ts +944 -0
  229. package/dist/src/lib/structure/export.ts +861 -0
  230. package/dist/src/lib/structure/index.ts +291 -0
  231. package/dist/src/lib/structure/label-placement.ts +130 -0
  232. package/dist/src/lib/structure/measure.ts +45 -0
  233. package/dist/src/lib/structure/parse.ts +1705 -0
  234. package/dist/src/lib/structure/partial-occupancy.ts +183 -0
  235. package/dist/src/lib/structure/pbc.ts +164 -0
  236. package/dist/src/lib/structure/supercell.ts +226 -0
  237. package/dist/src/lib/structure/validation.ts +11 -0
  238. package/dist/src/lib/symmetry/SymmetryStats.svelte +226 -0
  239. package/dist/src/lib/symmetry/WyckoffTable.svelte +120 -0
  240. package/dist/src/lib/symmetry/cell-transform.ts +118 -0
  241. package/dist/src/lib/symmetry/index.ts +348 -0
  242. package/dist/src/lib/symmetry/spacegroups.ts +404 -0
  243. package/dist/src/lib/table/HeatmapTable.svelte +1833 -0
  244. package/dist/src/lib/table/ToggleMenu.svelte +385 -0
  245. package/dist/src/lib/table/index.ts +139 -0
  246. package/dist/src/lib/theme/ThemeControl.svelte +53 -0
  247. package/dist/src/lib/theme/index.ts +107 -0
  248. package/dist/src/lib/theme/themes.mjs +297 -0
  249. package/dist/src/lib/time.ts +71 -0
  250. package/dist/src/lib/tooltip/TooltipContent.svelte +58 -0
  251. package/dist/src/lib/tooltip/index.ts +2 -0
  252. package/dist/src/lib/tooltip/types.ts +13 -0
  253. package/dist/src/lib/trajectory/Trajectory.svelte +1545 -0
  254. package/dist/src/lib/trajectory/TrajectoryError.svelte +128 -0
  255. package/dist/src/lib/trajectory/TrajectoryExportPane.svelte +357 -0
  256. package/dist/src/lib/trajectory/TrajectoryInfoPane.svelte +313 -0
  257. package/dist/src/lib/trajectory/constants.ts +7 -0
  258. package/dist/src/lib/trajectory/extract.ts +196 -0
  259. package/dist/src/lib/trajectory/format-detect.ts +96 -0
  260. package/dist/src/lib/trajectory/frame-reader.ts +456 -0
  261. package/dist/src/lib/trajectory/helpers.ts +217 -0
  262. package/dist/src/lib/trajectory/index.ts +218 -0
  263. package/dist/src/lib/trajectory/parse/ase.ts +109 -0
  264. package/dist/src/lib/trajectory/parse/hdf5.ts +173 -0
  265. package/dist/src/lib/trajectory/parse/index.ts +411 -0
  266. package/dist/src/lib/trajectory/parse/lammps.ts +215 -0
  267. package/dist/src/lib/trajectory/parse/vasp.ts +102 -0
  268. package/dist/src/lib/trajectory/parse/xyz.ts +143 -0
  269. package/dist/src/lib/trajectory/plotting.ts +599 -0
  270. package/dist/src/lib/trajectory/types.ts +13 -0
  271. package/dist/src/lib/utils.ts +56 -0
  272. package/dist/src/lib/xrd/XrdPlot.svelte +615 -0
  273. package/dist/src/lib/xrd/broadening.ts +130 -0
  274. package/dist/src/lib/xrd/calc-xrd.ts +397 -0
  275. package/dist/src/lib/xrd/index.ts +38 -0
  276. package/dist/src/lib/xrd/parse.ts +858 -0
  277. package/dist/webview.js +29421 -0
  278. package/icon.png +0 -0
  279. package/license +1 -1
  280. package/matterviz-0.3.2.vsix +0 -0
  281. package/matterviz-0.3.4.vsix +0 -0
  282. package/matterviz-0.3.5.vsix +0 -0
  283. package/package.json +1460 -215
  284. package/readme.md +171 -98
  285. package/scripts/sync-config.ts +101 -0
  286. package/src/declarations.d.ts +2 -0
  287. package/src/extension.ts +972 -0
  288. package/src/node-io.ts +65 -0
  289. package/src/types.ts +17 -0
  290. package/src/webview/JsonBrowser.svelte +1079 -0
  291. package/src/webview/PlotPanel.svelte +346 -0
  292. package/src/webview/detect.ts +444 -0
  293. package/src/webview/main.ts +764 -0
  294. package/src/webview/plot-utils.ts +250 -0
  295. package/test-fixtures/all-viz-types.json.gz +0 -0
  296. package/test-fixtures/plot-demo-data.json.gz +0 -0
  297. package/tests/detect.test.ts +604 -0
  298. package/tests/extension.test.ts +2041 -0
  299. package/tests/node-io.test.ts +39 -0
  300. package/tests/plot-utils.test.ts +302 -0
  301. package/tests/vite-plugin-json-gz.test.ts +114 -0
  302. package/tests/vscode-mock.ts +18 -0
  303. package/tests/webview.test.ts +231 -0
  304. package/tsconfig.json +20 -0
  305. package/vite-plugin-json-gz.ts +29 -0
  306. package/vite.config.ts +34 -0
  307. package/vite.extension.config.ts +34 -0
  308. package/dist/EmptyState.svelte.d.ts +0 -9
  309. package/dist/FilePicker.svelte +0 -360
  310. package/dist/FilePicker.svelte.d.ts +0 -17
  311. package/dist/Icon.svelte.d.ts +0 -13
  312. package/dist/MillerIndexInput.svelte +0 -66
  313. package/dist/MillerIndexInput.svelte.d.ts +0 -7
  314. package/dist/api/mp.d.ts +0 -6
  315. package/dist/api/mp.js +0 -22
  316. package/dist/api/optimade.d.ts +0 -45
  317. package/dist/api/optimade.js +0 -135
  318. package/dist/brillouin/BrillouinZone.svelte +0 -546
  319. package/dist/brillouin/BrillouinZone.svelte.d.ts +0 -83
  320. package/dist/brillouin/BrillouinZoneControls.svelte +0 -144
  321. package/dist/brillouin/BrillouinZoneControls.svelte.d.ts +0 -17
  322. package/dist/brillouin/BrillouinZoneExportPane.svelte +0 -148
  323. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +0 -15
  324. package/dist/brillouin/BrillouinZoneInfoPane.svelte +0 -146
  325. package/dist/brillouin/BrillouinZoneInfoPane.svelte.d.ts +0 -13
  326. package/dist/brillouin/BrillouinZoneScene.svelte +0 -476
  327. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +0 -48
  328. package/dist/brillouin/BrillouinZoneTooltip.svelte +0 -92
  329. package/dist/brillouin/BrillouinZoneTooltip.svelte.d.ts +0 -8
  330. package/dist/brillouin/compute.d.ts +0 -17
  331. package/dist/brillouin/compute.js +0 -426
  332. package/dist/brillouin/index.d.ts +0 -8
  333. package/dist/brillouin/index.js +0 -8
  334. package/dist/brillouin/types.d.ts +0 -48
  335. package/dist/brillouin/types.js +0 -1
  336. package/dist/chempot-diagram/ChemPotDiagram.svelte +0 -327
  337. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +0 -13
  338. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +0 -847
  339. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +0 -16
  340. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +0 -3194
  341. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +0 -16
  342. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +0 -7
  343. package/dist/chempot-diagram/async-compute.svelte.d.ts +0 -3
  344. package/dist/chempot-diagram/async-compute.svelte.js +0 -78
  345. package/dist/chempot-diagram/chempot-worker.d.ts +0 -1
  346. package/dist/chempot-diagram/chempot-worker.js +0 -11
  347. package/dist/chempot-diagram/color.d.ts +0 -10
  348. package/dist/chempot-diagram/color.js +0 -32
  349. package/dist/chempot-diagram/compute.d.ts +0 -48
  350. package/dist/chempot-diagram/compute.js +0 -812
  351. package/dist/chempot-diagram/index.d.ts +0 -6
  352. package/dist/chempot-diagram/index.js +0 -6
  353. package/dist/chempot-diagram/pointer.d.ts +0 -16
  354. package/dist/chempot-diagram/pointer.js +0 -40
  355. package/dist/chempot-diagram/temperature.d.ts +0 -15
  356. package/dist/chempot-diagram/temperature.js +0 -36
  357. package/dist/chempot-diagram/types.d.ts +0 -86
  358. package/dist/chempot-diagram/types.js +0 -28
  359. package/dist/colors/index.d.ts +0 -47
  360. package/dist/colors/index.js +0 -203
  361. package/dist/composition/BarChart.svelte +0 -297
  362. package/dist/composition/BarChart.svelte.d.ts +0 -39
  363. package/dist/composition/BubbleChart.svelte +0 -218
  364. package/dist/composition/BubbleChart.svelte.d.ts +0 -28
  365. package/dist/composition/Composition.svelte +0 -164
  366. package/dist/composition/Composition.svelte.d.ts +0 -15
  367. package/dist/composition/Formula.svelte +0 -265
  368. package/dist/composition/Formula.svelte.d.ts +0 -19
  369. package/dist/composition/FormulaFilter.svelte +0 -1259
  370. package/dist/composition/FormulaFilter.svelte.d.ts +0 -51
  371. package/dist/composition/PieChart.svelte +0 -323
  372. package/dist/composition/PieChart.svelte.d.ts +0 -37
  373. package/dist/composition/format.d.ts +0 -15
  374. package/dist/composition/format.js +0 -109
  375. package/dist/composition/index.d.ts +0 -20
  376. package/dist/composition/index.js +0 -14
  377. package/dist/composition/parse.d.ts +0 -55
  378. package/dist/composition/parse.js +0 -459
  379. package/dist/constants.d.ts +0 -29
  380. package/dist/constants.js +0 -99
  381. package/dist/controls.d.ts +0 -14
  382. package/dist/controls.js +0 -30
  383. package/dist/convex-hull/ConvexHull.svelte +0 -157
  384. package/dist/convex-hull/ConvexHull.svelte.d.ts +0 -13
  385. package/dist/convex-hull/ConvexHull2D.svelte +0 -814
  386. package/dist/convex-hull/ConvexHull2D.svelte.d.ts +0 -11
  387. package/dist/convex-hull/ConvexHull3D.svelte +0 -1790
  388. package/dist/convex-hull/ConvexHull3D.svelte.d.ts +0 -8
  389. package/dist/convex-hull/ConvexHull4D.svelte +0 -1386
  390. package/dist/convex-hull/ConvexHull4D.svelte.d.ts +0 -8
  391. package/dist/convex-hull/ConvexHullControls.svelte +0 -546
  392. package/dist/convex-hull/ConvexHullControls.svelte.d.ts +0 -48
  393. package/dist/convex-hull/ConvexHullInfoPane.svelte +0 -122
  394. package/dist/convex-hull/ConvexHullInfoPane.svelte.d.ts +0 -18
  395. package/dist/convex-hull/ConvexHullStats.svelte +0 -922
  396. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +0 -15
  397. package/dist/convex-hull/ConvexHullTooltip.svelte +0 -131
  398. package/dist/convex-hull/ConvexHullTooltip.svelte.d.ts +0 -33
  399. package/dist/convex-hull/GasPressureControls.svelte +0 -247
  400. package/dist/convex-hull/GasPressureControls.svelte.d.ts +0 -11
  401. package/dist/convex-hull/StructurePopup.svelte +0 -116
  402. package/dist/convex-hull/StructurePopup.svelte.d.ts +0 -18
  403. package/dist/convex-hull/TemperatureSlider.svelte +0 -137
  404. package/dist/convex-hull/TemperatureSlider.svelte.d.ts +0 -8
  405. package/dist/convex-hull/barycentric-coords.d.ts +0 -18
  406. package/dist/convex-hull/barycentric-coords.js +0 -182
  407. package/dist/convex-hull/demo-temperature.d.ts +0 -6
  408. package/dist/convex-hull/demo-temperature.js +0 -40
  409. package/dist/convex-hull/gas-thermodynamics.d.ts +0 -16
  410. package/dist/convex-hull/gas-thermodynamics.js +0 -316
  411. package/dist/convex-hull/helpers.d.ts +0 -103
  412. package/dist/convex-hull/helpers.js +0 -689
  413. package/dist/convex-hull/index.d.ts +0 -118
  414. package/dist/convex-hull/index.js +0 -57
  415. package/dist/convex-hull/thermodynamics.d.ts +0 -66
  416. package/dist/convex-hull/thermodynamics.js +0 -1752
  417. package/dist/convex-hull/types.d.ts +0 -162
  418. package/dist/convex-hull/types.js +0 -36
  419. package/dist/coordination/CoordinationBarPlot.svelte +0 -311
  420. package/dist/coordination/CoordinationBarPlot.svelte.d.ts +0 -30
  421. package/dist/coordination/calc-coordination.d.ts +0 -15
  422. package/dist/coordination/calc-coordination.js +0 -63
  423. package/dist/coordination/index.d.ts +0 -8
  424. package/dist/coordination/index.js +0 -7
  425. package/dist/element/BohrAtom.svelte +0 -147
  426. package/dist/element/BohrAtom.svelte.d.ts +0 -20
  427. package/dist/element/ElementHeading.svelte +0 -26
  428. package/dist/element/ElementHeading.svelte.d.ts +0 -8
  429. package/dist/element/ElementPhoto.svelte +0 -57
  430. package/dist/element/ElementPhoto.svelte.d.ts +0 -9
  431. package/dist/element/ElementStats.svelte +0 -80
  432. package/dist/element/ElementStats.svelte.d.ts +0 -8
  433. package/dist/element/ElementTile.svelte +0 -484
  434. package/dist/element/ElementTile.svelte.d.ts +0 -29
  435. package/dist/element/Nucleus.svelte.d.ts +0 -17
  436. package/dist/element/data.d.ts +0 -2
  437. package/dist/element/data.js +0 -2
  438. package/dist/element/data.json.gz.d.ts +0 -2
  439. package/dist/element/index.d.ts +0 -8
  440. package/dist/element/index.js +0 -8
  441. package/dist/element/types.d.ts +0 -57
  442. package/dist/element/types.js +0 -1
  443. package/dist/feedback/ClickFeedback.svelte +0 -58
  444. package/dist/feedback/ClickFeedback.svelte.d.ts +0 -12
  445. package/dist/feedback/DragOverlay.svelte +0 -42
  446. package/dist/feedback/DragOverlay.svelte.d.ts +0 -7
  447. package/dist/feedback/Spinner.svelte.d.ts +0 -7
  448. package/dist/feedback/StatusMessage.svelte.d.ts +0 -9
  449. package/dist/feedback/index.d.ts +0 -4
  450. package/dist/feedback/index.js +0 -4
  451. package/dist/fermi-surface/FermiSlice.svelte +0 -189
  452. package/dist/fermi-surface/FermiSlice.svelte.d.ts +0 -24
  453. package/dist/fermi-surface/FermiSurface.svelte +0 -600
  454. package/dist/fermi-surface/FermiSurface.svelte.d.ts +0 -83
  455. package/dist/fermi-surface/FermiSurfaceControls.svelte +0 -452
  456. package/dist/fermi-surface/FermiSurfaceControls.svelte.d.ts +0 -35
  457. package/dist/fermi-surface/FermiSurfaceScene.svelte +0 -792
  458. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +0 -50
  459. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +0 -111
  460. package/dist/fermi-surface/FermiSurfaceTooltip.svelte.d.ts +0 -8
  461. package/dist/fermi-surface/compute.d.ts +0 -5
  462. package/dist/fermi-surface/compute.js +0 -538
  463. package/dist/fermi-surface/constants.d.ts +0 -9
  464. package/dist/fermi-surface/constants.js +0 -27
  465. package/dist/fermi-surface/export.d.ts +0 -5
  466. package/dist/fermi-surface/export.js +0 -63
  467. package/dist/fermi-surface/index.d.ts +0 -12
  468. package/dist/fermi-surface/index.js +0 -13
  469. package/dist/fermi-surface/marching-cubes.d.ts +0 -2
  470. package/dist/fermi-surface/marching-cubes.js +0 -2
  471. package/dist/fermi-surface/parse.d.ts +0 -2
  472. package/dist/fermi-surface/parse.js +0 -495
  473. package/dist/fermi-surface/symmetry.d.ts +0 -3
  474. package/dist/fermi-surface/symmetry.js +0 -46
  475. package/dist/fermi-surface/types.d.ts +0 -113
  476. package/dist/fermi-surface/types.js +0 -4
  477. package/dist/heatmap-matrix/HeatmapMatrix.svelte +0 -1527
  478. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +0 -110
  479. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +0 -225
  480. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +0 -30
  481. package/dist/heatmap-matrix/index.d.ts +0 -53
  482. package/dist/heatmap-matrix/index.js +0 -100
  483. package/dist/heatmap-matrix/shared.d.ts +0 -2
  484. package/dist/heatmap-matrix/shared.js +0 -4
  485. package/dist/icons.d.ts +0 -569
  486. package/dist/icons.js +0 -648
  487. package/dist/index.d.ts +0 -39
  488. package/dist/index.js +0 -39
  489. package/dist/io/decompress.d.ts +0 -10
  490. package/dist/io/decompress.js +0 -74
  491. package/dist/io/export.d.ts +0 -16
  492. package/dist/io/export.js +0 -316
  493. package/dist/io/fetch.d.ts +0 -5
  494. package/dist/io/fetch.js +0 -39
  495. package/dist/io/file-drop.d.ts +0 -7
  496. package/dist/io/file-drop.js +0 -43
  497. package/dist/io/index.d.ts +0 -7
  498. package/dist/io/index.js +0 -7
  499. package/dist/io/is-binary.d.ts +0 -1
  500. package/dist/io/is-binary.js +0 -20
  501. package/dist/io/types.d.ts +0 -8
  502. package/dist/io/types.js +0 -1
  503. package/dist/io/url-drop.d.ts +0 -2
  504. package/dist/io/url-drop.js +0 -117
  505. package/dist/isosurface/Isosurface.svelte +0 -285
  506. package/dist/isosurface/Isosurface.svelte.d.ts +0 -8
  507. package/dist/isosurface/IsosurfaceControls.svelte +0 -291
  508. package/dist/isosurface/IsosurfaceControls.svelte.d.ts +0 -9
  509. package/dist/isosurface/index.d.ts +0 -5
  510. package/dist/isosurface/index.js +0 -6
  511. package/dist/isosurface/parse.d.ts +0 -6
  512. package/dist/isosurface/parse.js +0 -553
  513. package/dist/isosurface/slice.d.ts +0 -11
  514. package/dist/isosurface/slice.js +0 -140
  515. package/dist/isosurface/types.d.ts +0 -56
  516. package/dist/isosurface/types.js +0 -227
  517. package/dist/labels.d.ts +0 -53
  518. package/dist/labels.js +0 -274
  519. package/dist/layout/FullscreenToggle.svelte +0 -50
  520. package/dist/layout/FullscreenToggle.svelte.d.ts +0 -7
  521. package/dist/layout/InfoCard.svelte +0 -120
  522. package/dist/layout/InfoCard.svelte.d.ts +0 -21
  523. package/dist/layout/InfoTag.svelte +0 -183
  524. package/dist/layout/InfoTag.svelte.d.ts +0 -19
  525. package/dist/layout/PropertyFilter.svelte +0 -244
  526. package/dist/layout/PropertyFilter.svelte.d.ts +0 -24
  527. package/dist/layout/SettingsSection.svelte +0 -148
  528. package/dist/layout/SettingsSection.svelte.d.ts +0 -17
  529. package/dist/layout/SubpageGrid.svelte +0 -82
  530. package/dist/layout/SubpageGrid.svelte.d.ts +0 -14
  531. package/dist/layout/fullscreen.d.ts +0 -9
  532. package/dist/layout/fullscreen.js +0 -53
  533. package/dist/layout/index.d.ts +0 -10
  534. package/dist/layout/index.js +0 -8
  535. package/dist/layout/json-tree/JsonNode.svelte +0 -548
  536. package/dist/layout/json-tree/JsonNode.svelte.d.ts +0 -11
  537. package/dist/layout/json-tree/JsonTree.svelte +0 -1222
  538. package/dist/layout/json-tree/JsonTree.svelte.d.ts +0 -6
  539. package/dist/layout/json-tree/JsonValue.svelte +0 -334
  540. package/dist/layout/json-tree/JsonValue.svelte.d.ts +0 -9
  541. package/dist/layout/json-tree/index.d.ts +0 -3
  542. package/dist/layout/json-tree/index.js +0 -3
  543. package/dist/layout/json-tree/types.d.ts +0 -73
  544. package/dist/layout/json-tree/types.js +0 -3
  545. package/dist/layout/json-tree/utils.d.ts +0 -29
  546. package/dist/layout/json-tree/utils.js +0 -649
  547. package/dist/marching-cubes.d.ts +0 -14
  548. package/dist/marching-cubes.js +0 -542
  549. package/dist/math.d.ts +0 -91
  550. package/dist/math.js +0 -896
  551. package/dist/overlays/ContextMenu.svelte +0 -162
  552. package/dist/overlays/ContextMenu.svelte.d.ts +0 -25
  553. package/dist/overlays/CopyButton.svelte +0 -45
  554. package/dist/overlays/CopyButton.svelte.d.ts +0 -8
  555. package/dist/overlays/DraggablePane.svelte +0 -564
  556. package/dist/overlays/DraggablePane.svelte.d.ts +0 -36
  557. package/dist/overlays/InfoPaneCards.svelte +0 -149
  558. package/dist/overlays/InfoPaneCards.svelte.d.ts +0 -22
  559. package/dist/overlays/index.d.ts +0 -2
  560. package/dist/overlays/index.js +0 -2
  561. package/dist/periodic-table/PeriodicTable.svelte +0 -469
  562. package/dist/periodic-table/PeriodicTable.svelte.d.ts +0 -55
  563. package/dist/periodic-table/PeriodicTableControls.svelte +0 -557
  564. package/dist/periodic-table/PeriodicTableControls.svelte.d.ts +0 -24
  565. package/dist/periodic-table/PropertySelect.svelte +0 -37
  566. package/dist/periodic-table/PropertySelect.svelte.d.ts +0 -13
  567. package/dist/periodic-table/TableInset.svelte.d.ts +0 -9
  568. package/dist/periodic-table/index.d.ts +0 -10
  569. package/dist/periodic-table/index.js +0 -4
  570. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +0 -1084
  571. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +0 -44
  572. package/dist/phase-diagram/PhaseDiagramControls.svelte +0 -449
  573. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +0 -30
  574. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +0 -126
  575. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +0 -15
  576. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +0 -192
  577. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +0 -19
  578. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +0 -392
  579. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +0 -16
  580. package/dist/phase-diagram/TdbInfoPanel.svelte +0 -203
  581. package/dist/phase-diagram/TdbInfoPanel.svelte.d.ts +0 -12
  582. package/dist/phase-diagram/build-diagram.d.ts +0 -11
  583. package/dist/phase-diagram/build-diagram.js +0 -167
  584. package/dist/phase-diagram/colors.d.ts +0 -35
  585. package/dist/phase-diagram/colors.js +0 -51
  586. package/dist/phase-diagram/diagram-input.d.ts +0 -33
  587. package/dist/phase-diagram/diagram-input.js +0 -3
  588. package/dist/phase-diagram/index.d.ts +0 -13
  589. package/dist/phase-diagram/index.js +0 -13
  590. package/dist/phase-diagram/parse.d.ts +0 -55
  591. package/dist/phase-diagram/parse.js +0 -276
  592. package/dist/phase-diagram/svg-to-diagram.d.ts +0 -2
  593. package/dist/phase-diagram/svg-to-diagram.js +0 -867
  594. package/dist/phase-diagram/types.d.ts +0 -99
  595. package/dist/phase-diagram/types.js +0 -1
  596. package/dist/phase-diagram/utils.d.ts +0 -118
  597. package/dist/phase-diagram/utils.js +0 -606
  598. package/dist/plot/AxisLabel.svelte +0 -51
  599. package/dist/plot/AxisLabel.svelte.d.ts +0 -16
  600. package/dist/plot/BarPlot.svelte +0 -2265
  601. package/dist/plot/BarPlot.svelte.d.ts +0 -83
  602. package/dist/plot/BarPlotControls.svelte +0 -66
  603. package/dist/plot/BarPlotControls.svelte.d.ts +0 -18
  604. package/dist/plot/ColorBar.svelte +0 -719
  605. package/dist/plot/ColorBar.svelte.d.ts +0 -31
  606. package/dist/plot/ColorScaleSelect.svelte +0 -54
  607. package/dist/plot/ColorScaleSelect.svelte.d.ts +0 -15
  608. package/dist/plot/ElementScatter.svelte +0 -63
  609. package/dist/plot/ElementScatter.svelte.d.ts +0 -14
  610. package/dist/plot/FillArea.svelte +0 -225
  611. package/dist/plot/FillArea.svelte.d.ts +0 -21
  612. package/dist/plot/Histogram.svelte +0 -1672
  613. package/dist/plot/Histogram.svelte.d.ts +0 -50
  614. package/dist/plot/HistogramControls.svelte +0 -212
  615. package/dist/plot/HistogramControls.svelte.d.ts +0 -22
  616. package/dist/plot/InteractiveAxisLabel.svelte +0 -94
  617. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +0 -14
  618. package/dist/plot/Line.svelte +0 -84
  619. package/dist/plot/Line.svelte.d.ts +0 -15
  620. package/dist/plot/PlotControls.svelte +0 -537
  621. package/dist/plot/PlotControls.svelte.d.ts +0 -4
  622. package/dist/plot/PlotLegend.svelte +0 -569
  623. package/dist/plot/PlotLegend.svelte.d.ts +0 -29
  624. package/dist/plot/PlotTooltip.svelte +0 -67
  625. package/dist/plot/PlotTooltip.svelte.d.ts +0 -17
  626. package/dist/plot/PortalSelect.svelte +0 -253
  627. package/dist/plot/PortalSelect.svelte.d.ts +0 -16
  628. package/dist/plot/ReferenceLine.svelte.d.ts +0 -20
  629. package/dist/plot/ReferenceLine3D.svelte +0 -154
  630. package/dist/plot/ReferenceLine3D.svelte.d.ts +0 -14
  631. package/dist/plot/ReferencePlane.svelte +0 -178
  632. package/dist/plot/ReferencePlane.svelte.d.ts +0 -14
  633. package/dist/plot/ScatterPlot.svelte +0 -2845
  634. package/dist/plot/ScatterPlot.svelte.d.ts +0 -93
  635. package/dist/plot/ScatterPlot3D.svelte +0 -502
  636. package/dist/plot/ScatterPlot3D.svelte.d.ts +0 -94
  637. package/dist/plot/ScatterPlot3DControls.svelte +0 -437
  638. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +0 -20
  639. package/dist/plot/ScatterPlot3DScene.svelte +0 -912
  640. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +0 -74
  641. package/dist/plot/ScatterPlotControls.svelte +0 -307
  642. package/dist/plot/ScatterPlotControls.svelte.d.ts +0 -17
  643. package/dist/plot/ScatterPoint.svelte +0 -191
  644. package/dist/plot/ScatterPoint.svelte.d.ts +0 -21
  645. package/dist/plot/SpacegroupBarPlot.svelte +0 -293
  646. package/dist/plot/SpacegroupBarPlot.svelte.d.ts +0 -9
  647. package/dist/plot/Surface3D.svelte +0 -200
  648. package/dist/plot/Surface3D.svelte.d.ts +0 -13
  649. package/dist/plot/ZeroLines.svelte +0 -96
  650. package/dist/plot/ZeroLines.svelte.d.ts +0 -32
  651. package/dist/plot/ZoomRect.svelte +0 -23
  652. package/dist/plot/ZoomRect.svelte.d.ts +0 -8
  653. package/dist/plot/axis-utils.d.ts +0 -19
  654. package/dist/plot/axis-utils.js +0 -80
  655. package/dist/plot/data-cleaning.d.ts +0 -37
  656. package/dist/plot/data-cleaning.js +0 -855
  657. package/dist/plot/data-transform.d.ts +0 -16
  658. package/dist/plot/data-transform.js +0 -45
  659. package/dist/plot/defaults.d.ts +0 -19
  660. package/dist/plot/defaults.js +0 -9
  661. package/dist/plot/fill-utils.d.ts +0 -51
  662. package/dist/plot/fill-utils.js +0 -337
  663. package/dist/plot/hover-lock.svelte.d.ts +0 -14
  664. package/dist/plot/hover-lock.svelte.js +0 -46
  665. package/dist/plot/index.d.ts +0 -37
  666. package/dist/plot/index.js +0 -37
  667. package/dist/plot/interactions.d.ts +0 -12
  668. package/dist/plot/interactions.js +0 -100
  669. package/dist/plot/layout.d.ts +0 -60
  670. package/dist/plot/layout.js +0 -230
  671. package/dist/plot/reference-line.d.ts +0 -60
  672. package/dist/plot/reference-line.js +0 -316
  673. package/dist/plot/scales.d.ts +0 -48
  674. package/dist/plot/scales.js +0 -484
  675. package/dist/plot/svg.d.ts +0 -1
  676. package/dist/plot/svg.js +0 -11
  677. package/dist/plot/types.d.ts +0 -859
  678. package/dist/plot/types.js +0 -103
  679. package/dist/plot/utils/label-placement.d.ts +0 -47
  680. package/dist/plot/utils/label-placement.js +0 -256
  681. package/dist/plot/utils/series-visibility.d.ts +0 -9
  682. package/dist/plot/utils/series-visibility.js +0 -67
  683. package/dist/plot/utils.d.ts +0 -1
  684. package/dist/plot/utils.js +0 -14
  685. package/dist/rdf/RdfPlot.svelte +0 -247
  686. package/dist/rdf/RdfPlot.svelte.d.ts +0 -27
  687. package/dist/rdf/calc-rdf.d.ts +0 -4
  688. package/dist/rdf/calc-rdf.js +0 -111
  689. package/dist/rdf/index.d.ts +0 -23
  690. package/dist/rdf/index.js +0 -2
  691. package/dist/sanitize.d.ts +0 -4
  692. package/dist/sanitize.js +0 -114
  693. package/dist/settings.d.ts +0 -255
  694. package/dist/settings.js +0 -1132
  695. package/dist/spectral/Bands.svelte +0 -1040
  696. package/dist/spectral/Bands.svelte.d.ts +0 -40
  697. package/dist/spectral/BandsAndDos.svelte +0 -128
  698. package/dist/spectral/BandsAndDos.svelte.d.ts +0 -18
  699. package/dist/spectral/BrillouinBandsDos.svelte +0 -248
  700. package/dist/spectral/BrillouinBandsDos.svelte.d.ts +0 -20
  701. package/dist/spectral/Dos.svelte +0 -697
  702. package/dist/spectral/Dos.svelte.d.ts +0 -29
  703. package/dist/spectral/helpers.d.ts +0 -117
  704. package/dist/spectral/helpers.js +0 -1023
  705. package/dist/spectral/index.d.ts +0 -6
  706. package/dist/spectral/index.js +0 -7
  707. package/dist/spectral/types.d.ts +0 -84
  708. package/dist/spectral/types.js +0 -2
  709. package/dist/state.svelte.d.ts +0 -25
  710. package/dist/state.svelte.js +0 -45
  711. package/dist/structure/Arrow.svelte +0 -72
  712. package/dist/structure/Arrow.svelte.d.ts +0 -15
  713. package/dist/structure/AtomLegend.svelte +0 -798
  714. package/dist/structure/AtomLegend.svelte.d.ts +0 -34
  715. package/dist/structure/Bond.svelte +0 -140
  716. package/dist/structure/Bond.svelte.d.ts +0 -9
  717. package/dist/structure/CanvasTooltip.svelte +0 -33
  718. package/dist/structure/CanvasTooltip.svelte.d.ts +0 -12
  719. package/dist/structure/CellSelect.svelte +0 -351
  720. package/dist/structure/CellSelect.svelte.d.ts +0 -13
  721. package/dist/structure/Cylinder.svelte +0 -45
  722. package/dist/structure/Cylinder.svelte.d.ts +0 -10
  723. package/dist/structure/Lattice.svelte +0 -196
  724. package/dist/structure/Lattice.svelte.d.ts +0 -17
  725. package/dist/structure/Structure.svelte +0 -1999
  726. package/dist/structure/Structure.svelte.d.ts +0 -87
  727. package/dist/structure/StructureControls.svelte +0 -1298
  728. package/dist/structure/StructureControls.svelte.d.ts +0 -31
  729. package/dist/structure/StructureExportPane.svelte +0 -251
  730. package/dist/structure/StructureExportPane.svelte.d.ts +0 -17
  731. package/dist/structure/StructureInfoPane.svelte +0 -735
  732. package/dist/structure/StructureInfoPane.svelte.d.ts +0 -19
  733. package/dist/structure/StructureScene.svelte +0 -1905
  734. package/dist/structure/StructureScene.svelte.d.ts +0 -108
  735. package/dist/structure/atom-properties.d.ts +0 -37
  736. package/dist/structure/atom-properties.js +0 -200
  737. package/dist/structure/bond-order-perception.d.ts +0 -13
  738. package/dist/structure/bond-order-perception.js +0 -367
  739. package/dist/structure/bonding.d.ts +0 -42
  740. package/dist/structure/bonding.js +0 -525
  741. package/dist/structure/export.d.ts +0 -20
  742. package/dist/structure/export.js +0 -727
  743. package/dist/structure/index.d.ts +0 -125
  744. package/dist/structure/index.js +0 -171
  745. package/dist/structure/label-placement.d.ts +0 -14
  746. package/dist/structure/label-placement.js +0 -72
  747. package/dist/structure/measure.d.ts +0 -6
  748. package/dist/structure/measure.js +0 -29
  749. package/dist/structure/parse.d.ts +0 -66
  750. package/dist/structure/parse.js +0 -1363
  751. package/dist/structure/partial-occupancy.d.ts +0 -25
  752. package/dist/structure/partial-occupancy.js +0 -99
  753. package/dist/structure/pbc.d.ts +0 -9
  754. package/dist/structure/pbc.js +0 -123
  755. package/dist/structure/supercell.d.ts +0 -8
  756. package/dist/structure/supercell.js +0 -170
  757. package/dist/structure/validation.d.ts +0 -2
  758. package/dist/structure/validation.js +0 -10
  759. package/dist/symmetry/SymmetryStats.svelte +0 -226
  760. package/dist/symmetry/SymmetryStats.svelte.d.ts +0 -21
  761. package/dist/symmetry/WyckoffTable.svelte +0 -113
  762. package/dist/symmetry/WyckoffTable.svelte.d.ts +0 -11
  763. package/dist/symmetry/cell-transform.d.ts +0 -12
  764. package/dist/symmetry/cell-transform.js +0 -91
  765. package/dist/symmetry/index.d.ts +0 -43
  766. package/dist/symmetry/index.js +0 -229
  767. package/dist/symmetry/spacegroups.d.ts +0 -9
  768. package/dist/symmetry/spacegroups.js +0 -394
  769. package/dist/table/HeatmapTable.svelte +0 -1854
  770. package/dist/table/HeatmapTable.svelte.d.ts +0 -49
  771. package/dist/table/ToggleMenu.svelte +0 -376
  772. package/dist/table/ToggleMenu.svelte.d.ts +0 -11
  773. package/dist/table/index.d.ts +0 -74
  774. package/dist/table/index.js +0 -38
  775. package/dist/theme/ThemeControl.svelte +0 -53
  776. package/dist/theme/ThemeControl.svelte.d.ts +0 -9
  777. package/dist/theme/index.d.ts +0 -29
  778. package/dist/theme/index.js +0 -79
  779. package/dist/theme/themes.mjs +0 -285
  780. package/dist/time.d.ts +0 -4
  781. package/dist/time.js +0 -70
  782. package/dist/tooltip/TooltipContent.svelte +0 -58
  783. package/dist/tooltip/TooltipContent.svelte.d.ts +0 -31
  784. package/dist/tooltip/index.d.ts +0 -2
  785. package/dist/tooltip/index.js +0 -2
  786. package/dist/tooltip/types.d.ts +0 -8
  787. package/dist/tooltip/types.js +0 -1
  788. package/dist/trajectory/Trajectory.svelte +0 -1517
  789. package/dist/trajectory/Trajectory.svelte.d.ts +0 -77
  790. package/dist/trajectory/TrajectoryError.svelte +0 -128
  791. package/dist/trajectory/TrajectoryError.svelte.d.ts +0 -13
  792. package/dist/trajectory/TrajectoryExportPane.svelte +0 -357
  793. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +0 -17
  794. package/dist/trajectory/TrajectoryInfoPane.svelte +0 -313
  795. package/dist/trajectory/TrajectoryInfoPane.svelte.d.ts +0 -17
  796. package/dist/trajectory/constants.d.ts +0 -6
  797. package/dist/trajectory/constants.js +0 -7
  798. package/dist/trajectory/extract.d.ts +0 -5
  799. package/dist/trajectory/extract.js +0 -162
  800. package/dist/trajectory/format-detect.d.ts +0 -9
  801. package/dist/trajectory/format-detect.js +0 -76
  802. package/dist/trajectory/frame-reader.d.ts +0 -17
  803. package/dist/trajectory/frame-reader.js +0 -332
  804. package/dist/trajectory/helpers.d.ts +0 -14
  805. package/dist/trajectory/helpers.js +0 -172
  806. package/dist/trajectory/index.d.ts +0 -63
  807. package/dist/trajectory/index.js +0 -126
  808. package/dist/trajectory/parse/ase.d.ts +0 -2
  809. package/dist/trajectory/parse/ase.js +0 -73
  810. package/dist/trajectory/parse/hdf5.d.ts +0 -2
  811. package/dist/trajectory/parse/hdf5.js +0 -127
  812. package/dist/trajectory/parse/index.d.ts +0 -12
  813. package/dist/trajectory/parse/index.js +0 -299
  814. package/dist/trajectory/parse/lammps.d.ts +0 -5
  815. package/dist/trajectory/parse/lammps.js +0 -179
  816. package/dist/trajectory/parse/vasp.d.ts +0 -2
  817. package/dist/trajectory/parse/vasp.js +0 -68
  818. package/dist/trajectory/parse/xyz.d.ts +0 -2
  819. package/dist/trajectory/parse/xyz.js +0 -110
  820. package/dist/trajectory/plotting.d.ts +0 -28
  821. package/dist/trajectory/plotting.js +0 -423
  822. package/dist/trajectory/types.d.ts +0 -11
  823. package/dist/trajectory/types.js +0 -1
  824. package/dist/utils.d.ts +0 -5
  825. package/dist/utils.js +0 -36
  826. package/dist/xrd/XrdPlot.svelte +0 -615
  827. package/dist/xrd/XrdPlot.svelte.d.ts +0 -28
  828. package/dist/xrd/broadening.d.ts +0 -20
  829. package/dist/xrd/broadening.js +0 -97
  830. package/dist/xrd/calc-xrd.d.ts +0 -37
  831. package/dist/xrd/calc-xrd.js +0 -337
  832. package/dist/xrd/index.d.ts +0 -37
  833. package/dist/xrd/index.js +0 -4
  834. package/dist/xrd/parse.d.ts +0 -13
  835. package/dist/xrd/parse.js +0 -749
  836. /package/dist/{EmptyState.svelte → src/lib/EmptyState.svelte} +0 -0
  837. /package/dist/{Icon.svelte → src/lib/Icon.svelte} +0 -0
  838. /package/dist/{app.css → src/lib/app.css} +0 -0
  839. /package/dist/{chempot-diagram → src/lib/chempot-diagram}/ChemPotScene3D.svelte +0 -0
  840. /package/dist/{colors → src/lib/colors}/alloy-colors.json +0 -0
  841. /package/dist/{colors → src/lib/colors}/dark-mode-colors.json +0 -0
  842. /package/dist/{colors → src/lib/colors}/jmol-colors.json +0 -0
  843. /package/dist/{colors → src/lib/colors}/muted-colors.json +0 -0
  844. /package/dist/{colors → src/lib/colors}/pastel-colors.json +0 -0
  845. /package/dist/{colors → src/lib/colors}/vesta-colors.json +0 -0
  846. /package/dist/{element → src/lib/element}/Nucleus.svelte +0 -0
  847. /package/dist/{element → src/lib/element}/data.json +0 -0
  848. /package/dist/{element → src/lib/element}/data.json.gz +0 -0
  849. /package/dist/{element → src/lib/element}/data.schema.json +0 -0
  850. /package/dist/{element-image-urls.json → src/lib/element-image-urls.json} +0 -0
  851. /package/dist/{feedback → src/lib/feedback}/Spinner.svelte +0 -0
  852. /package/dist/{feedback → src/lib/feedback}/StatusMessage.svelte +0 -0
  853. /package/dist/{periodic-table → src/lib/periodic-table}/TableInset.svelte +0 -0
  854. /package/dist/{plot → src/lib/plot}/ReferenceLine.svelte +0 -0
  855. /package/dist/{xrd → src/lib/xrd}/atomic_scattering_params.json +0 -0
@@ -1,2265 +0,0 @@
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 {
10
- AxisLoadError,
11
- BarHandlerProps,
12
- BarMode,
13
- BarSeries,
14
- BarStyle,
15
- BasePlotProps,
16
- DataLoaderFn,
17
- InitialRanges,
18
- InternalPoint,
19
- LegendConfig,
20
- LegendItem,
21
- LineStyle,
22
- Orientation,
23
- PanConfig,
24
- PlotConfig,
25
- RefLine,
26
- RefLineEvent,
27
- ScaleType,
28
- UserContentProps,
29
- XyObj,
30
- } from './'
31
- import {
32
- AxisLabel,
33
- BarPlotControls,
34
- compute_element_placement,
35
- PlotLegend,
36
- ReferenceLine,
37
- ScatterPoint,
38
- } from './'
39
- import type { AxisChangeState } from './axis-utils'
40
- import { create_axis_change_handler } from './axis-utils'
41
- import { process_prop } from './data-transform'
42
- import {
43
- create_dimension_tracker,
44
- create_hover_lock,
45
- } from './hover-lock.svelte'
46
- import {
47
- get_relative_coords,
48
- pan_range,
49
- PINCH_ZOOM_THRESHOLD,
50
- pixels_to_data_delta,
51
- } from './interactions'
52
- import type { IndexedRefLine } from './reference-line'
53
- import { group_ref_lines_by_z, index_ref_lines } from './reference-line'
54
- import {
55
- create_color_scale,
56
- create_scale,
57
- create_size_scale,
58
- generate_ticks,
59
- get_nice_data_range,
60
- get_tick_label,
61
- } from './scales'
62
- import {
63
- DEFAULT_GRID_STYLE,
64
- DEFAULT_MARKERS,
65
- get_scale_type_name,
66
- } from './types'
67
- import { DEFAULTS } from '../settings'
68
- import { extent } from 'd3-array'
69
- import type { Snippet } from 'svelte'
70
- import { untrack } from 'svelte'
71
- import type { HTMLAttributes } from 'svelte/elements'
72
- import { Tween, type TweenOptions } from 'svelte/motion'
73
- import { SvelteMap } from 'svelte/reactivity'
74
- import type { Vec2 } from '../math'
75
- import {
76
- calc_auto_padding,
77
- constrain_tooltip_position,
78
- filter_padding,
79
- LABEL_GAP_DEFAULT,
80
- measure_max_tick_width,
81
- } from './layout'
82
- import PlotTooltip from './PlotTooltip.svelte'
83
- import { bar_path } from './svg'
84
- import ZeroLines from './ZeroLines.svelte'
85
- import ZoomRect from './ZoomRect.svelte'
86
-
87
- // Handler props for line marker events (extends BarHandlerProps with point-specific data)
88
- interface LineMarkerHandlerProps extends BarHandlerProps<Metadata> {
89
- point: InternalPoint<Metadata>
90
- }
91
-
92
- // Extended point type with computed screen coordinates (used internally for rendering)
93
- type LineSeriesPoint = InternalPoint<Metadata> & {
94
- x: number // Screen x coordinate
95
- y: number // Screen y coordinate
96
- data_x: number // Original data x value
97
- data_y: number // Original data y value
98
- idx: number // Index in series
99
- }
100
-
101
- let {
102
- series = $bindable([]),
103
- orientation = $bindable(`vertical`),
104
- mode = $bindable(`overlay`),
105
- x_axis = $bindable({}),
106
- x2_axis = $bindable({}),
107
- y_axis = $bindable({}),
108
- y2_axis = $bindable({}),
109
- display = $bindable(DEFAULTS.bar.display),
110
- x_range = [null, null],
111
- x2_range = [null, null],
112
- y_range = [null, null],
113
- y2_range = [null, null],
114
- range_padding = 0.05,
115
- padding = { t: 20, b: 60, l: 60, r: 20 },
116
- legend = {},
117
- show_legend,
118
- bar = {},
119
- line = {},
120
- tooltip,
121
- user_content,
122
- hovered = $bindable(false),
123
- change = () => {},
124
- on_bar_click,
125
- on_bar_hover,
126
- // Line marker props (matching ScatterPlot)
127
- color_scale = {
128
- type: `linear`,
129
- scheme: `interpolateViridis`,
130
- value_range: undefined,
131
- },
132
- size_scale = { type: `linear`, radius_range: [2, 10], value_range: undefined },
133
- point_tween,
134
- on_point_click,
135
- on_point_hover,
136
- ref_lines = $bindable([]),
137
- on_ref_line_click,
138
- on_ref_line_hover,
139
- show_controls = $bindable(true),
140
- controls_open = $bindable(false),
141
- controls_toggle_props,
142
- controls_pane_props,
143
- fullscreen = $bindable(false),
144
- fullscreen_toggle = true,
145
- children,
146
- header_controls,
147
- controls_extra,
148
- data_loader,
149
- on_axis_change,
150
- on_error,
151
- pan = {},
152
- ...rest
153
- }: HTMLAttributes<HTMLDivElement> & BasePlotProps & PlotConfig & {
154
- series?: BarSeries<Metadata>[]
155
- // Component-specific props
156
- orientation?: Orientation
157
- mode?: BarMode
158
- legend?: LegendConfig | null
159
- show_legend?: boolean
160
- bar?: BarStyle
161
- line?: LineStyle
162
- tooltip?: Snippet<[BarHandlerProps<Metadata>]>
163
- user_content?: Snippet<[UserContentProps]>
164
- header_controls?: Snippet<
165
- [{ height: number; width: number; fullscreen: boolean }]
166
- >
167
- controls_extra?: Snippet<
168
- [{ orientation: Orientation; mode: BarMode } & Required<PlotConfig>]
169
- >
170
- change?: (data: BarHandlerProps<Metadata> | null) => void
171
- on_bar_click?: (
172
- data: BarHandlerProps<Metadata> & { event: MouseEvent | KeyboardEvent },
173
- ) => void
174
- on_bar_hover?: (
175
- data:
176
- | (BarHandlerProps<Metadata> & {
177
- event: MouseEvent | FocusEvent | KeyboardEvent
178
- })
179
- | null,
180
- ) => void
181
- // Line marker props (matching ScatterPlot)
182
- // Note: For line series with markers, BOTH on_bar_* AND on_point_* events fire.
183
- // Use on_point_* for marker-specific data (includes `point` with InternalPoint details)
184
- // or on_bar_* for backward compatibility with bar-style event handling.
185
- color_scale?: {
186
- type?: ScaleType
187
- scheme?: D3ColorSchemeName | D3InterpolateName
188
- value_range?: [number, number]
189
- } | D3InterpolateName
190
- size_scale?: {
191
- type?: ScaleType
192
- radius_range?: [number, number]
193
- value_range?: [number, number]
194
- }
195
- point_tween?: TweenOptions<XyObj>
196
- on_point_click?: (
197
- data: LineMarkerHandlerProps & { event: MouseEvent | KeyboardEvent },
198
- ) => void
199
- on_point_hover?: (
200
- data:
201
- | (LineMarkerHandlerProps & {
202
- event: MouseEvent | FocusEvent | KeyboardEvent
203
- })
204
- | null,
205
- ) => void
206
- ref_lines?: RefLine[]
207
- on_ref_line_click?: (event: RefLineEvent) => void
208
- on_ref_line_hover?: (event: RefLineEvent | null) => void
209
- // Interactive axis props
210
- data_loader?: DataLoaderFn<Metadata, BarSeries<Metadata>>
211
- on_axis_change?: (
212
- axis: `x` | `x2` | `y` | `y2`,
213
- key: string,
214
- new_series: BarSeries<Metadata>[],
215
- ) => void
216
- on_error?: (error: AxisLoadError) => void
217
- pan?: PanConfig
218
- } = $props()
219
-
220
- // Initialize bar, line, y2_axis with defaults - using $derived for reactivity
221
- let bar_state = $derived({ ...DEFAULTS.bar.bar, ...bar })
222
- let line_state = $derived({ ...DEFAULTS.bar.line, ...line })
223
- y2_axis = {
224
- format: ``,
225
- scale_type: `linear`,
226
- ticks: 5,
227
- label_shift: { y: 60 },
228
- tick: { label: { shift: { x: 0, y: 0 } } }, // base offset handled in rendering
229
- range: [null, null],
230
- ...y2_axis,
231
- }
232
- x2_axis = {
233
- format: ``,
234
- scale_type: `linear`,
235
- ticks: 5,
236
- label_shift: { x: 0, y: 40 },
237
- tick: { label: { shift: { x: 0, y: 0 } } },
238
- range: [null, null],
239
- ...x2_axis,
240
- }
241
-
242
- let [width, height] = $state([0, 0])
243
- let wrapper: HTMLDivElement | undefined = $state()
244
- let svg_element: SVGElement | null = $state(null)
245
- let clip_path_id = `chart-clip-${crypto?.randomUUID?.()}`
246
-
247
- // Reference line hover state
248
- let hovered_ref_line_idx = $state<number | null>(null)
249
-
250
- // Interactive axis loading state
251
- let axis_loading = $state<`x` | `x2` | `y` | `y2` | null>(null)
252
-
253
- // Compute ref_lines with index and group by z-index (using shared utilities)
254
- let indexed_ref_lines = $derived(index_ref_lines(ref_lines))
255
- let ref_lines_by_z = $derived(group_ref_lines_by_z(indexed_ref_lines))
256
-
257
- // === Categorical Normalization ===
258
- // Internal type with guaranteed numeric x (for downstream scale/rendering code)
259
- type NumericBarSeries = Omit<BarSeries<Metadata>, `x`> & { x: readonly number[] }
260
-
261
- let is_categorical = $derived(
262
- series.some((srs) => srs.x.some((val) => typeof val === `string`)),
263
- )
264
-
265
- let category_list = $derived.by(() => {
266
- if (!is_categorical) return [] as string[]
267
- if (x_axis.categories?.length) return [...x_axis.categories]
268
- return [...new Set(series.flatMap((srs) => srs.x.map(String)))]
269
- })
270
-
271
- let category_indices = $derived(
272
- category_list.length ? category_list.map((_, idx) => idx) : null,
273
- )
274
-
275
- let internal_series = $derived.by<NumericBarSeries[]>(() => {
276
- // safe: when !category_indices, all x values are numeric (is_categorical is false)
277
- if (!category_indices) return series as unknown as NumericBarSeries[]
278
- return series.map((srs) => {
279
- const orig_map = new Map(srs.x.map((val, idx) => [String(val), idx]))
280
- if (orig_map.size < srs.x.length) {
281
- console.warn(
282
- `BarPlot: series "${
283
- srs.label ?? `?`
284
- }" has duplicate x values — last occurrence wins`,
285
- )
286
- }
287
- // Resolve original index for each category (undefined if series lacks it)
288
- const orig_indices = category_list.map((cat) => orig_map.get(cat))
289
- const remap = <T>(arr: readonly T[] | null | undefined, fallback: T): T[] =>
290
- orig_indices.map((oi) => oi != null ? (arr?.[oi] ?? fallback) : fallback)
291
- const bw_arr = Array.isArray(srs.bar_width) ? srs.bar_width : null
292
- const meta_arr = Array.isArray(srs.metadata) ? srs.metadata : null
293
- return {
294
- ...srs,
295
- x: category_indices,
296
- y: remap(srs.y, srs.render_mode === `line` ? NaN : 0),
297
- labels: remap(srs.labels, null),
298
- metadata: orig_indices.map((oi) =>
299
- oi != null ? (meta_arr ? meta_arr[oi] : srs.metadata) : undefined
300
- ) as Metadata[],
301
- ...(bw_arr ? { bar_width: remap(bw_arr, 0.5) } : {}),
302
- ...(srs.color_values ? { color_values: remap(srs.color_values, null) } : {}),
303
- ...(srs.size_values ? { size_values: remap(srs.size_values, null) } : {}),
304
- } as NumericBarSeries
305
- })
306
- })
307
-
308
- // Compute auto ranges from visible series
309
- let visible_series = $derived(
310
- internal_series.filter((srs) => srs?.visible ?? true),
311
- )
312
-
313
- // Separate series by y-axis
314
- let y1_series = $derived(
315
- visible_series.filter((srs) => (srs.y_axis ?? `y1`) === `y1`),
316
- )
317
- let y2_series = $derived(
318
- visible_series.filter((srs) => srs.y_axis === `y2`),
319
- )
320
- let x2_series = $derived(
321
- visible_series.filter((srs) => srs.x_axis === `x2`),
322
- )
323
-
324
- let auto_ranges = $derived.by(() => {
325
- // Calculate separate ranges for y1 and y2 axes
326
- const calc_y_range = (
327
- series_list: typeof visible_series,
328
- y_limit: typeof y_range,
329
- scale_type: ScaleType,
330
- ) => {
331
- let points = series_list.flatMap((srs) =>
332
- srs.x.map((x_val, idx) => ({ x: x_val, y: srs.y[idx] }))
333
- )
334
-
335
- // In stacked mode, calculate stacked totals for accurate range (only for bars on the same axis)
336
- if (mode === `stacked`) {
337
- const stacked_totals = new SvelteMap<number, { pos: number; neg: number }>()
338
-
339
- // Only include visible bar series (not lines) in stacking
340
- series_list
341
- .filter((srs) => srs.render_mode !== `line`)
342
- .forEach((srs) =>
343
- srs.x.forEach((x_val, idx) => {
344
- const y_val = srs.y[idx] ?? 0
345
- const totals = stacked_totals.get(x_val) ?? { pos: 0, neg: 0 }
346
- if (y_val >= 0) totals.pos += y_val
347
- else totals.neg += y_val
348
- stacked_totals.set(x_val, totals)
349
- })
350
- )
351
-
352
- // Replace points with stacked totals + line series (which don't stack)
353
- points = [
354
- ...Array.from(stacked_totals).flatMap(([x_val, { pos, neg }]) => [
355
- ...(pos > 0 ? [{ x: x_val, y: pos }] : []),
356
- ...(neg < 0 ? [{ x: x_val, y: neg }] : []),
357
- ]),
358
- ...series_list
359
- .filter((srs) => srs.render_mode === `line`)
360
- .flatMap((srs) =>
361
- srs.x.map((x_val, idx) => ({ x: x_val, y: srs.y[idx] }))
362
- ),
363
- ]
364
- }
365
-
366
- if (!points.length) return [0, 1]
367
-
368
- let computed_y_range = get_nice_data_range(
369
- points,
370
- (pt) => pt.y,
371
- y_limit,
372
- scale_type,
373
- range_padding,
374
- false,
375
- )
376
-
377
- // For bar plots, ensure the value axis starts at 0 unless there are negative values
378
- // Only apply zero-clamping for linear and arcsinh scales (not log)
379
- const type_name = get_scale_type_name(scale_type)
380
- if (type_name === `linear` || type_name === `arcsinh`) {
381
- const has_negative = points.some((pt) => pt.y < 0)
382
- const has_positive = points.some((pt) => pt.y > 0)
383
-
384
- // Only adjust if no explicit y_range is set
385
- if (y_limit?.[0] == null && y_limit?.[1] == null) {
386
- if (has_positive && !has_negative) computed_y_range = [0, computed_y_range[1]]
387
- else if (has_negative && !has_positive) computed_y_range = [computed_y_range[0], 0]
388
- }
389
- }
390
-
391
- return computed_y_range
392
- }
393
-
394
- // Get x values split by axis for range calculation
395
- // For categorical data, use fixed range centered on integer indices
396
- let x_auto_range: number[]
397
- if (category_list.length) {
398
- x_auto_range = [-0.5, category_list.length - 0.5]
399
- } else {
400
- const x1_x_points = visible_series
401
- .filter((srs) => (srs.x_axis ?? `x1`) === `x1`)
402
- .flatMap((srs) => srs.x.map((x_val) => ({ x: x_val, y: 0 })))
403
- x_auto_range = x1_x_points.length
404
- ? get_nice_data_range(
405
- x1_x_points,
406
- (pt) => pt.x,
407
- x_range,
408
- x_axis.scale_type ?? `linear`,
409
- range_padding,
410
- x_axis.format?.startsWith(`%`) || false,
411
- )
412
- : [0, 1]
413
- }
414
-
415
- const x2_x_points = x2_series.flatMap((srs) =>
416
- srs.x.map((x_val) => ({ x: x_val, y: 0 }))
417
- )
418
- const x2_scale_type = x2_axis.scale_type ?? `linear`
419
- const x2_auto_range = x2_x_points.length
420
- ? get_nice_data_range(
421
- x2_x_points,
422
- (pt) => pt.x,
423
- x2_range,
424
- x2_scale_type,
425
- range_padding,
426
- x2_axis.format?.startsWith(`%`) || false,
427
- )
428
- : [0, 1]
429
-
430
- const y1_range = calc_y_range(y1_series, y_range, y_axis.scale_type ?? `linear`)
431
- const y2_auto_range = calc_y_range(
432
- y2_series,
433
- y2_range,
434
- y2_axis.scale_type ?? `linear`,
435
- )
436
-
437
- // Map data ranges to axis ranges depending on orientation
438
- return orientation === `horizontal`
439
- ? ({ x: y1_range, x2: x2_auto_range, y: x_auto_range, y2: y2_auto_range })
440
- : ({ x: x_auto_range, x2: x2_auto_range, y: y1_range, y2: y2_auto_range })
441
- })
442
-
443
- // Initialize and current ranges
444
- let ranges = $state<{
445
- initial: { x: Vec2; x2: Vec2; y: Vec2; y2: Vec2 }
446
- current: { x: Vec2; x2: Vec2; y: Vec2; y2: Vec2 }
447
- }>({
448
- initial: { x: [0, 1], x2: [0, 1], y: [0, 1], y2: [0, 1] },
449
- current: { x: [0, 1], x2: [0, 1], y: [0, 1], y2: [0, 1] },
450
- })
451
-
452
- $effect(() => { // handle x_axis.range / x2_axis.range / y_axis.range / y2_axis.range changes
453
- const new_x = [
454
- x_axis.range?.[0] ?? auto_ranges.x[0],
455
- x_axis.range?.[1] ?? auto_ranges.x[1],
456
- ] as Vec2
457
- const new_x2 = [
458
- x2_axis.range?.[0] ?? auto_ranges.x2[0],
459
- x2_axis.range?.[1] ?? auto_ranges.x2[1],
460
- ] as Vec2
461
- const new_y = [
462
- y_axis.range?.[0] ?? auto_ranges.y[0],
463
- y_axis.range?.[1] ?? auto_ranges.y[1],
464
- ] as Vec2
465
- const new_y2 = [
466
- y2_axis.range?.[0] ?? auto_ranges.y2[0],
467
- y2_axis.range?.[1] ?? auto_ranges.y2[1],
468
- ] as Vec2
469
- // Only update if the initial (data-driven) ranges changed, not when user pans
470
- // Comparing against initial preserves user's pan/zoom state
471
- if (
472
- ranges.initial.x[0] !== new_x[0] ||
473
- ranges.initial.x[1] !== new_x[1] ||
474
- ranges.initial.x2[0] !== new_x2[0] ||
475
- ranges.initial.x2[1] !== new_x2[1] ||
476
- ranges.initial.y[0] !== new_y[0] ||
477
- ranges.initial.y[1] !== new_y[1] ||
478
- ranges.initial.y2[0] !== new_y2[0] ||
479
- ranges.initial.y2[1] !== new_y2[1]
480
- ) {
481
- ranges = {
482
- initial: { x: new_x, x2: new_x2, y: new_y, y2: new_y2 },
483
- current: { x: new_x, x2: new_x2, y: new_y, y2: new_y2 },
484
- }
485
- }
486
- })
487
-
488
- // Layout: dynamic padding based on tick label widths
489
- const default_padding = { t: 20, b: 60, l: 60, r: 20 }
490
- let pad = $derived(filter_padding(padding, default_padding))
491
-
492
- // Update padding when format or ticks change
493
- $effect(() => {
494
- const new_pad = width && height && ticks.y.length
495
- ? calc_auto_padding({
496
- padding,
497
- default_padding,
498
- x2_axis: { ...x2_axis, tick_values: ticks.x2 },
499
- y_axis: { ...y_axis, tick_values: ticks.y },
500
- y2_axis: { ...y2_axis, tick_values: ticks.y2 },
501
- })
502
- : filter_padding(padding, default_padding)
503
- // Expand right padding if y2 ticks are shown (only for vertical orientation)
504
- if (
505
- width && height && y2_series.length && ticks.y2.length &&
506
- orientation === `vertical`
507
- ) {
508
- // Need space for: tick shift + tick width + gap (30px) + label space (20px if present)
509
- // When ticks are inside, they don't contribute to padding
510
- const inside = y2_axis.tick?.label?.inside ?? false
511
- const tick_shift = inside ? 0 : (y2_axis.tick?.label?.shift?.x ?? 0) + 8
512
- const tick_width_contribution = inside ? 0 : tick_label_widths.y2_max
513
- const label_space = y2_axis.label ? 20 : 0
514
- new_pad.r = Math.max(
515
- new_pad.r,
516
- tick_shift + tick_width_contribution + 30 + label_space,
517
- )
518
- }
519
- // Expand top padding if x2 ticks are shown (only for vertical orientation)
520
- if (
521
- width && height && x2_series.length && ticks.x2.length &&
522
- orientation === `vertical`
523
- ) {
524
- const inside = x2_axis.tick?.label?.inside ?? false
525
- const tick_shift = inside ? 0 : Math.abs(x2_axis.tick?.label?.shift?.y ?? 0) + 5
526
- const tick_height = inside ? 0 : 16
527
- const label_space = x2_axis.label ? 20 : 0
528
- new_pad.t = Math.max(new_pad.t, tick_shift + tick_height + 30 + label_space)
529
- }
530
-
531
- // Only update if padding actually changed (prevents infinite loop)
532
- if (
533
- pad.t !== new_pad.t || pad.b !== new_pad.b || pad.l !== new_pad.l ||
534
- pad.r !== new_pad.r
535
- ) pad = new_pad
536
- })
537
- const chart_width = $derived(Math.max(1, width - pad.l - pad.r))
538
- const chart_height = $derived(Math.max(1, height - pad.t - pad.b))
539
-
540
- // Scales
541
- let scales = $derived({
542
- x: create_scale(x_axis.scale_type ?? `linear`, ranges.current.x, [
543
- pad.l,
544
- width - pad.r,
545
- ]),
546
- x2: create_scale(x2_axis.scale_type ?? `linear`, ranges.current.x2, [
547
- pad.l,
548
- width - pad.r,
549
- ]),
550
- y: create_scale(y_axis.scale_type ?? `linear`, ranges.current.y, [
551
- height - pad.b,
552
- pad.t,
553
- ]),
554
- y2: create_scale(y2_axis.scale_type ?? `linear`, ranges.current.y2, [
555
- height - pad.b,
556
- pad.t,
557
- ]),
558
- })
559
-
560
- // Compute plot center for point tweening origin
561
- let plot_center_x = $derived(pad.l + (width - pad.r - pad.l) / 2)
562
- let plot_center_y = $derived(pad.t + (height - pad.b - pad.t) / 2)
563
-
564
- // Compute color values from line series for color scaling (filter to numbers only)
565
- let all_color_values = $derived(
566
- visible_series
567
- .filter((srs: BarSeries<Metadata>) => srs.render_mode === `line`)
568
- .flatMap((srs: BarSeries<Metadata>) =>
569
- (srs.color_values ?? []).filter(
570
- (val): val is number => typeof val === `number`,
571
- )
572
- ),
573
- )
574
-
575
- // Create auto color range (safely handle empty arrays or undefined extent results)
576
- let auto_color_range: [number, number] = $derived.by(() => {
577
- if (all_color_values.length === 0) return [0, 1]
578
- const [min_val, max_val] = extent(all_color_values)
579
- return [min_val ?? 0, max_val ?? 1]
580
- })
581
-
582
- // All size values from line series (for size scale, filter to numbers only)
583
- let all_size_values = $derived(
584
- visible_series
585
- .filter((srs: BarSeries<Metadata>) => srs.render_mode === `line`)
586
- .flatMap((srs: BarSeries<Metadata>) =>
587
- [...(srs.size_values ?? [])].filter(
588
- (val): val is number => typeof val === `number`,
589
- )
590
- ),
591
- )
592
-
593
- // Color scale function (using shared utility)
594
- let color_scale_fn = $derived(create_color_scale(color_scale, auto_color_range))
595
-
596
- // Size scale function (using shared utility)
597
- let size_scale_fn = $derived(create_size_scale(size_scale, all_size_values))
598
-
599
- // Auto-generate tick labels for categorical data (unless user provides explicit ticks)
600
- // In vertical mode categories are on x-axis; in horizontal mode on y-axis
601
- let cat_axis = $derived(orientation === `horizontal` ? `y` : `x`)
602
- let effective_cat_ticks = $derived.by(() => {
603
- if (!category_list.length) return undefined
604
- // Only respect user ticks when they're a Record (custom label mapping),
605
- // not a number (tick count) or array (tick positions)
606
- const user_ticks = cat_axis === `x` ? x_axis.ticks : y_axis.ticks
607
- if (
608
- user_ticks != null && typeof user_ticks === `object` &&
609
- !Array.isArray(user_ticks)
610
- ) return user_ticks
611
- return Object.fromEntries(
612
- category_list.map((cat, idx) => [idx, cat]),
613
- ) as Record<number, string>
614
- })
615
-
616
- // Ticks
617
- let ticks = $derived({
618
- x: width && height
619
- ? (category_indices && cat_axis === `x` ? category_indices : generate_ticks(
620
- ranges.current.x,
621
- x_axis.scale_type ?? `linear`,
622
- x_axis.ticks,
623
- scales.x,
624
- { default_count: 8 },
625
- ))
626
- : [],
627
- y: width && height
628
- ? (category_indices && cat_axis === `y` ? category_indices : generate_ticks(
629
- ranges.current.y,
630
- y_axis.scale_type ?? `linear`,
631
- y_axis.ticks,
632
- scales.y,
633
- { default_count: 6 },
634
- ))
635
- : [],
636
- y2: width && height && y2_series.length > 0 && orientation === `vertical`
637
- ? generate_ticks(
638
- ranges.current.y2,
639
- y2_axis.scale_type ?? `linear`,
640
- y2_axis.ticks,
641
- scales.y2,
642
- {
643
- default_count: 6,
644
- },
645
- )
646
- : [],
647
- x2: width && height && x2_series.length > 0 && orientation === `vertical`
648
- ? generate_ticks(
649
- ranges.current.x2,
650
- x2_axis.scale_type ?? `linear`,
651
- x2_axis.ticks,
652
- scales.x2,
653
- {
654
- default_count: 8,
655
- },
656
- )
657
- : [],
658
- })
659
-
660
- // Cache measured tick-label widths so expensive canvas text measurement
661
- // only runs when ticks/format change, not on every template rerender.
662
- let tick_label_widths = $derived({
663
- y_max: measure_max_tick_width(ticks.y, y_axis.format ?? ``),
664
- y2_max: measure_max_tick_width(ticks.y2, y2_axis.format ?? ``),
665
- x2_max: measure_max_tick_width(ticks.x2, x2_axis.format ?? ``),
666
- })
667
-
668
- // Zoom drag state
669
- let drag_state = $state<{
670
- start: { x: number; y: number } | null
671
- current: { x: number; y: number } | null
672
- bounds: DOMRect | null
673
- }>({ start: null, current: null, bounds: null })
674
-
675
- // Pan state
676
- let is_focused = $state(false)
677
- let shift_held = $state(false)
678
- let pan_drag_state = $state<
679
- InitialRanges & { start: { x: number; y: number } } | null
680
- >(null)
681
- let touch_state = $state<
682
- InitialRanges & { start_touches: { x: number; y: number }[] } | null
683
- >(null)
684
- const on_window_mouse_move = (evt: MouseEvent) => {
685
- if (!drag_state.start || !drag_state.bounds) return
686
- drag_state.current = {
687
- x: evt.clientX - drag_state.bounds.left,
688
- y: evt.clientY - drag_state.bounds.top,
689
- }
690
- }
691
- const on_window_mouse_up = () => {
692
- if (drag_state.start && drag_state.current) {
693
- const x1_raw = scales.x.invert(drag_state.start.x) as number | Date
694
- const x2_raw = scales.x.invert(drag_state.current.x) as number | Date
695
- const y1 = scales.y.invert(drag_state.start.y)
696
- const y2 = scales.y.invert(drag_state.current.y)
697
- const y2_1 = scales.y2.invert(drag_state.start.y)
698
- const y2_2 = scales.y2.invert(drag_state.current.y)
699
- const x2a_1_raw = scales.x2.invert(drag_state.start.x) as number | Date
700
- const x2a_2_raw = scales.x2.invert(drag_state.current.x) as number | Date
701
- const dx = Math.abs(drag_state.start.x - drag_state.current.x)
702
- const dy = Math.abs(drag_state.start.y - drag_state.current.y)
703
-
704
- let xr1: number, xr2: number
705
- if (x1_raw instanceof Date && x2_raw instanceof Date) {
706
- ;[xr1, xr2] = [x1_raw.getTime(), x2_raw.getTime()]
707
- } else if (typeof x1_raw === `number` && typeof x2_raw === `number`) {
708
- ;[xr1, xr2] = [x1_raw, x2_raw]
709
- } else [xr1, xr2] = [NaN, NaN] // bail: mixed types
710
-
711
- let x2r1: number, x2r2: number
712
- if (x2a_1_raw instanceof Date && x2a_2_raw instanceof Date) {
713
- ;[x2r1, x2r2] = [x2a_1_raw.getTime(), x2a_2_raw.getTime()]
714
- } else if (typeof x2a_1_raw === `number` && typeof x2a_2_raw === `number`) {
715
- ;[x2r1, x2r2] = [x2a_1_raw, x2a_2_raw]
716
- } else [x2r1, x2r2] = [NaN, NaN]
717
-
718
- if (dx > 5 && dy > 5 && Number.isFinite(xr1) && Number.isFinite(xr2)) {
719
- // Update axis ranges to trigger reactivity and prevent effect from overriding
720
- x_axis = { ...x_axis, range: [Math.min(xr1, xr2), Math.max(xr1, xr2)] }
721
- if (x2_series.length > 0 && Number.isFinite(x2r1) && Number.isFinite(x2r2)) {
722
- x2_axis = {
723
- ...x2_axis,
724
- range: [Math.min(x2r1, x2r2), Math.max(x2r1, x2r2)],
725
- }
726
- }
727
- y_axis = { ...y_axis, range: [Math.min(y1, y2), Math.max(y1, y2)] }
728
- y2_axis = { ...y2_axis, range: [Math.min(y2_1, y2_2), Math.max(y2_1, y2_2)] }
729
- }
730
- }
731
- drag_state = { start: null, current: null, bounds: null }
732
- window.removeEventListener(`mousemove`, on_window_mouse_move)
733
- window.removeEventListener(`mouseup`, on_window_mouse_up)
734
- document.body.style.cursor = `default`
735
- }
736
-
737
- // Pan drag handlers
738
- const on_pan_move = (evt: MouseEvent) => {
739
- if (!pan_drag_state) return
740
- const dx = evt.clientX - pan_drag_state.start.x
741
- const dy = evt.clientY - pan_drag_state.start.y
742
-
743
- // Convert pixel delta to data delta (note: drag direction is inverted for natural pan feel)
744
- const sensitivity = pan?.drag_sensitivity ?? 1
745
-
746
- const x_delta = pixels_to_data_delta(
747
- -dx * sensitivity,
748
- pan_drag_state.initial_x_range,
749
- chart_width,
750
- )
751
- const x2_delta = pixels_to_data_delta(
752
- -dx * sensitivity,
753
- pan_drag_state.initial_x2_range,
754
- chart_width,
755
- )
756
- const y_delta = pixels_to_data_delta(
757
- dy * sensitivity,
758
- pan_drag_state.initial_y_range,
759
- chart_height,
760
- )
761
- const y2_delta = pixels_to_data_delta(
762
- dy * sensitivity,
763
- pan_drag_state.initial_y2_range,
764
- chart_height,
765
- )
766
-
767
- ranges.current.x = pan_range(pan_drag_state.initial_x_range, x_delta)
768
- ranges.current.x2 = pan_range(pan_drag_state.initial_x2_range, x2_delta)
769
- ranges.current.y = pan_range(pan_drag_state.initial_y_range, y_delta)
770
- ranges.current.y2 = pan_range(pan_drag_state.initial_y2_range, y2_delta)
771
- }
772
-
773
- const on_pan_end = () => {
774
- pan_drag_state = null
775
- document.body.style.cursor = ``
776
- window.removeEventListener(`mousemove`, on_pan_move)
777
- window.removeEventListener(`mouseup`, on_pan_end)
778
- }
779
-
780
- function handle_mouse_down(evt: MouseEvent) {
781
- const coords = get_relative_coords(evt)
782
- if (!coords || !svg_element) return
783
-
784
- // Check if pan is enabled and shift is held for pan mode
785
- const pan_enabled = pan?.enabled !== false
786
- if (pan_enabled && evt.shiftKey) {
787
- evt.preventDefault()
788
- pan_drag_state = {
789
- start: { x: evt.clientX, y: evt.clientY },
790
- initial_x_range: [...ranges.current.x] as [number, number],
791
- initial_x2_range: [...ranges.current.x2] as [number, number],
792
- initial_y_range: [...ranges.current.y] as [number, number],
793
- initial_y2_range: [...ranges.current.y2] as [number, number],
794
- }
795
- document.body.style.cursor = `grabbing`
796
- window.addEventListener(`mousemove`, on_pan_move)
797
- window.addEventListener(`mouseup`, on_pan_end)
798
- return
799
- }
800
-
801
- drag_state = {
802
- start: coords,
803
- current: coords,
804
- bounds: svg_element.getBoundingClientRect(),
805
- }
806
- window.addEventListener(`mousemove`, on_window_mouse_move)
807
- window.addEventListener(`mouseup`, on_window_mouse_up)
808
- evt.preventDefault()
809
- }
810
-
811
- // Wheel handler for pan (requires focus and shift)
812
- function handle_wheel(evt: WheelEvent) {
813
- const pan_enabled = pan?.enabled !== false
814
- // Only capture wheel when focused AND Shift is held
815
- // Use shift_held state (tracked via keydown/keyup) for compatibility with synthetic events
816
- if (!pan_enabled || !is_focused || !shift_held) return
817
-
818
- evt.preventDefault()
819
-
820
- const sensitivity = pan?.wheel_sensitivity ?? 1
821
-
822
- // Determine pan direction based on wheel delta
823
- const x_delta = pixels_to_data_delta(
824
- evt.deltaX * sensitivity,
825
- ranges.current.x,
826
- chart_width,
827
- )
828
- const x2_delta = pixels_to_data_delta(
829
- evt.deltaX * sensitivity,
830
- ranges.current.x2,
831
- chart_width,
832
- )
833
- const y_delta = pixels_to_data_delta(
834
- evt.deltaY * sensitivity,
835
- ranges.current.y,
836
- chart_height,
837
- )
838
- const y2_delta = pixels_to_data_delta(
839
- evt.deltaY * sensitivity,
840
- ranges.current.y2,
841
- chart_height,
842
- )
843
-
844
- if (Math.abs(evt.deltaX) > Math.abs(evt.deltaY)) {
845
- ranges.current.x = pan_range(ranges.current.x, x_delta)
846
- ranges.current.x2 = pan_range(ranges.current.x2, x2_delta)
847
- } else {
848
- ranges.current.y = pan_range(ranges.current.y, y_delta)
849
- ranges.current.y2 = pan_range(ranges.current.y2, y2_delta)
850
- }
851
- }
852
-
853
- // Touch handlers for pinch-zoom and two-finger pan
854
- function handle_touch_start(evt: TouchEvent) {
855
- const touch_enabled = pan?.enabled !== false && pan?.touch_enabled !== false
856
- if (!touch_enabled || evt.touches.length !== 2) return
857
-
858
- evt.preventDefault()
859
- const touches = Array.from(evt.touches)
860
- touch_state = {
861
- start_touches: touches.map((touch) => ({ x: touch.clientX, y: touch.clientY })),
862
- initial_x_range: [...ranges.current.x] as [number, number],
863
- initial_x2_range: [...ranges.current.x2] as [number, number],
864
- initial_y_range: [...ranges.current.y] as [number, number],
865
- initial_y2_range: [...ranges.current.y2] as [number, number],
866
- }
867
- }
868
-
869
- function handle_touch_move(evt: TouchEvent) {
870
- if (!touch_state || evt.touches.length !== 2) return
871
- evt.preventDefault()
872
-
873
- const [t1, t2] = Array.from(evt.touches)
874
- const [s1, s2] = touch_state.start_touches
875
-
876
- // Calculate center movement for pan
877
- const start_center = { x: (s1.x + s2.x) / 2, y: (s1.y + s2.y) / 2 }
878
- const curr_center = {
879
- x: (t1.clientX + t2.clientX) / 2,
880
- y: (t1.clientY + t2.clientY) / 2,
881
- }
882
- const dx = curr_center.x - start_center.x
883
- const dy = curr_center.y - start_center.y
884
-
885
- // Calculate pinch scale (curr/start so spread = zoom out, pinch = zoom in)
886
- const start_dist = Math.hypot(s2.x - s1.x, s2.y - s1.y)
887
- // Guard against zero-distance pinch to avoid Infinity scale
888
- if (start_dist < Number.EPSILON) return
889
- const curr_dist = Math.hypot(t2.clientX - t1.clientX, t2.clientY - t1.clientY)
890
- const scale = curr_dist / start_dist
891
-
892
- // If scale changed significantly, treat as pinch-zoom
893
- // Also guard against scale being too small to avoid division by zero
894
- if (Math.abs(scale - 1) > PINCH_ZOOM_THRESHOLD && scale > Number.EPSILON) {
895
- // Pinch zoom centered on gesture center
896
- // Divide by scale so spread (scale > 1) = smaller span (zoom in)
897
- const x_span = touch_state.initial_x_range[1] - touch_state.initial_x_range[0]
898
- const x2_span = touch_state.initial_x2_range[1] -
899
- touch_state.initial_x2_range[0]
900
- const y_span = touch_state.initial_y_range[1] - touch_state.initial_y_range[0]
901
- const y2_span = touch_state.initial_y2_range[1] -
902
- touch_state.initial_y2_range[0]
903
- const x_center =
904
- (touch_state.initial_x_range[0] + touch_state.initial_x_range[1]) / 2
905
- const x2_center =
906
- (touch_state.initial_x2_range[0] + touch_state.initial_x2_range[1]) / 2
907
- const y_center =
908
- (touch_state.initial_y_range[0] + touch_state.initial_y_range[1]) / 2
909
- const y2_center =
910
- (touch_state.initial_y2_range[0] + touch_state.initial_y2_range[1]) / 2
911
-
912
- ranges.current.x = [
913
- x_center - x_span / scale / 2,
914
- x_center + x_span / scale / 2,
915
- ]
916
- ranges.current.x2 = [
917
- x2_center - x2_span / scale / 2,
918
- x2_center + x2_span / scale / 2,
919
- ]
920
- ranges.current.y = [
921
- y_center - y_span / scale / 2,
922
- y_center + y_span / scale / 2,
923
- ]
924
- ranges.current.y2 = [
925
- y2_center - y2_span / scale / 2,
926
- y2_center + y2_span / scale / 2,
927
- ]
928
- } else {
929
- // Pan
930
- const x_delta = pixels_to_data_delta(
931
- -dx,
932
- touch_state.initial_x_range,
933
- chart_width,
934
- )
935
- const x2_delta = pixels_to_data_delta(
936
- -dx,
937
- touch_state.initial_x2_range,
938
- chart_width,
939
- )
940
- const y_delta = pixels_to_data_delta(
941
- dy,
942
- touch_state.initial_y_range,
943
- chart_height,
944
- )
945
- const y2_delta = pixels_to_data_delta(
946
- dy,
947
- touch_state.initial_y2_range,
948
- chart_height,
949
- )
950
- ranges.current.x = pan_range(touch_state.initial_x_range, x_delta)
951
- ranges.current.x2 = pan_range(touch_state.initial_x2_range, x2_delta)
952
- ranges.current.y = pan_range(touch_state.initial_y_range, y_delta)
953
- ranges.current.y2 = pan_range(touch_state.initial_y2_range, y2_delta)
954
- }
955
- }
956
-
957
- function handle_touch_end() {
958
- touch_state = null
959
- }
960
-
961
- // Legend data and handlers
962
- let legend_data = $derived.by<LegendItem[]>(() =>
963
- series.map((srs: BarSeries<Metadata>, idx: number) => {
964
- const is_line = srs.render_mode === `line`
965
- const series_markers = srs.markers ?? DEFAULT_MARKERS
966
- const has_line = series_markers === `line` || series_markers === `line+points`
967
- const has_points = series_markers === `points` ||
968
- series_markers === `line+points`
969
- const series_color = srs.color ?? (is_line ? line_state.color : bar_state.color)
970
-
971
- // Get point style for symbol color (handle array or single object)
972
- const first_point_style = Array.isArray(srs.point_style)
973
- ? srs.point_style[0]
974
- : srs.point_style
975
- const first_color_value = srs.color_values?.[0]
976
- const point_color = first_color_value != null
977
- ? color_scale_fn(first_color_value)
978
- : first_point_style?.fill ?? series_color
979
-
980
- if (is_line) {
981
- // Line series: show line and/or symbol based on markers
982
- return {
983
- series_idx: idx,
984
- label: srs.label ?? `Series ${idx + 1}`,
985
- visible: srs.visible ?? true,
986
- legend_group: srs.legend_group,
987
- display_style: {
988
- ...(has_line
989
- ? {
990
- line_color: series_color,
991
- line_dash: srs.line_style?.line_dash,
992
- }
993
- : {}),
994
- ...(has_points
995
- ? {
996
- symbol_type: first_point_style?.symbol_type ??
997
- DEFAULTS.scatter.symbol_type,
998
- symbol_color: point_color,
999
- }
1000
- : {}),
1001
- },
1002
- }
1003
- }
1004
- // Bar series: show square symbol
1005
- return {
1006
- series_idx: idx,
1007
- label: srs.label ?? `Series ${idx + 1}`,
1008
- visible: srs.visible ?? true,
1009
- legend_group: srs.legend_group,
1010
- display_style: {
1011
- symbol_type: `Square` as const,
1012
- symbol_color: series_color,
1013
- },
1014
- }
1015
- })
1016
- )
1017
-
1018
- function toggle_series_visibility(series_idx: number) {
1019
- if (series_idx >= 0 && series_idx < series.length) {
1020
- series = series.map((srs, idx) =>
1021
- idx === series_idx ? { ...srs, visible: !(srs.visible ?? true) } : srs
1022
- )
1023
- }
1024
- }
1025
-
1026
- function toggle_group_visibility(_group_name: string, series_indices: number[]) {
1027
- // Filter to valid indices upfront (consistent with shared toggle_group_visibility)
1028
- const valid_indices = series_indices.filter((idx) =>
1029
- idx >= 0 && idx < series.length
1030
- )
1031
- if (valid_indices.length === 0) return
1032
-
1033
- const idx_set = new Set(valid_indices)
1034
- // Check if all series in the group are currently visible
1035
- const all_visible = valid_indices.every((idx) => series[idx].visible ?? true)
1036
- // Toggle: if all visible, hide all; otherwise show all
1037
- const new_visibility = !all_visible
1038
- series = series.map((srs, idx) =>
1039
- idx_set.has(idx) ? { ...srs, visible: new_visibility } : srs
1040
- )
1041
- }
1042
-
1043
- // Collect bar and line positions for legend placement
1044
- let bar_points_for_placement = $derived.by(() => {
1045
- if (!width || !height || !visible_series.length) return []
1046
-
1047
- return internal_series.flatMap((srs, series_idx) => {
1048
- if (!(srs?.visible ?? true)) return []
1049
- const is_line = srs.render_mode === `line`
1050
- const series_offsets = stacked_offsets[series_idx] ?? []
1051
- const use_y2 = srs.y_axis === `y2`
1052
- const y_scale = use_y2 ? scales.y2 : scales.y
1053
- const use_x2_pl = srs.x_axis === `x2`
1054
- const x_scale_pl = use_x2_pl ? scales.x2 : scales.x
1055
- return srs.x
1056
- .map((x_val, bar_idx) => {
1057
- const y_val = srs.y[bar_idx]
1058
- const base = !is_line && mode === `stacked`
1059
- ? (series_offsets[bar_idx] ?? 0)
1060
- : 0
1061
- const [bar_x, bar_y] = orientation === `vertical`
1062
- ? [x_scale_pl(x_val), y_scale(base + y_val)]
1063
- : [x_scale_pl(base + y_val), scales.y(x_val)]
1064
- return { x: bar_x, y: bar_y }
1065
- })
1066
- .filter(({ x, y }) => isFinite(x) && isFinite(y))
1067
- })
1068
- })
1069
-
1070
- // Legend placement stability state
1071
- let legend_element = $state<HTMLDivElement | undefined>()
1072
- let hovered_legend_series_idx = $state<number | null>(null)
1073
- const legend_hover = create_hover_lock()
1074
- const dim_tracker = create_dimension_tracker()
1075
- let has_initial_legend_placement = $state(false)
1076
-
1077
- // Clear pending hover lock timeout on unmount
1078
- $effect(() => () => legend_hover.cleanup())
1079
-
1080
- // Calculate best legend placement using continuous grid sampling
1081
- let legend_placement = $derived.by(() => {
1082
- const should_show = show_legend !== undefined ? show_legend : series.length > 1
1083
- if (!should_show || !width || !height) return null
1084
-
1085
- // Use measured size if available, otherwise estimate
1086
- const legend_size = legend_element
1087
- ? { width: legend_element.offsetWidth, height: legend_element.offsetHeight }
1088
- : { width: 120, height: 60 }
1089
-
1090
- const result = compute_element_placement({
1091
- plot_bounds: { x: pad.l, y: pad.t, width: chart_width, height: chart_height },
1092
- element_size: legend_size,
1093
- axis_clearance: legend?.axis_clearance,
1094
- exclude_rects: [],
1095
- points: bar_points_for_placement,
1096
- })
1097
-
1098
- return result
1099
- })
1100
-
1101
- // Tweened legend coordinates for smooth animation - create once, update target via effect
1102
- // untrack() explicitly captures initial tween config (intentional - config set once at mount)
1103
- const tweened_legend_coords = new Tween(
1104
- { x: 0, y: 0 },
1105
- untrack(() => ({ duration: 400, ...legend?.tween })),
1106
- )
1107
-
1108
- // Update legend position with stability checks
1109
- $effect(() => {
1110
- if (!width || !height || !legend_placement) return
1111
-
1112
- // Track dimensions for resize detection
1113
- const dims_changed = dim_tracker.has_changed(width, height)
1114
- if (dims_changed) dim_tracker.update(width, height)
1115
-
1116
- const is_responsive = legend?.responsive ?? false
1117
- // Only update if: resize occurred, OR (not hover-locked AND (responsive OR not yet initially placed))
1118
- const should_update = dims_changed || (!legend_hover.is_locked.current &&
1119
- (is_responsive || !has_initial_legend_placement))
1120
-
1121
- if (should_update) {
1122
- tweened_legend_coords.set(
1123
- { x: legend_placement.x, y: legend_placement.y },
1124
- // Skip animation on initial placement to avoid jump from (0, 0)
1125
- has_initial_legend_placement ? undefined : { duration: 0 },
1126
- )
1127
- // Only lock position after we have actual measured size
1128
- if (legend_element) {
1129
- has_initial_legend_placement = true
1130
- }
1131
- }
1132
- })
1133
-
1134
- // Tooltip state
1135
- let hover_info = $state<BarHandlerProps<Metadata> | null>(null)
1136
- let tooltip_el = $state<HTMLDivElement | undefined>()
1137
-
1138
- function get_bar_data(
1139
- series_idx: number,
1140
- bar_idx: number,
1141
- color: string,
1142
- ): BarHandlerProps<Metadata> {
1143
- const srs = internal_series[series_idx]
1144
- const [x, y] = [srs.x[bar_idx], srs.y[bar_idx]]
1145
- const [orient_x, orient_y] = orientation === `horizontal` ? [y, x] : [x, y]
1146
- const metadata = Array.isArray(srs.metadata)
1147
- ? srs.metadata[bar_idx]
1148
- : srs.metadata
1149
- const label = srs.labels?.[bar_idx] ?? null
1150
- const active_y_axis = srs.y_axis ?? `y1`
1151
- const active_x_axis = srs.x_axis ?? `x1`
1152
- const category_label = category_list[x]
1153
- const coords = {
1154
- x,
1155
- y,
1156
- orient_x,
1157
- orient_y,
1158
- x_axis: active_x_axis === `x2` ? x2_axis : x_axis,
1159
- x2_axis,
1160
- y_axis: active_y_axis === `y2` ? y2_axis : y_axis,
1161
- y2_axis,
1162
- }
1163
- return {
1164
- ...coords,
1165
- metadata,
1166
- color,
1167
- label,
1168
- series_idx,
1169
- bar_idx,
1170
- active_y_axis,
1171
- active_x_axis,
1172
- category_label,
1173
- }
1174
- }
1175
-
1176
- // Find the point closest to the cursor on a polyline overlay (O(n) scan).
1177
- function find_closest_point(
1178
- evt: MouseEvent,
1179
- points: LineSeriesPoint[],
1180
- ): LineSeriesPoint | null {
1181
- const svg_el = (evt.target as Element).closest(`svg`)
1182
- if (!svg_el) return null
1183
- const rect = svg_el.getBoundingClientRect()
1184
- const mx = evt.clientX - rect.left
1185
- const my = evt.clientY - rect.top
1186
- let best: LineSeriesPoint | null = null
1187
- let best_dist = Infinity
1188
- for (const pt of points) {
1189
- const dist = (pt.x - mx) ** 2 + (pt.y - my) ** 2
1190
- if (dist < best_dist) {
1191
- best_dist = dist
1192
- best = pt
1193
- }
1194
- }
1195
- return best
1196
- }
1197
-
1198
- const line_point_fill = (pt: LineSeriesPoint, series_color: string): string =>
1199
- pt.color_value != null
1200
- ? color_scale_fn(pt.color_value)
1201
- : pt.point_style?.fill ?? series_color
1202
-
1203
- const handle_bar_hover =
1204
- (series_idx: number, bar_idx: number, color: string) => (event: MouseEvent) => {
1205
- hovered = true
1206
- hover_info = get_bar_data(series_idx, bar_idx, color)
1207
- change(hover_info)
1208
- on_bar_hover?.({ ...hover_info, event })
1209
- }
1210
-
1211
- // Stack offsets (only for bar series in stacked mode, grouped by y-axis)
1212
- let stacked_offsets = $derived.by(() => {
1213
- if (mode !== `stacked`) return [] as number[][]
1214
- const max_len = Math.max(
1215
- 0,
1216
- ...internal_series.map((srs) => srs.y.length),
1217
- )
1218
- const offsets = internal_series.map(() =>
1219
- Array.from({ length: max_len }, () => 0)
1220
- )
1221
-
1222
- // Separate accumulators for y1 and y2 axes
1223
- const y1_pos_acc = Array.from({ length: max_len }, () => 0)
1224
- const y1_neg_acc = Array.from({ length: max_len }, () => 0)
1225
- const y2_pos_acc = Array.from({ length: max_len }, () => 0)
1226
- const y2_neg_acc = Array.from({ length: max_len }, () => 0)
1227
-
1228
- internal_series.forEach((srs, series_idx) => {
1229
- if (!(srs?.visible ?? true) || srs.render_mode === `line`) return
1230
-
1231
- const use_y2 = srs.y_axis === `y2`
1232
- const pos_acc = use_y2 ? y2_pos_acc : y1_pos_acc
1233
- const neg_acc = use_y2 ? y2_neg_acc : y1_neg_acc
1234
-
1235
- for (let bar_idx = 0; bar_idx < max_len; bar_idx++) {
1236
- const y_val = srs.y[bar_idx] ?? 0
1237
- const acc = y_val >= 0 ? pos_acc : neg_acc
1238
- offsets[series_idx][bar_idx] = acc[bar_idx]
1239
- acc[bar_idx] += y_val
1240
- }
1241
- })
1242
- return offsets
1243
- })
1244
-
1245
- // Calculate group positions for grouped mode (side-by-side bars)
1246
- let group_info = $derived.by(() => {
1247
- if (mode !== `grouped`) return { bar_series_count: 0, bar_series_indices: [] }
1248
- const bar_series_indices = internal_series
1249
- .map((srs, idx) =>
1250
- (srs?.visible ?? true) && srs.render_mode !== `line` ? idx : -1
1251
- )
1252
- .filter((idx) => idx >= 0)
1253
- return { bar_series_count: bar_series_indices.length, bar_series_indices }
1254
- })
1255
-
1256
- // Set theme-aware background when entering fullscreen
1257
- $effect(() => {
1258
- set_fullscreen_bg(wrapper, fullscreen, `--barplot-fullscreen-bg`)
1259
- })
1260
-
1261
- // State accessors for shared axis change handler
1262
- const axis_state: AxisChangeState<BarSeries<Metadata>> = {
1263
- get_axis: (axis) => {
1264
- if (axis === `x`) return x_axis
1265
- if (axis === `x2`) return x2_axis
1266
- if (axis === `y`) return y_axis
1267
- return y2_axis
1268
- },
1269
- set_axis: (axis, config) => {
1270
- // Spread into existing state to preserve merged type structure
1271
- if (axis === `x`) x_axis = { ...x_axis, ...config }
1272
- else if (axis === `x2`) x2_axis = { ...x2_axis, ...config }
1273
- else if (axis === `y`) y_axis = { ...y_axis, ...config }
1274
- else y2_axis = { ...y2_axis, ...config }
1275
- },
1276
- get_series: () => series,
1277
- set_series: (new_series) => (series = new_series),
1278
- get_loading: () => axis_loading,
1279
- set_loading: (axis) => (axis_loading = axis),
1280
- }
1281
-
1282
- // Create shared handler bound to this component's state
1283
- // Using $derived so handler updates when callback props change
1284
- const handle_axis_change = $derived(create_axis_change_handler(
1285
- axis_state,
1286
- data_loader,
1287
- on_axis_change,
1288
- on_error,
1289
- ))
1290
-
1291
- let auto_load_attempted = false // prevent infinite retries on failure
1292
-
1293
- // Auto-load data if series is empty but options exist (runs once)
1294
- $effect(() => {
1295
- if (series.length === 0 && data_loader && !auto_load_attempted) {
1296
- // Check x-axis first, then y-axis
1297
- if (x_axis.options?.length) {
1298
- auto_load_attempted = true
1299
- const first_key = x_axis.selected_key ?? x_axis.options[0].key
1300
- handle_axis_change(`x`, first_key).catch(() => {})
1301
- } else if (y_axis.options?.length) {
1302
- auto_load_attempted = true
1303
- const first_key = y_axis.selected_key ?? y_axis.options[0].key
1304
- handle_axis_change(`y`, first_key).catch(() => {})
1305
- }
1306
- }
1307
- })
1308
- </script>
1309
-
1310
- {#snippet ref_lines_layer(lines: IndexedRefLine[])}
1311
- {#each lines as line (line.id ?? line.idx)}
1312
- <ReferenceLine
1313
- ref_line={line}
1314
- line_idx={line.idx}
1315
- x_min={line.x_axis === `x2` ? ranges.current.x2[0] : ranges.current.x[0]}
1316
- x_max={line.x_axis === `x2` ? ranges.current.x2[1] : ranges.current.x[1]}
1317
- y_min={line.y_axis === `y2` ? ranges.current.y2[0] : ranges.current.y[0]}
1318
- y_max={line.y_axis === `y2` ? ranges.current.y2[1] : ranges.current.y[1]}
1319
- x_scale={scales.x}
1320
- x2_scale={scales.x2}
1321
- y_scale={scales.y}
1322
- y2_scale={scales.y2}
1323
- {clip_path_id}
1324
- hovered_line_idx={hovered_ref_line_idx}
1325
- on_click={(event: RefLineEvent) => {
1326
- line.on_click?.(event)
1327
- on_ref_line_click?.(event)
1328
- }}
1329
- on_hover={(event: RefLineEvent | null) => {
1330
- hovered_ref_line_idx = event?.line_idx ?? null
1331
- line.on_hover?.(event)
1332
- on_ref_line_hover?.(event)
1333
- }}
1334
- />
1335
- {/each}
1336
- {/snippet}
1337
-
1338
- <svelte:window
1339
- onkeydown={(evt) => {
1340
- if (evt.key === `Escape` && fullscreen) {
1341
- evt.preventDefault()
1342
- fullscreen = false
1343
- }
1344
- if (evt.key === `Shift`) shift_held = true
1345
- }}
1346
- onkeyup={(evt) => {
1347
- if (evt.key === `Shift`) shift_held = false
1348
- }}
1349
- />
1350
-
1351
- <div
1352
- bind:this={wrapper}
1353
- bind:clientWidth={width}
1354
- bind:clientHeight={height}
1355
- {...rest}
1356
- class="bar-plot {rest.class ?? ``}"
1357
- class:fullscreen
1358
- >
1359
- {#if width && height}
1360
- <div class="header-controls">
1361
- {@render header_controls?.({ height, width, fullscreen })}
1362
- {#if fullscreen_toggle}
1363
- <FullscreenToggle bind:fullscreen />
1364
- {/if}
1365
- </div>
1366
- <!-- svelte-ignore a11y_no_noninteractive_tabindex -->
1367
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
1368
- <svg
1369
- bind:this={svg_element}
1370
- role="application"
1371
- aria-label={rest[`aria-label`] ??
1372
- ([x_axis.label, y_axis.label].filter(Boolean).join(` vs `) || `Bar chart`)}
1373
- tabindex="0"
1374
- onfocusin={() => (is_focused = true)}
1375
- onfocusout={() => (is_focused = false)}
1376
- onmousedown={handle_mouse_down}
1377
- ondblclick={() => {
1378
- // Reset zoom to initial ranges (undo any pan/zoom)
1379
- ranges.current.x = [...ranges.initial.x] as [number, number]
1380
- ranges.current.x2 = [...ranges.initial.x2] as [number, number]
1381
- ranges.current.y = [...ranges.initial.y] as [number, number]
1382
- ranges.current.y2 = [...ranges.initial.y2] as [number, number]
1383
- // Also reset axis props so future data changes recalculate auto ranges
1384
- x_axis = { ...x_axis, range: [null, null] }
1385
- x2_axis = { ...x2_axis, range: [null, null] }
1386
- y_axis = { ...y_axis, range: [null, null] }
1387
- y2_axis = { ...y2_axis, range: [null, null] }
1388
- }}
1389
- onmouseleave={() => {
1390
- hovered = false
1391
- hover_info = null
1392
- change(null)
1393
- on_bar_hover?.(null)
1394
- }}
1395
- onwheel={handle_wheel}
1396
- ontouchstart={handle_touch_start}
1397
- ontouchmove={handle_touch_move}
1398
- ontouchend={handle_touch_end}
1399
- style:cursor={pan_drag_state
1400
- ? `grabbing`
1401
- : shift_held && pan?.enabled !== false
1402
- ? `grab`
1403
- : `crosshair`}
1404
- >
1405
- <ZoomRect start={drag_state.start} current={drag_state.current} />
1406
-
1407
- <!-- User content (custom overlays, reference lines, etc.) -->
1408
- {@render user_content?.({
1409
- height,
1410
- width,
1411
- x_scale_fn: scales.x,
1412
- x2_scale_fn: scales.x2,
1413
- y_scale_fn: scales.y,
1414
- y2_scale_fn: scales.y2,
1415
- pad,
1416
- x_range: ranges.current.x,
1417
- x2_range: ranges.current.x2,
1418
- y_range: ranges.current.y,
1419
- y2_range: ranges.current.y2,
1420
- fullscreen,
1421
- })}
1422
-
1423
- <!-- Reference lines: below grid (rendered before axes which contain grid lines) -->
1424
- {@render ref_lines_layer(ref_lines_by_z.below_grid)}
1425
-
1426
- <!-- X-axis -->
1427
- <g class="x-axis">
1428
- <line
1429
- x1={pad.l}
1430
- x2={width - pad.r}
1431
- y1={height - pad.b}
1432
- y2={height - pad.b}
1433
- stroke={x_axis.color || `var(--border-color, gray)`}
1434
- stroke-width="1"
1435
- />
1436
- {#each ticks.x as tick (tick)}
1437
- {@const tick_x = scales.x(tick as number)}
1438
- {#if isFinite(tick_x)}
1439
- {@const rotation = x_axis.tick?.label?.rotation ?? 0}
1440
- {@const shift_x = x_axis.tick?.label?.shift?.x ?? 0}
1441
- {@const shift_y = x_axis.tick?.label?.shift?.y ?? 0}
1442
- {@const inside = x_axis.tick?.label?.inside ?? false}
1443
- {@const base_y = inside ? -8 : (rotation !== 0 ? 8 : 18)}
1444
- {@const text_y = base_y + shift_y}
1445
- {@const text_anchor = rotation !== 0 ? (inside ? `end` : `start`) : `middle`}
1446
- {@const dominant_baseline = inside ? `auto` : `hanging`}
1447
- <g class="tick" transform="translate({tick_x}, {height - pad.b})">
1448
- {#if display.x_grid}
1449
- <line
1450
- y1={-(height - pad.b - pad.t)}
1451
- y2="0"
1452
- {...DEFAULT_GRID_STYLE}
1453
- {...x_axis.grid_style}
1454
- />
1455
- {/if}
1456
- <line
1457
- y1="0"
1458
- y2={inside ? -5 : 5}
1459
- stroke={x_axis.color || `var(--border-color, gray)`}
1460
- stroke-width="1"
1461
- />
1462
- <text
1463
- x={shift_x}
1464
- y={text_y}
1465
- text-anchor={text_anchor}
1466
- dominant-baseline={dominant_baseline}
1467
- fill={x_axis.color || `var(--text-color)`}
1468
- transform={rotation !== 0
1469
- ? `rotate(${rotation}, ${shift_x}, ${text_y})`
1470
- : undefined}
1471
- >
1472
- {
1473
- get_tick_label(
1474
- tick as number,
1475
- cat_axis === `x` ? effective_cat_ticks : x_axis.ticks,
1476
- ) ??
1477
- format_value(tick, x_axis.format)
1478
- }
1479
- </text>
1480
- </g>
1481
- {/if}
1482
- {/each}
1483
- {#if x_axis.label || x_axis.options?.length}
1484
- {@const { label_shift, label = ``, options, selected_key, color } = x_axis}
1485
- <AxisLabel
1486
- x={pad.l + chart_width / 2 + (label_shift?.x ?? 0)}
1487
- y={height - (pad.b / 3) + (label_shift?.y ?? 0)}
1488
- {label}
1489
- {options}
1490
- {selected_key}
1491
- loading={axis_loading === `x`}
1492
- axis_type="x"
1493
- {color}
1494
- on_select={(key) => handle_axis_change(`x`, key)}
1495
- />
1496
- {/if}
1497
- </g>
1498
-
1499
- <!-- X2-axis (Top) -->
1500
- <!-- Note: x2 axis is only supported for vertical orientation -->
1501
- {#if x2_series.length > 0 && orientation === `vertical`}
1502
- <g class="x2-axis">
1503
- <line
1504
- x1={pad.l}
1505
- x2={width - pad.r}
1506
- y1={pad.t}
1507
- y2={pad.t}
1508
- stroke={x2_axis.color || `var(--border-color, gray)`}
1509
- stroke-width="1"
1510
- />
1511
- {#each ticks.x2 as tick (tick)}
1512
- {@const tick_x = scales.x2(tick as number)}
1513
- {#if isFinite(tick_x)}
1514
- {@const rotation = x2_axis.tick?.label?.rotation ?? 0}
1515
- {@const shift_x = x2_axis.tick?.label?.shift?.x ?? 0}
1516
- {@const shift_y = x2_axis.tick?.label?.shift?.y ?? 0}
1517
- {@const inside = x2_axis.tick?.label?.inside ?? false}
1518
- {@const base_y = inside ? 8 : (rotation !== 0 ? -8 : -18)}
1519
- {@const text_y = base_y + shift_y}
1520
- {@const text_anchor = rotation !== 0 ? (inside ? `start` : `end`) : `middle`}
1521
- {@const dominant_baseline = inside ? `hanging` : `auto`}
1522
- <g class="tick" transform="translate({tick_x}, {pad.t})">
1523
- {#if display.x2_grid}
1524
- <line
1525
- y1="0"
1526
- y2={height - pad.b - pad.t}
1527
- {...DEFAULT_GRID_STYLE}
1528
- {...x2_axis.grid_style}
1529
- />
1530
- {/if}
1531
- <line
1532
- y1={inside ? 5 : 0}
1533
- y2={inside ? 0 : -5}
1534
- stroke={x2_axis.color || `var(--border-color, gray)`}
1535
- stroke-width="1"
1536
- />
1537
- <text
1538
- x={shift_x}
1539
- y={text_y}
1540
- text-anchor={text_anchor}
1541
- dominant-baseline={dominant_baseline}
1542
- fill={x2_axis.color || `var(--text-color)`}
1543
- transform={rotation !== 0
1544
- ? `rotate(${rotation}, ${shift_x}, ${text_y})`
1545
- : undefined}
1546
- >
1547
- {
1548
- get_tick_label(tick as number, x2_axis.ticks) ??
1549
- format_value(tick, x2_axis.format)
1550
- }
1551
- </text>
1552
- </g>
1553
- {/if}
1554
- {/each}
1555
- {#if x2_axis.label || x2_axis.options?.length}
1556
- {@const { label_shift, label = ``, options, selected_key, color } = x2_axis}
1557
- <AxisLabel
1558
- x={pad.l + chart_width / 2 + (label_shift?.x ?? 0)}
1559
- y={Math.max(12, pad.t - (label_shift?.y ?? 40))}
1560
- {label}
1561
- {options}
1562
- {selected_key}
1563
- loading={axis_loading === `x2`}
1564
- axis_type="x2"
1565
- {color}
1566
- on_select={(key) => handle_axis_change(`x2`, key)}
1567
- />
1568
- {/if}
1569
- </g>
1570
- {/if}
1571
-
1572
- <!-- Y-axis -->
1573
- <g class="y-axis">
1574
- <line
1575
- x1={pad.l}
1576
- x2={pad.l}
1577
- y1={pad.t}
1578
- y2={height - pad.b}
1579
- stroke={y_axis.color || `var(--border-color, gray)`}
1580
- stroke-width="1"
1581
- />
1582
- {#each ticks.y as tick (tick)}
1583
- {@const tick_y = scales.y(tick as number)}
1584
- {#if isFinite(tick_y)}
1585
- {@const rotation = y_axis.tick?.label?.rotation ?? 0}
1586
- {@const shift_x = y_axis.tick?.label?.shift?.x ?? 0}
1587
- {@const shift_y = y_axis.tick?.label?.shift?.y ?? 0}
1588
- {@const inside = y_axis.tick?.label?.inside ?? false}
1589
- {@const base_x = inside ? 8 : -10}
1590
- {@const text_x = base_x + shift_x}
1591
- {@const text_anchor = inside ? `start` : `end`}
1592
- <g class="tick" transform="translate({pad.l}, {tick_y})">
1593
- {#if display.y_grid}
1594
- <line
1595
- x1="0"
1596
- x2={width - pad.l - pad.r}
1597
- {...DEFAULT_GRID_STYLE}
1598
- {...y_axis.grid_style}
1599
- />
1600
- {/if}
1601
- <line
1602
- x1={inside ? 0 : -5}
1603
- x2={inside ? 5 : 0}
1604
- stroke={y_axis.color || `var(--border-color, gray)`}
1605
- stroke-width="1"
1606
- />
1607
- <text
1608
- x={text_x}
1609
- y={shift_y}
1610
- text-anchor={text_anchor}
1611
- dominant-baseline="central"
1612
- fill={y_axis.color || `var(--text-color)`}
1613
- transform={rotation !== 0
1614
- ? `rotate(${rotation}, ${text_x}, ${shift_y})`
1615
- : undefined}
1616
- >
1617
- {
1618
- get_tick_label(
1619
- tick as number,
1620
- cat_axis === `y` ? effective_cat_ticks : y_axis.ticks,
1621
- ) ??
1622
- format_value(tick, y_axis.format)
1623
- }
1624
- </text>
1625
- </g>
1626
- {/if}
1627
- {/each}
1628
- {#if y_axis.label || y_axis.options?.length}
1629
- {@const { label_shift, label = ``, options, selected_key, color, tick } = y_axis}
1630
- {@const y_inside = tick?.label?.inside ?? false}
1631
- <AxisLabel
1632
- x={Math.max(
1633
- 12,
1634
- pad.l - (y_inside ? 0 : tick_label_widths.y_max) - LABEL_GAP_DEFAULT,
1635
- ) +
1636
- (label_shift?.x ?? 0)}
1637
- y={pad.t + chart_height / 2 + (label_shift?.y ?? 0)}
1638
- rotate
1639
- {label}
1640
- {options}
1641
- {selected_key}
1642
- loading={axis_loading === `y`}
1643
- axis_type="y"
1644
- {color}
1645
- on_select={(key) => handle_axis_change(`y`, key)}
1646
- />
1647
- {/if}
1648
- </g>
1649
-
1650
- <!-- Y2-axis (Right) -->
1651
- <!-- Note: y2 axis is only supported for vertical orientation. Implementing x2 for horizontal mode requires additional complexity. -->
1652
- {#if y2_series.length > 0 && orientation === `vertical`}
1653
- <g class="y2-axis">
1654
- <line
1655
- x1={width - pad.r}
1656
- x2={width - pad.r}
1657
- y1={pad.t}
1658
- y2={height - pad.b}
1659
- stroke={y2_axis.color || `var(--border-color, gray)`}
1660
- stroke-width="1"
1661
- />
1662
- {#each ticks.y2 as tick (tick)}
1663
- {@const tick_y = scales.y2(tick as number)}
1664
- {#if isFinite(tick_y)}
1665
- {@const rotation = y2_axis.tick?.label?.rotation ?? 0}
1666
- {@const inside = y2_axis.tick?.label?.inside ?? false}
1667
- {@const base_x = inside ? -8 : 8}
1668
- {@const shift_x = (y2_axis.tick?.label?.shift?.x ?? 0) + base_x}
1669
- {@const shift_y = y2_axis.tick?.label?.shift?.y ?? 0}
1670
- {@const text_anchor = inside ? `end` : `start`}
1671
- <g class="tick" transform="translate({width - pad.r}, {tick_y})">
1672
- {#if display.y2_grid}
1673
- <line
1674
- x1={-(width - pad.l - pad.r)}
1675
- x2="0"
1676
- {...DEFAULT_GRID_STYLE}
1677
- {...y2_axis.grid_style}
1678
- />
1679
- {/if}
1680
- <line
1681
- x1={inside ? -5 : 0}
1682
- x2={inside ? 0 : 5}
1683
- stroke={y2_axis.color || `var(--border-color, gray)`}
1684
- stroke-width="1"
1685
- />
1686
- <text
1687
- x={shift_x}
1688
- y={shift_y}
1689
- text-anchor={text_anchor}
1690
- dominant-baseline="central"
1691
- fill={y2_axis.color || `var(--text-color)`}
1692
- transform={rotation !== 0
1693
- ? `rotate(${rotation}, ${shift_x}, ${shift_y})`
1694
- : undefined}
1695
- >
1696
- {
1697
- get_tick_label(tick as number, y2_axis.ticks) ??
1698
- format_value(tick, y2_axis.format)
1699
- }
1700
- </text>
1701
- </g>
1702
- {/if}
1703
- {/each}
1704
- {#if y2_axis.label || y2_axis.options?.length}
1705
- {@const { label_shift, label = ``, options, selected_key, color, tick } =
1706
- y2_axis}
1707
- {@const inside = tick?.label?.inside ?? false}
1708
- {@const tick_shift = inside ? 0 : (tick?.label?.shift?.x ?? 0) + 8}
1709
- {@const tick_width_contribution = inside ? 0 : tick_label_widths.y2_max}
1710
- <AxisLabel
1711
- x={width - pad.r + tick_shift + tick_width_contribution +
1712
- LABEL_GAP_DEFAULT + (label_shift?.x ?? 0)}
1713
- y={pad.t + chart_height / 2 + (label_shift?.y ?? 0)}
1714
- rotate
1715
- {label}
1716
- {options}
1717
- {selected_key}
1718
- loading={axis_loading === `y2`}
1719
- axis_type="y2"
1720
- {color}
1721
- on_select={(key) => handle_axis_change(`y2`, key)}
1722
- />
1723
- {/if}
1724
- </g>
1725
- {/if}
1726
-
1727
- <!-- Define clip path for chart area -->
1728
- <defs>
1729
- <clipPath id={clip_path_id}>
1730
- <rect x={pad.l} y={pad.t} width={chart_width} height={chart_height} />
1731
- </clipPath>
1732
- </defs>
1733
-
1734
- <!-- Clipped content: zero lines, bars, and lines -->
1735
- <g clip-path="url(#{clip_path_id})">
1736
- <ZeroLines
1737
- {display}
1738
- x_scale_fn={scales.x}
1739
- x2_scale_fn={scales.x2}
1740
- y_scale_fn={scales.y}
1741
- y2_scale_fn={scales.y2}
1742
- x_range={ranges.current.x}
1743
- x2_range={ranges.current.x2}
1744
- y_range={ranges.current.y}
1745
- y2_range={ranges.current.y2}
1746
- x_scale_type={x_axis.scale_type}
1747
- x2_scale_type={x2_axis.scale_type}
1748
- y_scale_type={y_axis.scale_type}
1749
- y2_scale_type={y2_axis.scale_type}
1750
- x_is_time={x_axis.format?.startsWith(`%`) ?? false}
1751
- x2_is_time={x2_axis.format?.startsWith(`%`) ?? false}
1752
- has_x2={x2_series.length > 0}
1753
- has_y2={y2_series.length > 0}
1754
- {width}
1755
- {height}
1756
- {pad}
1757
- />
1758
-
1759
- <!-- Reference lines: below lines -->
1760
- {@render ref_lines_layer(ref_lines_by_z.below_lines)}
1761
-
1762
- <!-- Bars and Lines -->
1763
- {#each internal_series as srs, series_idx (srs?.id ?? series_idx)}
1764
- {#if srs?.visible ?? true}
1765
- {@const is_line = srs.render_mode === `line`}
1766
- <g
1767
- class={is_line ? `line-series` : `bar-series`}
1768
- data-series-idx={series_idx}
1769
- opacity={hovered_legend_series_idx !== null &&
1770
- hovered_legend_series_idx !== series_idx
1771
- ? 0.25
1772
- : 1}
1773
- >
1774
- {#if is_line}
1775
- <!-- Render as line -->
1776
- {@const color = srs.color ?? line_state.color ?? `steelblue`}
1777
- {@const stroke_width = srs.line_style?.stroke_width ?? line_state.width ?? 2}
1778
- {@const line_dash = srs.line_style?.line_dash ?? `none`}
1779
- {@const use_y2 = srs.y_axis === `y2`}
1780
- {@const y_scale = use_y2 ? scales.y2 : scales.y}
1781
- {@const use_x2 = srs.x_axis === `x2`}
1782
- {@const x_scale = use_x2 ? scales.x2 : scales.x}
1783
- {@const series_markers = srs.markers ?? DEFAULT_MARKERS}
1784
- {@const show_line = series_markers === `line` ||
1785
- series_markers === `line+points`}
1786
- {@const show_points = series_markers === `points` ||
1787
- series_markers === `line+points`}
1788
- {@const points = srs.x.map((x_val, idx) => {
1789
- const y_val = srs.y[idx]
1790
- // Lines don't stack - they show absolute values (useful for totals/trends)
1791
- const plot_x = orientation === `vertical`
1792
- ? x_scale(x_val)
1793
- : x_scale(y_val)
1794
- const plot_y = orientation === `vertical`
1795
- ? y_scale(y_val)
1796
- : scales.y(x_val)
1797
- // Create internal point with all needed data
1798
- const color_value = srs.color_values?.[idx] ?? null
1799
- const size_value = srs.size_values?.[idx] ?? null
1800
- const point_style = process_prop(srs.point_style, idx)
1801
- const point_hover = process_prop(srs.point_hover, idx)
1802
- const point_label = process_prop(srs.point_label, idx)
1803
- const point_offset = process_prop(srs.point_offset, idx)
1804
- const metadata = Array.isArray(srs.metadata)
1805
- ? srs.metadata[idx]
1806
- : srs.metadata
1807
- return {
1808
- x: plot_x,
1809
- y: plot_y,
1810
- data_x: x_val,
1811
- data_y: y_val,
1812
- idx,
1813
- color_value,
1814
- size_value,
1815
- point_style,
1816
- point_hover,
1817
- point_label,
1818
- point_offset,
1819
- metadata,
1820
- series_idx,
1821
- point_idx: idx,
1822
- } as LineSeriesPoint
1823
- }).filter((pt) => isFinite(pt.x) && isFinite(pt.y))}
1824
- {@const polyline_str = show_line && points.length > 1
1825
- ? points.map((pt) => `${pt.x},${pt.y}`).join(` `)
1826
- : ``}
1827
- {#if polyline_str}
1828
- <polyline
1829
- points={polyline_str}
1830
- fill="none"
1831
- stroke={color}
1832
- stroke-width={stroke_width}
1833
- stroke-dasharray={line_dash}
1834
- stroke-linejoin="round"
1835
- stroke-linecap="round"
1836
- />
1837
- {/if}
1838
- {#if polyline_str && !show_points && (on_bar_hover || on_bar_click)}
1839
- <!-- svelte-ignore a11y_no_static_element_interactions -->
1840
- <!-- svelte-ignore a11y_click_events_have_key_events -->
1841
- <polyline
1842
- points={polyline_str}
1843
- fill="none"
1844
- stroke="transparent"
1845
- stroke-width={Math.max(10, stroke_width * 3)}
1846
- stroke-linejoin="round"
1847
- stroke-linecap="round"
1848
- style:cursor={on_bar_click ? `pointer` : undefined}
1849
- onmousemove={(evt) => {
1850
- const pt = find_closest_point(evt, points)
1851
- if (!pt) return
1852
- hovered = true
1853
- const fill = line_point_fill(pt, color)
1854
- hover_info = get_bar_data(series_idx, pt.idx, fill)
1855
- change(hover_info)
1856
- on_bar_hover?.({ ...hover_info!, event: evt })
1857
- }}
1858
- onmouseleave={() => {
1859
- change(null)
1860
- hover_info = null
1861
- on_bar_hover?.(null)
1862
- }}
1863
- onclick={(evt) => {
1864
- const pt = find_closest_point(evt, points)
1865
- if (!pt) return
1866
- const fill = line_point_fill(pt, color)
1867
- const bar_data = get_bar_data(series_idx, pt.idx, fill)
1868
- on_bar_click?.({ ...bar_data, event: evt })
1869
- }}
1870
- />
1871
- {/if}
1872
- {#if show_points}
1873
- {@const clickable = on_bar_click || on_point_click}
1874
- {@const get_pt = (evt: Event) => {
1875
- const attr = evt.target instanceof Element
1876
- ? evt.target.closest(`[data-bar-idx]`)?.getAttribute(
1877
- `data-bar-idx`,
1878
- )
1879
- : null
1880
- return points.find((pt) => pt.idx === parseInt(attr ?? ``, 10))
1881
- }}
1882
- {@const set_hover = (
1883
- pt: LineSeriesPoint | null,
1884
- evt: MouseEvent | FocusEvent,
1885
- ) => {
1886
- if (pt) {
1887
- hovered = true
1888
- const fill = line_point_fill(pt, color)
1889
- hover_info = get_bar_data(series_idx, pt.idx, fill)
1890
- change(hover_info)
1891
- } else {
1892
- change(null)
1893
- hover_info = null
1894
- }
1895
- on_bar_hover?.(pt ? { ...hover_info!, event: evt } : null)
1896
- on_point_hover?.(
1897
- pt ? { ...hover_info!, event: evt, point: pt } : null,
1898
- )
1899
- }}
1900
- {@const do_click = (
1901
- pt: LineSeriesPoint,
1902
- evt: MouseEvent | KeyboardEvent,
1903
- ) => {
1904
- const fill = line_point_fill(pt, color)
1905
- const bar_data = get_bar_data(series_idx, pt.idx, fill)
1906
- on_bar_click?.({ ...bar_data, event: evt })
1907
- on_point_click?.({ ...bar_data, event: evt, point: pt })
1908
- }}
1909
- {@const leaving = (evt: MouseEvent | FocusEvent) =>
1910
- (evt.relatedTarget instanceof Element
1911
- ? evt.relatedTarget.closest(`.line-points`)
1912
- : null) !== evt.currentTarget}
1913
- <!-- svelte-ignore a11y_no_noninteractive_element_interactions, a11y_mouse_events_have_key_events -->
1914
- <g
1915
- class="line-points"
1916
- role="group"
1917
- onmouseover={(evt) => {
1918
- const pt = get_pt(evt)
1919
- if (pt) set_hover(pt, evt)
1920
- }}
1921
- onfocusin={(evt) => {
1922
- const pt = get_pt(evt)
1923
- if (pt) set_hover(pt, evt)
1924
- }}
1925
- onmouseout={(evt) => {
1926
- if (leaving(evt)) set_hover(null, evt)
1927
- }}
1928
- onfocusout={(evt) => {
1929
- if (leaving(evt)) set_hover(null, evt)
1930
- }}
1931
- onclick={(evt) => {
1932
- const pt = get_pt(evt)
1933
- if (pt && clickable) do_click(pt, evt)
1934
- }}
1935
- onkeydown={(evt) => {
1936
- const pt = get_pt(evt)
1937
- if (pt && clickable && (evt.key === `Enter` || evt.key === ` `)) {
1938
- evt.preventDefault()
1939
- do_click(pt, evt)
1940
- }
1941
- }}
1942
- >
1943
- {#each points as pt (pt.idx)}
1944
- {@const sty = pt.point_style}
1945
- {@const fl = line_point_fill(pt, color)}
1946
- {@const rad = pt.size_value != null
1947
- ? size_scale_fn(pt.size_value)
1948
- : sty?.radius ?? 4}
1949
- {@const hov = hover_info?.series_idx === series_idx &&
1950
- hover_info?.bar_idx === pt.idx}
1951
- <ScatterPoint
1952
- x={pt.x}
1953
- y={pt.y}
1954
- is_hovered={hov}
1955
- {point_tween}
1956
- style={{
1957
- ...sty,
1958
- radius: rad,
1959
- fill: fl,
1960
- stroke: sty?.stroke ?? `transparent`,
1961
- stroke_width: sty?.stroke_width ?? 1,
1962
- fill_opacity: sty?.fill_opacity ?? 1,
1963
- stroke_opacity: sty?.stroke_opacity ?? 1,
1964
- cursor: clickable ? `pointer` : undefined,
1965
- }}
1966
- hover={pt.point_hover ?? {}}
1967
- label={pt.point_label ?? {}}
1968
- offset={pt.point_offset ?? { x: 0, y: 0 }}
1969
- origin={{ x: plot_center_x, y: plot_center_y }}
1970
- --point-fill-color={fl}
1971
- data-bar-idx={pt.idx}
1972
- tabindex={clickable ? (hov ? 0 : -1) : undefined}
1973
- />
1974
- {/each}
1975
- </g>
1976
- {/if}
1977
- {:else}
1978
- <!-- Render as bars -->
1979
- {#each srs.x as x_val, bar_idx (bar_idx)}
1980
- {@const y_val = srs.y[bar_idx]}
1981
- {@const base = mode === `stacked`
1982
- ? (stacked_offsets[series_idx]?.[bar_idx] ?? 0)
1983
- : 0}
1984
- {@const color = srs.color ?? bar_state.color ?? `steelblue`}
1985
- {@const bar_width_val = Array.isArray(srs.bar_width)
1986
- ? (srs.bar_width[bar_idx] ?? 0.5)
1987
- : (srs.bar_width ?? 0.5)}
1988
- {@const half = mode === `grouped` && group_info.bar_series_count > 1
1989
- ? bar_width_val / (2 * group_info.bar_series_count)
1990
- : bar_width_val / 2}
1991
- {@const calculate_group_offset = (idx: number) => {
1992
- const position = group_info.bar_series_indices.indexOf(idx)
1993
- const offset = position - (group_info.bar_series_count - 1) / 2
1994
- return offset * (bar_width_val / group_info.bar_series_count)
1995
- }}
1996
- {@const group_offset = mode === `grouped` && group_info.bar_series_count > 1
1997
- ? calculate_group_offset(series_idx)
1998
- : 0}
1999
- {@const is_vertical = orientation === `vertical`}
2000
- {@const cat_val = x_val}
2001
- {@const val = y_val}
2002
- {@const use_y2 = srs.y_axis === `y2`}
2003
- {@const y_scale = use_y2 ? scales.y2 : scales.y}
2004
- {@const use_x2_bar = srs.x_axis === `x2`}
2005
- {@const x_scale_bar = use_x2_bar ? scales.x2 : scales.x}
2006
- {@const [cat_scale, val_scale] = is_vertical
2007
- ? [x_scale_bar, y_scale]
2008
- : [scales.y, x_scale_bar]}
2009
- {@const c0 = cat_scale(cat_val + group_offset - half)}
2010
- {@const c1 = cat_scale(cat_val + group_offset + half)}
2011
- {@const v0 = val_scale(base)}
2012
- {@const v1 = val_scale(base + val)}
2013
- {@const [rect_x, rect_y] = is_vertical
2014
- ? [Math.min(c0, c1), Math.min(v0, v1)]
2015
- : [Math.min(v0, v1), Math.min(c0, c1)]}
2016
- {@const [rect_w, rect_h] = is_vertical
2017
- ? [Math.max(1, Math.abs(c1 - c0)), Math.max(0, Math.abs(v1 - v0))]
2018
- : [Math.max(1, Math.abs(v1 - v0)), Math.max(0, Math.abs(c1 - c0))]}
2019
- {#if (is_vertical ? rect_h : rect_w) > 0}
2020
- <path
2021
- d={bar_path(
2022
- rect_x,
2023
- rect_y,
2024
- rect_w,
2025
- rect_h,
2026
- Math.min(bar_state.border_radius ?? 0, rect_w / 2, rect_h / 2),
2027
- is_vertical,
2028
- )}
2029
- fill={color}
2030
- opacity={mode === `overlay` ? bar_state.opacity : 1}
2031
- stroke={bar_state.stroke_color}
2032
- stroke-opacity={bar_state.stroke_opacity}
2033
- stroke-width={bar_state.stroke_width}
2034
- role="button"
2035
- tabindex="0"
2036
- aria-label={`bar ${bar_idx + 1} of ${srs.label ?? `series`}`}
2037
- style:cursor={on_bar_click ? `pointer` : undefined}
2038
- onmousemove={handle_bar_hover(series_idx, bar_idx, color)}
2039
- onmouseleave={() => {
2040
- hover_info = null
2041
- change(null)
2042
- on_bar_hover?.(null)
2043
- }}
2044
- onclick={(evt) =>
2045
- on_bar_click?.({
2046
- ...get_bar_data(series_idx, bar_idx, color),
2047
- event: evt,
2048
- })}
2049
- onkeydown={(evt) => {
2050
- if (evt.key === `Enter` || evt.key === ` `) {
2051
- evt.preventDefault()
2052
- on_bar_click?.({
2053
- ...get_bar_data(series_idx, bar_idx, color),
2054
- event: evt,
2055
- })
2056
- }
2057
- }}
2058
- />
2059
- {#if srs.labels?.[bar_idx]}
2060
- <text
2061
- x={is_vertical ? (c0 + c1) / 2 : Math.max(v0, v1) + 4}
2062
- y={is_vertical ? Math.max(0, Math.min(v0, v1) - 6) : (c0 + c1) / 2}
2063
- text-anchor={is_vertical ? `middle` : undefined}
2064
- dominant-baseline={is_vertical ? undefined : `central`}
2065
- class="bar-label"
2066
- >
2067
- {srs.labels[bar_idx]}
2068
- </text>
2069
- {/if}
2070
- {/if}
2071
- {/each}
2072
- {/if}
2073
- </g>
2074
- {/if}
2075
- {/each}
2076
-
2077
- <!-- Reference lines: below points -->
2078
- {@render ref_lines_layer(ref_lines_by_z.below_points)}
2079
-
2080
- <!-- Reference lines: above all -->
2081
- {@render ref_lines_layer(ref_lines_by_z.above_all)}
2082
- </g>
2083
- </svg>
2084
-
2085
- <!-- Legend -->
2086
- {#if legend && (show_legend !== undefined ? show_legend : series.length > 1)}
2087
- <PlotLegend
2088
- bind:root_element={legend_element}
2089
- {...legend}
2090
- series_data={legend_data}
2091
- on_toggle={legend?.on_toggle || toggle_series_visibility}
2092
- on_group_toggle={legend?.on_group_toggle || toggle_group_visibility}
2093
- on_hover_change={legend_hover.set_locked}
2094
- on_item_hover={(series_idx) =>
2095
- (hovered_legend_series_idx = series_idx != null && series_idx >= 0
2096
- ? series_idx
2097
- : null)}
2098
- active_series_idx={hover_info?.series_idx ?? hovered_legend_series_idx}
2099
- style={`
2100
- position: absolute;
2101
- left: ${legend_placement ? tweened_legend_coords.current.x : pad.l + 10}px;
2102
- top: ${legend_placement ? tweened_legend_coords.current.y : pad.t + 10}px;
2103
- pointer-events: auto;
2104
- ${legend?.style || ``}
2105
- `}
2106
- />
2107
- {/if}
2108
-
2109
- {#if hover_info && hovered}
2110
- {@const cx = (hover_info.active_x_axis === `x2` ? scales.x2 : scales.x)(
2111
- hover_info.orient_x,
2112
- )}
2113
- {@const cy = (hover_info.active_y_axis === `y2` ? scales.y2 : scales.y)(
2114
- hover_info.orient_y,
2115
- )}
2116
- {@const tooltip_pos = constrain_tooltip_position(
2117
- cx,
2118
- cy,
2119
- tooltip_el?.offsetWidth ?? 140,
2120
- tooltip_el?.offsetHeight ?? 50,
2121
- width,
2122
- height,
2123
- { offset_x: 10, offset_y: 5 },
2124
- )}
2125
- <PlotTooltip
2126
- x={tooltip_pos.x}
2127
- y={tooltip_pos.y}
2128
- offset={{ x: 0, y: 0 }}
2129
- bg_color={hover_info.color}
2130
- bind:wrapper={tooltip_el}
2131
- >
2132
- {#if tooltip}
2133
- {@render tooltip({ ...hover_info, fullscreen })}
2134
- {:else}
2135
- {@const series_label = series[hover_info.series_idx]?.label}
2136
- {#if series.length > 1 && series_label}
2137
- <div><strong>{series_label}</strong></div>
2138
- {/if}
2139
- <div>
2140
- {@html sanitize_html(hover_info.x_axis.label || `x`)}: {
2141
- (cat_axis === `x` ? hover_info.category_label : undefined) ??
2142
- format_value(hover_info.orient_x, hover_info.x_axis.format || `.3~s`)
2143
- }
2144
- </div>
2145
- <div>
2146
- {@html sanitize_html(hover_info.y_axis.label || `y`)}: {
2147
- (cat_axis === `y` ? hover_info.category_label : undefined) ??
2148
- format_value(hover_info.orient_y, hover_info.y_axis.format || `.3~s`)
2149
- }
2150
- </div>
2151
- {/if}
2152
- </PlotTooltip>
2153
- {/if}
2154
-
2155
- {#if show_controls}
2156
- <BarPlotControls
2157
- toggle_props={{
2158
- ...controls_toggle_props,
2159
- style: `--ctrl-btn-right: var(--fullscreen-btn-offset, 30px); ${
2160
- controls_toggle_props?.style ?? ``
2161
- }`,
2162
- }}
2163
- pane_props={controls_pane_props}
2164
- bind:show_controls
2165
- bind:controls_open
2166
- bind:orientation
2167
- bind:mode
2168
- bind:x_axis
2169
- bind:x2_axis
2170
- bind:y_axis
2171
- bind:y2_axis
2172
- bind:display
2173
- auto_x_range={auto_ranges.x as Vec2}
2174
- auto_x2_range={auto_ranges.x2 as Vec2}
2175
- auto_y_range={auto_ranges.y as Vec2}
2176
- auto_y2_range={auto_ranges.y2 as Vec2}
2177
- has_x2_points={x2_series.length > 0}
2178
- has_y2_points={y2_series.length > 0}
2179
- children={controls_extra}
2180
- />
2181
- {/if}
2182
- {/if}
2183
-
2184
- <!-- User-provided children (e.g. for custom absolutely-positioned overlays) -->
2185
- {@render children?.({ height, width, fullscreen })}
2186
- </div>
2187
-
2188
- <style>
2189
- .bar-plot {
2190
- position: relative;
2191
- width: 100%;
2192
- height: var(--barplot-height, auto);
2193
- min-height: var(--barplot-min-height, 300px);
2194
- container-type: size;
2195
- z-index: var(--barplot-z-index, auto);
2196
- border-radius: var(--barplot-border-radius, var(--border-radius, 3pt));
2197
- flex: var(--barplot-flex, 1);
2198
- display: var(--barplot-display, flex);
2199
- flex-direction: column;
2200
- background: var(--barplot-bg, var(--plot-bg));
2201
- }
2202
- .bar-plot.fullscreen {
2203
- position: fixed;
2204
- top: 0;
2205
- left: 0;
2206
- width: 100vw !important;
2207
- height: 100vh !important;
2208
- /* Must be higher than Structure.svelte's --struct-buttons-z-index. */
2209
- z-index: var(--barplot-fullscreen-z-index, var(--z-index-overlay-nav, 100000001));
2210
- margin: 0;
2211
- border-radius: 0;
2212
- background: var(--barplot-fullscreen-bg, var(--barplot-bg, var(--plot-bg)));
2213
- max-height: none !important;
2214
- overflow: hidden;
2215
- /* Add padding to prevent titles from being cropped at top */
2216
- padding-top: var(--plot-fullscreen-padding-top, 2em);
2217
- box-sizing: border-box;
2218
- }
2219
- .header-controls {
2220
- position: absolute;
2221
- top: var(--ctrl-btn-top, 5pt);
2222
- right: var(--fullscreen-btn-right, 4px);
2223
- z-index: var(--fullscreen-btn-z-index, 10);
2224
- display: flex;
2225
- align-items: center;
2226
- gap: 8px;
2227
- }
2228
- .header-controls :global(.fullscreen-toggle) {
2229
- position: static; /* Override absolute positioning since container handles it */
2230
- opacity: 1; /* Always visible when inside header-controls, container controls visibility */
2231
- }
2232
- /* Hide controls and fullscreen toggles by default, show on hover */
2233
- .bar-plot :global(.pane-toggle),
2234
- .bar-plot .header-controls {
2235
- opacity: 0;
2236
- transition: opacity 0.2s, background-color 0.2s;
2237
- }
2238
- .bar-plot:hover :global(.pane-toggle),
2239
- .bar-plot:hover .header-controls,
2240
- .bar-plot :global(.pane-toggle:focus-visible),
2241
- .bar-plot :global(.pane-toggle[aria-expanded='true']),
2242
- .bar-plot .header-controls:focus-within {
2243
- opacity: 1;
2244
- }
2245
- svg {
2246
- width: var(--barplot-svg-width, 100%);
2247
- height: var(--barplot-svg-height, 100%);
2248
- flex: var(--barplot-svg-flex, 1);
2249
- overflow: var(--barplot-svg-overflow, visible);
2250
- fill: var(--text-color);
2251
- font-weight: var(--scatter-font-weight);
2252
- font-size: var(--scatter-font-size);
2253
- }
2254
- .bar-plot.dragover {
2255
- border: var(--barplot-dragover-border, var(--dragover-border));
2256
- background-color: var(--barplot-dragover-bg, var(--dragover-bg));
2257
- }
2258
- g:is(.x-axis, .x2-axis, .y-axis, .y2-axis) .tick text {
2259
- font-size: var(--tick-font-size, 0.8em);
2260
- }
2261
- .bar-label {
2262
- fill: var(--text-color);
2263
- font-size: 11px;
2264
- }
2265
- </style>