react-cheminfo 0.27.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 (696) 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/clipboard/ui/CopyableValue.d.ts +12 -9
  159. package/lib/clipboard/ui/CopyableValue.d.ts.map +1 -1
  160. package/lib/clipboard/ui/CopyableValue.js +11 -15
  161. package/lib/clipboard/ui/CopyableValue.js.map +1 -1
  162. package/lib/core.d.ts +1 -0
  163. package/lib/core.d.ts.map +1 -1
  164. package/lib/core.js +1 -0
  165. package/lib/core.js.map +1 -1
  166. package/lib/download/core/exportStyles.d.ts +22 -0
  167. package/lib/download/core/exportStyles.d.ts.map +1 -0
  168. package/lib/download/core/exportStyles.js +19 -0
  169. package/lib/download/core/exportStyles.js.map +1 -0
  170. package/lib/download/core/imageResolution.d.ts +88 -0
  171. package/lib/download/core/imageResolution.d.ts.map +1 -0
  172. package/lib/download/core/imageResolution.js +77 -0
  173. package/lib/download/core/imageResolution.js.map +1 -0
  174. package/lib/download/core/index.d.ts +13 -0
  175. package/lib/download/core/index.d.ts.map +1 -1
  176. package/lib/download/core/index.js +8 -0
  177. package/lib/download/core/index.js.map +1 -1
  178. package/lib/download/core/pictureExport.d.ts +93 -0
  179. package/lib/download/core/pictureExport.d.ts.map +1 -0
  180. package/lib/download/core/pictureExport.js +116 -0
  181. package/lib/download/core/pictureExport.js.map +1 -0
  182. package/lib/download/core/stackedDrawing.d.ts +36 -0
  183. package/lib/download/core/stackedDrawing.d.ts.map +1 -0
  184. package/lib/download/core/stackedDrawing.js +98 -0
  185. package/lib/download/core/stackedDrawing.js.map +1 -0
  186. package/lib/download/core/svgBounds.d.ts +44 -0
  187. package/lib/download/core/svgBounds.d.ts.map +1 -0
  188. package/lib/download/core/svgBounds.js +69 -0
  189. package/lib/download/core/svgBounds.js.map +1 -0
  190. package/lib/download/core/svgNamespace.d.ts +9 -0
  191. package/lib/download/core/svgNamespace.d.ts.map +1 -0
  192. package/lib/download/core/svgNamespace.js +10 -0
  193. package/lib/download/core/svgNamespace.js.map +1 -0
  194. package/lib/download/core/svgToPng.d.ts +43 -0
  195. package/lib/download/core/svgToPng.d.ts.map +1 -0
  196. package/lib/download/core/svgToPng.js +79 -0
  197. package/lib/download/core/svgToPng.js.map +1 -0
  198. package/lib/download/core/svgToString.d.ts +45 -0
  199. package/lib/download/core/svgToString.d.ts.map +1 -0
  200. package/lib/download/core/svgToString.js +58 -0
  201. package/lib/download/core/svgToString.js.map +1 -0
  202. package/lib/download/ui/ExportDialogFrame.d.ts +46 -0
  203. package/lib/download/ui/ExportDialogFrame.d.ts.map +1 -0
  204. package/lib/download/ui/ExportDialogFrame.js +24 -0
  205. package/lib/download/ui/ExportDialogFrame.js.map +1 -0
  206. package/lib/download/ui/ExportImageDialog.d.ts +47 -0
  207. package/lib/download/ui/ExportImageDialog.d.ts.map +1 -0
  208. package/lib/download/ui/ExportImageDialog.js +25 -0
  209. package/lib/download/ui/ExportImageDialog.js.map +1 -0
  210. package/lib/download/ui/ExportNameField.d.ts +29 -0
  211. package/lib/download/ui/ExportNameField.d.ts.map +1 -0
  212. package/lib/download/ui/ExportNameField.js +99 -0
  213. package/lib/download/ui/ExportNameField.js.map +1 -0
  214. package/lib/download/ui/ExportPictureSection.d.ts +38 -0
  215. package/lib/download/ui/ExportPictureSection.d.ts.map +1 -0
  216. package/lib/download/ui/ExportPictureSection.js +48 -0
  217. package/lib/download/ui/ExportPictureSection.js.map +1 -0
  218. package/lib/download/ui/index.d.ts +10 -0
  219. package/lib/download/ui/index.d.ts.map +1 -1
  220. package/lib/download/ui/index.js +5 -0
  221. package/lib/download/ui/index.js.map +1 -1
  222. package/lib/download/ui/useDrawingBox.d.ts +23 -0
  223. package/lib/download/ui/useDrawingBox.d.ts.map +1 -0
  224. package/lib/download/ui/useDrawingBox.js +21 -0
  225. package/lib/download/ui/useDrawingBox.js.map +1 -0
  226. package/lib/error/core/describeSource.d.ts +17 -0
  227. package/lib/error/core/describeSource.d.ts.map +1 -0
  228. package/lib/error/core/describeSource.js +19 -0
  229. package/lib/error/core/describeSource.js.map +1 -0
  230. package/lib/error/core/index.d.ts +1 -0
  231. package/lib/error/core/index.d.ts.map +1 -1
  232. package/lib/error/core/index.js +1 -0
  233. package/lib/error/core/index.js.map +1 -1
  234. package/lib/help/ui/HelpBody.d.ts +10 -1
  235. package/lib/help/ui/HelpBody.d.ts.map +1 -1
  236. package/lib/help/ui/HelpBody.js +24 -1
  237. package/lib/help/ui/HelpBody.js.map +1 -1
  238. package/lib/help/ui/index.d.ts +1 -1
  239. package/lib/help/ui/index.d.ts.map +1 -1
  240. package/lib/help/ui/index.js.map +1 -1
  241. package/lib/ir/core/analysisSpectra.d.ts +46 -0
  242. package/lib/ir/core/analysisSpectra.d.ts.map +1 -0
  243. package/lib/ir/core/analysisSpectra.js +187 -0
  244. package/lib/ir/core/analysisSpectra.js.map +1 -0
  245. package/lib/ir/core/assignBands.d.ts +83 -0
  246. package/lib/ir/core/assignBands.d.ts.map +1 -0
  247. package/lib/ir/core/assignBands.js +83 -0
  248. package/lib/ir/core/assignBands.js.map +1 -0
  249. package/lib/ir/core/bandAssignments.d.ts +47 -0
  250. package/lib/ir/core/bandAssignments.d.ts.map +1 -0
  251. package/lib/ir/core/bandAssignments.js +305 -0
  252. package/lib/ir/core/bandAssignments.js.map +1 -0
  253. package/lib/ir/core/bandLabelPlan.d.ts +93 -0
  254. package/lib/ir/core/bandLabelPlan.d.ts.map +1 -0
  255. package/lib/ir/core/bandLabelPlan.js +104 -0
  256. package/lib/ir/core/bandLabelPlan.js.map +1 -0
  257. package/lib/ir/core/detectIrFormat.d.ts +23 -0
  258. package/lib/ir/core/detectIrFormat.d.ts.map +1 -0
  259. package/lib/ir/core/detectIrFormat.js +133 -0
  260. package/lib/ir/core/detectIrFormat.js.map +1 -0
  261. package/lib/ir/core/downloadSpectra.d.ts +26 -0
  262. package/lib/ir/core/downloadSpectra.d.ts.map +1 -0
  263. package/lib/ir/core/downloadSpectra.js +37 -0
  264. package/lib/ir/core/downloadSpectra.js.map +1 -0
  265. package/lib/ir/core/fromJcamp.d.ts +35 -0
  266. package/lib/ir/core/fromJcamp.d.ts.map +1 -0
  267. package/lib/ir/core/fromJcamp.js +48 -0
  268. package/lib/ir/core/fromJcamp.js.map +1 -0
  269. package/lib/ir/core/fromSpc.d.ts +30 -0
  270. package/lib/ir/core/fromSpc.d.ts.map +1 -0
  271. package/lib/ir/core/fromSpc.js +40 -0
  272. package/lib/ir/core/fromSpc.js.map +1 -0
  273. package/lib/ir/core/index.d.ts +51 -0
  274. package/lib/ir/core/index.d.ts.map +1 -0
  275. package/lib/ir/core/index.js +35 -0
  276. package/lib/ir/core/index.js.map +1 -0
  277. package/lib/ir/core/irBand.d.ts +45 -0
  278. package/lib/ir/core/irBand.d.ts.map +1 -0
  279. package/lib/ir/core/irBand.js +30 -0
  280. package/lib/ir/core/irBand.js.map +1 -0
  281. package/lib/ir/core/irCommands.d.ts +168 -0
  282. package/lib/ir/core/irCommands.d.ts.map +1 -0
  283. package/lib/ir/core/irCommands.js +94 -0
  284. package/lib/ir/core/irCommands.js.map +1 -0
  285. package/lib/ir/core/irDomain.d.ts +63 -0
  286. package/lib/ir/core/irDomain.d.ts.map +1 -0
  287. package/lib/ir/core/irDomain.js +136 -0
  288. package/lib/ir/core/irDomain.js.map +1 -0
  289. package/lib/ir/core/irEditorApi.d.ts +42 -0
  290. package/lib/ir/core/irEditorApi.d.ts.map +1 -0
  291. package/lib/ir/core/irEditorApi.js +10 -0
  292. package/lib/ir/core/irEditorApi.js.map +1 -0
  293. package/lib/ir/core/irFormat.d.ts +42 -0
  294. package/lib/ir/core/irFormat.d.ts.map +1 -0
  295. package/lib/ir/core/irFormat.js +51 -0
  296. package/lib/ir/core/irFormat.js.map +1 -0
  297. package/lib/ir/core/irMode.d.ts +160 -0
  298. package/lib/ir/core/irMode.d.ts.map +1 -0
  299. package/lib/ir/core/irMode.js +175 -0
  300. package/lib/ir/core/irMode.js.map +1 -0
  301. package/lib/ir/core/irReducer.d.ts +101 -0
  302. package/lib/ir/core/irReducer.d.ts.map +1 -0
  303. package/lib/ir/core/irReducer.js +207 -0
  304. package/lib/ir/core/irReducer.js.map +1 -0
  305. package/lib/ir/core/irSidePanels.d.ts +22 -0
  306. package/lib/ir/core/irSidePanels.d.ts.map +1 -0
  307. package/lib/ir/core/irSidePanels.js +12 -0
  308. package/lib/ir/core/irSidePanels.js.map +1 -0
  309. package/lib/ir/core/irSpectrum.d.ts +140 -0
  310. package/lib/ir/core/irSpectrum.d.ts.map +1 -0
  311. package/lib/ir/core/irSpectrum.js +34 -0
  312. package/lib/ir/core/irSpectrum.js.map +1 -0
  313. package/lib/ir/core/irState.d.ts +119 -0
  314. package/lib/ir/core/irState.d.ts.map +1 -0
  315. package/lib/ir/core/irState.js +92 -0
  316. package/lib/ir/core/irState.js.map +1 -0
  317. package/lib/ir/core/loadIrSpectra.d.ts +36 -0
  318. package/lib/ir/core/loadIrSpectra.d.ts.map +1 -0
  319. package/lib/ir/core/loadIrSpectra.js +44 -0
  320. package/lib/ir/core/loadIrSpectra.js.map +1 -0
  321. package/lib/ir/core/nearestBand.d.ts +35 -0
  322. package/lib/ir/core/nearestBand.d.ts.map +1 -0
  323. package/lib/ir/core/nearestBand.js +47 -0
  324. package/lib/ir/core/nearestBand.js.map +1 -0
  325. package/lib/ir/core/pickBands.d.ts +70 -0
  326. package/lib/ir/core/pickBands.d.ts.map +1 -0
  327. package/lib/ir/core/pickBands.js +125 -0
  328. package/lib/ir/core/pickBands.js.map +1 -0
  329. package/lib/ir/core/spectrumJcamp.d.ts +58 -0
  330. package/lib/ir/core/spectrumJcamp.d.ts.map +1 -0
  331. package/lib/ir/core/spectrumJcamp.js +156 -0
  332. package/lib/ir/core/spectrumJcamp.js.map +1 -0
  333. package/lib/ir/core/toIrSpectrum.d.ts +59 -0
  334. package/lib/ir/core/toIrSpectrum.d.ts.map +1 -0
  335. package/lib/ir/core/toIrSpectrum.js +56 -0
  336. package/lib/ir/core/toIrSpectrum.js.map +1 -0
  337. package/lib/ir/ui/BandMarks.d.ts +52 -0
  338. package/lib/ir/ui/BandMarks.d.ts.map +1 -0
  339. package/lib/ir/ui/BandMarks.js +71 -0
  340. package/lib/ir/ui/BandMarks.js.map +1 -0
  341. package/lib/ir/ui/BandsPanel.d.ts +31 -0
  342. package/lib/ir/ui/BandsPanel.d.ts.map +1 -0
  343. package/lib/ir/ui/BandsPanel.js +94 -0
  344. package/lib/ir/ui/BandsPanel.js.map +1 -0
  345. package/lib/ir/ui/IrAboutDialog.d.ts +18 -0
  346. package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -0
  347. package/lib/ir/ui/IrAboutDialog.js +32 -0
  348. package/lib/ir/ui/IrAboutDialog.js.map +1 -0
  349. package/lib/ir/ui/IrCanvas.d.ts +38 -0
  350. package/lib/ir/ui/IrCanvas.d.ts.map +1 -0
  351. package/lib/ir/ui/IrCanvas.js +41 -0
  352. package/lib/ir/ui/IrCanvas.js.map +1 -0
  353. package/lib/ir/ui/IrChart.d.ts +28 -0
  354. package/lib/ir/ui/IrChart.d.ts.map +1 -0
  355. package/lib/ir/ui/IrChart.js +114 -0
  356. package/lib/ir/ui/IrChart.js.map +1 -0
  357. package/lib/ir/ui/IrCommandProvider.d.ts +15 -0
  358. package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -0
  359. package/lib/ir/ui/IrCommandProvider.js +14 -0
  360. package/lib/ir/ui/IrCommandProvider.js.map +1 -0
  361. package/lib/ir/ui/IrCommandTooltip.d.ts +16 -0
  362. package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -0
  363. package/lib/ir/ui/IrCommandTooltip.js +22 -0
  364. package/lib/ir/ui/IrCommandTooltip.js.map +1 -0
  365. package/lib/ir/ui/IrDocumentationDialog.d.ts +18 -0
  366. package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -0
  367. package/lib/ir/ui/IrDocumentationDialog.js +68 -0
  368. package/lib/ir/ui/IrDocumentationDialog.js.map +1 -0
  369. package/lib/ir/ui/IrEditor.d.ts +60 -0
  370. package/lib/ir/ui/IrEditor.d.ts.map +1 -0
  371. package/lib/ir/ui/IrEditor.js +42 -0
  372. package/lib/ir/ui/IrEditor.js.map +1 -0
  373. package/lib/ir/ui/IrHeader.d.ts +13 -0
  374. package/lib/ir/ui/IrHeader.d.ts.map +1 -0
  375. package/lib/ir/ui/IrHeader.js +21 -0
  376. package/lib/ir/ui/IrHeader.js.map +1 -0
  377. package/lib/ir/ui/IrLogo.d.ts +20 -0
  378. package/lib/ir/ui/IrLogo.d.ts.map +1 -0
  379. package/lib/ir/ui/IrLogo.js +17 -0
  380. package/lib/ir/ui/IrLogo.js.map +1 -0
  381. package/lib/ir/ui/IrPointerTracker.d.ts +29 -0
  382. package/lib/ir/ui/IrPointerTracker.d.ts.map +1 -0
  383. package/lib/ir/ui/IrPointerTracker.js +47 -0
  384. package/lib/ir/ui/IrPointerTracker.js.map +1 -0
  385. package/lib/ir/ui/IrShell.d.ts +25 -0
  386. package/lib/ir/ui/IrShell.d.ts.map +1 -0
  387. package/lib/ir/ui/IrShell.js +178 -0
  388. package/lib/ir/ui/IrShell.js.map +1 -0
  389. package/lib/ir/ui/IrSidePanel.d.ts +26 -0
  390. package/lib/ir/ui/IrSidePanel.d.ts.map +1 -0
  391. package/lib/ir/ui/IrSidePanel.js +39 -0
  392. package/lib/ir/ui/IrSidePanel.js.map +1 -0
  393. package/lib/ir/ui/IrStateProvider.d.ts +19 -0
  394. package/lib/ir/ui/IrStateProvider.d.ts.map +1 -0
  395. package/lib/ir/ui/IrStateProvider.js +16 -0
  396. package/lib/ir/ui/IrStateProvider.js.map +1 -0
  397. package/lib/ir/ui/IrStatusBar.d.ts +14 -0
  398. package/lib/ir/ui/IrStatusBar.d.ts.map +1 -0
  399. package/lib/ir/ui/IrStatusBar.js +48 -0
  400. package/lib/ir/ui/IrStatusBar.js.map +1 -0
  401. package/lib/ir/ui/IrToolbar.d.ts +18 -0
  402. package/lib/ir/ui/IrToolbar.d.ts.map +1 -0
  403. package/lib/ir/ui/IrToolbar.js +32 -0
  404. package/lib/ir/ui/IrToolbar.js.map +1 -0
  405. package/lib/ir/ui/IrTraces.d.ts +63 -0
  406. package/lib/ir/ui/IrTraces.d.ts.map +1 -0
  407. package/lib/ir/ui/IrTraces.js +72 -0
  408. package/lib/ir/ui/IrTraces.js.map +1 -0
  409. package/lib/ir/ui/MetadataPanel.d.ts +15 -0
  410. package/lib/ir/ui/MetadataPanel.d.ts.map +1 -0
  411. package/lib/ir/ui/MetadataPanel.js +49 -0
  412. package/lib/ir/ui/MetadataPanel.js.map +1 -0
  413. package/lib/ir/ui/SpectraPanel.d.ts +20 -0
  414. package/lib/ir/ui/SpectraPanel.d.ts.map +1 -0
  415. package/lib/ir/ui/SpectraPanel.js +42 -0
  416. package/lib/ir/ui/SpectraPanel.js.map +1 -0
  417. package/lib/ir/ui/SpectrumRow.d.ts +26 -0
  418. package/lib/ir/ui/SpectrumRow.d.ts.map +1 -0
  419. package/lib/ir/ui/SpectrumRow.js +41 -0
  420. package/lib/ir/ui/SpectrumRow.js.map +1 -0
  421. package/lib/ir/ui/index.d.ts +56 -0
  422. package/lib/ir/ui/index.d.ts.map +1 -0
  423. package/lib/ir/ui/index.js +36 -0
  424. package/lib/ir/ui/index.js.map +1 -0
  425. package/lib/ir/ui/irActions.d.ts +52 -0
  426. package/lib/ir/ui/irActions.d.ts.map +1 -0
  427. package/lib/ir/ui/irActions.js +62 -0
  428. package/lib/ir/ui/irActions.js.map +1 -0
  429. package/lib/ir/ui/irChartProps.d.ts +116 -0
  430. package/lib/ir/ui/irChartProps.d.ts.map +1 -0
  431. package/lib/ir/ui/irChartProps.js +14 -0
  432. package/lib/ir/ui/irChartProps.js.map +1 -0
  433. package/lib/ir/ui/irCommandContext.d.ts +35 -0
  434. package/lib/ir/ui/irCommandContext.d.ts.map +1 -0
  435. package/lib/ir/ui/irCommandContext.js +44 -0
  436. package/lib/ir/ui/irCommandContext.js.map +1 -0
  437. package/lib/ir/ui/irStateContext.d.ts +26 -0
  438. package/lib/ir/ui/irStateContext.d.ts.map +1 -0
  439. package/lib/ir/ui/irStateContext.js +37 -0
  440. package/lib/ir/ui/irStateContext.js.map +1 -0
  441. package/lib/ir/ui/useIrEditor.d.ts +51 -0
  442. package/lib/ir/ui/useIrEditor.d.ts.map +1 -0
  443. package/lib/ir/ui/useIrEditor.js +88 -0
  444. package/lib/ir/ui/useIrEditor.js.map +1 -0
  445. package/lib/ir/ui/useIrPointer.d.ts +66 -0
  446. package/lib/ir/ui/useIrPointer.d.ts.map +1 -0
  447. package/lib/ir/ui/useIrPointer.js +53 -0
  448. package/lib/ir/ui/useIrPointer.js.map +1 -0
  449. package/lib/ir/ui/useIrShortcuts.d.ts +24 -0
  450. package/lib/ir/ui/useIrShortcuts.d.ts.map +1 -0
  451. package/lib/ir/ui/useIrShortcuts.js +73 -0
  452. package/lib/ir/ui/useIrShortcuts.js.map +1 -0
  453. package/lib/ir/ui/useIrZoom.d.ts +51 -0
  454. package/lib/ir/ui/useIrZoom.d.ts.map +1 -0
  455. package/lib/ir/ui/useIrZoom.js +46 -0
  456. package/lib/ir/ui/useIrZoom.js.map +1 -0
  457. package/lib/ir.d.ts +13 -0
  458. package/lib/ir.d.ts.map +1 -0
  459. package/lib/ir.js +13 -0
  460. package/lib/ir.js.map +1 -0
  461. package/lib/panel/core/dialogStyles.d.ts +13 -0
  462. package/lib/panel/core/dialogStyles.d.ts.map +1 -0
  463. package/lib/panel/core/dialogStyles.js +11 -0
  464. package/lib/panel/core/dialogStyles.js.map +1 -0
  465. package/lib/panel/core/index.d.ts +19 -0
  466. package/lib/panel/core/index.d.ts.map +1 -0
  467. package/lib/panel/core/index.js +18 -0
  468. package/lib/panel/core/index.js.map +1 -0
  469. package/lib/panel/core/isEditingField.d.ts +17 -0
  470. package/lib/panel/core/isEditingField.d.ts.map +1 -0
  471. package/lib/panel/core/isEditingField.js +25 -0
  472. package/lib/panel/core/isEditingField.js.map +1 -0
  473. package/lib/panel/core/panelStyles.d.ts +242 -0
  474. package/lib/panel/core/panelStyles.d.ts.map +1 -0
  475. package/lib/panel/core/panelStyles.js +228 -0
  476. package/lib/panel/core/panelStyles.js.map +1 -0
  477. package/lib/panel/core/rowSpacers.d.ts +38 -0
  478. package/lib/panel/core/rowSpacers.d.ts.map +1 -0
  479. package/lib/panel/core/rowSpacers.js +31 -0
  480. package/lib/panel/core/rowSpacers.js.map +1 -0
  481. package/lib/panel/core/statusBar.d.ts +44 -0
  482. package/lib/panel/core/statusBar.d.ts.map +1 -0
  483. package/lib/panel/core/statusBar.js +40 -0
  484. package/lib/panel/core/statusBar.js.map +1 -0
  485. package/lib/panel/core/textFilter.d.ts +22 -0
  486. package/lib/panel/core/textFilter.d.ts.map +1 -0
  487. package/lib/panel/core/textFilter.js +32 -0
  488. package/lib/panel/core/textFilter.js.map +1 -0
  489. package/lib/panel/core/yieldToPainting.d.ts +17 -0
  490. package/lib/panel/core/yieldToPainting.d.ts.map +1 -0
  491. package/lib/panel/core/yieldToPainting.js +21 -0
  492. package/lib/panel/core/yieldToPainting.js.map +1 -0
  493. package/lib/panel/ui/AboutDialogFrame.d.ts +36 -0
  494. package/lib/panel/ui/AboutDialogFrame.d.ts.map +1 -0
  495. package/lib/panel/ui/AboutDialogFrame.js +43 -0
  496. package/lib/panel/ui/AboutDialogFrame.js.map +1 -0
  497. package/lib/panel/ui/ClearButton.d.ts +28 -0
  498. package/lib/panel/ui/ClearButton.d.ts.map +1 -0
  499. package/lib/panel/ui/ClearButton.js +23 -0
  500. package/lib/panel/ui/ClearButton.js.map +1 -0
  501. package/lib/panel/ui/DocumentationDialogFrame.d.ts +39 -0
  502. package/lib/panel/ui/DocumentationDialogFrame.d.ts.map +1 -0
  503. package/lib/panel/ui/DocumentationDialogFrame.js +29 -0
  504. package/lib/panel/ui/DocumentationDialogFrame.js.map +1 -0
  505. package/lib/panel/ui/FilterInput.d.ts +31 -0
  506. package/lib/panel/ui/FilterInput.d.ts.map +1 -0
  507. package/lib/panel/ui/FilterInput.js +23 -0
  508. package/lib/panel/ui/FilterInput.js.map +1 -0
  509. package/lib/panel/ui/HelpLabel.d.ts +24 -0
  510. package/lib/panel/ui/HelpLabel.d.ts.map +1 -0
  511. package/lib/panel/ui/HelpLabel.js +23 -0
  512. package/lib/panel/ui/HelpLabel.js.map +1 -0
  513. package/lib/panel/ui/PanelMessage.d.ts +41 -0
  514. package/lib/panel/ui/PanelMessage.d.ts.map +1 -0
  515. package/lib/panel/ui/PanelMessage.js +30 -0
  516. package/lib/panel/ui/PanelMessage.js.map +1 -0
  517. package/lib/panel/ui/PanelRail.d.ts +41 -0
  518. package/lib/panel/ui/PanelRail.d.ts.map +1 -0
  519. package/lib/panel/ui/PanelRail.js +12 -0
  520. package/lib/panel/ui/PanelRail.js.map +1 -0
  521. package/lib/panel/ui/Section.d.ts +25 -0
  522. package/lib/panel/ui/Section.d.ts.map +1 -0
  523. package/lib/panel/ui/Section.js +41 -0
  524. package/lib/panel/ui/Section.js.map +1 -0
  525. package/lib/panel/ui/SidePanelStack.d.ts +62 -0
  526. package/lib/panel/ui/SidePanelStack.d.ts.map +1 -0
  527. package/lib/panel/ui/SidePanelStack.js +40 -0
  528. package/lib/panel/ui/SidePanelStack.js.map +1 -0
  529. package/lib/panel/ui/SpectrumColorSwatch.d.ts +33 -0
  530. package/lib/panel/ui/SpectrumColorSwatch.d.ts.map +1 -0
  531. package/lib/panel/ui/SpectrumColorSwatch.js +76 -0
  532. package/lib/panel/ui/SpectrumColorSwatch.js.map +1 -0
  533. package/lib/panel/ui/index.d.ts +37 -0
  534. package/lib/panel/ui/index.d.ts.map +1 -0
  535. package/lib/panel/ui/index.js +24 -0
  536. package/lib/panel/ui/index.js.map +1 -0
  537. package/lib/panel/ui/useConfirmOnEnter.d.ts +19 -0
  538. package/lib/panel/ui/useConfirmOnEnter.d.ts.map +1 -0
  539. package/lib/panel/ui/useConfirmOnEnter.js +64 -0
  540. package/lib/panel/ui/useConfirmOnEnter.js.map +1 -0
  541. package/lib/panel/ui/useFilterBox.d.ts +23 -0
  542. package/lib/panel/ui/useFilterBox.d.ts.map +1 -0
  543. package/lib/panel/ui/useFilterBox.js +22 -0
  544. package/lib/panel/ui/useFilterBox.js.map +1 -0
  545. package/lib/panel/ui/useVirtualRows.d.ts +46 -0
  546. package/lib/panel/ui/useVirtualRows.d.ts.map +1 -0
  547. package/lib/panel/ui/useVirtualRows.js +56 -0
  548. package/lib/panel/ui/useVirtualRows.js.map +1 -0
  549. package/lib/panel/ui/useVirtualWindowRows.d.ts +40 -0
  550. package/lib/panel/ui/useVirtualWindowRows.d.ts.map +1 -0
  551. package/lib/panel/ui/useVirtualWindowRows.js +65 -0
  552. package/lib/panel/ui/useVirtualWindowRows.js.map +1 -0
  553. package/lib/ui.d.ts +1 -0
  554. package/lib/ui.d.ts.map +1 -1
  555. package/lib/ui.js +1 -0
  556. package/lib/ui.js.map +1 -1
  557. package/package.json +8 -1
  558. package/src/chart/core/axisLabels.ts +117 -0
  559. package/src/chart/core/boxLayout.ts +126 -0
  560. package/src/chart/core/chartAxisScale.ts +92 -10
  561. package/src/chart/core/chartDomain.ts +185 -0
  562. package/src/chart/core/chartGeometry.ts +159 -0
  563. package/src/chart/core/chartPane.ts +10 -0
  564. package/src/chart/core/chartScale.ts +7 -4
  565. package/src/chart/core/chartTheme.ts +161 -0
  566. package/src/chart/core/chartViewport.ts +40 -13
  567. package/src/chart/core/guidePlacement.ts +66 -0
  568. package/src/chart/core/index.ts +121 -2
  569. package/src/chart/core/labelStack.ts +72 -0
  570. package/src/chart/core/legendBox.ts +263 -0
  571. package/src/chart/core/selectionGeometry.ts +68 -0
  572. package/src/chart/core/spectrumColor.ts +129 -0
  573. package/src/chart/core/stackCapacity.ts +162 -0
  574. package/src/chart/core/svgPoint.ts +77 -0
  575. package/src/chart/core/tracePath.ts +228 -0
  576. package/src/chart/core/trackerReadout.ts +78 -0
  577. package/src/chart/core/viewTransform.ts +287 -0
  578. package/src/chart/core/zoomDomain.ts +235 -0
  579. package/src/chart/ui/Axes.tsx +361 -0
  580. package/src/chart/ui/AxisGuide.tsx +187 -0
  581. package/src/chart/ui/ChartStack.tsx +130 -0
  582. package/src/chart/ui/ChartTracker.tsx +101 -0
  583. package/src/chart/ui/PlotCaption.tsx +108 -0
  584. package/src/chart/ui/SelectionRect.tsx +52 -0
  585. package/src/chart/ui/TraceLegend.tsx +193 -0
  586. package/src/chart/ui/chartGestures.ts +270 -0
  587. package/src/chart/ui/chartStackLevel.tsx +210 -0
  588. package/src/chart/ui/chartSurface.ts +66 -0
  589. package/src/chart/ui/index.ts +35 -0
  590. package/src/chart/ui/useChartPointer.ts +223 -0
  591. package/src/chart/ui/useChartSize.ts +115 -0
  592. package/src/chart/ui/useChartWindow.ts +240 -0
  593. package/src/chart/ui/useChartZoom.ts +255 -0
  594. package/src/chart/ui/useWheelListener.ts +62 -0
  595. package/src/clipboard/core/copyPng.ts +20 -0
  596. package/src/clipboard/core/index.ts +1 -0
  597. package/src/clipboard/ui/CopyableValue.tsx +22 -35
  598. package/src/core.ts +1 -0
  599. package/src/download/core/exportStyles.ts +20 -0
  600. package/src/download/core/imageResolution.ts +118 -0
  601. package/src/download/core/index.ts +34 -0
  602. package/src/download/core/pictureExport.ts +207 -0
  603. package/src/download/core/stackedDrawing.ts +108 -0
  604. package/src/download/core/svgBounds.ts +80 -0
  605. package/src/download/core/svgNamespace.ts +9 -0
  606. package/src/download/core/svgToPng.ts +121 -0
  607. package/src/download/core/svgToString.ts +95 -0
  608. package/src/download/ui/ExportDialogFrame.tsx +86 -0
  609. package/src/download/ui/ExportImageDialog.tsx +91 -0
  610. package/src/download/ui/ExportNameField.tsx +148 -0
  611. package/src/download/ui/ExportPictureSection.tsx +142 -0
  612. package/src/download/ui/index.ts +11 -0
  613. package/src/download/ui/useDrawingBox.ts +37 -0
  614. package/src/error/core/describeSource.ts +18 -0
  615. package/src/error/core/index.ts +1 -0
  616. package/src/help/ui/HelpBody.tsx +41 -2
  617. package/src/help/ui/index.ts +6 -1
  618. package/src/ir/core/analysisSpectra.ts +231 -0
  619. package/src/ir/core/assignBands.ts +144 -0
  620. package/src/ir/core/bandAssignments.ts +329 -0
  621. package/src/ir/core/bandLabelPlan.ts +194 -0
  622. package/src/ir/core/detectIrFormat.ts +139 -0
  623. package/src/ir/core/downloadSpectra.ts +57 -0
  624. package/src/ir/core/fromJcamp.ts +70 -0
  625. package/src/ir/core/fromSpc.ts +61 -0
  626. package/src/ir/core/index.ts +113 -0
  627. package/src/ir/core/irBand.ts +57 -0
  628. package/src/ir/core/irCommands.ts +154 -0
  629. package/src/ir/core/irDomain.ts +163 -0
  630. package/src/ir/core/irEditorApi.ts +44 -0
  631. package/src/ir/core/irFormat.ts +57 -0
  632. package/src/ir/core/irMode.ts +203 -0
  633. package/src/ir/core/irReducer.ts +273 -0
  634. package/src/ir/core/irSidePanels.ts +20 -0
  635. package/src/ir/core/irSpectrum.ts +155 -0
  636. package/src/ir/core/irState.ts +173 -0
  637. package/src/ir/core/loadIrSpectra.ts +79 -0
  638. package/src/ir/core/nearestBand.ts +57 -0
  639. package/src/ir/core/pickBands.ts +181 -0
  640. package/src/ir/core/spectrumJcamp.ts +178 -0
  641. package/src/ir/core/toIrSpectrum.ts +102 -0
  642. package/src/ir/ui/BandMarks.tsx +166 -0
  643. package/src/ir/ui/BandsPanel.tsx +271 -0
  644. package/src/ir/ui/IrAboutDialog.tsx +121 -0
  645. package/src/ir/ui/IrCanvas.tsx +91 -0
  646. package/src/ir/ui/IrChart.tsx +215 -0
  647. package/src/ir/ui/IrCommandProvider.tsx +32 -0
  648. package/src/ir/ui/IrCommandTooltip.tsx +36 -0
  649. package/src/ir/ui/IrDocumentationDialog.tsx +174 -0
  650. package/src/ir/ui/IrEditor.tsx +99 -0
  651. package/src/ir/ui/IrHeader.tsx +39 -0
  652. package/src/ir/ui/IrLogo.tsx +49 -0
  653. package/src/ir/ui/IrPointerTracker.tsx +102 -0
  654. package/src/ir/ui/IrShell.tsx +285 -0
  655. package/src/ir/ui/IrSidePanel.tsx +78 -0
  656. package/src/ir/ui/IrStateProvider.tsx +32 -0
  657. package/src/ir/ui/IrStatusBar.tsx +97 -0
  658. package/src/ir/ui/IrToolbar.tsx +102 -0
  659. package/src/ir/ui/IrTraces.tsx +134 -0
  660. package/src/ir/ui/MetadataPanel.tsx +88 -0
  661. package/src/ir/ui/SpectraPanel.tsx +114 -0
  662. package/src/ir/ui/SpectrumRow.tsx +127 -0
  663. package/src/ir/ui/index.ts +56 -0
  664. package/src/ir/ui/irActions.ts +103 -0
  665. package/src/ir/ui/irChartProps.ts +118 -0
  666. package/src/ir/ui/irCommandContext.tsx +62 -0
  667. package/src/ir/ui/irStateContext.ts +48 -0
  668. package/src/ir/ui/useIrEditor.ts +139 -0
  669. package/src/ir/ui/useIrPointer.ts +109 -0
  670. package/src/ir/ui/useIrShortcuts.ts +95 -0
  671. package/src/ir/ui/useIrZoom.ts +86 -0
  672. package/src/ir.ts +13 -0
  673. package/src/panel/core/dialogStyles.ts +11 -0
  674. package/src/panel/core/index.ts +47 -0
  675. package/src/panel/core/isEditingField.ts +23 -0
  676. package/src/panel/core/panelStyles.ts +248 -0
  677. package/src/panel/core/rowSpacers.ts +50 -0
  678. package/src/panel/core/statusBar.ts +48 -0
  679. package/src/panel/core/textFilter.ts +33 -0
  680. package/src/panel/core/yieldToPainting.ts +20 -0
  681. package/src/panel/ui/AboutDialogFrame.tsx +100 -0
  682. package/src/panel/ui/ClearButton.tsx +42 -0
  683. package/src/panel/ui/DocumentationDialogFrame.tsx +86 -0
  684. package/src/panel/ui/FilterInput.tsx +60 -0
  685. package/src/panel/ui/HelpLabel.tsx +43 -0
  686. package/src/panel/ui/PanelMessage.tsx +64 -0
  687. package/src/panel/ui/PanelRail.tsx +64 -0
  688. package/src/panel/ui/Section.tsx +66 -0
  689. package/src/panel/ui/SidePanelStack.tsx +109 -0
  690. package/src/panel/ui/SpectrumColorSwatch.tsx +119 -0
  691. package/src/panel/ui/index.ts +47 -0
  692. package/src/panel/ui/useConfirmOnEnter.ts +68 -0
  693. package/src/panel/ui/useFilterBox.ts +35 -0
  694. package/src/panel/ui/useVirtualRows.ts +82 -0
  695. package/src/panel/ui/useVirtualWindowRows.ts +86 -0
  696. package/src/ui.ts +1 -0
