matterviz 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (358) hide show
  1. package/dist/EmptyState.svelte +10 -2
  2. package/dist/FilePicker.svelte +154 -96
  3. package/dist/Icon.svelte +20 -14
  4. package/dist/MillerIndexInput.svelte +27 -21
  5. package/dist/api/optimade.js +6 -6
  6. package/dist/app.css +216 -178
  7. package/dist/brillouin/BrillouinZone.svelte +299 -198
  8. package/dist/brillouin/BrillouinZone.svelte.d.ts +1 -1
  9. package/dist/brillouin/BrillouinZoneControls.svelte +32 -5
  10. package/dist/brillouin/BrillouinZoneExportPane.svelte +74 -55
  11. package/dist/brillouin/BrillouinZoneExportPane.svelte.d.ts +1 -1
  12. package/dist/brillouin/BrillouinZoneInfoPane.svelte +99 -68
  13. package/dist/brillouin/BrillouinZoneScene.svelte +277 -165
  14. package/dist/brillouin/BrillouinZoneScene.svelte.d.ts +1 -1
  15. package/dist/brillouin/BrillouinZoneTooltip.svelte +17 -7
  16. package/dist/brillouin/compute.js +11 -6
  17. package/dist/chempot-diagram/ChemPotDiagram.svelte +327 -0
  18. package/dist/chempot-diagram/ChemPotDiagram.svelte.d.ts +13 -0
  19. package/dist/chempot-diagram/ChemPotDiagram2D.svelte +847 -0
  20. package/dist/chempot-diagram/ChemPotDiagram2D.svelte.d.ts +16 -0
  21. package/dist/chempot-diagram/ChemPotDiagram3D.svelte +3194 -0
  22. package/dist/chempot-diagram/ChemPotDiagram3D.svelte.d.ts +16 -0
  23. package/dist/chempot-diagram/ChemPotScene3D.svelte +11 -0
  24. package/dist/chempot-diagram/ChemPotScene3D.svelte.d.ts +7 -0
  25. package/dist/chempot-diagram/async-compute.svelte.d.ts +3 -0
  26. package/dist/chempot-diagram/async-compute.svelte.js +77 -0
  27. package/dist/chempot-diagram/chempot-worker.d.ts +1 -0
  28. package/dist/chempot-diagram/chempot-worker.js +11 -0
  29. package/dist/chempot-diagram/color.d.ts +10 -0
  30. package/dist/chempot-diagram/color.js +32 -0
  31. package/dist/chempot-diagram/compute.d.ts +48 -0
  32. package/dist/chempot-diagram/compute.js +812 -0
  33. package/dist/chempot-diagram/index.d.ts +6 -0
  34. package/dist/chempot-diagram/index.js +6 -0
  35. package/dist/chempot-diagram/pointer.d.ts +16 -0
  36. package/dist/chempot-diagram/pointer.js +40 -0
  37. package/dist/chempot-diagram/temperature.d.ts +15 -0
  38. package/dist/chempot-diagram/temperature.js +36 -0
  39. package/dist/chempot-diagram/types.d.ts +86 -0
  40. package/dist/chempot-diagram/types.js +28 -0
  41. package/dist/colors/index.d.ts +3 -1
  42. package/dist/colors/index.js +9 -3
  43. package/dist/composition/BarChart.svelte +141 -77
  44. package/dist/composition/BubbleChart.svelte +107 -52
  45. package/dist/composition/Composition.svelte +100 -79
  46. package/dist/composition/Formula.svelte +108 -62
  47. package/dist/composition/FormulaFilter.svelte +973 -353
  48. package/dist/composition/FormulaFilter.svelte.d.ts +35 -1
  49. package/dist/composition/PieChart.svelte +199 -99
  50. package/dist/composition/PieChart.svelte.d.ts +1 -1
  51. package/dist/composition/format.d.ts +5 -0
  52. package/dist/composition/format.js +20 -3
  53. package/dist/composition/parse.js +14 -9
  54. package/dist/convex-hull/ConvexHull.svelte +93 -38
  55. package/dist/convex-hull/ConvexHull2D.svelte +551 -393
  56. package/dist/convex-hull/ConvexHull3D.svelte +1303 -825
  57. package/dist/convex-hull/ConvexHull4D.svelte +1012 -686
  58. package/dist/convex-hull/ConvexHullControls.svelte +115 -28
  59. package/dist/convex-hull/ConvexHullInfoPane.svelte +29 -3
  60. package/dist/convex-hull/ConvexHullStats.svelte +821 -249
  61. package/dist/convex-hull/ConvexHullStats.svelte.d.ts +6 -1
  62. package/dist/convex-hull/ConvexHullTooltip.svelte +41 -16
  63. package/dist/convex-hull/GasPressureControls.svelte +104 -61
  64. package/dist/convex-hull/StructurePopup.svelte +25 -4
  65. package/dist/convex-hull/TemperatureSlider.svelte +45 -25
  66. package/dist/convex-hull/barycentric-coords.js +13 -7
  67. package/dist/convex-hull/demo-temperature.d.ts +6 -0
  68. package/dist/convex-hull/demo-temperature.js +40 -0
  69. package/dist/convex-hull/gas-thermodynamics.js +17 -12
  70. package/dist/convex-hull/helpers.d.ts +10 -1
  71. package/dist/convex-hull/helpers.js +79 -38
  72. package/dist/convex-hull/index.d.ts +1 -0
  73. package/dist/convex-hull/index.js +1 -0
  74. package/dist/convex-hull/thermodynamics.d.ts +8 -21
  75. package/dist/convex-hull/thermodynamics.js +163 -69
  76. package/dist/convex-hull/types.d.ts +12 -12
  77. package/dist/convex-hull/types.js +0 -12
  78. package/dist/coordination/CoordinationBarPlot.svelte +232 -176
  79. package/dist/element/BohrAtom.svelte +56 -13
  80. package/dist/element/ElementHeading.svelte +7 -2
  81. package/dist/element/ElementPhoto.svelte +15 -9
  82. package/dist/element/ElementStats.svelte +10 -4
  83. package/dist/element/ElementTile.svelte +137 -73
  84. package/dist/element/Nucleus.svelte +39 -11
  85. package/dist/element/data.js +2 -14
  86. package/dist/element/data.json.gz +0 -0
  87. package/dist/element/types.d.ts +1 -0
  88. package/dist/feedback/ClickFeedback.svelte +16 -5
  89. package/dist/feedback/DragOverlay.svelte +10 -2
  90. package/dist/feedback/Spinner.svelte +4 -2
  91. package/dist/feedback/StatusMessage.svelte +8 -2
  92. package/dist/fermi-surface/FermiSlice.svelte +118 -88
  93. package/dist/fermi-surface/FermiSurface.svelte +336 -239
  94. package/dist/fermi-surface/FermiSurface.svelte.d.ts +1 -1
  95. package/dist/fermi-surface/FermiSurfaceControls.svelte +113 -46
  96. package/dist/fermi-surface/FermiSurfaceScene.svelte +536 -343
  97. package/dist/fermi-surface/FermiSurfaceScene.svelte.d.ts +1 -1
  98. package/dist/fermi-surface/FermiSurfaceTooltip.svelte +14 -5
  99. package/dist/fermi-surface/compute.js +16 -20
  100. package/dist/fermi-surface/parse.js +37 -33
  101. package/dist/fermi-surface/symmetry.js +2 -7
  102. package/dist/fermi-surface/types.d.ts +3 -5
  103. package/dist/heatmap-matrix/HeatmapMatrix.svelte +1527 -0
  104. package/dist/heatmap-matrix/HeatmapMatrix.svelte.d.ts +110 -0
  105. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte +225 -0
  106. package/dist/heatmap-matrix/HeatmapMatrixControls.svelte.d.ts +30 -0
  107. package/dist/heatmap-matrix/index.d.ts +53 -0
  108. package/dist/heatmap-matrix/index.js +100 -0
  109. package/dist/heatmap-matrix/shared.d.ts +2 -0
  110. package/dist/heatmap-matrix/shared.js +4 -0
  111. package/dist/icons.d.ts +111 -0
  112. package/dist/icons.js +158 -0
  113. package/dist/index.d.ts +5 -2
  114. package/dist/index.js +5 -2
  115. package/dist/io/decompress.js +1 -1
  116. package/dist/io/export.d.ts +3 -0
  117. package/dist/io/export.js +138 -140
  118. package/dist/io/file-drop.d.ts +7 -0
  119. package/dist/io/file-drop.js +43 -0
  120. package/dist/io/index.d.ts +2 -2
  121. package/dist/io/index.js +2 -112
  122. package/dist/io/is-binary.js +2 -3
  123. package/dist/io/types.d.ts +1 -0
  124. package/dist/io/url-drop.d.ts +2 -0
  125. package/dist/io/url-drop.js +117 -0
  126. package/dist/isosurface/Isosurface.svelte +220 -110
  127. package/dist/isosurface/IsosurfaceControls.svelte +65 -28
  128. package/dist/isosurface/parse.js +104 -56
  129. package/dist/isosurface/slice.d.ts +2 -1
  130. package/dist/isosurface/slice.js +8 -13
  131. package/dist/isosurface/types.d.ts +14 -1
  132. package/dist/isosurface/types.js +152 -5
  133. package/dist/labels.d.ts +2 -1
  134. package/dist/labels.js +12 -8
  135. package/dist/layout/FullscreenToggle.svelte +11 -2
  136. package/dist/layout/InfoCard.svelte +38 -6
  137. package/dist/layout/InfoTag.svelte +125 -94
  138. package/dist/layout/PropertyFilter.svelte +82 -37
  139. package/dist/layout/SettingsSection.svelte +85 -55
  140. package/dist/layout/SubpageGrid.svelte +82 -0
  141. package/dist/layout/SubpageGrid.svelte.d.ts +14 -0
  142. package/dist/layout/index.d.ts +1 -0
  143. package/dist/layout/index.js +1 -0
  144. package/dist/layout/json-tree/JsonNode.svelte +266 -223
  145. package/dist/layout/json-tree/JsonTree.svelte +516 -429
  146. package/dist/layout/json-tree/JsonTree.svelte.d.ts +1 -1
  147. package/dist/layout/json-tree/JsonValue.svelte +281 -173
  148. package/dist/layout/json-tree/types.d.ts +10 -2
  149. package/dist/layout/json-tree/utils.d.ts +2 -0
  150. package/dist/layout/json-tree/utils.js +37 -2
  151. package/dist/marching-cubes.js +25 -2
  152. package/dist/math.d.ts +20 -17
  153. package/dist/math.js +474 -57
  154. package/dist/overlays/ContextMenu.svelte +66 -40
  155. package/dist/overlays/DraggablePane.svelte +331 -154
  156. package/dist/overlays/DraggablePane.svelte.d.ts +2 -0
  157. package/dist/periodic-table/PeriodicTable.svelte +278 -145
  158. package/dist/periodic-table/PeriodicTableControls.svelte +178 -128
  159. package/dist/periodic-table/PropertySelect.svelte +25 -7
  160. package/dist/periodic-table/TableInset.svelte +8 -3
  161. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte +559 -267
  162. package/dist/phase-diagram/IsobaricBinaryPhaseDiagram.svelte.d.ts +6 -2
  163. package/dist/phase-diagram/PhaseDiagramControls.svelte +131 -51
  164. package/dist/phase-diagram/PhaseDiagramControls.svelte.d.ts +3 -2
  165. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte +126 -0
  166. package/dist/phase-diagram/PhaseDiagramEditorPane.svelte.d.ts +15 -0
  167. package/dist/phase-diagram/PhaseDiagramExportPane.svelte +160 -110
  168. package/dist/phase-diagram/PhaseDiagramExportPane.svelte.d.ts +8 -1
  169. package/dist/phase-diagram/PhaseDiagramTooltip.svelte +217 -86
  170. package/dist/phase-diagram/PhaseDiagramTooltip.svelte.d.ts +6 -3
  171. package/dist/phase-diagram/TdbInfoPanel.svelte +28 -4
  172. package/dist/phase-diagram/build-diagram.js +9 -9
  173. package/dist/phase-diagram/colors.js +1 -3
  174. package/dist/phase-diagram/index.d.ts +2 -0
  175. package/dist/phase-diagram/index.js +2 -0
  176. package/dist/phase-diagram/parse.js +10 -9
  177. package/dist/phase-diagram/svg-to-diagram.d.ts +2 -0
  178. package/dist/phase-diagram/svg-to-diagram.js +869 -0
  179. package/dist/phase-diagram/types.d.ts +10 -0
  180. package/dist/phase-diagram/utils.d.ts +8 -4
  181. package/dist/phase-diagram/utils.js +219 -74
  182. package/dist/plot/AxisLabel.svelte +51 -0
  183. package/dist/plot/AxisLabel.svelte.d.ts +16 -0
  184. package/dist/plot/BarPlot.svelte +1461 -768
  185. package/dist/plot/BarPlot.svelte.d.ts +3 -3
  186. package/dist/plot/BarPlotControls.svelte +33 -6
  187. package/dist/plot/BarPlotControls.svelte.d.ts +1 -1
  188. package/dist/plot/ColorBar.svelte +533 -383
  189. package/dist/plot/ColorBar.svelte.d.ts +1 -1
  190. package/dist/plot/ColorScaleSelect.svelte +28 -7
  191. package/dist/plot/ElementScatter.svelte +38 -16
  192. package/dist/plot/FillArea.svelte +152 -92
  193. package/dist/plot/Histogram.svelte +1162 -709
  194. package/dist/plot/Histogram.svelte.d.ts +1 -1
  195. package/dist/plot/HistogramControls.svelte +81 -18
  196. package/dist/plot/HistogramControls.svelte.d.ts +6 -2
  197. package/dist/plot/InteractiveAxisLabel.svelte +34 -11
  198. package/dist/plot/InteractiveAxisLabel.svelte.d.ts +1 -1
  199. package/dist/plot/Line.svelte +63 -28
  200. package/dist/plot/PlotControls.svelte +221 -96
  201. package/dist/plot/PlotControls.svelte.d.ts +1 -1
  202. package/dist/plot/PlotLegend.svelte +174 -91
  203. package/dist/plot/PlotTooltip.svelte +45 -6
  204. package/dist/plot/PortalSelect.svelte +175 -146
  205. package/dist/plot/ReferenceLine.svelte +77 -22
  206. package/dist/plot/ReferenceLine.svelte.d.ts +1 -0
  207. package/dist/plot/ReferenceLine3D.svelte +132 -107
  208. package/dist/plot/ReferencePlane.svelte +146 -123
  209. package/dist/plot/ScatterPlot.svelte +1880 -1156
  210. package/dist/plot/ScatterPlot.svelte.d.ts +3 -3
  211. package/dist/plot/ScatterPlot3D.svelte +256 -131
  212. package/dist/plot/ScatterPlot3D.svelte.d.ts +2 -2
  213. package/dist/plot/ScatterPlot3DControls.svelte +300 -297
  214. package/dist/plot/ScatterPlot3DControls.svelte.d.ts +2 -1
  215. package/dist/plot/ScatterPlot3DScene.svelte +608 -406
  216. package/dist/plot/ScatterPlot3DScene.svelte.d.ts +2 -2
  217. package/dist/plot/ScatterPlotControls.svelte +150 -70
  218. package/dist/plot/ScatterPlotControls.svelte.d.ts +1 -1
  219. package/dist/plot/ScatterPoint.svelte +98 -26
  220. package/dist/plot/ScatterPoint.svelte.d.ts +1 -0
  221. package/dist/plot/SpacegroupBarPlot.svelte +142 -85
  222. package/dist/plot/Surface3D.svelte +159 -108
  223. package/dist/plot/ZeroLines.svelte +96 -0
  224. package/dist/plot/ZeroLines.svelte.d.ts +32 -0
  225. package/dist/plot/ZoomRect.svelte +23 -0
  226. package/dist/plot/ZoomRect.svelte.d.ts +8 -0
  227. package/dist/plot/axis-utils.d.ts +1 -1
  228. package/dist/plot/axis-utils.js +1 -3
  229. package/dist/plot/data-cleaning.js +12 -28
  230. package/dist/plot/data-transform.js +2 -1
  231. package/dist/plot/fill-utils.js +2 -0
  232. package/dist/plot/index.d.ts +6 -2
  233. package/dist/plot/index.js +6 -2
  234. package/dist/plot/interactions.d.ts +8 -10
  235. package/dist/plot/interactions.js +2 -3
  236. package/dist/plot/layout.d.ts +11 -2
  237. package/dist/plot/layout.js +44 -17
  238. package/dist/plot/reference-line.d.ts +5 -22
  239. package/dist/plot/reference-line.js +12 -84
  240. package/dist/plot/scales.js +24 -36
  241. package/dist/plot/types.d.ts +53 -40
  242. package/dist/plot/types.js +12 -7
  243. package/dist/plot/utils/label-placement.d.ts +32 -15
  244. package/dist/plot/utils/label-placement.js +227 -63
  245. package/dist/plot/utils/series-visibility.js +2 -3
  246. package/dist/plot/utils.d.ts +1 -0
  247. package/dist/plot/utils.js +14 -0
  248. package/dist/rdf/RdfPlot.svelte +173 -132
  249. package/dist/rdf/calc-rdf.js +4 -5
  250. package/dist/sanitize.d.ts +4 -0
  251. package/dist/sanitize.js +107 -0
  252. package/dist/settings.d.ts +21 -6
  253. package/dist/settings.js +63 -19
  254. package/dist/spectral/Bands.svelte +963 -412
  255. package/dist/spectral/Bands.svelte.d.ts +22 -2
  256. package/dist/spectral/BandsAndDos.svelte +90 -49
  257. package/dist/spectral/BrillouinBandsDos.svelte +151 -93
  258. package/dist/spectral/Dos.svelte +389 -258
  259. package/dist/spectral/helpers.d.ts +23 -1
  260. package/dist/spectral/helpers.js +119 -51
  261. package/dist/spectral/types.d.ts +2 -0
  262. package/dist/state.svelte.d.ts +1 -1
  263. package/dist/state.svelte.js +3 -2
  264. package/dist/structure/Arrow.svelte +59 -20
  265. package/dist/structure/AtomLegend.svelte +231 -129
  266. package/dist/structure/AtomLegend.svelte.d.ts +1 -1
  267. package/dist/structure/Bond.svelte +73 -47
  268. package/dist/structure/CanvasTooltip.svelte +10 -2
  269. package/dist/structure/CellSelect.svelte +148 -51
  270. package/dist/structure/Cylinder.svelte +33 -17
  271. package/dist/structure/Lattice.svelte +88 -33
  272. package/dist/structure/Structure.svelte +1077 -821
  273. package/dist/structure/Structure.svelte.d.ts +1 -1
  274. package/dist/structure/StructureControls.svelte +373 -139
  275. package/dist/structure/StructureControls.svelte.d.ts +1 -1
  276. package/dist/structure/StructureExportPane.svelte +124 -89
  277. package/dist/structure/StructureExportPane.svelte.d.ts +1 -1
  278. package/dist/structure/StructureInfoPane.svelte +304 -231
  279. package/dist/structure/StructureScene.svelte +919 -445
  280. package/dist/structure/StructureScene.svelte.d.ts +16 -7
  281. package/dist/structure/atom-properties.d.ts +6 -2
  282. package/dist/structure/atom-properties.js +42 -29
  283. package/dist/structure/bonding.js +6 -7
  284. package/dist/structure/export.js +22 -34
  285. package/dist/structure/ferrox-wasm-types.d.ts +3 -2
  286. package/dist/structure/ferrox-wasm-types.js +0 -3
  287. package/dist/structure/ferrox-wasm.d.ts +3 -2
  288. package/dist/structure/ferrox-wasm.js +2 -3
  289. package/dist/structure/index.d.ts +16 -0
  290. package/dist/structure/index.js +88 -6
  291. package/dist/structure/measure.d.ts +2 -2
  292. package/dist/structure/measure.js +4 -44
  293. package/dist/structure/parse.js +130 -155
  294. package/dist/structure/partial-occupancy.d.ts +25 -0
  295. package/dist/structure/partial-occupancy.js +99 -0
  296. package/dist/structure/pbc.d.ts +1 -0
  297. package/dist/structure/pbc.js +16 -6
  298. package/dist/structure/supercell.d.ts +2 -2
  299. package/dist/structure/supercell.js +12 -22
  300. package/dist/structure/validation.js +5 -3
  301. package/dist/symmetry/SymmetryStats.svelte +94 -37
  302. package/dist/symmetry/WyckoffTable.svelte +42 -14
  303. package/dist/symmetry/cell-transform.js +5 -3
  304. package/dist/symmetry/index.d.ts +7 -4
  305. package/dist/symmetry/index.js +87 -21
  306. package/dist/symmetry/spacegroups.js +148 -148
  307. package/dist/table/HeatmapTable.svelte +1112 -516
  308. package/dist/table/HeatmapTable.svelte.d.ts +12 -1
  309. package/dist/table/ToggleMenu.svelte +125 -90
  310. package/dist/table/index.d.ts +2 -0
  311. package/dist/table/index.js +2 -4
  312. package/dist/theme/ThemeControl.svelte +21 -12
  313. package/dist/time.js +4 -1
  314. package/dist/tooltip/TooltipContent.svelte +33 -8
  315. package/dist/trajectory/Trajectory.svelte +889 -687
  316. package/dist/trajectory/TrajectoryError.svelte +14 -3
  317. package/dist/trajectory/TrajectoryExportPane.svelte +148 -90
  318. package/dist/trajectory/TrajectoryExportPane.svelte.d.ts +1 -1
  319. package/dist/trajectory/TrajectoryInfoPane.svelte +272 -143
  320. package/dist/trajectory/constants.d.ts +6 -0
  321. package/dist/trajectory/constants.js +7 -0
  322. package/dist/trajectory/extract.js +13 -31
  323. package/dist/trajectory/format-detect.d.ts +9 -0
  324. package/dist/trajectory/format-detect.js +76 -0
  325. package/dist/trajectory/frame-reader.d.ts +17 -0
  326. package/dist/trajectory/frame-reader.js +332 -0
  327. package/dist/trajectory/helpers.d.ts +14 -0
  328. package/dist/trajectory/helpers.js +172 -0
  329. package/dist/trajectory/index.d.ts +1 -0
  330. package/dist/trajectory/index.js +23 -14
  331. package/dist/trajectory/parse/ase.d.ts +2 -0
  332. package/dist/trajectory/parse/ase.js +77 -0
  333. package/dist/trajectory/parse/hdf5.d.ts +2 -0
  334. package/dist/trajectory/parse/hdf5.js +129 -0
  335. package/dist/trajectory/parse/index.d.ts +12 -0
  336. package/dist/trajectory/parse/index.js +299 -0
  337. package/dist/trajectory/parse/lammps.d.ts +5 -0
  338. package/dist/trajectory/parse/lammps.js +179 -0
  339. package/dist/trajectory/parse/vasp.d.ts +2 -0
  340. package/dist/trajectory/parse/vasp.js +68 -0
  341. package/dist/trajectory/parse/xyz.d.ts +2 -0
  342. package/dist/trajectory/parse/xyz.js +110 -0
  343. package/dist/trajectory/plotting.js +13 -8
  344. package/dist/trajectory/types.d.ts +11 -0
  345. package/dist/trajectory/types.js +1 -0
  346. package/dist/utils.d.ts +3 -0
  347. package/dist/utils.js +17 -0
  348. package/dist/xrd/XrdPlot.svelte +337 -245
  349. package/dist/xrd/broadening.js +14 -9
  350. package/dist/xrd/calc-xrd.js +12 -19
  351. package/dist/xrd/parse.d.ts +1 -1
  352. package/dist/xrd/parse.js +17 -17
  353. package/package.json +103 -101
  354. package/readme.md +4 -4
  355. package/dist/trajectory/parse.d.ts +0 -42
  356. package/dist/trajectory/parse.js +0 -1267
  357. /package/dist/element/{data.json.d.ts → data.json.gz.d.ts} +0 -0
  358. /package/dist/theme/{themes.js → themes.mjs} +0 -0
