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,162 @@
1
+ /**
2
+ * How many charts a column of a given height can stack, and how tall each stands.
3
+ *
4
+ * A viewer that draws one pane per selected spectrum has to answer a question
5
+ * the stack itself never asks. A reader who ticks a dozen spectra has not asked
6
+ * for twelve panes of fifty pixels, and a stack handed them draws twelve stubs
7
+ * with a full set of axes over each — the failure `ChartStack.tsx`'s header
8
+ * describes, arrived at from above instead of through a splitter. So the number
9
+ * of panes is settled from the height actually available, against the stack's
10
+ * own floors rather than a number somebody hoped for, and whatever a reader
11
+ * selects past that number is overlaid together into the last pane rather than
12
+ * dropped, which is the one outcome a reader cannot see happening.
13
+ *
14
+ * All of it is arithmetic over `chartStackLevel.tsx`'s floors and
15
+ * `chartGeometry.ts`'s margins; nothing here renders, measures or reads a
16
+ * spectrum.
17
+ */
18
+
19
+ import { MARGIN, SHARED_AXIS_MARGIN } from './chartGeometry.ts';
20
+
21
+ /**
22
+ * The shortest a pane that is *not* at the foot of the stack may stand, in
23
+ * pixels.
24
+ *
25
+ * Ninety, and ninety exactly, because it is not a judgement about how short a
26
+ * chart may be: `chartStackLevel.tsx` hands `SplitPane` a `closeThreshold` of 90
27
+ * at every non-foot split, and a split measuring under that closes its pane
28
+ * outright — before a splitter has ever been touched, so a stack built on a
29
+ * floor of 80 would come up with panes already shut and no gesture that made
30
+ * them so. The threshold is applied as `>=`, which is why standing exactly on it
31
+ * is allowed. That constant is module-private over there, so its value is
32
+ * restated here and the two have to move together.
33
+ *
34
+ * A caller must state this as each pane's own `minimumHeight`. Left unsaid,
35
+ * `paneHeight` clamps the pane up to the 120 pixels it defaults to, and five
36
+ * panes would then demand 688 pixels where 538 draws them.
37
+ */
38
+ export const STACKED_MINIMUM = 90;
39
+
40
+ /**
41
+ * What the pane at the foot pays for its axis beyond what every pane pays, in
42
+ * pixels.
43
+ *
44
+ * Only the foot of a stack writes the tick row and the axis title under its
45
+ * plot, and that is `MARGIN.bottom` less the `SHARED_AXIS_MARGIN` a pane keeps
46
+ * even when it writes no axis — 26 of them, not 34. The *difference* is what
47
+ * matters and the whole bottom margin is not it: a stacked pane still leaves a
48
+ * little room under its trace, and charging the foot for all 34 draws its plot
49
+ * eight pixels taller than the others, so a peak of one intensity comes out
50
+ * taller at the bottom of the stack than at the top. Every other side of the margin
51
+ * is paid alike by every pane, the room kept above the plot for the tallest
52
+ * peak's label as much as the gutter the value labels are written in, so it
53
+ * cancels out of the difference between two panes and does not appear here.
54
+ * This one asymmetry is the whole of why an equal split of the *boxes* is not an
55
+ * equal split of the *plots*.
56
+ */
57
+ export const FOOT_FURNITURE = MARGIN.bottom - SHARED_AXIS_MARGIN;
58
+
59
+ /**
60
+ * The shortest the pane at the foot may stand, in pixels.
61
+ *
62
+ * The ordinary floor plus the tick row and axis title only it writes, so that
63
+ * the plot left inside it is the same plot `STACKED_MINIMUM` leaves inside a
64
+ * pane above it. Deriving it rather than picking 116 is what makes the tightest
65
+ * stack land exactly on both floors at once: at a height of
66
+ * `FOOT_MINIMUM + (n - 1) * STACKED_MINIMUM`, `stackShares` gives every pane
67
+ * above the foot exactly `STACKED_MINIMUM` and the foot exactly this.
68
+ */
69
+ export const FOOT_MINIMUM = STACKED_MINIMUM + FOOT_FURNITURE;
70
+
71
+ /**
72
+ * How much room the splitter between two panes takes, in pixels.
73
+ *
74
+ * `react-science` draws a vertical splitter as a ten-pixel bar, and there is one
75
+ * between each *pair* of panes rather than one per pane — five of them under six
76
+ * panes. Small enough to be forgotten and large enough that forgetting it costs
77
+ * a pane: the fifty it comes to across a full stack is more than half a stacked
78
+ * minimum.
79
+ */
80
+ export const SPLITTER = 10;
81
+
82
+ /**
83
+ * The most panes worth stacking at all, however tall the column.
84
+ *
85
+ * Six, and the height is not what settles it. A 1080-pixel screen with the side
86
+ * panels open leaves the stack something near 900 pixels; six panes take 50 of
87
+ * those in splitters and share the rest, which is a box of 133 pixels each and a
88
+ * plot inside it of barely a hundred — about the height of the label stack a
89
+ * mass spectrum draws over its tallest sticks, so a seventh pane makes the
90
+ * labels taller than the trace they belong to. And the reader stacked the panes
91
+ * in order to compare them: past six the first and the last are most of a page
92
+ * apart, and an eye travelling that far is no longer comparing anything.
93
+ * Whatever is selected beyond this is overlaid into the last pane, where traces
94
+ * drawn over one another are compared the way they always were.
95
+ */
96
+ export const STACK_LIMIT = 6;
97
+
98
+ /**
99
+ * How many panes a column of a given height can hold and still draw spectra.
100
+ *
101
+ * The arithmetic is the stack as it will actually be built: one pane at the foot
102
+ * carrying the horizontal axis, every other pane at the stacked floor, and a
103
+ * splitter between each pair. Nothing here rounds in the caller's favour — a
104
+ * height one pixel short of the fourth pane holds three.
105
+ * @param height - The whole column the stack fills, in pixels, with the
106
+ * splitters counted in: it is the box `ChartStack` is handed, not the room its
107
+ * panes are left with.
108
+ * @returns At least one, because a lone pane squeezed short is still the
109
+ * measurement and the stack draws it rather than nothing — that is why the foot
110
+ * pane is given no close threshold — and never more than `STACK_LIMIT`.
111
+ */
112
+ export function stackCapacity(height: number): number {
113
+ const beyondTheFoot = height - FOOT_MINIMUM;
114
+ const fits = 1 + Math.floor(beyondTheFoot / (STACKED_MINIMUM + SPLITTER));
115
+ return Math.min(STACK_LIMIT, Math.max(1, fits));
116
+ }
117
+
118
+ /**
119
+ * How tall each pane of the stack stands, top to bottom.
120
+ *
121
+ * The split equalises the **plot** rather than the box. An equal share of the
122
+ * box hands the foot pane 34 pixels of tick row and axis title that the panes
123
+ * above it do not draw, so its trace comes out visibly shorter than theirs while
124
+ * every box measures the same — the one thing a reader comparing two spectra
125
+ * side by side must not be shown. So `FOOT_FURNITURE` is taken off the top, what
126
+ * is left is divided evenly, and the foot is given its share back with the
127
+ * furniture on it.
128
+ *
129
+ * The division is floored, so the panes above the foot are whole pixels and the
130
+ * remainder — never more than `count - 1` of them — lands on the foot, which is
131
+ * the tallest pane and the one where two pixels are least visible. That keeps
132
+ * the sum exact, and it is also why the foot's share is *at least*
133
+ * `FOOT_FURNITURE` above a stacked one rather than exactly it.
134
+ * @param height - The room the panes themselves share, in pixels. A caller
135
+ * holding the whole column subtracts the splitters first — `height -
136
+ * (count - 1) * SPLITTER` — because `SplitPane` takes those out of the panes,
137
+ * not out of the column.
138
+ * @param count - How many panes to stack, normally whatever `stackCapacity`
139
+ * answered.
140
+ * @returns One height per pane, summing exactly to `height`, each at or above
141
+ * its own floor. The two cannot both hold for a height short of what `count`
142
+ * panes need, and there the floors win and the sum overshoots: a pane under its
143
+ * floor is the stub with a full set of axes over it, which is the worse of the
144
+ * two pictures. A lone pane is the exception and takes the whole height floor
145
+ * and all, since there is nothing to redistribute to and nothing to compare it
146
+ * against.
147
+ */
148
+ export function stackShares(height: number, count: number): readonly number[] {
149
+ if (!Number.isInteger(count) || count < 1) return [];
150
+ if (count === 1) return [height];
151
+
152
+ const stacked = Math.max(
153
+ STACKED_MINIMUM,
154
+ Math.floor((height - FOOT_FURNITURE) / count),
155
+ );
156
+ const shares = new Array<number>(count);
157
+ for (let index = 0; index < count - 1; index++) {
158
+ shares[index] = stacked;
159
+ }
160
+ shares[count - 1] = Math.max(FOOT_MINIMUM, height - stacked * (count - 1));
161
+ return shares;
162
+ }
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Turning a pointer on the screen into a point on the chart.
3
+ *
4
+ * Asked by everything that reads a gesture — the crosshair, the box zoom, the
5
+ * click that pins a label — so it is answered once, here, and all of them place
6
+ * the pointer in the same place.
7
+ *
8
+ * The SVG's own screen matrix is the only correct answer once the chart carries
9
+ * a `viewBox`: the element then draws in user units of its own, and a pointer
10
+ * 300 CSS pixels from the left edge of an 800-pixel-wide chart showing 600 user
11
+ * units is at 225 of them, not at 300. The matrix carries that scaling, the
12
+ * device pixel ratio and any transform an ancestor applies, all at once, so
13
+ * nothing downstream has to know that any of them happened.
14
+ */
15
+
16
+ /** A point on the chart, in the user units its `viewBox` is written in. */
17
+ export interface ChartPoint {
18
+ /** Distance from the left edge of the SVG. */
19
+ x: number;
20
+ /** Distance from its top edge. */
21
+ y: number;
22
+ }
23
+
24
+ /** The little of an SVG matrix a pointer position is worked out from. */
25
+ export interface ScreenMatrix {
26
+ /** Horizontal scaling. */
27
+ a: number;
28
+ /** Vertical shear. */
29
+ b: number;
30
+ /** Horizontal shear. */
31
+ c: number;
32
+ /** Vertical scaling. */
33
+ d: number;
34
+ /** Horizontal translation. */
35
+ e: number;
36
+ /** Vertical translation. */
37
+ f: number;
38
+ /** The matrix that undoes this one. */
39
+ inverse: () => ScreenMatrix;
40
+ }
41
+
42
+ /** The little of an SVG element a pointer position is asked of. */
43
+ export interface PointerSurface {
44
+ /** How the SVG's user units are laid over the screen. */
45
+ getScreenCTM: () => ScreenMatrix | null;
46
+ }
47
+
48
+ /**
49
+ * Where a pointer is, in the user units the SVG draws in.
50
+ *
51
+ * The matrix maps user units onto the screen, so it is inverted to go the other
52
+ * way. It is applied here rather than through a `DOMPoint` so that the
53
+ * arithmetic can be read — and tested — without a browser standing by.
54
+ *
55
+ * A surface that is not laid out has no matrix to give: an SVG inside a folded
56
+ * panel, or one whose `viewBox` has collapsed to nothing, answers `null` rather
57
+ * than a matrix of zeros, and the caller is then told there is no position
58
+ * instead of being handed an infinity that lands every gesture at the same
59
+ * impossible place.
60
+ * @param surface - The SVG, `null` before it is on screen.
61
+ * @param clientX - Where the pointer is on the screen, horizontally.
62
+ * @param clientY - Where it is vertically.
63
+ * @returns The point, `null` when the surface cannot place it.
64
+ */
65
+ export function svgPointAt(
66
+ surface: PointerSurface | null,
67
+ clientX: number,
68
+ clientY: number,
69
+ ): ChartPoint | null {
70
+ const screen = surface?.getScreenCTM();
71
+ if (!screen) return null;
72
+ const inverse = screen.inverse();
73
+ const x = clientX * inverse.a + clientY * inverse.c + inverse.e;
74
+ const y = clientX * inverse.b + clientY * inverse.d + inverse.f;
75
+ if (!Number.isFinite(x) || !Number.isFinite(y)) return null;
76
+ return { x, y };
77
+ }
@@ -0,0 +1,228 @@
1
+ /**
2
+ * The one string a trace becomes, and why it is only ever one.
3
+ *
4
+ * A profile scan is a few hundred thousand samples and a peak table a few
5
+ * thousand sticks. Drawn as an element each, the browser holds a hundred
6
+ * thousand nodes for a picture that is a single stroke, and every pointer move
7
+ * across the chart then costs a walk of all of them. Both traces are therefore
8
+ * one `<path>` built here, and the only thing that ever changes is its `d`.
9
+ *
10
+ * Coordinates are rounded to a hundredth of a pixel. No display resolves more
11
+ * than that, while the full precision of a double writes `312.40000000000003`
12
+ * where `312.4` was meant — six times the string for a distance nobody can see.
13
+ */
14
+
15
+ import type { NumberArray } from 'cheminfo-types';
16
+
17
+ import type { ChartScale } from './chartScale.ts';
18
+ import { chartPixel } from './chartScale.ts';
19
+
20
+ /**
21
+ * The path of a continuous trace: every sample joined to the next.
22
+ *
23
+ * A sample that maps to nothing finite — a `NaN` intensity a reader let
24
+ * through, a mass a degenerate scale sent to infinity — breaks the line in two
25
+ * rather than being passed over, because joining the two sound samples either
26
+ * side of it draws a straight run across a stretch the instrument never
27
+ * reported. Writing the `NaN` into the string instead would void the whole
28
+ * path, and the trace would then silently not be drawn at all.
29
+ * @param x - Where each sample was taken, ascending.
30
+ * @param y - What was measured there, one per sample.
31
+ * @param xScale - The x axis as it is currently zoomed.
32
+ * @param yScale - The y axis as it is currently zoomed.
33
+ * @returns The `d` of one path; empty when there is nothing to draw, and a bare
34
+ * `M` for a trace of a single sample, which is a point and not a line.
35
+ */
36
+ export function profilePath(
37
+ x: NumberArray,
38
+ y: NumberArray,
39
+ xScale: ChartScale,
40
+ yScale: ChartScale,
41
+ ): string {
42
+ // The two scales are read out here and the multiply-add written inline, as
43
+ // `chartScale` asks a loop over points to: a trace is tens of thousands of
44
+ // samples, and a helper call per sample per axis is the one cost this file
45
+ // can avoid without changing what it draws.
46
+ const { offset: xOffset, factor: xFactor } = xScale;
47
+ const { offset: yOffset, factor: yFactor } = yScale;
48
+ const count = Math.min(x.length, y.length);
49
+ let path = '';
50
+ let drawnInRun = 0;
51
+ for (let index = 0; index < count; index++) {
52
+ const pixelX = xOffset + (x[index] as number) * xFactor;
53
+ const pixelY = yOffset + (y[index] as number) * yFactor;
54
+ if (!Number.isFinite(pixelX) || !Number.isFinite(pixelY)) {
55
+ drawnInRun = 0;
56
+ continue;
57
+ }
58
+ const point = `${roundPixel(pixelX)} ${roundPixel(pixelY)}`;
59
+ if (drawnInRun === 0) path += `M${point}`;
60
+ else if (drawnInRun === 1) path += `L${point}`;
61
+ else path += ` ${point}`;
62
+ drawnInRun++;
63
+ }
64
+ return path;
65
+ }
66
+
67
+ /**
68
+ * The path of a centroid: one stick per peak, standing on zero.
69
+ *
70
+ * The foot of every stick is where the intensity axis reads zero rather than
71
+ * the bottom of the plot, which is the same pixel until the chart is mirrored
72
+ * and then is not — a stick of the inverted half hangs from the rule the pair
73
+ * is reflected in. Nothing is clipped here: a peak taller than the window still
74
+ * gets its full stick, and the clip path over the data band is what stops it at
75
+ * the edge, so a zoom into the baseline shows the tall peak leaving the top
76
+ * rather than a gap where it stood.
77
+ * @param x - Where each peak sits, ascending.
78
+ * @param y - How tall each one is, one per peak.
79
+ * @param xScale - The x axis as it is currently zoomed.
80
+ * @param yScale - The y axis as it is currently zoomed, which the foot of the
81
+ * sticks is read off.
82
+ * @returns The `d` of one path, empty when there is nothing to draw.
83
+ */
84
+ export function stickPath(
85
+ x: NumberArray,
86
+ y: NumberArray,
87
+ xScale: ChartScale,
88
+ yScale: ChartScale,
89
+ ): string {
90
+ const count = Math.min(x.length, y.length);
91
+ const foot = chartPixel(yScale, 0);
92
+ if (!Number.isFinite(foot)) return '';
93
+ const baseline = roundPixel(foot);
94
+ // The two scales are read out here and the multiply-add written inline, as
95
+ // `chartScale` asks a loop over points to: a trace is tens of thousands of
96
+ // samples, and a helper call per sample per axis is the one cost this file
97
+ // can avoid without changing what it draws.
98
+ const { offset: xOffset, factor: xFactor } = xScale;
99
+ const { offset: yOffset, factor: yFactor } = yScale;
100
+ let path = '';
101
+ for (let index = 0; index < count; index++) {
102
+ const pixelX = xOffset + (x[index] as number) * xFactor;
103
+ const pixelY = yOffset + (y[index] as number) * yFactor;
104
+ if (!Number.isFinite(pixelX) || !Number.isFinite(pixelY)) continue;
105
+ path += `M${roundPixel(pixelX)} ${baseline}V${roundPixel(pixelY)}`;
106
+ }
107
+ return path;
108
+ }
109
+
110
+ /** What an area is closed at, when the ground it stands on is not zero. */
111
+ export interface AreaPathOptions {
112
+ /**
113
+ * The value the area is closed down onto, in the units of the y axis.
114
+ *
115
+ * A chromatographic baseline is neither at zero nor horizontal — a gradient
116
+ * run drifts a few thousand counts between the first peak and the last — so
117
+ * shading a peak down to the axis shades the column of baseline under it as
118
+ * well, which at a weak peak is most of what the eye then reads as the peak.
119
+ * Given the value the integration was corrected against, the shading and the
120
+ * number in the table are about the same region.
121
+ * @default 0
122
+ */
123
+ baseline?: number;
124
+ }
125
+
126
+ /**
127
+ * The path of the region under a trace: its top edge, closed onto a baseline.
128
+ *
129
+ * `profilePath` draws where a trace went and stops there, so nothing built on
130
+ * it can shade a region — and an integrated chromatographic peak, a UV band
131
+ * and an NMR integral are all that same picture, a stretch of one trace filled
132
+ * in to say how much of it was counted. The top edge is written exactly as
133
+ * `profilePath` writes it, so an area drawn under a trace lies along it to the
134
+ * hundredth of a pixel rather than a rounding apart from it.
135
+ *
136
+ * Each unbroken run of samples is closed on its own: down to the baseline
137
+ * where it ended, back along the baseline to where it began, and shut. A run
138
+ * of one sample encloses nothing and is left out altogether, which is what
139
+ * stops a break in the data from shading a spike of zero width.
140
+ *
141
+ * Nothing is clipped here, exactly as in `profilePath` and `stickPath` — a
142
+ * peak taller than the window keeps its whole area and the clip path over the
143
+ * data band is what stops it at the edge.
144
+ * @param x - Where each sample was taken, ascending.
145
+ * @param y - What was measured there, one per sample.
146
+ * @param xScale - The x axis as it is currently zoomed.
147
+ * @param yScale - The y axis as it is currently zoomed, which the baseline is
148
+ * read off.
149
+ * @param options - Where the ground under the area is.
150
+ * @returns The `d` of one path, holding one closed shape per unbroken run;
151
+ * empty when there is nothing wide enough to enclose anything.
152
+ */
153
+ export function areaPath(
154
+ x: NumberArray,
155
+ y: NumberArray,
156
+ xScale: ChartScale,
157
+ yScale: ChartScale,
158
+ options: AreaPathOptions = {},
159
+ ): string {
160
+ const { baseline = 0 } = options;
161
+ const ground = chartPixel(yScale, baseline);
162
+ if (!Number.isFinite(ground)) return '';
163
+ const foot = roundPixel(ground);
164
+ const count = Math.min(x.length, y.length);
165
+ // The two scales are read out here and the multiply-add written inline, as
166
+ // `chartScale` asks a loop over points to: a trace is tens of thousands of
167
+ // samples, and a helper call per sample per axis is the one cost this file
168
+ // can avoid without changing what it draws.
169
+ const { offset: xOffset, factor: xFactor } = xScale;
170
+ const { offset: yOffset, factor: yFactor } = yScale;
171
+ let path = '';
172
+ let edge = '';
173
+ let drawnInRun = 0;
174
+ let runStart = 0;
175
+ for (let index = 0; index < count; index++) {
176
+ const pixelX = xOffset + (x[index] as number) * xFactor;
177
+ const pixelY = yOffset + (y[index] as number) * yFactor;
178
+ if (!Number.isFinite(pixelX) || !Number.isFinite(pixelY)) {
179
+ path += closedRun(edge, drawnInRun, runStart, foot);
180
+ edge = '';
181
+ drawnInRun = 0;
182
+ continue;
183
+ }
184
+ const left = roundPixel(pixelX);
185
+ const point = `${left} ${roundPixel(pixelY)}`;
186
+ if (drawnInRun === 0) {
187
+ edge = `M${point}`;
188
+ runStart = left;
189
+ } else if (drawnInRun === 1) {
190
+ edge += `L${point}`;
191
+ } else {
192
+ edge += ` ${point}`;
193
+ }
194
+ drawnInRun++;
195
+ }
196
+ return path + closedRun(edge, drawnInRun, runStart, foot);
197
+ }
198
+
199
+ /**
200
+ * Shut one run of samples down onto the baseline.
201
+ * @param edge - The top edge of the run, as `profilePath` would have written it.
202
+ * @param drawnInRun - How many samples that edge was drawn from.
203
+ * @param runStart - Where the run began, in pixels.
204
+ * @param foot - Where the baseline falls, in pixels.
205
+ * @returns The closed shape, empty for a run of fewer than two samples, which
206
+ * has no width and so encloses nothing.
207
+ */
208
+ function closedRun(
209
+ edge: string,
210
+ drawnInRun: number,
211
+ runStart: number,
212
+ foot: number,
213
+ ): string {
214
+ if (drawnInRun < 2) return '';
215
+ return `${edge}V${foot}H${runStart}Z`;
216
+ }
217
+
218
+ /** How many parts of a pixel a coordinate is written to. */
219
+ const PIXEL_PRECISION = 100;
220
+
221
+ /**
222
+ * A coordinate as the path writes it.
223
+ * @param value - Where the point falls, in pixels.
224
+ * @returns The same place, to a hundredth of a pixel.
225
+ */
226
+ function roundPixel(value: number): number {
227
+ return Math.round(value * PIXEL_PRECISION) / PIXEL_PRECISION;
228
+ }
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Where the crosshair writes what the axes say under it.
3
+ *
4
+ * The readout is the one thing on the chart that must never be clipped: it is
5
+ * what the pointer was put there to read, and the places it is most often put
6
+ * are exactly the awkward ones — on the tallest peak, hard against the top of
7
+ * the plot, or out at the far right where a label written rightwards runs off
8
+ * the edge. So the side it is written on and the line it starts on are both
9
+ * decided from the room there is, and neither is a fixed offset.
10
+ */
11
+
12
+ import type { PlotRect } from './chartGeometry.ts';
13
+ import { CHART_FONT, PEAK_LABEL } from './chartTheme.ts';
14
+ import type { ChartPoint } from './svgPoint.ts';
15
+
16
+ /** The clear space between the crosshair and what is written beside it. */
17
+ export const READOUT_GAP = 6;
18
+
19
+ /**
20
+ * The room the readout claims, in pixels.
21
+ *
22
+ * A value at a deep zoom is `1234.5678` and the one under it is shorter, so this
23
+ * is the width of the longest line either can be — measured from the font rather
24
+ * than from the text, because the text is not on screen yet when the side it goes
25
+ * on has to be chosen.
26
+ */
27
+ export const READOUT_WIDTH = 88;
28
+
29
+ /** How many lines the readout is written on: one for each axis. */
30
+ export const READOUT_LINES = 2;
31
+
32
+ /** Where the readout is written, and which way it runs from there. */
33
+ export interface ReadoutPlacement {
34
+ /** The edge the lines are anchored on. */
35
+ x: number;
36
+ /** The baseline of the first line. */
37
+ y: number;
38
+ /** Which way the text runs from `x`. */
39
+ anchor: 'start' | 'end';
40
+ }
41
+
42
+ /**
43
+ * Work out where the readout beside the pointer goes.
44
+ *
45
+ * It is written to the right of the crosshair and above the pointer, which is
46
+ * where a hand holding a mouse is not covering it, and flips to the left as soon
47
+ * as it would otherwise cross the right edge of the plot. Flipping rather than
48
+ * sliding: a readout pinned to the edge would drift away from the crosshair it
49
+ * belongs to as the pointer went further right, and the pair would stop reading
50
+ * as one thing.
51
+ *
52
+ * Both bounds are honoured rather than only the near one, so the last line never
53
+ * runs off the bottom of a short plot. In a plot too short to hold every line
54
+ * the top edge wins: the first line is the one worth keeping, because every
55
+ * viewer writes what its horizontal axis reads there first.
56
+ * @param point - Where the pointer is, in user units.
57
+ * @param plot - Where the plot sits inside the SVG.
58
+ * @param lines - How many lines are written. Defaults to `READOUT_LINES`.
59
+ * @returns The anchor, the first baseline, and which way the text runs.
60
+ */
61
+ export function readoutPlacement(
62
+ point: ChartPoint,
63
+ plot: PlotRect,
64
+ lines = READOUT_LINES,
65
+ ): ReadoutPlacement {
66
+ const runsRight = point.x + READOUT_GAP + READOUT_WIDTH <= plot.right;
67
+ const x = runsRight ? point.x + READOUT_GAP : point.x - READOUT_GAP;
68
+
69
+ const written = Math.max(1, lines);
70
+ const highest = plot.top + CHART_FONT.readout;
71
+ const lowest = plot.bottom - (written - 1) * PEAK_LABEL.lineHeight;
72
+ const y = Math.min(
73
+ Math.max(point.y - READOUT_GAP, highest),
74
+ Math.max(highest, lowest),
75
+ );
76
+
77
+ return { x, y, anchor: runsRight ? 'start' : 'end' };
78
+ }