@@ -0,0 +1,185 @@
1
+ /**
2
+ * The window a chart is showing, which is the one thing every viewer built on
3
+ * this package holds in common.
4
+ *
5
+ * Two numbers on each axis and nothing else — no units, no labels, no notion of
6
+ * what is being measured. That absence is the point: a mass spectrum reads its
7
+ * x axis as m/z and an infrared spectrum reads the same two numbers as
8
+ * wavenumbers, so a window that named either would need converting at every
9
+ * boundary, and a zoom gesture would have to be written twice to do the same
10
+ * arithmetic.
11
+ *
12
+ * The y axis is called nothing more specific than y for the same reason. It
13
+ * carries intensity in one viewer, absorbance or percent transmittance in
14
+ * another, and the arithmetic that maps it to pixels cares only that it is a
15
+ * range of numbers.
16
+ */
17
+
18
+ /** The window a chart is showing, in data units. */
19
+ export interface ChartDomain {
20
+ /** `[min, max]` on the horizontal axis. */
21
+ x: [number, number];
22
+ /** `[min, max]` on the vertical axis, the lower bound negative in mirror mode. */
23
+ y: [number, number];
24
+ }
25
+
26
+ /**
27
+ * How the vertical axis behaves under a gesture, where the two viewers differ.
28
+ *
29
+ * A mass spectrum is drawn as sticks standing on zero, so zero has to stay in
30
+ * the window however it is zoomed — a window starting at a tenth of the base
31
+ * peak cuts every stick off at the ankles. A continuous trace has no feet: an
32
+ * infrared band dragged out at 20 to 60 percent transmittance is asked about at
33
+ * 20 to 60 percent, and forcing 100 into the window would undo the zoom that was
34
+ * just asked for.
35
+ *
36
+ * The baseline is also what the wheel scales about, which is not always zero:
37
+ * percent transmittance runs *down* from 100, and scaling it about zero would
38
+ * walk the whole trace off the top of the plot instead of stretching it.
39
+ */
40
+ export interface YAxisRules {
41
+ /**
42
+ * The value the wheel scales about, and the line a drag is judged against.
43
+ * @default 0
44
+ */
45
+ baseline?: number;
46
+ /**
47
+ * Whether the baseline must stay inside the window a drag asks for — true for
48
+ * a stick spectrum standing on it, false for a continuous trace.
49
+ * @default true
50
+ */
51
+ keepBaseline?: boolean;
52
+ /**
53
+ * Whether the features hang **down** from the baseline rather than standing up
54
+ * out of it.
55
+ *
56
+ * This is which side of the baseline the data is on, and it decides which way
57
+ * "released past the baseline" points. A mass peak and an absorbance band both
58
+ * stand up out of a baseline at the foot of the plot, so the gesture is a drag
59
+ * released *below* it. Percent transmittance hangs down from 100, which sits
60
+ * near the *top* — so there the gesture is a drag released above it, and asking
61
+ * the mass question instead would make almost every drag in the plot take the
62
+ * value axis with it.
63
+ * @default false
64
+ */
65
+ pointsDown?: boolean;
66
+ }
67
+
68
+ /** What the rules come to when a viewer states none of them. */
69
+ export const DEFAULT_Y_AXIS_RULES: Required<YAxisRules> = {
70
+ baseline: 0,
71
+ keepBaseline: true,
72
+ pointsDown: false,
73
+ };
74
+
75
+ /**
76
+ * What a drag across the plot zooms to.
77
+ *
78
+ * `xAxis` is the reading gesture and the default: the question a chemist asks of
79
+ * a spectrum is nearly always "what is between 1650 and 1750", never "what is
80
+ * between forty and sixty percent", so a drag narrows the horizontal axis and
81
+ * leaves the height alone unless it is released past the baseline.
82
+ *
83
+ * `box` is the tool: while it is chosen, the rectangle dragged out is the window,
84
+ * both axes at once. It is a mode rather than a modifier because it is used in
85
+ * runs — a baseline being examined is examined several times over — and a
86
+ * modifier held down through each of them is a worse gesture than a tool pressed
87
+ * once.
88
+ *
89
+ * The two are named apart from the whole of `DragMode` so that a chart offering
90
+ * nothing but zoom tools can say so in its own signature — which is what stops
91
+ * `select`, the one drag that moves no axis, from reaching a chart with no
92
+ * handler for it.
93
+ */
94
+ export type ZoomDragMode = 'xAxis' | 'box';
95
+
96
+ /**
97
+ * What a drag across the plot asks for.
98
+ *
99
+ * `select` is the third and it is not a zoom at all: the rectangle swept out is
100
+ * handed back as a range and the window is left exactly where it was. A
101
+ * chromatographic peak is integrated between two retention times a chemist
102
+ * chose, and choosing them by dragging over them is the gesture — so the answer
103
+ * to it is two numbers on the horizontal axis rather than a new window, and a
104
+ * chart that zoomed to them as well would take the neighbouring peaks off the
105
+ * screen the moment the boundaries were set.
106
+ *
107
+ * It is a mode rather than a modifier for the reason `ZoomDragMode` already
108
+ * gives — integration is done in runs — and it is kept out of `ZoomDragMode` so
109
+ * that a chart offering only zoom tools, which is what the infrared toolbar
110
+ * hands to its `zoomGestures`, cannot be handed it by a widening nobody noticed.
111
+ * Handed one, that chart would sweep out a rectangle and then do nothing at all.
112
+ */
113
+ export type DragMode = ZoomDragMode | 'select';
114
+
115
+ /** How the y axis behaves, and what a drag is taken to mean. */
116
+ export interface ZoomRules extends YAxisRules {
117
+ /**
118
+ * What a drag asks for.
119
+ * @default 'xAxis'
120
+ */
121
+ drag?: DragMode;
122
+ }
123
+
124
+ /**
125
+ * Which gestures a chart answers, for a viewer that offers fewer than all of
126
+ * them.
127
+ *
128
+ * A gesture is worth having only where the axis it moves has somewhere to go,
129
+ * and that is a property of what is being measured rather than of the chart. An
130
+ * axis running between two ends the data fills — percent transmittance from 0 to
131
+ * 100 — has nothing for the wheel to scale: stretching it about its baseline
132
+ * pushes the trace off the plot and leaves an axis that no longer reads as
133
+ * percent. An axis open at one end — intensity, absorbance — has weak features
134
+ * lying against the baseline, and bringing those up is what the wheel is for.
135
+ *
136
+ * Saying it here, once, is what keeps a viewer from answering a gesture in one
137
+ * mode and quietly ignoring it in another: the whole set travels as one object
138
+ * from whatever knows the measurement into `useChartZoom`.
139
+ */
140
+ export interface ZoomGestures {
141
+ /**
142
+ * What a drag across the plot asks for.
143
+ * @default 'xAxis'
144
+ */
145
+ drag?: DragMode;
146
+ /**
147
+ * Whether the wheel scales the value axis about its baseline.
148
+ *
149
+ * Turned off, the wheel is left entirely alone — the page scrolls under the
150
+ * pointer as it does anywhere else, which is what a reader expects of a chart
151
+ * that does not answer the gesture.
152
+ * @default true
153
+ */
154
+ wheel?: boolean;
155
+ }
156
+
157
+ /** What the gestures come to when a viewer states none of them. */
158
+ export const DEFAULT_ZOOM_GESTURES: Required<ZoomGestures> = {
159
+ drag: 'xAxis',
160
+ wheel: true,
161
+ };
162
+
163
+ /**
164
+ * Whether two windows show the same thing, compared by their four numbers.
165
+ *
166
+ * By value and never by identity, because the fitted window is rebuilt from the
167
+ * spectra whenever anything about them changes — a colour, a name, a visibility
168
+ * — and only some of those changes move an axis. A chart that told the two
169
+ * apart by identity would throw the user's zoom away every time they touched
170
+ * the list beside it.
171
+ * @param current - The window in force.
172
+ * @param next - The window just worked out.
173
+ * @returns Whether both axes already run between the same bounds.
174
+ */
175
+ export function sameChartDomain(
176
+ current: ChartDomain,
177
+ next: ChartDomain,
178
+ ): boolean {
179
+ return (
180
+ current.x[0] === next.x[0] &&
181
+ current.x[1] === next.x[1] &&
182
+ current.y[0] === next.y[0] &&
183
+ current.y[1] === next.y[1]
184
+ );
185
+ }
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Where the plot sits inside the SVG, and in what order its bands are painted.
3
+ *
4
+ * The margins are deliberately not symmetric, because the two axes ask for very
5
+ * different room: a value label runs to `1.2e6` and needs the width on the
6
+ * left, while the horizontal axis carries its ticks and its title stacked under the
7
+ * plot. Nothing here is responsive — whatever lays the chart out decides how big
8
+ * it is, and this module only says what is left over for the data.
9
+ */
10
+
11
+ /** The box a chart was given, in CSS pixels. */
12
+ export interface ChartSize {
13
+ /** How wide the SVG is. */
14
+ width: number;
15
+ /** How tall the SVG is. */
16
+ height: number;
17
+ }
18
+
19
+ /**
20
+ * The plotting area inside the margins, in SVG user units.
21
+ *
22
+ * `right` and `bottom` are carried rather than recomputed at each use: a clip
23
+ * path, the brush rectangle and both axes all need the far edge, and three
24
+ * copies of `left + width` are three chances for one of them to drift.
25
+ */
26
+ export interface PlotRect {
27
+ /** Distance from the left edge of the SVG to the plot. */
28
+ left: number;
29
+ /** Distance from the top edge of the SVG to the plot. */
30
+ top: number;
31
+ /** How wide the plot is, never below `MINIMUM_PLOT_SIDE`. */
32
+ width: number;
33
+ /** How tall the plot is, never below `MINIMUM_PLOT_SIDE`. */
34
+ height: number;
35
+ /** `left + width`, where the horizontal axis ends. */
36
+ right: number;
37
+ /** `top + height`, the baseline the horizontal axis is drawn on. */
38
+ bottom: number;
39
+ }
40
+
41
+ /**
42
+ * The four sides of the room kept around a plot, in CSS pixels.
43
+ *
44
+ * Named as a type of its own because `MARGIN` is frozen at literal values, so a
45
+ * caller asking for `{ bottom: 4 }` would be told that 4 is not 34 — the
46
+ * defaults are constants, but a margin is four numbers.
47
+ */
48
+ export interface ChartMargin {
49
+ /** Room above the plot. */
50
+ top: number;
51
+ /** Room to the right of the plot. */
52
+ right: number;
53
+ /** Room below the plot, where the horizontal axis is written. */
54
+ bottom: number;
55
+ /** Room to the left of the plot, where the value axis is written. */
56
+ left: number;
57
+ }
58
+
59
+ /**
60
+ * The room kept around the plot for the axes and their titles.
61
+ *
62
+ * `left` is the widest because it has to hold a value label; `bottom` is
63
+ * deeper than `top` because it stacks the tick labels and the axis title under
64
+ * the plot, where `top` only keeps the topmost value label off the edge.
65
+ *
66
+ * Each of them is the furniture and no more than the furniture. `Axes` writes
67
+ * its tick row five pixels under the plot and its title thirteen under that,
68
+ * which puts the deepest ink of a `(min)` some thirty pixels down; what is left
69
+ * is slack. A stack pays these four numbers once per pane — a column of three
70
+ * chromatograms over a spectrum pays `bottom` four times — and a pixel of slack
71
+ * in here is a pixel the measurement was not drawn in, over and over.
72
+ */
73
+ export const MARGIN = { top: 10, right: 16, bottom: 34, left: 60 } as const;
74
+
75
+ /**
76
+ * How much room a chart leaves under its plot when it writes no horizontal axis
77
+ * of its own.
78
+ *
79
+ * A pane of a stack above the foot draws no tick row and no axis title — the
80
+ * panes share one window, so one axis under the last of them says everything —
81
+ * and this is what it keeps instead: enough that the trace does not run into
82
+ * the splitter under it, and no more. It lives here beside `MARGIN` rather than
83
+ * in the viewer that uses it, because the arithmetic that shares a stack's
84
+ * height between its panes has to subtract exactly the difference between the
85
+ * two, and a second copy of either number is a stack whose plots do not line up.
86
+ */
87
+ export const SHARED_AXIS_MARGIN = 8;
88
+
89
+ /**
90
+ * The smallest plot the arithmetic is allowed to describe.
91
+ *
92
+ * A chart is briefly laid out at nothing — a panel opening, a splitter dragged
93
+ * shut, the first render before the container has been measured — and the naive
94
+ * subtraction then gives a negative width, which every scale built from it turns
95
+ * into an infinity and the DOM refuses outright. Ten pixels is small enough to
96
+ * be invisible and large enough to keep every number finite until the real size
97
+ * arrives.
98
+ */
99
+ export const MINIMUM_PLOT_SIDE = 10;
100
+
101
+ /**
102
+ * The six bands of the chart, bottom to top, in the order they are painted.
103
+ *
104
+ * The order is the whole interaction design in one array. `defs` holds the clip
105
+ * paths and markers and is never painted itself. `axes` sits under the data so a
106
+ * grid line can never be mistaken for a peak. `data` is the only clipped band,
107
+ * so a zoomed trace stops at the plot edge instead of running out over the
108
+ * labels — which is also why `guide` is separate: an annotation's label sits
109
+ * above the tallest peak and must be allowed out of the clip. `selection` covers
110
+ * the data so a drag stays visible over it, and `tracker` is last so the
111
+ * crosshair and its readout are never occluded by anything.
112
+ */
113
+ export const CHART_LAYERS = [
114
+ 'defs',
115
+ 'axes',
116
+ 'data',
117
+ 'guide',
118
+ 'selection',
119
+ 'tracker',
120
+ ] as const;
121
+
122
+ /** One band of the chart. */
123
+ export type ChartLayer = (typeof CHART_LAYERS)[number];
124
+
125
+ /**
126
+ * Work out the plotting area for a chart of a given size.
127
+ * @param size - The box the chart was given.
128
+ * @param margin - Room to keep around the plot instead of the module default.
129
+ * Whatever side it names is used and every side it omits keeps `MARGIN`, because
130
+ * a chart that only wants its foot back should not have to restate the 60 px its
131
+ * value labels need. A chart standing alone wants all four sides, but panes
132
+ * stacked one above another do not: only the pane at the foot of the stack draws
133
+ * a tick row, and only the topmost has anything above it to be kept clear of.
134
+ * Three panes sharing a 400 px column each pay 48 px at the bottom and 16 px at
135
+ * the top, which is 192 px of axis furniture where 64 px is all that can be seen
136
+ * — the other 128 px is blank room taken out of the traces, and the middle pane
137
+ * is left drawing in barely half of its third. Passing `{ top: 4, bottom: 4 }`
138
+ * to every pane but the two that need the room hands it back.
139
+ * @returns The plot inside the margins, clamped so it is never degenerate.
140
+ */
141
+ export function plotRect(
142
+ size: ChartSize,
143
+ margin?: Partial<ChartMargin>,
144
+ ): PlotRect {
145
+ const top = margin?.top ?? MARGIN.top;
146
+ const right = margin?.right ?? MARGIN.right;
147
+ const bottom = margin?.bottom ?? MARGIN.bottom;
148
+ const left = margin?.left ?? MARGIN.left;
149
+ const width = Math.max(MINIMUM_PLOT_SIDE, size.width - left - right);
150
+ const height = Math.max(MINIMUM_PLOT_SIDE, size.height - top - bottom);
151
+ return {
152
+ left,
153
+ top,
154
+ width,
155
+ height,
156
+ right: left + width,
157
+ bottom: top + height,
158
+ };
159
+ }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Marks the box one pane of a chart stack is drawn in.
3
+ *
4
+ * A stack is laid out in `chartStackLevel.tsx` and read again, from the outside,
5
+ * by whatever takes a picture of the editor the stack sits in — `drawingIn` has
6
+ * to know that a box holding a chromatogram over a spectrum holds two drawings
7
+ * rather than one, and this mark is how it tells. It sits in a file of its own
8
+ * so that neither of them has to import the other's React.
9
+ */
10
+ export const CHART_PANE_ATTRIBUTE = 'data-chart-pane';
@@ -27,7 +27,10 @@ export interface ChartScale {
27
27
  * @param rangeMax - The pixel `domainMax` maps to.
28
28
  * @returns The mapping. A zero-width or non-finite domain gives a `factor` of
29
29
  * zero, which pins every value to the middle of the range so that a constant
30
- * column still draws instead of vanishing.
30
+ * column still draws instead of vanishing. A range that is not a range — a
31
+ * plot measured before it was laid out — gives an `offset` of `NaN` instead,
32
+ * because there is no pixel a value could honestly be put at, and every mark
33
+ * already declines to draw what does not map.
31
34
  */
32
35
  export function chartScale(
33
36
  domainMin: number,
@@ -37,9 +40,9 @@ export function chartScale(
37
40
  ): ChartScale {
38
41
  const span = domainMax - domainMin;
39
42
  const reach = rangeMax - rangeMin;
40
- if (span === 0 || !Number.isFinite(span) || !Number.isFinite(reach)) {
41
- const middle = (rangeMin + rangeMax) / 2;
42
- return { offset: Number.isFinite(middle) ? middle : 0, factor: 0 };
43
+ if (!Number.isFinite(reach)) return { offset: Number.NaN, factor: 0 };
44
+ if (span === 0 || !Number.isFinite(span)) {
45
+ return { offset: (rangeMin + rangeMax) / 2, factor: 0 };
43
46
  }
44
47
  const factor = reach / span;
45
48
  return { offset: rangeMin - domainMin * factor, factor };
@@ -0,0 +1,161 @@
1
+ /**
2
+ * Every colour and every measurement the chart is drawn with.
3
+ *
4
+ * Each colour is a custom property with a literal fallback baked in, and is
5
+ * applied through the `style` prop rather than through the matching SVG
6
+ * attribute — `fill="var(--spectrum-axis, #64748b)"` is not a colour any browser
7
+ * resolves, because `var()` is a CSS value and a presentation attribute is not
8
+ * parsed as one. `style={{ fill: CHART_COLORS.axis }}` is.
9
+ *
10
+ * One set of tokens for every viewer built on this package, rather than one per
11
+ * viewer: a page showing a mass spectrum beside an infrared one is showing two
12
+ * charts that have to look like the same instrument, and two token families
13
+ * would let them drift apart at the first theme change.
14
+ *
15
+ * The fallbacks are what make the package usable on its own: a host that sets
16
+ * none of these tokens still gets a chart that reads correctly, and a host with
17
+ * a dark theme or a house palette overrides whichever it cares about by setting
18
+ * the properties on any ancestor. Nothing here is a prop, because a colour
19
+ * threaded through props is a colour that ends up hard-coded in one component
20
+ * that forgot to accept it.
21
+ */
22
+
23
+ /** The colours of everything the chart draws that is not a spectrum. */
24
+ export const CHART_COLORS = {
25
+ /** The two axis lines and their ticks. */
26
+ axis: 'var(--spectrum-axis, #64748b)',
27
+ /** The numbers along both axes. */
28
+ tick: 'var(--spectrum-tick, #475569)',
29
+ /** The axis titles, whatever the viewer calls its two axes. */
30
+ title: 'var(--spectrum-title, #334155)',
31
+ /** The rules across the plot, behind the data. */
32
+ grid: 'var(--spectrum-grid, #e2e8f0)',
33
+ /** The rule at zero, which a mirrored pair is reflected in. */
34
+ zeroRule: 'var(--spectrum-zero-rule, #cbd5e1)',
35
+ /** A mark on a feature an annotation explained. */
36
+ annotation: 'var(--spectrum-annotation, #2563eb)',
37
+ /**
38
+ * A mark where an annotation nothing answered would fall, drawn dashed. Grey
39
+ * rather than red: a fragment the spectrum does not carry is an answer, and
40
+ * colouring it as a failure would say the opposite.
41
+ */
42
+ annotationUnmatched: 'var(--spectrum-annotation-unmatched, #cbd5e1)',
43
+ /**
44
+ * A mark on a place the measurement drawn below was cut from — the peaks a
45
+ * survey scan was fragmented at.
46
+ *
47
+ * Its own token rather than the annotation blue, because the two are claims
48
+ * of different kinds laid over the same peaks: an annotation says *this is
49
+ * what I think that peak is*, and a precursor mark says *this is what the
50
+ * instrument did with it*. A spectrum can carry both at once, and a reader
51
+ * has to be able to tell one row of marks from the other.
52
+ */
53
+ precursor: 'var(--spectrum-precursor, #7c3aed)',
54
+ /** The line from a label back down to the peak it belongs to. */
55
+ leader: 'var(--spectrum-leader, #94a3b8)',
56
+ /** The fill of a label box, opaque enough to read over a dense trace. */
57
+ labelBackground:
58
+ 'var(--spectrum-label-background, rgba(255, 255, 255, 0.88))',
59
+ /** Its border. */
60
+ labelBorder: 'var(--spectrum-label-border, #cbd5e1)',
61
+ /** The text inside it. */
62
+ labelText: 'var(--spectrum-label-text, #1e293b)',
63
+ /**
64
+ * The paper a label written straight onto the plot is set on, laid behind its
65
+ * glyphs rather than in a box around them — the colour of the chart itself,
66
+ * which is why a host with a dark theme has to override it along with the rest.
67
+ */
68
+ labelHalo: 'var(--spectrum-label-halo, #ffffff)',
69
+ /** Whatever the pointer has come to rest on, wherever it was hovered. */
70
+ highlight: 'var(--spectrum-highlight, #f97316)',
71
+ /** The rectangle a drag is sweeping out. */
72
+ selection: 'var(--spectrum-selection, rgba(37, 99, 235, 0.12))',
73
+ /** Its edge. */
74
+ selectionBorder: 'var(--spectrum-selection-border, #2563eb)',
75
+ /** The crosshair following the pointer. */
76
+ tracker: 'var(--spectrum-tracker, #94a3b8)',
77
+ /** What it reads out. */
78
+ trackerText: 'var(--spectrum-tracker-text, #0f172a)',
79
+ } as const;
80
+
81
+ /**
82
+ * The type sizes, in pixels.
83
+ *
84
+ * Small and fixed rather than inherited: the chart is a drawing, and a host
85
+ * whose base font is 18px would push its tick labels into one another. The
86
+ * family is deliberately not set here, so the chart still looks like the
87
+ * application it is embedded in.
88
+ */
89
+ export const CHART_FONT = {
90
+ /** The numbers along both axes. */
91
+ tick: 10,
92
+ /** The axis titles. */
93
+ title: 12,
94
+ /** The labels pinned above the peaks. */
95
+ label: 11,
96
+ /** The readout the crosshair carries. */
97
+ readout: 11,
98
+ } as const;
99
+
100
+ /**
101
+ * The geometry of a label pinned above a feature.
102
+ *
103
+ * A label is two lines often enough — an m/z over a formula, a wavenumber over
104
+ * the group it is assigned to — that the spacing has to be a constant both the
105
+ * drawing and the declutter sweep agree on, or the boxes are spaced for one
106
+ * height and drawn at another.
107
+ */
108
+ export const PEAK_LABEL = {
109
+ /** The baseline-to-baseline distance between two stacked lines. */
110
+ lineHeight: 11,
111
+ /** The clear space between the top of a stick and its first line. */
112
+ topPad: 10,
113
+ /**
114
+ * How far the mark on a named peak reaches from the tip of its stick.
115
+ *
116
+ * It reaches *away* from the stack, down into the peak, because the clear
117
+ * space above the tip is where the numbers are written and the mark is there
118
+ * to say which peak they are about. Short on purpose: what is drawn is the
119
+ * **top of the centroid stick**, enough to put a picked peak exactly on the
120
+ * profile it was picked from — a rule carried all the way to the baseline is
121
+ * the centroid trace itself, which is the other thing the row toggles.
122
+ */
123
+ topMark: 10,
124
+ /**
125
+ * Half the width a label claims while the pointer is on it, which is what the
126
+ * declutter sweep keeps its neighbours out of.
127
+ */
128
+ hoverHalfWidth: 26,
129
+ } as const;
130
+
131
+ /**
132
+ * The halo a label written straight onto the plot carries.
133
+ *
134
+ * A number over a peak is written over whatever the plot has there — a grid
135
+ * line, a dense trace, the crosshair following the pointer, the tail of the
136
+ * label beside it — and a glyph crossed by a line is a glyph read twice before
137
+ * it is read at all. So the glyphs are stroked in the colour of the paper and
138
+ * that stroke is painted *first*, which clears a hairline of chart from around
139
+ * every letter without a box, a border or a fill hiding the data underneath.
140
+ *
141
+ * `paintOrder` is the whole of it and is easy to leave out: the default order
142
+ * paints the stroke over the fill, so the same three properties without it draw
143
+ * every label in white on white.
144
+ */
145
+ export const LABEL_HALO = {
146
+ paintOrder: 'stroke',
147
+ stroke: CHART_COLORS.labelHalo,
148
+ strokeWidth: 3,
149
+ strokeLinejoin: 'round',
150
+ } as const;
151
+
152
+ /**
153
+ * How far the supporting line of a label is let back towards the paper.
154
+ *
155
+ * A label is rarely one thing: a mass peak carries what it is *and* how tall it
156
+ * stood, and the crosshair reads a place on both axes at once. Written in one
157
+ * ink they are read together, which means the line somebody wants has to be
158
+ * found among the ones they do not. Six tenths is enough to grade them apart at
159
+ * eleven pixels and not so far as to make the quiet line look disabled.
160
+ */
161
+ export const LABEL_QUIET = 0.6;
@@ -33,8 +33,20 @@ export const CHART_WHEEL_LINE = 16;
33
33
  /** Pixels it is worth where the browser reports pages. */
34
34
  export const CHART_WHEEL_PAGE = 400;
35
35
 
36
- /** The most one wheel event may zoom by, so a stray burst cannot jump. */
37
- export const CHART_WHEEL_LARGEST = 4;
36
+ /**
37
+ * The most travel one wheel event is read as, in pixels.
38
+ *
39
+ * A trackpad flick arrives as a handful of events carrying several hundred
40
+ * pixels each, and an inertial one keeps arriving after the fingers have left
41
+ * the glass. Uncapped, a single flick takes an axis through several orders of
42
+ * magnitude and the data is gone; capped, the gesture stays fast and is always
43
+ * recoverable by flicking the other way.
44
+ *
45
+ * The cap is written in travel rather than as a largest factor because travel
46
+ * is what the browser reports and what varies between them — so a chart that
47
+ * zooms at its own pace is held to the same burst as every other.
48
+ */
49
+ export const CHART_WHEEL_TRAVEL = 240;
38
50
 
39
51
  /**
40
52
  * The viewport a zoom about one point leaves behind.
@@ -130,9 +142,13 @@ export function chartZoomDomain(
130
142
  * The travel is normalised first, because the same notch of the same wheel
131
143
  * arrives as pixels in one browser and as lines in another, and a zoom that
132
144
  * moves three times as fast in Firefox is a fault the reader blames on the
133
- * figure. One event is capped: a trackpad flick can deliver a whole page of
134
- * travel at once, and landing four hundred times out is not recoverable by
135
- * feel.
145
+ * figure. Then it is capped at {@link CHART_WHEEL_TRAVEL}, so one burst can
146
+ * only ever be worth one flick.
147
+ *
148
+ * The factor is `exp(pixels x rate)`, so the gesture is multiplicative: two
149
+ * notches in and two notches out land back where they started, whichever way
150
+ * round they were made, and a zoom deep into one small feature comes back out
151
+ * at the pace it went in.
136
152
  * @param delta - The event's `deltaY`; positive scrolls away and zooms out.
137
153
  * @param mode - Its `deltaMode`: 0 pixels, 1 lines, 2 pages. Defaults to `0`.
138
154
  * @param speed - Share zoomed per pixel of travel. Defaults to {@link CHART_WHEEL_SPEED}.
@@ -143,15 +159,26 @@ export function chartWheelFactor(
143
159
  mode = 0,
144
160
  speed = CHART_WHEEL_SPEED,
145
161
  ): number {
146
- if (!Number.isFinite(delta) || delta === 0) return 1;
147
- const pixels = delta * wheelPixels(mode);
162
+ const travel = chartWheelTravel(delta, mode);
163
+ if (travel === 0) return 1;
148
164
  const rate = Number.isFinite(speed) && speed > 0 ? speed : CHART_WHEEL_SPEED;
149
- const factor = Math.exp(pixels * rate);
150
- if (!Number.isFinite(factor)) return delta > 0 ? CHART_WHEEL_LARGEST : 1;
151
- return Math.min(
152
- CHART_WHEEL_LARGEST,
153
- Math.max(1 / CHART_WHEEL_LARGEST, factor),
154
- );
165
+ return Math.exp(travel * rate);
166
+ }
167
+
168
+ /**
169
+ * The travel one wheel event carries, in pixels, capped.
170
+ *
171
+ * Separate from the factor because a gesture that is not a zoom — a wheel that
172
+ * scales a value axis about its baseline — needs the same normalisation and
173
+ * the same cap while computing something else entirely.
174
+ * @param delta - The event's `deltaY`.
175
+ * @param mode - Its `deltaMode`: 0 pixels, 1 lines, 2 pages. Defaults to `0`.
176
+ * @returns The travel, `0` for an event that says nothing.
177
+ */
178
+ export function chartWheelTravel(delta: number, mode = 0): number {
179
+ if (!Number.isFinite(delta) || delta === 0) return 0;
180
+ const pixels = delta * wheelPixels(mode);
181
+ return Math.min(CHART_WHEEL_TRAVEL, Math.max(-CHART_WHEEL_TRAVEL, pixels));
155
182
  }
156
183
 
157
184
  function wheelPixels(mode: number): number {