react-cheminfo 0.28.0 → 0.29.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (691) hide show
  1. package/README.md +38 -25
  2. package/lib/chart/core/axisLabels.d.ts +82 -0
  3. package/lib/chart/core/axisLabels.d.ts.map +1 -0
  4. package/lib/chart/core/axisLabels.js +111 -0
  5. package/lib/chart/core/axisLabels.js.map +1 -0
  6. package/lib/chart/core/boxLayout.d.ts +53 -0
  7. package/lib/chart/core/boxLayout.d.ts.map +1 -0
  8. package/lib/chart/core/boxLayout.js +112 -0
  9. package/lib/chart/core/boxLayout.js.map +1 -0
  10. package/lib/chart/core/chartAxisScale.d.ts +23 -2
  11. package/lib/chart/core/chartAxisScale.d.ts.map +1 -1
  12. package/lib/chart/core/chartAxisScale.js +64 -13
  13. package/lib/chart/core/chartAxisScale.js.map +1 -1
  14. package/lib/chart/core/chartDomain.d.ts +160 -0
  15. package/lib/chart/core/chartDomain.d.ts.map +1 -0
  16. package/lib/chart/core/chartDomain.js +46 -0
  17. package/lib/chart/core/chartDomain.js.map +1 -0
  18. package/lib/chart/core/chartGeometry.d.ts +131 -0
  19. package/lib/chart/core/chartGeometry.d.ts.map +1 -0
  20. package/lib/chart/core/chartGeometry.js +101 -0
  21. package/lib/chart/core/chartGeometry.js.map +1 -0
  22. package/lib/chart/core/chartPane.d.ts +11 -0
  23. package/lib/chart/core/chartPane.d.ts.map +1 -0
  24. package/lib/chart/core/chartPane.js +11 -0
  25. package/lib/chart/core/chartPane.js.map +1 -0
  26. package/lib/chart/core/chartScale.d.ts +4 -1
  27. package/lib/chart/core/chartScale.d.ts.map +1 -1
  28. package/lib/chart/core/chartScale.js +8 -4
  29. package/lib/chart/core/chartScale.js.map +1 -1
  30. package/lib/chart/core/chartTheme.d.ts +156 -0
  31. package/lib/chart/core/chartTheme.d.ts.map +1 -0
  32. package/lib/chart/core/chartTheme.js +156 -0
  33. package/lib/chart/core/chartTheme.js.map +1 -0
  34. package/lib/chart/core/chartViewport.d.ts +32 -5
  35. package/lib/chart/core/chartViewport.d.ts.map +1 -1
  36. package/lib/chart/core/chartViewport.js +40 -11
  37. package/lib/chart/core/chartViewport.js.map +1 -1
  38. package/lib/chart/core/guidePlacement.d.ts +52 -0
  39. package/lib/chart/core/guidePlacement.d.ts.map +1 -0
  40. package/lib/chart/core/guidePlacement.js +52 -0
  41. package/lib/chart/core/guidePlacement.js.map +1 -0
  42. package/lib/chart/core/index.d.ts +29 -2
  43. package/lib/chart/core/index.d.ts.map +1 -1
  44. package/lib/chart/core/index.js +19 -2
  45. package/lib/chart/core/index.js.map +1 -1
  46. package/lib/chart/core/labelStack.d.ts +27 -0
  47. package/lib/chart/core/labelStack.d.ts.map +1 -0
  48. package/lib/chart/core/labelStack.js +62 -0
  49. package/lib/chart/core/labelStack.js.map +1 -0
  50. package/lib/chart/core/legendBox.d.ts +152 -0
  51. package/lib/chart/core/legendBox.d.ts.map +1 -0
  52. package/lib/chart/core/legendBox.js +169 -0
  53. package/lib/chart/core/legendBox.js.map +1 -0
  54. package/lib/chart/core/selectionGeometry.d.ts +45 -0
  55. package/lib/chart/core/selectionGeometry.d.ts.map +1 -0
  56. package/lib/chart/core/selectionGeometry.js +49 -0
  57. package/lib/chart/core/selectionGeometry.js.map +1 -0
  58. package/lib/chart/core/spectrumColor.d.ts +80 -0
  59. package/lib/chart/core/spectrumColor.d.ts.map +1 -0
  60. package/lib/chart/core/spectrumColor.js +120 -0
  61. package/lib/chart/core/spectrumColor.js.map +1 -0
  62. package/lib/chart/core/stackCapacity.d.ts +136 -0
  63. package/lib/chart/core/stackCapacity.d.ts.map +1 -0
  64. package/lib/chart/core/stackCapacity.js +153 -0
  65. package/lib/chart/core/stackCapacity.js.map +1 -0
  66. package/lib/chart/core/svgPoint.d.ts +62 -0
  67. package/lib/chart/core/svgPoint.d.ts.map +1 -0
  68. package/lib/chart/core/svgPoint.js +43 -0
  69. package/lib/chart/core/svgPoint.js.map +1 -0
  70. package/lib/chart/core/tracePath.d.ts +94 -0
  71. package/lib/chart/core/tracePath.d.ts.map +1 -0
  72. package/lib/chart/core/tracePath.js +191 -0
  73. package/lib/chart/core/tracePath.js.map +1 -0
  74. package/lib/chart/core/trackerReadout.d.ts +55 -0
  75. package/lib/chart/core/trackerReadout.d.ts.map +1 -0
  76. package/lib/chart/core/trackerReadout.js +53 -0
  77. package/lib/chart/core/trackerReadout.js.map +1 -0
  78. package/lib/chart/core/viewTransform.d.ts +167 -0
  79. package/lib/chart/core/viewTransform.d.ts.map +1 -0
  80. package/lib/chart/core/viewTransform.js +188 -0
  81. package/lib/chart/core/viewTransform.js.map +1 -0
  82. package/lib/chart/core/zoomDomain.d.ts +127 -0
  83. package/lib/chart/core/zoomDomain.d.ts.map +1 -0
  84. package/lib/chart/core/zoomDomain.js +175 -0
  85. package/lib/chart/core/zoomDomain.js.map +1 -0
  86. package/lib/chart/ui/Axes.d.ts +104 -0
  87. package/lib/chart/ui/Axes.d.ts.map +1 -0
  88. package/lib/chart/ui/Axes.js +155 -0
  89. package/lib/chart/ui/Axes.js.map +1 -0
  90. package/lib/chart/ui/AxisGuide.d.ts +60 -0
  91. package/lib/chart/ui/AxisGuide.d.ts.map +1 -0
  92. package/lib/chart/ui/AxisGuide.js +111 -0
  93. package/lib/chart/ui/AxisGuide.js.map +1 -0
  94. package/lib/chart/ui/ChartStack.d.ts +81 -0
  95. package/lib/chart/ui/ChartStack.d.ts.map +1 -0
  96. package/lib/chart/ui/ChartStack.js +42 -0
  97. package/lib/chart/ui/ChartStack.js.map +1 -0
  98. package/lib/chart/ui/ChartTracker.d.ts +36 -0
  99. package/lib/chart/ui/ChartTracker.d.ts.map +1 -0
  100. package/lib/chart/ui/ChartTracker.js +27 -0
  101. package/lib/chart/ui/ChartTracker.js.map +1 -0
  102. package/lib/chart/ui/PlotCaption.d.ts +44 -0
  103. package/lib/chart/ui/PlotCaption.d.ts.map +1 -0
  104. package/lib/chart/ui/PlotCaption.js +68 -0
  105. package/lib/chart/ui/PlotCaption.js.map +1 -0
  106. package/lib/chart/ui/SelectionRect.d.ts +27 -0
  107. package/lib/chart/ui/SelectionRect.d.ts.map +1 -0
  108. package/lib/chart/ui/SelectionRect.js +31 -0
  109. package/lib/chart/ui/SelectionRect.js.map +1 -0
  110. package/lib/chart/ui/TraceLegend.d.ts +99 -0
  111. package/lib/chart/ui/TraceLegend.d.ts.map +1 -0
  112. package/lib/chart/ui/TraceLegend.js +45 -0
  113. package/lib/chart/ui/TraceLegend.js.map +1 -0
  114. package/lib/chart/ui/chartGestures.d.ts +158 -0
  115. package/lib/chart/ui/chartGestures.d.ts.map +1 -0
  116. package/lib/chart/ui/chartGestures.js +145 -0
  117. package/lib/chart/ui/chartGestures.js.map +1 -0
  118. package/lib/chart/ui/chartStackLevel.d.ts +115 -0
  119. package/lib/chart/ui/chartStackLevel.d.ts.map +1 -0
  120. package/lib/chart/ui/chartStackLevel.js +96 -0
  121. package/lib/chart/ui/chartStackLevel.js.map +1 -0
  122. package/lib/chart/ui/chartSurface.d.ts +35 -0
  123. package/lib/chart/ui/chartSurface.d.ts.map +1 -0
  124. package/lib/chart/ui/chartSurface.js +58 -0
  125. package/lib/chart/ui/chartSurface.js.map +1 -0
  126. package/lib/chart/ui/index.d.ts +24 -0
  127. package/lib/chart/ui/index.d.ts.map +1 -1
  128. package/lib/chart/ui/index.js +13 -0
  129. package/lib/chart/ui/index.js.map +1 -1
  130. package/lib/chart/ui/useChartPointer.d.ts +124 -0
  131. package/lib/chart/ui/useChartPointer.d.ts.map +1 -0
  132. package/lib/chart/ui/useChartPointer.js +152 -0
  133. package/lib/chart/ui/useChartPointer.js.map +1 -0
  134. package/lib/chart/ui/useChartSize.d.ts +49 -0
  135. package/lib/chart/ui/useChartSize.d.ts.map +1 -0
  136. package/lib/chart/ui/useChartSize.js +91 -0
  137. package/lib/chart/ui/useChartSize.js.map +1 -0
  138. package/lib/chart/ui/useChartWindow.d.ts +147 -0
  139. package/lib/chart/ui/useChartWindow.d.ts.map +1 -0
  140. package/lib/chart/ui/useChartWindow.js +135 -0
  141. package/lib/chart/ui/useChartWindow.js.map +1 -0
  142. package/lib/chart/ui/useChartZoom.d.ts +88 -0
  143. package/lib/chart/ui/useChartZoom.d.ts.map +1 -0
  144. package/lib/chart/ui/useChartZoom.js +142 -0
  145. package/lib/chart/ui/useChartZoom.js.map +1 -0
  146. package/lib/chart/ui/useWheelListener.d.ts +30 -0
  147. package/lib/chart/ui/useWheelListener.d.ts.map +1 -0
  148. package/lib/chart/ui/useWheelListener.js +57 -0
  149. package/lib/chart/ui/useWheelListener.js.map +1 -0
  150. package/lib/clipboard/core/copyPng.d.ts +13 -0
  151. package/lib/clipboard/core/copyPng.d.ts.map +1 -0
  152. package/lib/clipboard/core/copyPng.js +19 -0
  153. package/lib/clipboard/core/copyPng.js.map +1 -0
  154. package/lib/clipboard/core/index.d.ts +1 -0
  155. package/lib/clipboard/core/index.d.ts.map +1 -1
  156. package/lib/clipboard/core/index.js +1 -0
  157. package/lib/clipboard/core/index.js.map +1 -1
  158. package/lib/core.d.ts +1 -0
  159. package/lib/core.d.ts.map +1 -1
  160. package/lib/core.js +1 -0
  161. package/lib/core.js.map +1 -1
  162. package/lib/download/core/exportStyles.d.ts +22 -0
  163. package/lib/download/core/exportStyles.d.ts.map +1 -0
  164. package/lib/download/core/exportStyles.js +19 -0
  165. package/lib/download/core/exportStyles.js.map +1 -0
  166. package/lib/download/core/imageResolution.d.ts +88 -0
  167. package/lib/download/core/imageResolution.d.ts.map +1 -0
  168. package/lib/download/core/imageResolution.js +77 -0
  169. package/lib/download/core/imageResolution.js.map +1 -0
  170. package/lib/download/core/index.d.ts +13 -0
  171. package/lib/download/core/index.d.ts.map +1 -1
  172. package/lib/download/core/index.js +8 -0
  173. package/lib/download/core/index.js.map +1 -1
  174. package/lib/download/core/pictureExport.d.ts +93 -0
  175. package/lib/download/core/pictureExport.d.ts.map +1 -0
  176. package/lib/download/core/pictureExport.js +116 -0
  177. package/lib/download/core/pictureExport.js.map +1 -0
  178. package/lib/download/core/stackedDrawing.d.ts +36 -0
  179. package/lib/download/core/stackedDrawing.d.ts.map +1 -0
  180. package/lib/download/core/stackedDrawing.js +98 -0
  181. package/lib/download/core/stackedDrawing.js.map +1 -0
  182. package/lib/download/core/svgBounds.d.ts +44 -0
  183. package/lib/download/core/svgBounds.d.ts.map +1 -0
  184. package/lib/download/core/svgBounds.js +69 -0
  185. package/lib/download/core/svgBounds.js.map +1 -0
  186. package/lib/download/core/svgNamespace.d.ts +9 -0
  187. package/lib/download/core/svgNamespace.d.ts.map +1 -0
  188. package/lib/download/core/svgNamespace.js +10 -0
  189. package/lib/download/core/svgNamespace.js.map +1 -0
  190. package/lib/download/core/svgToPng.d.ts +43 -0
  191. package/lib/download/core/svgToPng.d.ts.map +1 -0
  192. package/lib/download/core/svgToPng.js +79 -0
  193. package/lib/download/core/svgToPng.js.map +1 -0
  194. package/lib/download/core/svgToString.d.ts +45 -0
  195. package/lib/download/core/svgToString.d.ts.map +1 -0
  196. package/lib/download/core/svgToString.js +58 -0
  197. package/lib/download/core/svgToString.js.map +1 -0
  198. package/lib/download/ui/ExportDialogFrame.d.ts +46 -0
  199. package/lib/download/ui/ExportDialogFrame.d.ts.map +1 -0
  200. package/lib/download/ui/ExportDialogFrame.js +24 -0
  201. package/lib/download/ui/ExportDialogFrame.js.map +1 -0
  202. package/lib/download/ui/ExportImageDialog.d.ts +47 -0
  203. package/lib/download/ui/ExportImageDialog.d.ts.map +1 -0
  204. package/lib/download/ui/ExportImageDialog.js +25 -0
  205. package/lib/download/ui/ExportImageDialog.js.map +1 -0
  206. package/lib/download/ui/ExportNameField.d.ts +29 -0
  207. package/lib/download/ui/ExportNameField.d.ts.map +1 -0
  208. package/lib/download/ui/ExportNameField.js +99 -0
  209. package/lib/download/ui/ExportNameField.js.map +1 -0
  210. package/lib/download/ui/ExportPictureSection.d.ts +38 -0
  211. package/lib/download/ui/ExportPictureSection.d.ts.map +1 -0
  212. package/lib/download/ui/ExportPictureSection.js +48 -0
  213. package/lib/download/ui/ExportPictureSection.js.map +1 -0
  214. package/lib/download/ui/index.d.ts +10 -0
  215. package/lib/download/ui/index.d.ts.map +1 -1
  216. package/lib/download/ui/index.js +5 -0
  217. package/lib/download/ui/index.js.map +1 -1
  218. package/lib/download/ui/useDrawingBox.d.ts +23 -0
  219. package/lib/download/ui/useDrawingBox.d.ts.map +1 -0
  220. package/lib/download/ui/useDrawingBox.js +21 -0
  221. package/lib/download/ui/useDrawingBox.js.map +1 -0
  222. package/lib/error/core/describeSource.d.ts +17 -0
  223. package/lib/error/core/describeSource.d.ts.map +1 -0
  224. package/lib/error/core/describeSource.js +19 -0
  225. package/lib/error/core/describeSource.js.map +1 -0
  226. package/lib/error/core/index.d.ts +1 -0
  227. package/lib/error/core/index.d.ts.map +1 -1
  228. package/lib/error/core/index.js +1 -0
  229. package/lib/error/core/index.js.map +1 -1
  230. package/lib/help/ui/HelpBody.d.ts +10 -1
  231. package/lib/help/ui/HelpBody.d.ts.map +1 -1
  232. package/lib/help/ui/HelpBody.js +24 -1
  233. package/lib/help/ui/HelpBody.js.map +1 -1
  234. package/lib/help/ui/index.d.ts +1 -1
  235. package/lib/help/ui/index.d.ts.map +1 -1
  236. package/lib/help/ui/index.js.map +1 -1
  237. package/lib/ir/core/analysisSpectra.d.ts +46 -0
  238. package/lib/ir/core/analysisSpectra.d.ts.map +1 -0
  239. package/lib/ir/core/analysisSpectra.js +187 -0
  240. package/lib/ir/core/analysisSpectra.js.map +1 -0
  241. package/lib/ir/core/assignBands.d.ts +83 -0
  242. package/lib/ir/core/assignBands.d.ts.map +1 -0
  243. package/lib/ir/core/assignBands.js +83 -0
  244. package/lib/ir/core/assignBands.js.map +1 -0
  245. package/lib/ir/core/bandAssignments.d.ts +47 -0
  246. package/lib/ir/core/bandAssignments.d.ts.map +1 -0
  247. package/lib/ir/core/bandAssignments.js +305 -0
  248. package/lib/ir/core/bandAssignments.js.map +1 -0
  249. package/lib/ir/core/bandLabelPlan.d.ts +93 -0
  250. package/lib/ir/core/bandLabelPlan.d.ts.map +1 -0
  251. package/lib/ir/core/bandLabelPlan.js +104 -0
  252. package/lib/ir/core/bandLabelPlan.js.map +1 -0
  253. package/lib/ir/core/detectIrFormat.d.ts +23 -0
  254. package/lib/ir/core/detectIrFormat.d.ts.map +1 -0
  255. package/lib/ir/core/detectIrFormat.js +133 -0
  256. package/lib/ir/core/detectIrFormat.js.map +1 -0
  257. package/lib/ir/core/downloadSpectra.d.ts +26 -0
  258. package/lib/ir/core/downloadSpectra.d.ts.map +1 -0
  259. package/lib/ir/core/downloadSpectra.js +37 -0
  260. package/lib/ir/core/downloadSpectra.js.map +1 -0
  261. package/lib/ir/core/fromJcamp.d.ts +35 -0
  262. package/lib/ir/core/fromJcamp.d.ts.map +1 -0
  263. package/lib/ir/core/fromJcamp.js +48 -0
  264. package/lib/ir/core/fromJcamp.js.map +1 -0
  265. package/lib/ir/core/fromSpc.d.ts +30 -0
  266. package/lib/ir/core/fromSpc.d.ts.map +1 -0
  267. package/lib/ir/core/fromSpc.js +40 -0
  268. package/lib/ir/core/fromSpc.js.map +1 -0
  269. package/lib/ir/core/index.d.ts +51 -0
  270. package/lib/ir/core/index.d.ts.map +1 -0
  271. package/lib/ir/core/index.js +35 -0
  272. package/lib/ir/core/index.js.map +1 -0
  273. package/lib/ir/core/irBand.d.ts +45 -0
  274. package/lib/ir/core/irBand.d.ts.map +1 -0
  275. package/lib/ir/core/irBand.js +30 -0
  276. package/lib/ir/core/irBand.js.map +1 -0
  277. package/lib/ir/core/irCommands.d.ts +168 -0
  278. package/lib/ir/core/irCommands.d.ts.map +1 -0
  279. package/lib/ir/core/irCommands.js +94 -0
  280. package/lib/ir/core/irCommands.js.map +1 -0
  281. package/lib/ir/core/irDomain.d.ts +63 -0
  282. package/lib/ir/core/irDomain.d.ts.map +1 -0
  283. package/lib/ir/core/irDomain.js +136 -0
  284. package/lib/ir/core/irDomain.js.map +1 -0
  285. package/lib/ir/core/irEditorApi.d.ts +42 -0
  286. package/lib/ir/core/irEditorApi.d.ts.map +1 -0
  287. package/lib/ir/core/irEditorApi.js +10 -0
  288. package/lib/ir/core/irEditorApi.js.map +1 -0
  289. package/lib/ir/core/irFormat.d.ts +42 -0
  290. package/lib/ir/core/irFormat.d.ts.map +1 -0
  291. package/lib/ir/core/irFormat.js +51 -0
  292. package/lib/ir/core/irFormat.js.map +1 -0
  293. package/lib/ir/core/irMode.d.ts +160 -0
  294. package/lib/ir/core/irMode.d.ts.map +1 -0
  295. package/lib/ir/core/irMode.js +175 -0
  296. package/lib/ir/core/irMode.js.map +1 -0
  297. package/lib/ir/core/irReducer.d.ts +101 -0
  298. package/lib/ir/core/irReducer.d.ts.map +1 -0
  299. package/lib/ir/core/irReducer.js +207 -0
  300. package/lib/ir/core/irReducer.js.map +1 -0
  301. package/lib/ir/core/irSidePanels.d.ts +22 -0
  302. package/lib/ir/core/irSidePanels.d.ts.map +1 -0
  303. package/lib/ir/core/irSidePanels.js +12 -0
  304. package/lib/ir/core/irSidePanels.js.map +1 -0
  305. package/lib/ir/core/irSpectrum.d.ts +140 -0
  306. package/lib/ir/core/irSpectrum.d.ts.map +1 -0
  307. package/lib/ir/core/irSpectrum.js +34 -0
  308. package/lib/ir/core/irSpectrum.js.map +1 -0
  309. package/lib/ir/core/irState.d.ts +119 -0
  310. package/lib/ir/core/irState.d.ts.map +1 -0
  311. package/lib/ir/core/irState.js +92 -0
  312. package/lib/ir/core/irState.js.map +1 -0
  313. package/lib/ir/core/loadIrSpectra.d.ts +36 -0
  314. package/lib/ir/core/loadIrSpectra.d.ts.map +1 -0
  315. package/lib/ir/core/loadIrSpectra.js +44 -0
  316. package/lib/ir/core/loadIrSpectra.js.map +1 -0
  317. package/lib/ir/core/nearestBand.d.ts +35 -0
  318. package/lib/ir/core/nearestBand.d.ts.map +1 -0
  319. package/lib/ir/core/nearestBand.js +47 -0
  320. package/lib/ir/core/nearestBand.js.map +1 -0
  321. package/lib/ir/core/pickBands.d.ts +70 -0
  322. package/lib/ir/core/pickBands.d.ts.map +1 -0
  323. package/lib/ir/core/pickBands.js +125 -0
  324. package/lib/ir/core/pickBands.js.map +1 -0
  325. package/lib/ir/core/spectrumJcamp.d.ts +58 -0
  326. package/lib/ir/core/spectrumJcamp.d.ts.map +1 -0
  327. package/lib/ir/core/spectrumJcamp.js +156 -0
  328. package/lib/ir/core/spectrumJcamp.js.map +1 -0
  329. package/lib/ir/core/toIrSpectrum.d.ts +59 -0
  330. package/lib/ir/core/toIrSpectrum.d.ts.map +1 -0
  331. package/lib/ir/core/toIrSpectrum.js +56 -0
  332. package/lib/ir/core/toIrSpectrum.js.map +1 -0
  333. package/lib/ir/ui/BandMarks.d.ts +52 -0
  334. package/lib/ir/ui/BandMarks.d.ts.map +1 -0
  335. package/lib/ir/ui/BandMarks.js +71 -0
  336. package/lib/ir/ui/BandMarks.js.map +1 -0
  337. package/lib/ir/ui/BandsPanel.d.ts +31 -0
  338. package/lib/ir/ui/BandsPanel.d.ts.map +1 -0
  339. package/lib/ir/ui/BandsPanel.js +94 -0
  340. package/lib/ir/ui/BandsPanel.js.map +1 -0
  341. package/lib/ir/ui/IrAboutDialog.d.ts +18 -0
  342. package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -0
  343. package/lib/ir/ui/IrAboutDialog.js +32 -0
  344. package/lib/ir/ui/IrAboutDialog.js.map +1 -0
  345. package/lib/ir/ui/IrCanvas.d.ts +38 -0
  346. package/lib/ir/ui/IrCanvas.d.ts.map +1 -0
  347. package/lib/ir/ui/IrCanvas.js +41 -0
  348. package/lib/ir/ui/IrCanvas.js.map +1 -0
  349. package/lib/ir/ui/IrChart.d.ts +28 -0
  350. package/lib/ir/ui/IrChart.d.ts.map +1 -0
  351. package/lib/ir/ui/IrChart.js +114 -0
  352. package/lib/ir/ui/IrChart.js.map +1 -0
  353. package/lib/ir/ui/IrCommandProvider.d.ts +15 -0
  354. package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -0
  355. package/lib/ir/ui/IrCommandProvider.js +14 -0
  356. package/lib/ir/ui/IrCommandProvider.js.map +1 -0
  357. package/lib/ir/ui/IrCommandTooltip.d.ts +16 -0
  358. package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -0
  359. package/lib/ir/ui/IrCommandTooltip.js +22 -0
  360. package/lib/ir/ui/IrCommandTooltip.js.map +1 -0
  361. package/lib/ir/ui/IrDocumentationDialog.d.ts +18 -0
  362. package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -0
  363. package/lib/ir/ui/IrDocumentationDialog.js +68 -0
  364. package/lib/ir/ui/IrDocumentationDialog.js.map +1 -0
  365. package/lib/ir/ui/IrEditor.d.ts +60 -0
  366. package/lib/ir/ui/IrEditor.d.ts.map +1 -0
  367. package/lib/ir/ui/IrEditor.js +42 -0
  368. package/lib/ir/ui/IrEditor.js.map +1 -0
  369. package/lib/ir/ui/IrHeader.d.ts +13 -0
  370. package/lib/ir/ui/IrHeader.d.ts.map +1 -0
  371. package/lib/ir/ui/IrHeader.js +21 -0
  372. package/lib/ir/ui/IrHeader.js.map +1 -0
  373. package/lib/ir/ui/IrLogo.d.ts +20 -0
  374. package/lib/ir/ui/IrLogo.d.ts.map +1 -0
  375. package/lib/ir/ui/IrLogo.js +17 -0
  376. package/lib/ir/ui/IrLogo.js.map +1 -0
  377. package/lib/ir/ui/IrPointerTracker.d.ts +29 -0
  378. package/lib/ir/ui/IrPointerTracker.d.ts.map +1 -0
  379. package/lib/ir/ui/IrPointerTracker.js +47 -0
  380. package/lib/ir/ui/IrPointerTracker.js.map +1 -0
  381. package/lib/ir/ui/IrShell.d.ts +25 -0
  382. package/lib/ir/ui/IrShell.d.ts.map +1 -0
  383. package/lib/ir/ui/IrShell.js +178 -0
  384. package/lib/ir/ui/IrShell.js.map +1 -0
  385. package/lib/ir/ui/IrSidePanel.d.ts +26 -0
  386. package/lib/ir/ui/IrSidePanel.d.ts.map +1 -0
  387. package/lib/ir/ui/IrSidePanel.js +39 -0
  388. package/lib/ir/ui/IrSidePanel.js.map +1 -0
  389. package/lib/ir/ui/IrStateProvider.d.ts +19 -0
  390. package/lib/ir/ui/IrStateProvider.d.ts.map +1 -0
  391. package/lib/ir/ui/IrStateProvider.js +16 -0
  392. package/lib/ir/ui/IrStateProvider.js.map +1 -0
  393. package/lib/ir/ui/IrStatusBar.d.ts +14 -0
  394. package/lib/ir/ui/IrStatusBar.d.ts.map +1 -0
  395. package/lib/ir/ui/IrStatusBar.js +48 -0
  396. package/lib/ir/ui/IrStatusBar.js.map +1 -0
  397. package/lib/ir/ui/IrToolbar.d.ts +18 -0
  398. package/lib/ir/ui/IrToolbar.d.ts.map +1 -0
  399. package/lib/ir/ui/IrToolbar.js +32 -0
  400. package/lib/ir/ui/IrToolbar.js.map +1 -0
  401. package/lib/ir/ui/IrTraces.d.ts +63 -0
  402. package/lib/ir/ui/IrTraces.d.ts.map +1 -0
  403. package/lib/ir/ui/IrTraces.js +72 -0
  404. package/lib/ir/ui/IrTraces.js.map +1 -0
  405. package/lib/ir/ui/MetadataPanel.d.ts +15 -0
  406. package/lib/ir/ui/MetadataPanel.d.ts.map +1 -0
  407. package/lib/ir/ui/MetadataPanel.js +49 -0
  408. package/lib/ir/ui/MetadataPanel.js.map +1 -0
  409. package/lib/ir/ui/SpectraPanel.d.ts +20 -0
  410. package/lib/ir/ui/SpectraPanel.d.ts.map +1 -0
  411. package/lib/ir/ui/SpectraPanel.js +42 -0
  412. package/lib/ir/ui/SpectraPanel.js.map +1 -0
  413. package/lib/ir/ui/SpectrumRow.d.ts +26 -0
  414. package/lib/ir/ui/SpectrumRow.d.ts.map +1 -0
  415. package/lib/ir/ui/SpectrumRow.js +41 -0
  416. package/lib/ir/ui/SpectrumRow.js.map +1 -0
  417. package/lib/ir/ui/index.d.ts +56 -0
  418. package/lib/ir/ui/index.d.ts.map +1 -0
  419. package/lib/ir/ui/index.js +36 -0
  420. package/lib/ir/ui/index.js.map +1 -0
  421. package/lib/ir/ui/irActions.d.ts +52 -0
  422. package/lib/ir/ui/irActions.d.ts.map +1 -0
  423. package/lib/ir/ui/irActions.js +62 -0
  424. package/lib/ir/ui/irActions.js.map +1 -0
  425. package/lib/ir/ui/irChartProps.d.ts +116 -0
  426. package/lib/ir/ui/irChartProps.d.ts.map +1 -0
  427. package/lib/ir/ui/irChartProps.js +14 -0
  428. package/lib/ir/ui/irChartProps.js.map +1 -0
  429. package/lib/ir/ui/irCommandContext.d.ts +35 -0
  430. package/lib/ir/ui/irCommandContext.d.ts.map +1 -0
  431. package/lib/ir/ui/irCommandContext.js +44 -0
  432. package/lib/ir/ui/irCommandContext.js.map +1 -0
  433. package/lib/ir/ui/irStateContext.d.ts +26 -0
  434. package/lib/ir/ui/irStateContext.d.ts.map +1 -0
  435. package/lib/ir/ui/irStateContext.js +37 -0
  436. package/lib/ir/ui/irStateContext.js.map +1 -0
  437. package/lib/ir/ui/useIrEditor.d.ts +51 -0
  438. package/lib/ir/ui/useIrEditor.d.ts.map +1 -0
  439. package/lib/ir/ui/useIrEditor.js +88 -0
  440. package/lib/ir/ui/useIrEditor.js.map +1 -0
  441. package/lib/ir/ui/useIrPointer.d.ts +66 -0
  442. package/lib/ir/ui/useIrPointer.d.ts.map +1 -0
  443. package/lib/ir/ui/useIrPointer.js +53 -0
  444. package/lib/ir/ui/useIrPointer.js.map +1 -0
  445. package/lib/ir/ui/useIrShortcuts.d.ts +24 -0
  446. package/lib/ir/ui/useIrShortcuts.d.ts.map +1 -0
  447. package/lib/ir/ui/useIrShortcuts.js +73 -0
  448. package/lib/ir/ui/useIrShortcuts.js.map +1 -0
  449. package/lib/ir/ui/useIrZoom.d.ts +51 -0
  450. package/lib/ir/ui/useIrZoom.d.ts.map +1 -0
  451. package/lib/ir/ui/useIrZoom.js +46 -0
  452. package/lib/ir/ui/useIrZoom.js.map +1 -0
  453. package/lib/ir.d.ts +13 -0
  454. package/lib/ir.d.ts.map +1 -0
  455. package/lib/ir.js +13 -0
  456. package/lib/ir.js.map +1 -0
  457. package/lib/panel/core/dialogStyles.d.ts +13 -0
  458. package/lib/panel/core/dialogStyles.d.ts.map +1 -0
  459. package/lib/panel/core/dialogStyles.js +11 -0
  460. package/lib/panel/core/dialogStyles.js.map +1 -0
  461. package/lib/panel/core/index.d.ts +19 -0
  462. package/lib/panel/core/index.d.ts.map +1 -0
  463. package/lib/panel/core/index.js +18 -0
  464. package/lib/panel/core/index.js.map +1 -0
  465. package/lib/panel/core/isEditingField.d.ts +17 -0
  466. package/lib/panel/core/isEditingField.d.ts.map +1 -0
  467. package/lib/panel/core/isEditingField.js +25 -0
  468. package/lib/panel/core/isEditingField.js.map +1 -0
  469. package/lib/panel/core/panelStyles.d.ts +242 -0
  470. package/lib/panel/core/panelStyles.d.ts.map +1 -0
  471. package/lib/panel/core/panelStyles.js +228 -0
  472. package/lib/panel/core/panelStyles.js.map +1 -0
  473. package/lib/panel/core/rowSpacers.d.ts +38 -0
  474. package/lib/panel/core/rowSpacers.d.ts.map +1 -0
  475. package/lib/panel/core/rowSpacers.js +31 -0
  476. package/lib/panel/core/rowSpacers.js.map +1 -0
  477. package/lib/panel/core/statusBar.d.ts +44 -0
  478. package/lib/panel/core/statusBar.d.ts.map +1 -0
  479. package/lib/panel/core/statusBar.js +40 -0
  480. package/lib/panel/core/statusBar.js.map +1 -0
  481. package/lib/panel/core/textFilter.d.ts +22 -0
  482. package/lib/panel/core/textFilter.d.ts.map +1 -0
  483. package/lib/panel/core/textFilter.js +32 -0
  484. package/lib/panel/core/textFilter.js.map +1 -0
  485. package/lib/panel/core/yieldToPainting.d.ts +17 -0
  486. package/lib/panel/core/yieldToPainting.d.ts.map +1 -0
  487. package/lib/panel/core/yieldToPainting.js +21 -0
  488. package/lib/panel/core/yieldToPainting.js.map +1 -0
  489. package/lib/panel/ui/AboutDialogFrame.d.ts +36 -0
  490. package/lib/panel/ui/AboutDialogFrame.d.ts.map +1 -0
  491. package/lib/panel/ui/AboutDialogFrame.js +43 -0
  492. package/lib/panel/ui/AboutDialogFrame.js.map +1 -0
  493. package/lib/panel/ui/ClearButton.d.ts +28 -0
  494. package/lib/panel/ui/ClearButton.d.ts.map +1 -0
  495. package/lib/panel/ui/ClearButton.js +23 -0
  496. package/lib/panel/ui/ClearButton.js.map +1 -0
  497. package/lib/panel/ui/DocumentationDialogFrame.d.ts +39 -0
  498. package/lib/panel/ui/DocumentationDialogFrame.d.ts.map +1 -0
  499. package/lib/panel/ui/DocumentationDialogFrame.js +29 -0
  500. package/lib/panel/ui/DocumentationDialogFrame.js.map +1 -0
  501. package/lib/panel/ui/FilterInput.d.ts +31 -0
  502. package/lib/panel/ui/FilterInput.d.ts.map +1 -0
  503. package/lib/panel/ui/FilterInput.js +23 -0
  504. package/lib/panel/ui/FilterInput.js.map +1 -0
  505. package/lib/panel/ui/HelpLabel.d.ts +24 -0
  506. package/lib/panel/ui/HelpLabel.d.ts.map +1 -0
  507. package/lib/panel/ui/HelpLabel.js +23 -0
  508. package/lib/panel/ui/HelpLabel.js.map +1 -0
  509. package/lib/panel/ui/PanelMessage.d.ts +41 -0
  510. package/lib/panel/ui/PanelMessage.d.ts.map +1 -0
  511. package/lib/panel/ui/PanelMessage.js +30 -0
  512. package/lib/panel/ui/PanelMessage.js.map +1 -0
  513. package/lib/panel/ui/PanelRail.d.ts +41 -0
  514. package/lib/panel/ui/PanelRail.d.ts.map +1 -0
  515. package/lib/panel/ui/PanelRail.js +12 -0
  516. package/lib/panel/ui/PanelRail.js.map +1 -0
  517. package/lib/panel/ui/Section.d.ts +25 -0
  518. package/lib/panel/ui/Section.d.ts.map +1 -0
  519. package/lib/panel/ui/Section.js +41 -0
  520. package/lib/panel/ui/Section.js.map +1 -0
  521. package/lib/panel/ui/SidePanelStack.d.ts +62 -0
  522. package/lib/panel/ui/SidePanelStack.d.ts.map +1 -0
  523. package/lib/panel/ui/SidePanelStack.js +40 -0
  524. package/lib/panel/ui/SidePanelStack.js.map +1 -0
  525. package/lib/panel/ui/SpectrumColorSwatch.d.ts +33 -0
  526. package/lib/panel/ui/SpectrumColorSwatch.d.ts.map +1 -0
  527. package/lib/panel/ui/SpectrumColorSwatch.js +76 -0
  528. package/lib/panel/ui/SpectrumColorSwatch.js.map +1 -0
  529. package/lib/panel/ui/index.d.ts +37 -0
  530. package/lib/panel/ui/index.d.ts.map +1 -0
  531. package/lib/panel/ui/index.js +24 -0
  532. package/lib/panel/ui/index.js.map +1 -0
  533. package/lib/panel/ui/useConfirmOnEnter.d.ts +19 -0
  534. package/lib/panel/ui/useConfirmOnEnter.d.ts.map +1 -0
  535. package/lib/panel/ui/useConfirmOnEnter.js +64 -0
  536. package/lib/panel/ui/useConfirmOnEnter.js.map +1 -0
  537. package/lib/panel/ui/useFilterBox.d.ts +23 -0
  538. package/lib/panel/ui/useFilterBox.d.ts.map +1 -0
  539. package/lib/panel/ui/useFilterBox.js +22 -0
  540. package/lib/panel/ui/useFilterBox.js.map +1 -0
  541. package/lib/panel/ui/useVirtualRows.d.ts +46 -0
  542. package/lib/panel/ui/useVirtualRows.d.ts.map +1 -0
  543. package/lib/panel/ui/useVirtualRows.js +56 -0
  544. package/lib/panel/ui/useVirtualRows.js.map +1 -0
  545. package/lib/panel/ui/useVirtualWindowRows.d.ts +40 -0
  546. package/lib/panel/ui/useVirtualWindowRows.d.ts.map +1 -0
  547. package/lib/panel/ui/useVirtualWindowRows.js +65 -0
  548. package/lib/panel/ui/useVirtualWindowRows.js.map +1 -0
  549. package/lib/ui.d.ts +1 -0
  550. package/lib/ui.d.ts.map +1 -1
  551. package/lib/ui.js +1 -0
  552. package/lib/ui.js.map +1 -1
  553. package/package.json +8 -1
  554. package/src/chart/core/axisLabels.ts +117 -0
  555. package/src/chart/core/boxLayout.ts +126 -0
  556. package/src/chart/core/chartAxisScale.ts +92 -10
  557. package/src/chart/core/chartDomain.ts +185 -0
  558. package/src/chart/core/chartGeometry.ts +159 -0
  559. package/src/chart/core/chartPane.ts +10 -0
  560. package/src/chart/core/chartScale.ts +7 -4
  561. package/src/chart/core/chartTheme.ts +161 -0
  562. package/src/chart/core/chartViewport.ts +40 -13
  563. package/src/chart/core/guidePlacement.ts +66 -0
  564. package/src/chart/core/index.ts +121 -2
  565. package/src/chart/core/labelStack.ts +72 -0
  566. package/src/chart/core/legendBox.ts +263 -0
  567. package/src/chart/core/selectionGeometry.ts +68 -0
  568. package/src/chart/core/spectrumColor.ts +129 -0
  569. package/src/chart/core/stackCapacity.ts +162 -0
  570. package/src/chart/core/svgPoint.ts +77 -0
  571. package/src/chart/core/tracePath.ts +228 -0
  572. package/src/chart/core/trackerReadout.ts +78 -0
  573. package/src/chart/core/viewTransform.ts +287 -0
  574. package/src/chart/core/zoomDomain.ts +235 -0
  575. package/src/chart/ui/Axes.tsx +361 -0
  576. package/src/chart/ui/AxisGuide.tsx +187 -0
  577. package/src/chart/ui/ChartStack.tsx +130 -0
  578. package/src/chart/ui/ChartTracker.tsx +101 -0
  579. package/src/chart/ui/PlotCaption.tsx +108 -0
  580. package/src/chart/ui/SelectionRect.tsx +52 -0
  581. package/src/chart/ui/TraceLegend.tsx +193 -0
  582. package/src/chart/ui/chartGestures.ts +270 -0
  583. package/src/chart/ui/chartStackLevel.tsx +210 -0
  584. package/src/chart/ui/chartSurface.ts +66 -0
  585. package/src/chart/ui/index.ts +35 -0
  586. package/src/chart/ui/useChartPointer.ts +223 -0
  587. package/src/chart/ui/useChartSize.ts +115 -0
  588. package/src/chart/ui/useChartWindow.ts +240 -0
  589. package/src/chart/ui/useChartZoom.ts +255 -0
  590. package/src/chart/ui/useWheelListener.ts +62 -0
  591. package/src/clipboard/core/copyPng.ts +20 -0
  592. package/src/clipboard/core/index.ts +1 -0
  593. package/src/core.ts +1 -0
  594. package/src/download/core/exportStyles.ts +20 -0
  595. package/src/download/core/imageResolution.ts +118 -0
  596. package/src/download/core/index.ts +34 -0
  597. package/src/download/core/pictureExport.ts +207 -0
  598. package/src/download/core/stackedDrawing.ts +108 -0
  599. package/src/download/core/svgBounds.ts +80 -0
  600. package/src/download/core/svgNamespace.ts +9 -0
  601. package/src/download/core/svgToPng.ts +121 -0
  602. package/src/download/core/svgToString.ts +95 -0
  603. package/src/download/ui/ExportDialogFrame.tsx +86 -0
  604. package/src/download/ui/ExportImageDialog.tsx +91 -0
  605. package/src/download/ui/ExportNameField.tsx +148 -0
  606. package/src/download/ui/ExportPictureSection.tsx +142 -0
  607. package/src/download/ui/index.ts +11 -0
  608. package/src/download/ui/useDrawingBox.ts +37 -0
  609. package/src/error/core/describeSource.ts +18 -0
  610. package/src/error/core/index.ts +1 -0
  611. package/src/help/ui/HelpBody.tsx +41 -2
  612. package/src/help/ui/index.ts +6 -1
  613. package/src/ir/core/analysisSpectra.ts +231 -0
  614. package/src/ir/core/assignBands.ts +144 -0
  615. package/src/ir/core/bandAssignments.ts +329 -0
  616. package/src/ir/core/bandLabelPlan.ts +194 -0
  617. package/src/ir/core/detectIrFormat.ts +139 -0
  618. package/src/ir/core/downloadSpectra.ts +57 -0
  619. package/src/ir/core/fromJcamp.ts +70 -0
  620. package/src/ir/core/fromSpc.ts +61 -0
  621. package/src/ir/core/index.ts +113 -0
  622. package/src/ir/core/irBand.ts +57 -0
  623. package/src/ir/core/irCommands.ts +154 -0
  624. package/src/ir/core/irDomain.ts +163 -0
  625. package/src/ir/core/irEditorApi.ts +44 -0
  626. package/src/ir/core/irFormat.ts +57 -0
  627. package/src/ir/core/irMode.ts +203 -0
  628. package/src/ir/core/irReducer.ts +273 -0
  629. package/src/ir/core/irSidePanels.ts +20 -0
  630. package/src/ir/core/irSpectrum.ts +155 -0
  631. package/src/ir/core/irState.ts +173 -0
  632. package/src/ir/core/loadIrSpectra.ts +79 -0
  633. package/src/ir/core/nearestBand.ts +57 -0
  634. package/src/ir/core/pickBands.ts +181 -0
  635. package/src/ir/core/spectrumJcamp.ts +178 -0
  636. package/src/ir/core/toIrSpectrum.ts +102 -0
  637. package/src/ir/ui/BandMarks.tsx +166 -0
  638. package/src/ir/ui/BandsPanel.tsx +271 -0
  639. package/src/ir/ui/IrAboutDialog.tsx +121 -0
  640. package/src/ir/ui/IrCanvas.tsx +91 -0
  641. package/src/ir/ui/IrChart.tsx +215 -0
  642. package/src/ir/ui/IrCommandProvider.tsx +32 -0
  643. package/src/ir/ui/IrCommandTooltip.tsx +36 -0
  644. package/src/ir/ui/IrDocumentationDialog.tsx +174 -0
  645. package/src/ir/ui/IrEditor.tsx +99 -0
  646. package/src/ir/ui/IrHeader.tsx +39 -0
  647. package/src/ir/ui/IrLogo.tsx +49 -0
  648. package/src/ir/ui/IrPointerTracker.tsx +102 -0
  649. package/src/ir/ui/IrShell.tsx +285 -0
  650. package/src/ir/ui/IrSidePanel.tsx +78 -0
  651. package/src/ir/ui/IrStateProvider.tsx +32 -0
  652. package/src/ir/ui/IrStatusBar.tsx +97 -0
  653. package/src/ir/ui/IrToolbar.tsx +102 -0
  654. package/src/ir/ui/IrTraces.tsx +134 -0
  655. package/src/ir/ui/MetadataPanel.tsx +88 -0
  656. package/src/ir/ui/SpectraPanel.tsx +114 -0
  657. package/src/ir/ui/SpectrumRow.tsx +127 -0
  658. package/src/ir/ui/index.ts +56 -0
  659. package/src/ir/ui/irActions.ts +103 -0
  660. package/src/ir/ui/irChartProps.ts +118 -0
  661. package/src/ir/ui/irCommandContext.tsx +62 -0
  662. package/src/ir/ui/irStateContext.ts +48 -0
  663. package/src/ir/ui/useIrEditor.ts +139 -0
  664. package/src/ir/ui/useIrPointer.ts +109 -0
  665. package/src/ir/ui/useIrShortcuts.ts +95 -0
  666. package/src/ir/ui/useIrZoom.ts +86 -0
  667. package/src/ir.ts +13 -0
  668. package/src/panel/core/dialogStyles.ts +11 -0
  669. package/src/panel/core/index.ts +47 -0
  670. package/src/panel/core/isEditingField.ts +23 -0
  671. package/src/panel/core/panelStyles.ts +248 -0
  672. package/src/panel/core/rowSpacers.ts +50 -0
  673. package/src/panel/core/statusBar.ts +48 -0
  674. package/src/panel/core/textFilter.ts +33 -0
  675. package/src/panel/core/yieldToPainting.ts +20 -0
  676. package/src/panel/ui/AboutDialogFrame.tsx +100 -0
  677. package/src/panel/ui/ClearButton.tsx +42 -0
  678. package/src/panel/ui/DocumentationDialogFrame.tsx +86 -0
  679. package/src/panel/ui/FilterInput.tsx +60 -0
  680. package/src/panel/ui/HelpLabel.tsx +43 -0
  681. package/src/panel/ui/PanelMessage.tsx +64 -0
  682. package/src/panel/ui/PanelRail.tsx +64 -0
  683. package/src/panel/ui/Section.tsx +66 -0
  684. package/src/panel/ui/SidePanelStack.tsx +109 -0
  685. package/src/panel/ui/SpectrumColorSwatch.tsx +119 -0
  686. package/src/panel/ui/index.ts +47 -0
  687. package/src/panel/ui/useConfirmOnEnter.ts +68 -0
  688. package/src/panel/ui/useFilterBox.ts +35 -0
  689. package/src/panel/ui/useVirtualRows.ts +82 -0
  690. package/src/panel/ui/useVirtualWindowRows.ts +86 -0
  691. package/src/ui.ts +1 -0