@@ -1,20 +1,148 @@
1
1
  import { is_time_scale } from '../types';
2
- import { forceCollide, forceLink, forceManyBody, forceSimulation } from 'd3-force';
3
- function parse_font_size(size_str) {
2
+ const DEFAULT_WEIGHTS = {
3
+ overlap: 30,
4
+ marker: 100,
5
+ leader_cross: 10,
6
+ leader_text: 8,
7
+ distance: 0.5,
8
+ bounds: 100,
9
+ };
10
+ export function parse_font_size(size_str) {
4
11
  if (!size_str)
5
12
  return 12;
6
- const match = size_str.match(/^(\d+(?:\.\d+)?)(px|em|rem)?$/);
13
+ const match = /^(\d+(?:\.\d+)?)(px|em|rem)?$/.exec(size_str);
7
14
  if (!match)
8
15
  return 12;
9
16
  const value = parseFloat(match[1]);
10
17
  return match[2] === `em` || match[2] === `rem` ? value * 16 : value;
11
18
  }
19
+ // === Geometry helpers ===
20
+ export function rect_overlap_area(a, b) {
21
+ const ox = Math.max(0, Math.min(a.x + a.w, b.x + b.w) - Math.max(a.x, b.x));
22
+ const oy = Math.max(0, Math.min(a.y + a.h, b.y + b.h) - Math.max(a.y, b.y));
23
+ return ox * oy;
24
+ }
25
+ export function rect_circle_overlap(rect, cx, cy, radius) {
26
+ // Inflate rect by radius to create an exclusion zone around the marker
27
+ const left = rect.x - radius;
28
+ const top = rect.y - radius;
29
+ const right = rect.x + rect.w + radius;
30
+ const bottom = rect.y + rect.h + radius;
31
+ if (cx < left || cx > right || cy < top || cy > bottom)
32
+ return 0;
33
+ // Penalty proportional to how deep the marker center is inside the exclusion zone
34
+ const dx = Math.min(cx - left, right - cx);
35
+ const dy = Math.min(cy - top, bottom - cy);
36
+ return Math.min(dx, dy) + radius;
37
+ }
38
+ export function segments_intersect(ax1, ay1, ax2, ay2, bx1, by1, bx2, by2) {
39
+ const d1x = ax2 - ax1, d1y = ay2 - ay1;
40
+ const d2x = bx2 - bx1, d2y = by2 - by1;
41
+ const cross = d1x * d2y - d1y * d2x;
42
+ if (Math.abs(cross) < 1e-10)
43
+ return false;
44
+ const t_val = ((bx1 - ax1) * d2y - (by1 - ay1) * d2x) / cross;
45
+ const u_val = ((bx1 - ax1) * d1y - (by1 - ay1) * d1x) / cross;
46
+ return t_val > 0 && t_val < 1 && u_val > 0 && u_val < 1;
47
+ }
48
+ export function segment_rect_intersects(sx1, sy1, sx2, sy2, rect) {
49
+ const rx = rect.x, ry = rect.y, rx2 = rx + rect.w, ry2 = ry + rect.h;
50
+ return (segments_intersect(sx1, sy1, sx2, sy2, rx, ry, rx2, ry) ||
51
+ segments_intersect(sx1, sy1, sx2, sy2, rx2, ry, rx2, ry2) ||
52
+ segments_intersect(sx1, sy1, sx2, sy2, rx, ry2, rx2, ry2) ||
53
+ segments_intersect(sx1, sy1, sx2, sy2, rx, ry, rx, ry2));
54
+ }
55
+ export function rect_out_of_bounds_area(rect, bounds) {
56
+ let penalty = 0;
57
+ if (rect.x < bounds.min_x)
58
+ penalty += (bounds.min_x - rect.x) * rect.h;
59
+ if (rect.y < bounds.min_y)
60
+ penalty += (bounds.min_y - rect.y) * rect.w;
61
+ if (rect.x + rect.w > bounds.max_x)
62
+ penalty += (rect.x + rect.w - bounds.max_x) * rect.h;
63
+ if (rect.y + rect.h > bounds.max_y)
64
+ penalty += (rect.y + rect.h - bounds.max_y) * rect.w;
65
+ return penalty;
66
+ }
67
+ // 8 candidate positions around anchor: R, TR, T, TL, L, BL, B, BR
68
+ // Positions are top-left corner of the label bounding box.
69
+ // All positions keep a full `offset` gap from the marker edge.
70
+ export function generate_candidates(ax, ay, point_radius, label_w, label_h, gap) {
71
+ const offset = point_radius + gap;
72
+ return [
73
+ { x: ax + offset, y: ay - label_h + offset / 2 }, // R (baseline just below center)
74
+ { x: ax + offset, y: ay - label_h - offset / 2 }, // TR
75
+ { x: ax - label_w / 2, y: ay - label_h - offset }, // T
76
+ { x: ax - label_w - offset, y: ay - label_h - offset / 2 }, // TL
77
+ { x: ax - label_w - offset, y: ay - label_h + offset / 2 }, // L (baseline just below center)
78
+ { x: ax - label_w - offset, y: ay + offset / 2 }, // BL
79
+ { x: ax - label_w / 2, y: ay + offset }, // B
80
+ { x: ax + offset, y: ay + offset / 2 }, // BR
81
+ ];
82
+ }
83
+ // Compute energy delta when only label at `changed_idx` moves
84
+ export function compute_delta_energy(labels, anchors, changed_idx, old_state, new_state, weights, bounds) {
85
+ let delta = 0;
86
+ const anchor = anchors[new_state.anchor_idx];
87
+ const old_cx = old_state.x + old_state.w / 2, old_cy = old_state.y + old_state.h / 2;
88
+ const new_cx = new_state.x + new_state.w / 2, new_cy = new_state.y + new_state.h / 2;
89
+ // Distance penalty change
90
+ delta +=
91
+ weights.distance *
92
+ (Math.hypot(new_cx - anchor.x, new_cy - anchor.y) -
93
+ Math.hypot(old_cx - anchor.x, old_cy - anchor.y));
94
+ // Bounds penalty change
95
+ delta +=
96
+ weights.bounds *
97
+ (rect_out_of_bounds_area(new_state, bounds) - rect_out_of_bounds_area(old_state, bounds));
98
+ // Marker overlap change (all markers)
99
+ for (const marker of anchors) {
100
+ delta +=
101
+ weights.marker *
102
+ (rect_circle_overlap(new_state, marker.x, marker.y, marker.radius) -
103
+ rect_circle_overlap(old_state, marker.x, marker.y, marker.radius));
104
+ }
105
+ // Pairwise interactions with all other labels
106
+ for (let jdx = 0; jdx < labels.length; jdx++) {
107
+ if (jdx === changed_idx)
108
+ continue;
109
+ const other = labels[jdx];
110
+ const anchor_j = anchors[other.anchor_idx];
111
+ const other_cx = other.x + other.w / 2, other_cy = other.y + other.h / 2;
112
+ // Label-label overlap delta
113
+ delta +=
114
+ weights.overlap *
115
+ (rect_overlap_area(new_state, other) - rect_overlap_area(old_state, other));
116
+ // Leader line crossing delta (changed label's leader vs other's leader)
117
+ const old_cross = segments_intersect(anchor.x, anchor.y, old_cx, old_cy, anchor_j.x, anchor_j.y, other_cx, other_cy);
118
+ const new_cross = segments_intersect(anchor.x, anchor.y, new_cx, new_cy, anchor_j.x, anchor_j.y, other_cx, other_cy);
119
+ if (new_cross !== old_cross)
120
+ delta += (new_cross ? 1 : -1) * weights.leader_cross;
121
+ // Changed label's leader crossing other label's rect
122
+ const old_text = segment_rect_intersects(anchor.x, anchor.y, old_cx, old_cy, other);
123
+ const new_text = segment_rect_intersects(anchor.x, anchor.y, new_cx, new_cy, other);
124
+ if (new_text !== old_text)
125
+ delta += (new_text ? 1 : -1) * weights.leader_text;
126
+ // Other label's leader crossing changed label's rect
127
+ const old_other = segment_rect_intersects(anchor_j.x, anchor_j.y, other_cx, other_cy, old_state);
128
+ const new_other = segment_rect_intersects(anchor_j.x, anchor_j.y, other_cx, other_cy, new_state);
129
+ if (new_other !== old_other)
130
+ delta += (new_other ? 1 : -1) * weights.leader_text;
131
+ }
132
+ return delta;
133
+ }
134
+ // === Main export ===
12
135
  export function compute_label_positions(filtered_series, config, scales, bounds) {
13
- const { width, height, pad } = bounds;
14
136
  const { x_scale_fn, y_scale_fn, y2_scale_fn, x_axis } = scales;
15
- const label_nodes = [];
16
- const anchor_nodes = [];
17
- const links = [];
137
+ const { width, height, pad } = bounds;
138
+ const plot_bounds = {
139
+ min_x: pad.l,
140
+ min_y: pad.t,
141
+ max_x: width - pad.r,
142
+ max_y: height - pad.b,
143
+ };
144
+ // Collect all label data in a single pass
145
+ const label_infos = [];
18
146
  for (const series of filtered_series) {
19
147
  for (const pt of series.filtered_data ?? []) {
20
148
  if (!pt.point_label?.auto_placement || !pt.point_label.text)
@@ -23,70 +151,106 @@ export function compute_label_positions(filtered_series, config, scales, bounds)
23
151
  ? x_scale_fn(new Date(pt.x))
24
152
  : x_scale_fn(pt.x);
25
153
  const ay = (series.y_axis === `y2` ? y2_scale_fn : y_scale_fn)(pt.y);
26
- const id = `${pt.series_idx}-${pt.point_idx}`;
27
154
  const font_size = parse_font_size(pt.point_label.font_size);
28
- const w = pt.point_label.text.length * font_size * 0.6 + 10;
29
- const h = font_size * 1.2;
30
- const r = pt.point_style?.radius ?? 3;
31
- label_nodes.push({
32
- id,
33
- anchor_x: ax,
34
- anchor_y: ay,
35
- point_node: pt,
36
- label_width: w,
37
- label_height: h,
38
- x: ax + (pt.point_label.offset?.x ?? 5),
39
- y: ay + (pt.point_label.offset?.y ?? r + h / 2 + 3),
155
+ const label_w = pt.point_label.text.length * font_size * 0.6 + 10;
156
+ const label_h = font_size * 1.2;
157
+ const radius = pt.point_style?.radius ?? 3;
158
+ label_infos.push({
159
+ id: `${pt.series_idx}-${pt.point_idx}`,
160
+ anchor: { x: ax, y: ay, radius },
161
+ width: label_w,
162
+ height: label_h,
163
+ candidates: generate_candidates(ax, ay, radius, label_w, label_h, 4),
40
164
  });
41
- anchor_nodes.push({ id: `anchor-${id}`, fx: ax, fy: ay, point_radius: r });
42
- links.push({ source: id, target: `anchor-${id}` });
43
165
  }
44
166
  }
45
- if (label_nodes.length === 0)
167
+ const num_labels = label_infos.length;
168
+ if (num_labels === 0)
46
169
  return {};
47
- if (config.max_labels && label_nodes.length > config.max_labels) {
48
- return Object.fromEntries(label_nodes.map((n) => [n.id, { x: n.x ?? 0, y: n.y ?? 0 }]));
170
+ // Fallback: too many labels, just offset to the right with bounds clamping
171
+ if (config.max_labels && num_labels > config.max_labels) {
172
+ return Object.fromEntries(label_infos.map((info) => [
173
+ info.id,
174
+ {
175
+ x: Math.min(Math.max(info.anchor.x + 5, plot_bounds.min_x), plot_bounds.max_x - info.width),
176
+ y: Math.min(Math.max(info.anchor.y, plot_bounds.min_y), plot_bounds.max_y - info.height),
177
+ },
178
+ ]));
49
179
  }
50
- const sim = forceSimulation([...label_nodes, ...anchor_nodes])
51
- .force(`link`, forceLink(links).id((d) => d.id).distance(config.link_distance)
52
- .strength(config.link_strength))
53
- .force(`collide`, forceCollide().radius((n) => {
54
- const l = n;
55
- const a = n;
56
- return l.label_width
57
- ? Math.sqrt(l.label_width ** 2 + l.label_height ** 2) / 2 + 2
58
- : (a.point_radius ?? 0) + 2;
59
- }).strength(config.collision_strength))
60
- .force(`charge`, forceManyBody().strength((n) => {
61
- const a = n;
62
- return a.point_radius !== undefined && a.fx !== undefined
63
- ? -(config.charge_strength ?? 50)
64
- : 0;
65
- }).distanceMax(config.charge_distance_max ?? 30));
66
- sim.stop().tick(config.placement_ticks);
67
- const [min_dist, max_dist] = config.link_distance_range ?? [null, null];
68
- const result = {};
69
- for (const node of label_nodes) {
70
- const node_x = node.x ?? 0;
71
- const node_y = node.y ?? 0;
72
- let x = Math.max(pad.l + node.label_width / 2, Math.min(width - pad.r - node.label_width / 2, node_x));
73
- let y = Math.max(pad.t + node.label_height / 2, Math.min(height - pad.b - node.label_height / 2, node_y));
74
- if (min_dist || max_dist) {
75
- const dx = x - node.anchor_x;
76
- const dy = y - node.anchor_y;
77
- const dist = Math.hypot(dx, dy);
78
- if (max_dist && dist > max_dist) {
79
- const s = max_dist / dist;
80
- x = node.anchor_x + dx * s;
81
- y = node.anchor_y + dy * s;
180
+ const weights = { ...DEFAULT_WEIGHTS, ...config.weights };
181
+ const anchors = label_infos.map((info) => info.anchor);
182
+ // Greedy initialization: pick best candidate per label
183
+ const labels = [];
184
+ for (let idx = 0; idx < num_labels; idx++) {
185
+ const { candidates, width: lw, height: lh, anchor } = label_infos[idx];
186
+ let best_candidate = candidates[0];
187
+ let best_score = Infinity;
188
+ for (const candidate of candidates) {
189
+ const test_rect = { x: candidate.x, y: candidate.y, w: lw, h: lh };
190
+ let score = weights.bounds * rect_out_of_bounds_area(test_rect, plot_bounds);
191
+ for (const placed of labels) {
192
+ score += weights.overlap * rect_overlap_area(test_rect, placed);
193
+ }
194
+ for (const marker of anchors) {
195
+ score +=
196
+ weights.marker * rect_circle_overlap(test_rect, marker.x, marker.y, marker.radius);
82
197
  }
83
- else if (min_dist && dist > 0 && dist < min_dist) {
84
- const s = min_dist / dist;
85
- x = node.anchor_x + dx * s;
86
- y = node.anchor_y + dy * s;
198
+ score +=
199
+ weights.distance *
200
+ Math.hypot(candidate.x + lw / 2 - anchor.x, candidate.y + lh / 2 - anchor.y);
201
+ if (score < best_score) {
202
+ best_score = score;
203
+ best_candidate = candidate;
87
204
  }
88
205
  }
89
- result[node.id] = { x, y };
206
+ labels.push({ x: best_candidate.x, y: best_candidate.y, w: lw, h: lh, anchor_idx: idx });
207
+ }
208
+ // Simulated annealing
209
+ const sa_iterations = config.sa_iterations ?? 2000;
210
+ const total_steps = sa_iterations * num_labels;
211
+ const cooling_rate = 1 / total_steps;
212
+ // Seeded pseudo-random for deterministic results
213
+ let rng_state = 42;
214
+ const next_random = () => {
215
+ rng_state = (rng_state * 1664525 + 1013904223) & 0x7fffffff;
216
+ return rng_state / 0x7fffffff;
217
+ };
218
+ // Reusable scratch objects to avoid allocations in the hot loop
219
+ const old_scratch = { x: 0, y: 0, w: 0, h: 0, anchor_idx: 0 };
220
+ const new_scratch = { x: 0, y: 0, w: 0, h: 0, anchor_idx: 0 };
221
+ const copy_state = (dst, src) => {
222
+ dst.x = src.x;
223
+ dst.y = src.y;
224
+ dst.w = src.w;
225
+ dst.h = src.h;
226
+ dst.anchor_idx = src.anchor_idx;
227
+ };
228
+ for (let step = 0; step < total_steps; step++) {
229
+ const temperature = Math.max(0.001, 1.0 - step * cooling_rate);
230
+ const label_idx = Math.floor(next_random() * num_labels);
231
+ const current = labels[label_idx];
232
+ copy_state(old_scratch, current);
233
+ copy_state(new_scratch, current);
234
+ // 70% try a candidate position, 30% small perturbation
235
+ if (next_random() < 0.7) {
236
+ const candidate = label_infos[label_idx].candidates[Math.floor(next_random() * label_infos[label_idx].candidates.length)];
237
+ new_scratch.x = candidate.x;
238
+ new_scratch.y = candidate.y;
239
+ }
240
+ else {
241
+ const max_shift = 30 * temperature + 5;
242
+ new_scratch.x += (next_random() - 0.5) * 2 * max_shift;
243
+ new_scratch.y += (next_random() - 0.5) * 2 * max_shift;
244
+ }
245
+ const delta = compute_delta_energy(labels, anchors, label_idx, old_scratch, new_scratch, weights, plot_bounds);
246
+ if (delta < 0 || next_random() < Math.exp(-delta / (temperature * 10 + 0.1))) {
247
+ current.x = new_scratch.x;
248
+ current.y = new_scratch.y;
249
+ }
90
250
  }
91
- return result;
251
+ // Return label center positions (matching existing API)
252
+ return Object.fromEntries(labels.map((label, idx) => [
253
+ label_infos[idx].id,
254
+ { x: label.x + label.w / 2, y: label.y + label.h / 2 },
255
+ ]));
92
256
  }
@@ -44,7 +44,7 @@ export function handle_legend_double_click(series, idx, prev_visibility) {
44
44
  const check_series = prev_visibility ? series.slice(0, prev_visibility.length) : series;
45
45
  const is_isolated = check_series.every((srs, srs_idx) => {
46
46
  const in_group = label ? srs.label === label : srs_idx === idx;
47
- return in_group ? srs.visible ?? true : !(srs.visible ?? true);
47
+ return in_group ? (srs.visible ?? true) : !(srs.visible ?? true);
48
48
  });
49
49
  // Restore from isolation
50
50
  if (is_isolated && prev_visibility) {
@@ -56,8 +56,7 @@ export function handle_legend_double_click(series, idx, prev_visibility) {
56
56
  };
57
57
  }
58
58
  // Isolate series
59
- const new_prev = prev_visibility ??
60
- (current.filter(Boolean).length > 1 ? [...current] : null);
59
+ const new_prev = prev_visibility ?? (current.filter(Boolean).length > 1 ? [...current] : null);
61
60
  return {
62
61
  series: series.map((srs, srs_idx) => {
63
62
  const in_group = label ? srs.label === label : srs_idx === idx;
@@ -0,0 +1 @@
1
+ export declare function calc_auto_range(values: number[]): [number, number];
@@ -0,0 +1,14 @@
1
+ export function calc_auto_range(values) {
2
+ const finite_values = values.filter(Number.isFinite);
3
+ if (finite_values.length === 0)
4
+ return [0, 1];
5
+ let [min_value, max_value] = [finite_values[0], finite_values[0]];
6
+ for (const value of finite_values) {
7
+ if (value < min_value)
8
+ min_value = value;
9
+ else if (value > max_value)
10
+ max_value = value;
11
+ }
12
+ const padding = (max_value - min_value) * 0.05 || 0.5;
13
+ return [min_value - padding, max_value + padding];
14
+ }