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,271 @@
1
+ import { Icon } from '@blueprintjs/core';
2
+ import { useMemo } from 'react';
3
+ import { Button, Toolbar } from 'react-science/ui';
4
+
5
+ import {
6
+ panelBodyStyle,
7
+ panelCellStyle,
8
+ panelEmptyStyle,
9
+ panelHeaderCellStyle,
10
+ panelNumberCellStyle,
11
+ panelStyle,
12
+ panelTableStyle,
13
+ panelToolbarStyle,
14
+ } from '../../panel/core/panelStyles.ts';
15
+ import type { AssignedBand } from '../core/assignBands.ts';
16
+ import type { IrBand } from '../core/irBand.ts';
17
+ import { sameIrBand } from '../core/irBand.ts';
18
+ import { formatIrValue, formatWavenumber } from '../core/irFormat.ts';
19
+
20
+ import { useIrActions, useIrEditorState } from './irStateContext.ts';
21
+
22
+ export interface BandsPanelProps {
23
+ /**
24
+ * The band the pointer is resting on, wherever it was hovered.
25
+ * @default null
26
+ */
27
+ highlight?: IrBand | null;
28
+ /**
29
+ * Told which band a row is hovered, so the chart can mark it.
30
+ * @default undefined
31
+ */
32
+ onHighlight?: (band: IrBand | null) => void;
33
+ }
34
+
35
+ /**
36
+ * Every band of the selected spectrum, and everything each one might be.
37
+ *
38
+ * This is the panel the viewer exists for. A trace can be looked at on its own;
39
+ * it is the table beside it that lets it be *read*, and the column that matters
40
+ * is the last one — **every** vibration whose range contains the band, not the
41
+ * best-fitting one. A band at 1715 cm⁻¹ genuinely is a ketone, an aldehyde and a
42
+ * carboxylic acid until something else decides, and a panel that named one would
43
+ * be asserting a structure the spectrum does not determine.
44
+ *
45
+ * Hovering a row marks the band on the chart and hovering the chart lights the
46
+ * row, which is the whole reason the highlight is threaded through the shell
47
+ * rather than held here: the two views are of one thing.
48
+ * @param props - Component props.
49
+ * @returns The panel.
50
+ */
51
+ export function BandsPanel(props: BandsPanelProps) {
52
+ const { highlight = null, onHighlight } = props;
53
+ const { state, selectedSpectrum, assigned } = useIrEditorState();
54
+ const actions = useIrActions();
55
+ const { mode, pickBands, showAssignments, picking } = state.settings;
56
+
57
+ const rows = useMemo(() => assigned, [assigned]);
58
+
59
+ const tsv = useMemo(() => bandsToTsv(rows, mode), [rows, mode]);
60
+
61
+ return (
62
+ <div style={panelStyle}>
63
+ <div style={panelToolbarStyle}>
64
+ <Toolbar aria-label="Band actions">
65
+ <Toolbar.Item
66
+ icon="locate"
67
+ active={pickBands}
68
+ tooltip={pickBands ? 'Stop picking bands' : 'Pick the bands'}
69
+ aria-label="Pick the bands"
70
+ onClick={() => actions.setSettings({ pickBands: !pickBands })}
71
+ />
72
+ <Toolbar.Item
73
+ icon="label"
74
+ active={showAssignments}
75
+ tooltip="Name the assignments on the chart"
76
+ aria-label="Name the assignments on the chart"
77
+ disabled={!pickBands}
78
+ onClick={() =>
79
+ actions.setSettings({ showAssignments: !showAssignments })
80
+ }
81
+ />
82
+ </Toolbar>
83
+
84
+ {/* The threshold is the one picking setting worth reaching for while
85
+ reading: everything else about a band follows from the spectrum, and
86
+ this is what decides whether a shoulder is a band at all. */}
87
+ <label style={thresholdStyle}>
88
+ <span style={{ opacity: 0.7 }}>threshold</span>
89
+ <input
90
+ type="range"
91
+ min={0.005}
92
+ max={0.3}
93
+ step={0.005}
94
+ value={picking.minRelativeHeight ?? 0.02}
95
+ disabled={!pickBands}
96
+ aria-label="How tall a band must be to be picked"
97
+ onChange={(event) =>
98
+ actions.setSettings({
99
+ picking: { minRelativeHeight: event.target.valueAsNumber },
100
+ })
101
+ }
102
+ />
103
+ </label>
104
+
105
+ <span style={{ flex: 1 }} />
106
+
107
+ <Button
108
+ variant="minimal"
109
+ icon="clipboard"
110
+ disabled={rows.length === 0}
111
+ tooltipProps={{ content: 'Copy the table' }}
112
+ aria-label="Copy the table"
113
+ onClick={() => void navigator.clipboard?.writeText(tsv)}
114
+ />
115
+ </div>
116
+
117
+ <div style={panelBodyStyle}>
118
+ {selectedSpectrum === null ? (
119
+ <p style={panelEmptyStyle}>No spectrum is selected.</p>
120
+ ) : !pickBands ? (
121
+ <p style={panelEmptyStyle}>
122
+ The bands are not being picked. Press the locate button above to
123
+ find them.
124
+ </p>
125
+ ) : rows.length === 0 ? (
126
+ <p style={panelEmptyStyle}>
127
+ No band was found above the threshold. Lower it to pick the weaker
128
+ ones.
129
+ </p>
130
+ ) : (
131
+ <table style={panelTableStyle}>
132
+ <thead>
133
+ <tr>
134
+ <th style={panelHeaderCellStyle}>cm⁻¹</th>
135
+ <th style={panelHeaderCellStyle} />
136
+ <th style={{ ...panelHeaderCellStyle, textAlign: 'right' }}>
137
+ {mode === 'absorbance' ? 'A' : '%T'}
138
+ </th>
139
+ <th style={panelHeaderCellStyle}>could be</th>
140
+ </tr>
141
+ </thead>
142
+ <tbody>
143
+ {rows.map((entry) => (
144
+ <BandRow
145
+ key={`${entry.band.spectrumId} ${entry.band.wavenumber}`}
146
+ entry={entry}
147
+ mode={mode}
148
+ lit={sameIrBand(entry.band, highlight)}
149
+ onHighlight={onHighlight}
150
+ />
151
+ ))}
152
+ </tbody>
153
+ </table>
154
+ )}
155
+ </div>
156
+ </div>
157
+ );
158
+ }
159
+
160
+ interface BandRowProps {
161
+ /** The band and everything it might be. */
162
+ entry: AssignedBand;
163
+ /** Which value axis is being read. */
164
+ mode: 'absorbance' | 'transmittance';
165
+ /** Whether the pointer is on this band, here or on the chart. */
166
+ lit: boolean;
167
+ /** Told when the pointer arrives on this row, and when it leaves. */
168
+ onHighlight?: (band: IrBand | null) => void;
169
+ }
170
+
171
+ /**
172
+ * One band: where it is, how strong, and every vibration it could be.
173
+ *
174
+ * The candidates are written as one line rather than a list, so a strong band
175
+ * with four of them stays one row of the table and the wavenumbers keep reading
176
+ * down the column. The `title` carries them again with each one's note, which is
177
+ * where the reason to prefer one lives.
178
+ * @param props - Component props.
179
+ * @returns The row.
180
+ */
181
+ function BandRow(props: BandRowProps) {
182
+ const { entry, mode, lit, onHighlight } = props;
183
+ const { band, candidates } = entry;
184
+
185
+ const value = mode === 'absorbance' ? band.absorbance : band.transmittance;
186
+ const detail = candidates
187
+ .map((candidate) =>
188
+ candidate.note === undefined
189
+ ? `${candidate.group} ${candidate.vibration}`
190
+ : `${candidate.group} ${candidate.vibration} — ${candidate.note}`,
191
+ )
192
+ .join('\n');
193
+
194
+ return (
195
+ <tr
196
+ style={lit ? litRowStyle : undefined}
197
+ onPointerEnter={() => onHighlight?.(band)}
198
+ onPointerLeave={() => onHighlight?.(null)}
199
+ >
200
+ <td style={panelNumberCellStyle}>{formatWavenumber(band.wavenumber)}</td>
201
+ <td style={panelCellStyle} title={STRENGTH_TITLES[band.strength]}>
202
+ {band.strength}
203
+ </td>
204
+ <td style={panelNumberCellStyle}>{formatIrValue(value, mode)}</td>
205
+ <td style={panelCellStyle} title={detail}>
206
+ {candidates.length === 0 ? (
207
+ <span style={{ opacity: 0.5 }}>—</span>
208
+ ) : (
209
+ <span style={{ whiteSpace: 'normal' }}>
210
+ {candidates[0]?.group} {candidates[0]?.vibration}
211
+ {candidates.length > 1 ? (
212
+ <span style={{ opacity: 0.6 }}>
213
+ {' '}
214
+ <Icon icon="more" size={10} /> {candidates.length - 1} more
215
+ </span>
216
+ ) : null}
217
+ </span>
218
+ )}
219
+ </td>
220
+ </tr>
221
+ );
222
+ }
223
+
224
+ /** What each strength letter means, for the column that shows only the letter. */
225
+ const STRENGTH_TITLES = {
226
+ w: 'weak, relative to this spectrum',
227
+ m: 'medium, relative to this spectrum',
228
+ S: 'strong, relative to this spectrum',
229
+ } as const;
230
+
231
+ /**
232
+ * The table as text, for pasting into a notebook.
233
+ *
234
+ * Tab separated with every candidate on the row, because the reason to copy a
235
+ * band table is to put it beside a structure and argue about it — and the
236
+ * argument is over the candidates rather than over the wavenumbers.
237
+ * @param rows - The bands, as they are shown.
238
+ * @param mode - Which value axis is being read.
239
+ * @returns The table, one line per band, with a heading.
240
+ */
241
+ function bandsToTsv(
242
+ rows: readonly AssignedBand[],
243
+ mode: 'absorbance' | 'transmittance',
244
+ ): string {
245
+ const heading = ['wavenumber', 'strength', mode, 'could be'].join('\t');
246
+ const lines = rows.map((entry) =>
247
+ [
248
+ formatWavenumber(entry.band.wavenumber),
249
+ entry.band.strength,
250
+ formatIrValue(
251
+ mode === 'absorbance'
252
+ ? entry.band.absorbance
253
+ : entry.band.transmittance,
254
+ mode,
255
+ ),
256
+ entry.candidates
257
+ .map((candidate) => `${candidate.group} ${candidate.vibration}`)
258
+ .join('; '),
259
+ ].join('\t'),
260
+ );
261
+ return [heading, ...lines].join('\n');
262
+ }
263
+
264
+ const litRowStyle = { background: '#fff3e0' } as const;
265
+
266
+ const thresholdStyle = {
267
+ display: 'inline-flex',
268
+ alignItems: 'center',
269
+ gap: 4,
270
+ fontSize: 11,
271
+ } as const;
@@ -0,0 +1,121 @@
1
+ import { Dialog, DialogBody } from '@blueprintjs/core';
2
+
3
+ import { IrLogo } from './IrLogo.tsx';
4
+
5
+ export interface IrAboutDialogProps {
6
+ /** Whether the dialog is open. */
7
+ isOpen: boolean;
8
+ /** Close it. */
9
+ onClose: () => void;
10
+ }
11
+
12
+ /**
13
+ * What the viewer is, what it stands on, and who is owed for it.
14
+ *
15
+ * The credits are not decoration. Every band this viewer names is named out of a
16
+ * correlation table that generations of chemists compiled, every file it opens is
17
+ * read by somebody else's parser, and the examples it opens on are somebody
18
+ * else's measurements — so each is named here, with its licence where it has one.
19
+ * @param props - Component props.
20
+ * @returns The dialog.
21
+ */
22
+ export function IrAboutDialog(props: IrAboutDialogProps) {
23
+ const { isOpen, onClose } = props;
24
+
25
+ return (
26
+ <Dialog
27
+ isOpen={isOpen}
28
+ onClose={onClose}
29
+ title="About the infrared viewer"
30
+ icon={<IrLogo size={20} />}
31
+ style={dialogStyle}
32
+ >
33
+ <DialogBody>
34
+ <div style={brandStyle}>
35
+ <IrLogo size={64} />
36
+ <div>
37
+ <p style={leadStyle}>react-cheminfo/ir</p>
38
+ <p style={paragraphStyle}>
39
+ Draws an infrared spectrum the way infrared is printed, reads it
40
+ as absorbance or as percent transmittance, picks its bands and
41
+ offers every functional group each band could be.
42
+ </p>
43
+ </div>
44
+ </div>
45
+
46
+ <h4 style={headingStyle}>Credits</h4>
47
+ <ul style={listStyle}>
48
+ <li>
49
+ <strong>ir-spectrum</strong> (cheminfo, MIT) reads the JCAMP-DX and
50
+ SPC files, derives the absorbance/transmittance pair, and picks the
51
+ bands. This package deliberately does none of that arithmetic
52
+ itself.
53
+ </li>
54
+ <li>
55
+ <strong>common-spectrum</strong>, <strong>jcampconverter</strong>{' '}
56
+ and <strong>spc-parser</strong> (cheminfo, MIT) are what it reads
57
+ through.
58
+ </li>
59
+ <li>
60
+ <strong>ml-spectra-processing</strong> (mljs, MIT) for the array
61
+ work.
62
+ </li>
63
+ <li>
64
+ The <strong>shared chart</strong> of this package for the drawing —
65
+ the same arithmetic every other spectrum viewer of the family is
66
+ drawn with.
67
+ </li>
68
+ <li>
69
+ <strong>react-science</strong> and <strong>BlueprintJS</strong>
70
+ (zakodium, Palantir) for the shell this viewer is shaped like.
71
+ </li>
72
+ <li>
73
+ The <strong>correlation table</strong> is the conventional teaching
74
+ set of group frequencies, as any introductory spectroscopy text
75
+ tabulates them. The ranges are deliberately the rounded, generous
76
+ ones: narrowing them to look precise would rule out assignments that
77
+ are genuinely possible.
78
+ </li>
79
+ <li>
80
+ The <strong>colours</strong> are Okabe and Ito&apos;s
81
+ colour-universal palette, so two traces stay distinguishable for a
82
+ reader with a colour vision deficiency.
83
+ </li>
84
+ </ul>
85
+
86
+ <h4 style={headingStyle}>Licence</h4>
87
+ <p style={paragraphStyle}>
88
+ MIT, in the{' '}
89
+ <a
90
+ href="https://github.com/cheminfo/glycans"
91
+ target="_blank"
92
+ rel="noopener noreferrer"
93
+ >
94
+ cheminfo/glycans
95
+ </a>{' '}
96
+ monorepo.
97
+ </p>
98
+ </DialogBody>
99
+ </Dialog>
100
+ );
101
+ }
102
+
103
+ const dialogStyle = { width: 'min(680px, 92vw)' } as const;
104
+
105
+ const brandStyle = {
106
+ display: 'flex',
107
+ alignItems: 'flex-start',
108
+ gap: 16,
109
+ } as const;
110
+
111
+ const leadStyle = {
112
+ margin: '0 0 4px',
113
+ fontWeight: 600,
114
+ fontSize: 16,
115
+ } as const;
116
+
117
+ const paragraphStyle = { margin: '0 0 6px' } as const;
118
+
119
+ const headingStyle = { margin: '14px 0 4px' } as const;
120
+
121
+ const listStyle = { margin: 0, paddingLeft: 20 } as const;
@@ -0,0 +1,91 @@
1
+ import { useCallback } from 'react';
2
+
3
+ import type { IrBand } from '../core/irBand.ts';
4
+ import type { IrDomain } from '../core/irSpectrum.ts';
5
+
6
+ import { IrChart } from './IrChart.tsx';
7
+ import { IrStatusBar } from './IrStatusBar.tsx';
8
+ import { useIrActions, useIrEditorState } from './irStateContext.ts';
9
+
10
+ export interface IrCanvasProps {
11
+ /**
12
+ * The band the pointer is resting on, wherever it was hovered — the chart or
13
+ * the band table.
14
+ * @default null
15
+ */
16
+ highlight?: IrBand | null;
17
+ /**
18
+ * Told which band the pointer has come to rest on.
19
+ * @default undefined
20
+ */
21
+ onHighlight?: (band: IrBand | null) => void;
22
+ /**
23
+ * Put on the box the chart is drawn in, so a picture can be taken of it. The
24
+ * box rather than the chart itself, because the chart is laid out again on
25
+ * every resize.
26
+ * @default undefined
27
+ */
28
+ attachChart?: (element: HTMLDivElement | null) => void;
29
+ }
30
+
31
+ /**
32
+ * The chart, and the status bar under it.
33
+ *
34
+ * This is where the state meets the drawing: the chart holds nothing, so
35
+ * everything it draws is read out of the state here and every gesture it reports
36
+ * is written back. The window in particular goes **both** ways — the chart is
37
+ * told what to show and reports what it arrives at — which is what lets a toolbar
38
+ * button and a drag both move it.
39
+ *
40
+ * The status bar is inside the canvas rather than under the whole shell, so it
41
+ * stops at the splitter: what is open on the right belongs to the chart, and a
42
+ * bar running under the panels as well would read as belonging to the page.
43
+ * @param props - Component props.
44
+ * @returns The canvas.
45
+ */
46
+ export function IrCanvas(props: IrCanvasProps) {
47
+ const { highlight = null, onHighlight, attachChart } = props;
48
+ const { state, visibleSpectra, assigned } = useIrEditorState();
49
+ const actions = useIrActions();
50
+ const { domain, tool, selectedId } = state.view;
51
+ const { mode, showAssignments, labelLimit } = state.settings;
52
+
53
+ const onDomainChange = useCallback(
54
+ (next: IrDomain) => {
55
+ actions.setDomain(next);
56
+ },
57
+ [actions],
58
+ );
59
+
60
+ return (
61
+ <div style={rootStyle}>
62
+ <div ref={attachChart} style={chartStyle}>
63
+ <IrChart
64
+ spectra={visibleSpectra}
65
+ mode={mode}
66
+ assigned={assigned}
67
+ showAssignments={showAssignments}
68
+ labelLimit={labelLimit}
69
+ highlight={highlight}
70
+ onHighlight={onHighlight}
71
+ domain={domain}
72
+ onDomainChange={onDomainChange}
73
+ drag={tool === 'box' ? 'box' : 'xAxis'}
74
+ emphasisedId={selectedId}
75
+ />
76
+ </div>
77
+ <IrStatusBar />
78
+ </div>
79
+ );
80
+ }
81
+
82
+ const rootStyle = {
83
+ display: 'flex',
84
+ flexDirection: 'column',
85
+ flex: '1 1 1px',
86
+ minWidth: 0,
87
+ minHeight: 0,
88
+ } as const;
89
+
90
+ /** The chart takes what the status bar does not. */
91
+ const chartStyle = { flex: '1 1 1px', minHeight: 0 } as const;
@@ -0,0 +1,215 @@
1
+ import type { ReactElement } from 'react';
2
+ import { useCallback, useId, useLayoutEffect, useMemo, useRef } from 'react';
3
+
4
+ import { sameChartDomain } from '../../chart/core/chartDomain.ts';
5
+ import { MARGIN, plotRect } from '../../chart/core/chartGeometry.ts';
6
+ import { Axes } from '../../chart/ui/Axes.tsx';
7
+ import { SelectionRect } from '../../chart/ui/SelectionRect.tsx';
8
+ import { chartSurfaceStyle } from '../../chart/ui/chartSurface.ts';
9
+ import { useChartSize } from '../../chart/ui/useChartSize.ts';
10
+ import type { AssignedBand } from '../core/assignBands.ts';
11
+ import type { IrBand } from '../core/irBand.ts';
12
+ import { boxZoomOnly, yAxisTitle } from '../core/irMode.ts';
13
+ import type { IrMode } from '../core/irSpectrum.ts';
14
+
15
+ import { BandMarks } from './BandMarks.tsx';
16
+ import { IrPointerTracker } from './IrPointerTracker.tsx';
17
+ import { IrTraces } from './IrTraces.tsx';
18
+ import type { IrChartProps } from './irChartProps.ts';
19
+ import { useIrPointer } from './useIrPointer.ts';
20
+ import { useIrZoom } from './useIrZoom.ts';
21
+
22
+ /**
23
+ * The chart: every layer of an infrared spectrum, in one SVG.
24
+ *
25
+ * **The wavenumber axis runs right to left**, 4000 at the left edge down to 400
26
+ * at the right, which is how every infrared spectrum has been printed since the
27
+ * technique was dispersive and the instrument scanned that way. It is done by
28
+ * building the scale onto a reversed pixel range and nothing else: the data stays
29
+ * in ascending wavenumbers, every window stays low end first, and no other piece
30
+ * of arithmetic in either package has to know. That is the whole reason
31
+ * `createScale` takes its range rather than deriving it.
32
+ *
33
+ * The axes go under the data, so a grid line is never read as a band. Only the
34
+ * data band is clipped, so a zoomed trace stops at the plot edge while the
35
+ * wavenumbers pinned to the bands are allowed out over the margin — clip those
36
+ * and the strongest band in the window loses its label. The drag rectangle and
37
+ * the crosshair go over everything, because each answers a question being asked
38
+ * right now.
39
+ *
40
+ * Nothing is held here. The spectra, the bands, what is being looked at and the
41
+ * window are all props, and every gesture comes back out as a callback — so one
42
+ * component draws an editor's chart, a report page's single spectrum and a test.
43
+ * @param props - Component props.
44
+ * @returns The chart.
45
+ */
46
+ export function IrChart(props: IrChartProps): ReactElement {
47
+ const {
48
+ spectra,
49
+ mode = 'transmittance',
50
+ assigned = NO_BANDS,
51
+ showAssignments = false,
52
+ labelLimit,
53
+ highlight = null,
54
+ onHighlight,
55
+ domain = null,
56
+ onDomainChange,
57
+ drag = 'xAxis',
58
+ emphasisedId = null,
59
+ width,
60
+ height,
61
+ children,
62
+ } = props;
63
+
64
+ const [containerRef, measured] = useChartSize<HTMLDivElement>();
65
+ const svgRef = useRef<SVGSVGElement | null>(null);
66
+
67
+ const plot = useMemo(
68
+ () =>
69
+ plotRect({
70
+ width: width ?? measured.width,
71
+ height: height ?? measured.height,
72
+ }),
73
+ [width, height, measured.width, measured.height],
74
+ );
75
+ // Read back off the plot rather than off the measurement, so a chart briefly
76
+ // laid out at nothing still draws its axes inside a box that holds them.
77
+ const frameWidth = plot.right + MARGIN.right;
78
+ const frameHeight = plot.bottom + MARGIN.bottom;
79
+
80
+ // The host's window goes *into* the zoom rather than over it, so a drag is
81
+ // always measured against what is on screen.
82
+ const zoom = useIrZoom({ spectra, mode, svgRef, plot, domain, drag });
83
+
84
+ // The scales the zoom measured its gestures against — the x one running right
85
+ // to left. Taken from the hook rather than built here, because two scales over
86
+ // one axis is two chances to disagree about which way it runs, and a chart that
87
+ // disagreed with its own gestures would zoom to the mirror image of whatever
88
+ // was dragged over.
89
+ const { domain: shown, xScale, yScale, selection, handlers } = zoom;
90
+
91
+ const reported = useRef(shown);
92
+ // Before the browser paints, so a host that stores the window and hands it
93
+ // back does so in the frame the gesture landed in rather than the one after.
94
+ useLayoutEffect(() => {
95
+ if (sameChartDomain(reported.current, shown)) return;
96
+ reported.current = shown;
97
+ onDomainChange?.(shown);
98
+ }, [shown, onDomainChange]);
99
+
100
+ const bands = useMemo(() => {
101
+ const found: IrBand[] = [];
102
+ for (const entry of assigned) found.push(entry.band);
103
+ return found;
104
+ }, [assigned]);
105
+
106
+ const onBand = useCallback(
107
+ (band: IrBand | null) => {
108
+ onHighlight?.(band);
109
+ },
110
+ [onHighlight],
111
+ );
112
+ const pointer = useIrPointer({
113
+ svgRef,
114
+ plot,
115
+ xScale,
116
+ yScale,
117
+ mode,
118
+ bands,
119
+ onBand,
120
+ });
121
+
122
+ // React's generated id carries the punctuation it keeps its own ids apart
123
+ // with, which a URL fragment is under no obligation to accept.
124
+ const clipId = `ir-plot-${useId().replaceAll(/\W/g, '')}`;
125
+
126
+ return (
127
+ <div ref={containerRef} style={containerStyle}>
128
+ <svg
129
+ ref={svgRef}
130
+ role="img"
131
+ aria-label={chartLabel(mode)}
132
+ width={frameWidth}
133
+ height={frameHeight}
134
+ viewBox={`0 0 ${frameWidth} ${frameHeight}`}
135
+ // The arrow gives way to the chart's own crosshair over the plot, and
136
+ // comes back over the margins, exactly as it does on a mass chart.
137
+ style={chartSurfaceStyle(pointer.position !== null)}
138
+ {...handlers}
139
+ >
140
+ <defs>
141
+ <clipPath id={clipId}>
142
+ <rect
143
+ x={plot.left}
144
+ y={plot.top}
145
+ width={plot.width}
146
+ height={plot.height}
147
+ />
148
+ </clipPath>
149
+ </defs>
150
+
151
+ <Axes
152
+ plot={plot}
153
+ xDomain={shown.x}
154
+ yDomain={shown.y}
155
+ xScale={xScale}
156
+ yScale={yScale}
157
+ xTitle="wavenumber (cm⁻¹)"
158
+ yTitle={yAxisTitle(mode)}
159
+ />
160
+
161
+ <g clipPath={`url(#${clipId})`}>
162
+ <IrTraces
163
+ spectra={spectra}
164
+ mode={mode}
165
+ plot={plot}
166
+ xDomain={shown.x}
167
+ xScale={xScale}
168
+ yScale={yScale}
169
+ emphasisedId={emphasisedId}
170
+ />
171
+ {children}
172
+ </g>
173
+
174
+ <BandMarks
175
+ assigned={assigned}
176
+ plot={plot}
177
+ xScale={xScale}
178
+ yScale={yScale}
179
+ mode={mode}
180
+ showAssignments={showAssignments}
181
+ highlight={highlight}
182
+ {...(labelLimit === undefined ? {} : { limit: labelLimit })}
183
+ />
184
+ <SelectionRect selection={selection} plot={plot} />
185
+ <IrPointerTracker
186
+ position={pointer.position}
187
+ readout={pointer.readout}
188
+ plot={plot}
189
+ />
190
+ </svg>
191
+ </div>
192
+ );
193
+ }
194
+
195
+ /**
196
+ * What the chart is, and what can be done to it, for whoever cannot see it.
197
+ *
198
+ * The gestures differ by mode, so the sentence does too — a label promising the
199
+ * wheel to a reader who cannot watch it fail to do anything is worse than no
200
+ * label at all.
201
+ * @param mode - Which value axis is being drawn.
202
+ * @returns The label.
203
+ */
204
+ function chartLabel(mode: IrMode): string {
205
+ const axis = `Infrared spectrum read as ${yAxisTitle(mode)}, wavenumber running from high at the left to low at the right.`;
206
+ return boxZoomOnly(mode)
207
+ ? `${axis} Drag a rectangle over it to zoom to that rectangle, and double click to fit everything again.`
208
+ : `${axis} Drag across it to zoom the wavenumber axis, drag past the baseline to take the value axis with it, turn the wheel to scale the value axis, and double click to fit everything again.`;
209
+ }
210
+
211
+ /** What a chart nobody has picked any bands for marks. */
212
+ const NO_BANDS: readonly AssignedBand[] = Object.freeze([]);
213
+
214
+ /** The box the chart is measured against, and fills. */
215
+ const containerStyle = { width: '100%', height: '100%' } as const;