@@ -0,0 +1,117 @@
1
+ /**
2
+ * How a number is written wherever a chart writes one.
3
+ *
4
+ * The axis decides, not the number: the precision comes from the tick step, and
5
+ * the notation from the largest tick, so every label on one axis is written the
6
+ * same way and a reader can run an eye down a column of them. `chartAxisScale`
7
+ * works both out; this is where they turn into text.
8
+ *
9
+ * It is a second way of writing the labels `chartAxisScale` already carries,
10
+ * and it exists because the two answer different questions. A figure lifts a
11
+ * common power of ten into its axis title and writes short labels under it — a
12
+ * chart whose axis title is fixed by the measurement cannot, so a spectrum
13
+ * writes the magnitude into each label instead.
14
+ */
15
+
16
+ import type { ChartAxisScale } from './chartAxisScale.ts';
17
+
18
+ /**
19
+ * Write a number the way an axis label or a readout wants it.
20
+ *
21
+ * The decimals come from the axis, so every label on it is written to the same
22
+ * precision — but a tick that happens to land on a round number then reads
23
+ * `500.0000` where `500` was meant, and half its width is zeros carrying
24
+ * nothing. They are trimmed off the end only, never out of the middle, so
25
+ * `500.0002` keeps every digit it needs.
26
+ *
27
+ * `toFixed` also writes `-0` for anything that rounds to zero from below, which
28
+ * is never what an axis means and is jarring on the one tick a chemist looks at
29
+ * most.
30
+ * @param value - The number to write.
31
+ * @param decimals - How many decimals to write it to, as `niceTicks` derived.
32
+ * @returns The label.
33
+ */
34
+ export function formatNumber(value: number, decimals: number): string {
35
+ const text = value.toFixed(Math.min(20, Math.max(0, Math.floor(decimals))));
36
+ const trimmed = text.includes('.') ? text.replace(/\.?0+$/, '') : text;
37
+ return trimmed === '-0' ? '0' : trimmed;
38
+ }
39
+
40
+ /**
41
+ * The magnitude above which a number is quicker read as a power of ten.
42
+ *
43
+ * An ion count is quoted in whatever the instrument counted in, so an intensity
44
+ * axis written out in full reads `200000000` — nine digits a reader has to group
45
+ * into threes before knowing which power of ten they are looking at, and wide
46
+ * enough to run into the axis title printed beside them. Above this the same
47
+ * tick is written `2e+8`, which says the magnitude first and in four characters.
48
+ *
49
+ * A hundred thousand rather than a million because that is where a number stops
50
+ * being read at a glance, and because it is the threshold every intensity in the
51
+ * mass side is already written against — a colourbar and an axis that disagreed
52
+ * about how one count is spelled would read as two measurements.
53
+ */
54
+ export const SCIENTIFIC_ABOVE = 1e5;
55
+
56
+ /**
57
+ * The magnitude below which the digits that mean anything are all behind zeros.
58
+ *
59
+ * The mirror of `SCIENTIFIC_ABOVE`: `0.00002` is four characters of nothing
60
+ * followed by the one digit that was measured.
61
+ */
62
+ export const SCIENTIFIC_BELOW = 1e-4;
63
+
64
+ /**
65
+ * Write a number as a mantissa and a power of ten.
66
+ *
67
+ * With no precision asked for, the mantissa keeps only the digits it needs — a
68
+ * tick at a hundred and fifty million is `1.5e+8` and the one above it `2e+8`,
69
+ * rather than both being padded to the same width with zeros that say nothing.
70
+ * The value is rounded to a few significant digits first, because a tick is
71
+ * reached by multiplying a step by an index and `3 * 0.1` is `0.30000000000000004`
72
+ * — which the shortest form would write out in full, every digit of it noise.
73
+ * @param value - The number to write.
74
+ * @param digits - How many decimals the mantissa carries. Left out, it carries
75
+ * as few as tell this number from its neighbours.
76
+ * @returns The number in scientific notation, or `0` for zero, which has no
77
+ * exponent and is written the same way on any axis.
78
+ */
79
+ export function formatScientific(value: number, digits?: number): string {
80
+ if (value === 0) return '0';
81
+ if (digits === undefined) {
82
+ return Number(value.toPrecision(SCIENTIFIC_DIGITS)).toExponential();
83
+ }
84
+ return value.toExponential(Math.min(100, Math.max(0, Math.floor(digits))));
85
+ }
86
+
87
+ /**
88
+ * How one axis writes every one of its labels.
89
+ *
90
+ * The notation is chosen once, from the largest tick on the axis, and then used
91
+ * for all of them — including the small ones and the zero. An axis is read by
92
+ * running an eye along it, and one whose labels changed notation partway would
93
+ * have to be read a label at a time instead.
94
+ * @param axis - The axis, as `chartAxisScale` divided it.
95
+ * @returns A writer for every label on that axis.
96
+ */
97
+ export function axisLabeller(axis: ChartAxisScale): (value: number) => string {
98
+ const { values, decimals } = axis;
99
+ let largest = 0;
100
+ for (const tick of values) {
101
+ const magnitude = Math.abs(tick);
102
+ if (magnitude > largest) largest = magnitude;
103
+ }
104
+ const scientific =
105
+ largest >= SCIENTIFIC_ABOVE || (largest > 0 && largest < SCIENTIFIC_BELOW);
106
+ return scientific
107
+ ? (value) => formatScientific(value)
108
+ : (value) => formatNumber(value, decimals);
109
+ }
110
+
111
+ /**
112
+ * How many significant digits survive the rounding that sheds floating noise.
113
+ *
114
+ * A tick is 1, 2 or 5 times a power of ten times an index, so two digits carry
115
+ * every one of them and six is room to spare for a readout written this way.
116
+ */
117
+ const SCIENTIFIC_DIGITS = 6;
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Keeping the labels above the peaks apart from one another.
3
+ *
4
+ * An annotated spectrum wants a box over every peak it explains, and an
5
+ * isotopologue cluster puts four of them within a few pixels. Sliding them
6
+ * apart is most of the job, and the leader line back to the stick is what says
7
+ * which peak a box belongs to — so a box a little out of place is still
8
+ * readable.
9
+ *
10
+ * A box slid *far* out of place is not. Spacing a crowd out marches the last of
11
+ * them across the whole plot, where it comes to rest over peaks it says nothing
12
+ * about, with a leader long enough to be read as pointing at one of them. Those
13
+ * are dropped, and only those: a mark still sits on every annotated peak, so
14
+ * the fragment is not one the chemist concludes the spectrum lacks — it is one
15
+ * whose picture is a zoom away.
16
+ */
17
+
18
+ import type { NumberArray } from 'cheminfo-types';
19
+
20
+ /**
21
+ * Slide overlapping boxes apart, keeping every one of them inside the plot.
22
+ *
23
+ * Two sweeps, and the order of the clamps is the whole behaviour. The first
24
+ * sweep runs left to right and pushes each box far enough past its neighbour to
25
+ * clear it, which piles the crowding up against the right edge; the second runs
26
+ * back the other way, pulling that pile inside the right bound and spacing it
27
+ * out leftwards again.
28
+ *
29
+ * The left bound is then applied last, after the spacing, and so beats it. A
30
+ * cluster too wide for the room it is in therefore ends with its leftmost boxes
31
+ * overlapping rather than with one of them hanging off the plot — an overlap is
32
+ * two labels a reader can still pick apart with the leader lines, while a box
33
+ * outside the plot is clipped away and reads as an annotation that was never
34
+ * made.
35
+ * @param centres - Where each box would like to be centred, in pixels; any
36
+ * order, and the result comes back in that same order.
37
+ * @param bounds - `[from, to]` in pixels that no box may extend beyond.
38
+ * @param width - How wide every box is.
39
+ * @param gap - The clear space wanted between two neighbouring boxes.
40
+ * @param maximumDrift - How far a box may be slid from where it wanted to be
41
+ * before it is dropped instead, in pixels. Defaults to two whole box steps.
42
+ * @returns The centre each box was actually given, `NaN` for one that was slid
43
+ * too far and dropped.
44
+ */
45
+ export function layoutAnnotationBoxes(
46
+ centres: NumberArray,
47
+ bounds: readonly [number, number],
48
+ width: number,
49
+ gap: number,
50
+ maximumDrift = (width + gap) * MAXIMUM_DRIFT_STEPS,
51
+ ): Float64Array {
52
+ const count = centres.length;
53
+ const placed = new Float64Array(count);
54
+ if (count === 0) return placed;
55
+
56
+ const half = width / 2;
57
+ const minimumCentre = bounds[0] + half;
58
+ const maximumCentre = bounds[1] - half;
59
+ const step = width + gap;
60
+ const order = ascendingOrder(centres);
61
+
62
+ let previous = Number.NEGATIVE_INFINITY;
63
+ for (let position = 0; position < count; position++) {
64
+ const index = order[position] as number;
65
+ let centre = Math.min(
66
+ Math.max(centres[index] as number, minimumCentre),
67
+ maximumCentre,
68
+ );
69
+ if (centre < previous + step) centre = previous + step;
70
+ placed[index] = centre;
71
+ previous = centre;
72
+ }
73
+
74
+ let next = Number.POSITIVE_INFINITY;
75
+ for (let position = count - 1; position >= 0; position--) {
76
+ const index = order[position] as number;
77
+ let centre = placed[index] as number;
78
+ if (centre > maximumCentre) centre = maximumCentre;
79
+ if (centre > next - step) centre = next - step;
80
+ if (centre < minimumCentre) centre = minimumCentre;
81
+ placed[index] = centre;
82
+ next = centre;
83
+ }
84
+
85
+ // A picture that has been slid too far from the peak it explains is worse
86
+ // than no picture: it hangs over a peak it says nothing about, and the leader
87
+ // back to its own is long enough to be read as pointing at something else.
88
+ // Those are dropped rather than drawn, and the mark on the peak still says
89
+ // the annotation is there.
90
+ for (let index = 0; index < count; index++) {
91
+ const wanted = centres[index] as number;
92
+ if (Math.abs((placed[index] as number) - wanted) > maximumDrift) {
93
+ placed[index] = Number.NaN;
94
+ }
95
+ }
96
+ return placed;
97
+ }
98
+
99
+ /**
100
+ * How far a picture may be slid from its peak, counted in whole box steps.
101
+ *
102
+ * Two: a box may be pushed past two neighbours and still be read as belonging
103
+ * to the peak under it, which is what a cluster of three peaks needs. Past that
104
+ * the leader is longer than the box is wide and reaches across other peaks, so
105
+ * the picture reads as answering for one of them instead.
106
+ */
107
+ export const MAXIMUM_DRIFT_STEPS = 2;
108
+
109
+ /**
110
+ * The indices of the boxes, ordered by where they want to be.
111
+ *
112
+ * The sweeps only make sense left to right, and the caller's order is whatever
113
+ * the annotations came in — usually by mass, but a second producer's marks are
114
+ * appended rather than merged.
115
+ * @param centres - Where each box would like to be centred.
116
+ * @returns The indices, ascending by centre.
117
+ */
118
+ function ascendingOrder(centres: NumberArray): Uint32Array {
119
+ const order = new Uint32Array(centres.length);
120
+ for (let index = 0; index < centres.length; index++) {
121
+ order[index] = index;
122
+ }
123
+ return order.toSorted(
124
+ (first, second) => (centres[first] as number) - (centres[second] as number),
125
+ );
126
+ }
@@ -12,6 +12,15 @@ const COMFORTABLE_LABEL = 6;
12
12
  const STEP_10 = Math.sqrt(50);
13
13
  const STEP_5 = Math.sqrt(10);
14
14
  const STEP_2 = Math.SQRT2;
15
+ /**
16
+ * How far a fraction may sit above 1, 2 or 5 and still count as being on it.
17
+ *
18
+ * `span / count` is computed in floating point, so a window that ought to give
19
+ * a step of exactly one lands a hair above it — `1.0000000000000002` — and an
20
+ * exact comparison would take the next step up and halve the number of ticks
21
+ * for no visible reason.
22
+ */
23
+ const STEP_EPSILON = 1e-9;
15
24
 
16
25
  /** A niced axis: its domain, its ticks, and the labels they are written with. */
17
26
  export interface ChartAxisScale {
@@ -29,6 +38,22 @@ export interface ChartAxisScale {
29
38
  readonly labels: readonly string[];
30
39
  }
31
40
 
41
+ /**
42
+ * How the step is chosen when an even division lands between two nice ones.
43
+ *
44
+ * - `nearest` — take whichever of 1, 2 or 5 the division is closest to, which
45
+ * puts the tick count near what was asked for from either side.
46
+ * - `atMost` — always take the larger, so the count asked for is a budget the
47
+ * axis never exceeds.
48
+ *
49
+ * The difference is not cosmetic. A figure asking for about five ticks wants
50
+ * them spaced as evenly as the numbers allow, and one either way costs it
51
+ * nothing. An axis in a two-hundred-pixel panel has worked its count out from
52
+ * the room it has and the width of a label, so one tick more than it asked for
53
+ * is two labels touching.
54
+ */
55
+ export type ChartAxisStep = 'nearest' | 'atMost';
56
+
32
57
  /** How an axis is divided. */
33
58
  export interface ChartAxisScaleOptions {
34
59
  /**
@@ -39,10 +64,15 @@ export interface ChartAxisScaleOptions {
39
64
  /**
40
65
  * Whether to widen the domain outward to whole steps, so the axis ends on a
41
66
  * labelled tick. Turn it off when the domain is already exact — a share that
42
- * must end at 100%.
67
+ * must end at 100%, or a window a reader dragged out for themselves.
43
68
  * @default true
44
69
  */
45
70
  nice?: boolean;
71
+ /**
72
+ * How the step is chosen. See {@link ChartAxisStep}.
73
+ * @default 'nearest'
74
+ */
75
+ step?: ChartAxisStep;
46
76
  }
47
77
 
48
78
  /**
@@ -68,11 +98,34 @@ export function chartAxisScale(
68
98
  max: number,
69
99
  options: ChartAxisScaleOptions = {},
70
100
  ): ChartAxisScale {
71
- const { count = DEFAULT_COUNT, nice = true } = options;
101
+ const { count = DEFAULT_COUNT, nice = true, step: rounding } = options;
72
102
  const wanted = tickCount(count);
103
+ // A window of one point is not a window: there is no step to read a
104
+ // precision off, so the single label is written at the precision its own
105
+ // magnitude asks for. Only when the domain is taken as given — a domain that
106
+ // is to be niced is opened instead, so that a constant column still draws an
107
+ // axis to stand on.
108
+ if (!nice && min === max && Number.isFinite(min)) {
109
+ const decimals = chartTickDecimals(Math.abs(min));
110
+ return {
111
+ domain: [min, min],
112
+ values: [min],
113
+ step: 0,
114
+ decimals,
115
+ exponent: 0,
116
+ labels: [chartTickLabel(min, decimals)],
117
+ };
118
+ }
73
119
  const opened = openDomain(min, max);
74
- const domain = nice ? chartNiceDomain(opened[0], opened[1], wanted) : opened;
75
- const [first, last, increment] = tickSpec(domain[0], domain[1], wanted);
120
+ const domain = nice
121
+ ? chartNiceDomain(opened[0], opened[1], wanted, rounding)
122
+ : opened;
123
+ const [first, last, increment] = tickSpec(
124
+ domain[0],
125
+ domain[1],
126
+ wanted,
127
+ rounding,
128
+ );
76
129
  const spacing = increment < 0 ? -1 / increment : increment;
77
130
  const step = Number.isFinite(spacing) && spacing > 0 ? spacing : 0;
78
131
  const values = step === 0 ? [] : tickValues(first, last, increment);
@@ -93,18 +146,20 @@ export function chartAxisScale(
93
146
  * @param min - One end, in either order.
94
147
  * @param max - The other end.
95
148
  * @param count - Roughly how many ticks the domain will carry. Defaults to `5`.
149
+ * @param rounding - How the step is chosen. See {@link ChartAxisStep}.
96
150
  * @returns The widened domain, ascending.
97
151
  */
98
152
  export function chartNiceDomain(
99
153
  min: number,
100
154
  max: number,
101
155
  count = DEFAULT_COUNT,
156
+ rounding: ChartAxisStep = 'nearest',
102
157
  ): [number, number] {
103
158
  const wanted = tickCount(count);
104
159
  let [start, stop] = openDomain(min, max);
105
160
  let previous = 0;
106
161
  for (let pass = 0; pass < NICE_PASSES; pass++) {
107
- const [, , increment] = tickSpec(start, stop, wanted);
162
+ const [, , increment] = tickSpec(start, stop, wanted, rounding);
108
163
  if (increment === previous || !Number.isFinite(increment)) break;
109
164
  const low = wholeStep(start, increment, true);
110
165
  const high = wholeStep(stop, increment, false);
@@ -163,14 +218,41 @@ export function chartExponentSuffix(exponent: number): string {
163
218
 
164
219
  type TickSpec = [first: number, last: number, increment: number];
165
220
 
166
- function tickSpec(start: number, stop: number, count: number): TickSpec {
221
+ /**
222
+ * The nice factor a division is closest to.
223
+ * @param error - The division's mantissa, between 1 and 10.
224
+ * @returns 1, 2, 5 or 10.
225
+ */
226
+ function stepNearest(error: number): number {
227
+ if (error >= STEP_10) return 10;
228
+ if (error >= STEP_5) return 5;
229
+ if (error >= STEP_2) return 2;
230
+ return 1;
231
+ }
232
+
233
+ /**
234
+ * The smallest nice factor at or above a division, so the ticks are never
235
+ * closer together than asked for.
236
+ * @param error - The division's mantissa, between 1 and 10.
237
+ * @returns 1, 2, 5 or 10.
238
+ */
239
+ function stepAtMost(error: number): number {
240
+ if (error <= 1 + STEP_EPSILON) return 1;
241
+ if (error <= 2 + STEP_EPSILON) return 2;
242
+ if (error <= 5 + STEP_EPSILON) return 5;
243
+ return 10;
244
+ }
245
+
246
+ function tickSpec(
247
+ start: number,
248
+ stop: number,
249
+ count: number,
250
+ rounding: ChartAxisStep = 'nearest',
251
+ ): TickSpec {
167
252
  const rawStep = (stop - start) / count;
168
253
  const power = Math.floor(Math.log10(rawStep));
169
254
  const error = rawStep / 10 ** power;
170
- let factor = 1;
171
- if (error >= STEP_2) factor = 2;
172
- if (error >= STEP_5) factor = 5;
173
- if (error >= STEP_10) factor = 10;
255
+ const factor = rounding === 'atMost' ? stepAtMost(error) : stepNearest(error);
174
256
  if (power < 0) {
175
257
  const divisor = 10 ** -power / factor;
176
258
  let first = Math.round(start * divisor);
@@ -0,0 +1,185 @@
1
+ /**
2
+ * The window a chart is showing, which is the one thing every viewer built on
3
+ * this package holds in common.
4
+ *
5
+ * Two numbers on each axis and nothing else — no units, no labels, no notion of
6
+ * what is being measured. That absence is the point: a mass spectrum reads its
7
+ * x axis as m/z and an infrared spectrum reads the same two numbers as
8
+ * wavenumbers, so a window that named either would need converting at every
9
+ * boundary, and a zoom gesture would have to be written twice to do the same
10
+ * arithmetic.
11
+ *
12
+ * The y axis is called nothing more specific than y for the same reason. It
13
+ * carries intensity in one viewer, absorbance or percent transmittance in
14
+ * another, and the arithmetic that maps it to pixels cares only that it is a
15
+ * range of numbers.
16
+ */
17
+
18
+ /** The window a chart is showing, in data units. */
19
+ export interface ChartDomain {
20
+ /** `[min, max]` on the horizontal axis. */
21
+ x: [number, number];
22
+ /** `[min, max]` on the vertical axis, the lower bound negative in mirror mode. */
23
+ y: [number, number];
24
+ }
25
+
26
+ /**
27
+ * How the vertical axis behaves under a gesture, where the two viewers differ.
28
+ *
29
+ * A mass spectrum is drawn as sticks standing on zero, so zero has to stay in
30
+ * the window however it is zoomed — a window starting at a tenth of the base
31
+ * peak cuts every stick off at the ankles. A continuous trace has no feet: an
32
+ * infrared band dragged out at 20 to 60 percent transmittance is asked about at
33
+ * 20 to 60 percent, and forcing 100 into the window would undo the zoom that was
34
+ * just asked for.
35
+ *
36
+ * The baseline is also what the wheel scales about, which is not always zero:
37
+ * percent transmittance runs *down* from 100, and scaling it about zero would
38
+ * walk the whole trace off the top of the plot instead of stretching it.
39
+ */
40
+ export interface YAxisRules {
41
+ /**
42
+ * The value the wheel scales about, and the line a drag is judged against.
43
+ * @default 0
44
+ */
45
+ baseline?: number;
46
+ /**
47
+ * Whether the baseline must stay inside the window a drag asks for — true for
48
+ * a stick spectrum standing on it, false for a continuous trace.
49
+ * @default true
50
+ */
51
+ keepBaseline?: boolean;
52
+ /**
53
+ * Whether the features hang **down** from the baseline rather than standing up
54
+ * out of it.
55
+ *
56
+ * This is which side of the baseline the data is on, and it decides which way
57
+ * "released past the baseline" points. A mass peak and an absorbance band both
58
+ * stand up out of a baseline at the foot of the plot, so the gesture is a drag
59
+ * released *below* it. Percent transmittance hangs down from 100, which sits
60
+ * near the *top* — so there the gesture is a drag released above it, and asking
61
+ * the mass question instead would make almost every drag in the plot take the
62
+ * value axis with it.
63
+ * @default false
64
+ */
65
+ pointsDown?: boolean;
66
+ }
67
+
68
+ /** What the rules come to when a viewer states none of them. */
69
+ export const DEFAULT_Y_AXIS_RULES: Required<YAxisRules> = {
70
+ baseline: 0,
71
+ keepBaseline: true,
72
+ pointsDown: false,
73
+ };
74
+
75
+ /**
76
+ * What a drag across the plot zooms to.
77
+ *
78
+ * `xAxis` is the reading gesture and the default: the question a chemist asks of
79
+ * a spectrum is nearly always "what is between 1650 and 1750", never "what is
80
+ * between forty and sixty percent", so a drag narrows the horizontal axis and
81
+ * leaves the height alone unless it is released past the baseline.
82
+ *
83
+ * `box` is the tool: while it is chosen, the rectangle dragged out is the window,
84
+ * both axes at once. It is a mode rather than a modifier because it is used in
85
+ * runs — a baseline being examined is examined several times over — and a
86
+ * modifier held down through each of them is a worse gesture than a tool pressed
87
+ * once.
88
+ *
89
+ * The two are named apart from the whole of `DragMode` so that a chart offering
90
+ * nothing but zoom tools can say so in its own signature — which is what stops
91
+ * `select`, the one drag that moves no axis, from reaching a chart with no
92
+ * handler for it.
93
+ */
94
+ export type ZoomDragMode = 'xAxis' | 'box';
95
+
96
+ /**
97
+ * What a drag across the plot asks for.
98
+ *
99
+ * `select` is the third and it is not a zoom at all: the rectangle swept out is
100
+ * handed back as a range and the window is left exactly where it was. A
101
+ * chromatographic peak is integrated between two retention times a chemist
102
+ * chose, and choosing them by dragging over them is the gesture — so the answer
103
+ * to it is two numbers on the horizontal axis rather than a new window, and a
104
+ * chart that zoomed to them as well would take the neighbouring peaks off the
105
+ * screen the moment the boundaries were set.
106
+ *
107
+ * It is a mode rather than a modifier for the reason `ZoomDragMode` already
108
+ * gives — integration is done in runs — and it is kept out of `ZoomDragMode` so
109
+ * that a chart offering only zoom tools, which is what the infrared toolbar
110
+ * hands to its `zoomGestures`, cannot be handed it by a widening nobody noticed.
111
+ * Handed one, that chart would sweep out a rectangle and then do nothing at all.
112
+ */
113
+ export type DragMode = ZoomDragMode | 'select';
114
+
115
+ /** How the y axis behaves, and what a drag is taken to mean. */
116
+ export interface ZoomRules extends YAxisRules {
117
+ /**
118
+ * What a drag asks for.
119
+ * @default 'xAxis'
120
+ */
121
+ drag?: DragMode;
122
+ }
123
+
124
+ /**
125
+ * Which gestures a chart answers, for a viewer that offers fewer than all of
126
+ * them.
127
+ *
128
+ * A gesture is worth having only where the axis it moves has somewhere to go,
129
+ * and that is a property of what is being measured rather than of the chart. An
130
+ * axis running between two ends the data fills — percent transmittance from 0 to
131
+ * 100 — has nothing for the wheel to scale: stretching it about its baseline
132
+ * pushes the trace off the plot and leaves an axis that no longer reads as
133
+ * percent. An axis open at one end — intensity, absorbance — has weak features
134
+ * lying against the baseline, and bringing those up is what the wheel is for.
135
+ *
136
+ * Saying it here, once, is what keeps a viewer from answering a gesture in one
137
+ * mode and quietly ignoring it in another: the whole set travels as one object
138
+ * from whatever knows the measurement into `useChartZoom`.
139
+ */
140
+ export interface ZoomGestures {
141
+ /**
142
+ * What a drag across the plot asks for.
143
+ * @default 'xAxis'
144
+ */
145
+ drag?: DragMode;
146
+ /**
147
+ * Whether the wheel scales the value axis about its baseline.
148
+ *
149
+ * Turned off, the wheel is left entirely alone — the page scrolls under the
150
+ * pointer as it does anywhere else, which is what a reader expects of a chart
151
+ * that does not answer the gesture.
152
+ * @default true
153
+ */
154
+ wheel?: boolean;
155
+ }
156
+
157
+ /** What the gestures come to when a viewer states none of them. */
158
+ export const DEFAULT_ZOOM_GESTURES: Required<ZoomGestures> = {
159
+ drag: 'xAxis',
160
+ wheel: true,
161
+ };
162
+
163
+ /**
164
+ * Whether two windows show the same thing, compared by their four numbers.
165
+ *
166
+ * By value and never by identity, because the fitted window is rebuilt from the
167
+ * spectra whenever anything about them changes — a colour, a name, a visibility
168
+ * — and only some of those changes move an axis. A chart that told the two
169
+ * apart by identity would throw the user's zoom away every time they touched
170
+ * the list beside it.
171
+ * @param current - The window in force.
172
+ * @param next - The window just worked out.
173
+ * @returns Whether both axes already run between the same bounds.
174
+ */
175
+ export function sameChartDomain(
176
+ current: ChartDomain,
177
+ next: ChartDomain,
178
+ ): boolean {
179
+ return (
180
+ current.x[0] === next.x[0] &&
181
+ current.x[1] === next.x[1] &&
182
+ current.y[0] === next.y[0] &&
183
+ current.y[1] === next.y[1]
184
+ );
185
+ }