react-cheminfo 0.28.0 → 0.30.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.
- package/README.md +79 -26
- package/lib/chart/core/axisLabels.d.ts +82 -0
- package/lib/chart/core/axisLabels.d.ts.map +1 -0
- package/lib/chart/core/axisLabels.js +111 -0
- package/lib/chart/core/axisLabels.js.map +1 -0
- package/lib/chart/core/boxLayout.d.ts +53 -0
- package/lib/chart/core/boxLayout.d.ts.map +1 -0
- package/lib/chart/core/boxLayout.js +112 -0
- package/lib/chart/core/boxLayout.js.map +1 -0
- package/lib/chart/core/chartAxisScale.d.ts +23 -2
- package/lib/chart/core/chartAxisScale.d.ts.map +1 -1
- package/lib/chart/core/chartAxisScale.js +64 -13
- package/lib/chart/core/chartAxisScale.js.map +1 -1
- package/lib/chart/core/chartDomain.d.ts +160 -0
- package/lib/chart/core/chartDomain.d.ts.map +1 -0
- package/lib/chart/core/chartDomain.js +46 -0
- package/lib/chart/core/chartDomain.js.map +1 -0
- package/lib/chart/core/chartGeometry.d.ts +131 -0
- package/lib/chart/core/chartGeometry.d.ts.map +1 -0
- package/lib/chart/core/chartGeometry.js +101 -0
- package/lib/chart/core/chartGeometry.js.map +1 -0
- package/lib/chart/core/chartPane.d.ts +11 -0
- package/lib/chart/core/chartPane.d.ts.map +1 -0
- package/lib/chart/core/chartPane.js +11 -0
- package/lib/chart/core/chartPane.js.map +1 -0
- package/lib/chart/core/chartScale.d.ts +4 -1
- package/lib/chart/core/chartScale.d.ts.map +1 -1
- package/lib/chart/core/chartScale.js +8 -4
- package/lib/chart/core/chartScale.js.map +1 -1
- package/lib/chart/core/chartTheme.d.ts +156 -0
- package/lib/chart/core/chartTheme.d.ts.map +1 -0
- package/lib/chart/core/chartTheme.js +156 -0
- package/lib/chart/core/chartTheme.js.map +1 -0
- package/lib/chart/core/chartViewport.d.ts +32 -5
- package/lib/chart/core/chartViewport.d.ts.map +1 -1
- package/lib/chart/core/chartViewport.js +40 -11
- package/lib/chart/core/chartViewport.js.map +1 -1
- package/lib/chart/core/guidePlacement.d.ts +52 -0
- package/lib/chart/core/guidePlacement.d.ts.map +1 -0
- package/lib/chart/core/guidePlacement.js +52 -0
- package/lib/chart/core/guidePlacement.js.map +1 -0
- package/lib/chart/core/index.d.ts +29 -2
- package/lib/chart/core/index.d.ts.map +1 -1
- package/lib/chart/core/index.js +19 -2
- package/lib/chart/core/index.js.map +1 -1
- package/lib/chart/core/labelStack.d.ts +27 -0
- package/lib/chart/core/labelStack.d.ts.map +1 -0
- package/lib/chart/core/labelStack.js +62 -0
- package/lib/chart/core/labelStack.js.map +1 -0
- package/lib/chart/core/legendBox.d.ts +152 -0
- package/lib/chart/core/legendBox.d.ts.map +1 -0
- package/lib/chart/core/legendBox.js +169 -0
- package/lib/chart/core/legendBox.js.map +1 -0
- package/lib/chart/core/selectionGeometry.d.ts +45 -0
- package/lib/chart/core/selectionGeometry.d.ts.map +1 -0
- package/lib/chart/core/selectionGeometry.js +49 -0
- package/lib/chart/core/selectionGeometry.js.map +1 -0
- package/lib/chart/core/spectrumColor.d.ts +80 -0
- package/lib/chart/core/spectrumColor.d.ts.map +1 -0
- package/lib/chart/core/spectrumColor.js +120 -0
- package/lib/chart/core/spectrumColor.js.map +1 -0
- package/lib/chart/core/stackCapacity.d.ts +136 -0
- package/lib/chart/core/stackCapacity.d.ts.map +1 -0
- package/lib/chart/core/stackCapacity.js +153 -0
- package/lib/chart/core/stackCapacity.js.map +1 -0
- package/lib/chart/core/svgPoint.d.ts +62 -0
- package/lib/chart/core/svgPoint.d.ts.map +1 -0
- package/lib/chart/core/svgPoint.js +43 -0
- package/lib/chart/core/svgPoint.js.map +1 -0
- package/lib/chart/core/tracePath.d.ts +94 -0
- package/lib/chart/core/tracePath.d.ts.map +1 -0
- package/lib/chart/core/tracePath.js +191 -0
- package/lib/chart/core/tracePath.js.map +1 -0
- package/lib/chart/core/trackerReadout.d.ts +55 -0
- package/lib/chart/core/trackerReadout.d.ts.map +1 -0
- package/lib/chart/core/trackerReadout.js +53 -0
- package/lib/chart/core/trackerReadout.js.map +1 -0
- package/lib/chart/core/viewTransform.d.ts +167 -0
- package/lib/chart/core/viewTransform.d.ts.map +1 -0
- package/lib/chart/core/viewTransform.js +188 -0
- package/lib/chart/core/viewTransform.js.map +1 -0
- package/lib/chart/core/zoomDomain.d.ts +127 -0
- package/lib/chart/core/zoomDomain.d.ts.map +1 -0
- package/lib/chart/core/zoomDomain.js +175 -0
- package/lib/chart/core/zoomDomain.js.map +1 -0
- package/lib/chart/ui/Axes.d.ts +104 -0
- package/lib/chart/ui/Axes.d.ts.map +1 -0
- package/lib/chart/ui/Axes.js +155 -0
- package/lib/chart/ui/Axes.js.map +1 -0
- package/lib/chart/ui/AxisGuide.d.ts +60 -0
- package/lib/chart/ui/AxisGuide.d.ts.map +1 -0
- package/lib/chart/ui/AxisGuide.js +111 -0
- package/lib/chart/ui/AxisGuide.js.map +1 -0
- package/lib/chart/ui/ChartStack.d.ts +81 -0
- package/lib/chart/ui/ChartStack.d.ts.map +1 -0
- package/lib/chart/ui/ChartStack.js +42 -0
- package/lib/chart/ui/ChartStack.js.map +1 -0
- package/lib/chart/ui/ChartTracker.d.ts +36 -0
- package/lib/chart/ui/ChartTracker.d.ts.map +1 -0
- package/lib/chart/ui/ChartTracker.js +27 -0
- package/lib/chart/ui/ChartTracker.js.map +1 -0
- package/lib/chart/ui/PlotCaption.d.ts +44 -0
- package/lib/chart/ui/PlotCaption.d.ts.map +1 -0
- package/lib/chart/ui/PlotCaption.js +68 -0
- package/lib/chart/ui/PlotCaption.js.map +1 -0
- package/lib/chart/ui/SelectionRect.d.ts +27 -0
- package/lib/chart/ui/SelectionRect.d.ts.map +1 -0
- package/lib/chart/ui/SelectionRect.js +31 -0
- package/lib/chart/ui/SelectionRect.js.map +1 -0
- package/lib/chart/ui/TraceLegend.d.ts +99 -0
- package/lib/chart/ui/TraceLegend.d.ts.map +1 -0
- package/lib/chart/ui/TraceLegend.js +45 -0
- package/lib/chart/ui/TraceLegend.js.map +1 -0
- package/lib/chart/ui/chartGestures.d.ts +158 -0
- package/lib/chart/ui/chartGestures.d.ts.map +1 -0
- package/lib/chart/ui/chartGestures.js +145 -0
- package/lib/chart/ui/chartGestures.js.map +1 -0
- package/lib/chart/ui/chartStackLevel.d.ts +115 -0
- package/lib/chart/ui/chartStackLevel.d.ts.map +1 -0
- package/lib/chart/ui/chartStackLevel.js +96 -0
- package/lib/chart/ui/chartStackLevel.js.map +1 -0
- package/lib/chart/ui/chartSurface.d.ts +35 -0
- package/lib/chart/ui/chartSurface.d.ts.map +1 -0
- package/lib/chart/ui/chartSurface.js +58 -0
- package/lib/chart/ui/chartSurface.js.map +1 -0
- package/lib/chart/ui/index.d.ts +24 -0
- package/lib/chart/ui/index.d.ts.map +1 -1
- package/lib/chart/ui/index.js +13 -0
- package/lib/chart/ui/index.js.map +1 -1
- package/lib/chart/ui/useChartPointer.d.ts +124 -0
- package/lib/chart/ui/useChartPointer.d.ts.map +1 -0
- package/lib/chart/ui/useChartPointer.js +152 -0
- package/lib/chart/ui/useChartPointer.js.map +1 -0
- package/lib/chart/ui/useChartSize.d.ts +49 -0
- package/lib/chart/ui/useChartSize.d.ts.map +1 -0
- package/lib/chart/ui/useChartSize.js +91 -0
- package/lib/chart/ui/useChartSize.js.map +1 -0
- package/lib/chart/ui/useChartWindow.d.ts +147 -0
- package/lib/chart/ui/useChartWindow.d.ts.map +1 -0
- package/lib/chart/ui/useChartWindow.js +135 -0
- package/lib/chart/ui/useChartWindow.js.map +1 -0
- package/lib/chart/ui/useChartZoom.d.ts +88 -0
- package/lib/chart/ui/useChartZoom.d.ts.map +1 -0
- package/lib/chart/ui/useChartZoom.js +142 -0
- package/lib/chart/ui/useChartZoom.js.map +1 -0
- package/lib/chart/ui/useWheelListener.d.ts +30 -0
- package/lib/chart/ui/useWheelListener.d.ts.map +1 -0
- package/lib/chart/ui/useWheelListener.js +57 -0
- package/lib/chart/ui/useWheelListener.js.map +1 -0
- package/lib/chrome/ui/AccountButton.d.ts +76 -0
- package/lib/chrome/ui/AccountButton.d.ts.map +1 -0
- package/lib/chrome/ui/AccountButton.js +66 -0
- package/lib/chrome/ui/AccountButton.js.map +1 -0
- package/lib/chrome/ui/index.d.ts +2 -0
- package/lib/chrome/ui/index.d.ts.map +1 -1
- package/lib/chrome/ui/index.js +1 -0
- package/lib/chrome/ui/index.js.map +1 -1
- package/lib/clipboard/core/copyPng.d.ts +13 -0
- package/lib/clipboard/core/copyPng.d.ts.map +1 -0
- package/lib/clipboard/core/copyPng.js +19 -0
- package/lib/clipboard/core/copyPng.js.map +1 -0
- package/lib/clipboard/core/index.d.ts +1 -0
- package/lib/clipboard/core/index.d.ts.map +1 -1
- package/lib/clipboard/core/index.js +1 -0
- package/lib/clipboard/core/index.js.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.d.ts +6 -0
- package/lib/clipboard/ui/ClickToCopy.d.ts.map +1 -1
- package/lib/clipboard/ui/ClickToCopy.js +3 -3
- package/lib/clipboard/ui/ClickToCopy.js.map +1 -1
- package/lib/core.d.ts +1 -0
- package/lib/core.d.ts.map +1 -1
- package/lib/core.js +1 -0
- package/lib/core.js.map +1 -1
- package/lib/download/core/exportStyles.d.ts +22 -0
- package/lib/download/core/exportStyles.d.ts.map +1 -0
- package/lib/download/core/exportStyles.js +19 -0
- package/lib/download/core/exportStyles.js.map +1 -0
- package/lib/download/core/imageResolution.d.ts +88 -0
- package/lib/download/core/imageResolution.d.ts.map +1 -0
- package/lib/download/core/imageResolution.js +77 -0
- package/lib/download/core/imageResolution.js.map +1 -0
- package/lib/download/core/index.d.ts +13 -0
- package/lib/download/core/index.d.ts.map +1 -1
- package/lib/download/core/index.js +8 -0
- package/lib/download/core/index.js.map +1 -1
- package/lib/download/core/pictureExport.d.ts +93 -0
- package/lib/download/core/pictureExport.d.ts.map +1 -0
- package/lib/download/core/pictureExport.js +116 -0
- package/lib/download/core/pictureExport.js.map +1 -0
- package/lib/download/core/stackedDrawing.d.ts +36 -0
- package/lib/download/core/stackedDrawing.d.ts.map +1 -0
- package/lib/download/core/stackedDrawing.js +98 -0
- package/lib/download/core/stackedDrawing.js.map +1 -0
- package/lib/download/core/svgBounds.d.ts +44 -0
- package/lib/download/core/svgBounds.d.ts.map +1 -0
- package/lib/download/core/svgBounds.js +69 -0
- package/lib/download/core/svgBounds.js.map +1 -0
- package/lib/download/core/svgNamespace.d.ts +9 -0
- package/lib/download/core/svgNamespace.d.ts.map +1 -0
- package/lib/download/core/svgNamespace.js +10 -0
- package/lib/download/core/svgNamespace.js.map +1 -0
- package/lib/download/core/svgToPng.d.ts +43 -0
- package/lib/download/core/svgToPng.d.ts.map +1 -0
- package/lib/download/core/svgToPng.js +79 -0
- package/lib/download/core/svgToPng.js.map +1 -0
- package/lib/download/core/svgToString.d.ts +45 -0
- package/lib/download/core/svgToString.d.ts.map +1 -0
- package/lib/download/core/svgToString.js +58 -0
- package/lib/download/core/svgToString.js.map +1 -0
- package/lib/download/ui/ExportDialogFrame.d.ts +46 -0
- package/lib/download/ui/ExportDialogFrame.d.ts.map +1 -0
- package/lib/download/ui/ExportDialogFrame.js +24 -0
- package/lib/download/ui/ExportDialogFrame.js.map +1 -0
- package/lib/download/ui/ExportImageDialog.d.ts +47 -0
- package/lib/download/ui/ExportImageDialog.d.ts.map +1 -0
- package/lib/download/ui/ExportImageDialog.js +25 -0
- package/lib/download/ui/ExportImageDialog.js.map +1 -0
- package/lib/download/ui/ExportNameField.d.ts +29 -0
- package/lib/download/ui/ExportNameField.d.ts.map +1 -0
- package/lib/download/ui/ExportNameField.js +99 -0
- package/lib/download/ui/ExportNameField.js.map +1 -0
- package/lib/download/ui/ExportPictureSection.d.ts +38 -0
- package/lib/download/ui/ExportPictureSection.d.ts.map +1 -0
- package/lib/download/ui/ExportPictureSection.js +48 -0
- package/lib/download/ui/ExportPictureSection.js.map +1 -0
- package/lib/download/ui/index.d.ts +10 -0
- package/lib/download/ui/index.d.ts.map +1 -1
- package/lib/download/ui/index.js +5 -0
- package/lib/download/ui/index.js.map +1 -1
- package/lib/download/ui/useDrawingBox.d.ts +23 -0
- package/lib/download/ui/useDrawingBox.d.ts.map +1 -0
- package/lib/download/ui/useDrawingBox.js +21 -0
- package/lib/download/ui/useDrawingBox.js.map +1 -0
- package/lib/error/core/describeSource.d.ts +17 -0
- package/lib/error/core/describeSource.d.ts.map +1 -0
- package/lib/error/core/describeSource.js +19 -0
- package/lib/error/core/describeSource.js.map +1 -0
- package/lib/error/core/index.d.ts +1 -0
- package/lib/error/core/index.d.ts.map +1 -1
- package/lib/error/core/index.js +1 -0
- package/lib/error/core/index.js.map +1 -1
- package/lib/help/ui/HelpBody.d.ts +10 -1
- package/lib/help/ui/HelpBody.d.ts.map +1 -1
- package/lib/help/ui/HelpBody.js +24 -1
- package/lib/help/ui/HelpBody.js.map +1 -1
- package/lib/help/ui/index.d.ts +1 -1
- package/lib/help/ui/index.d.ts.map +1 -1
- package/lib/help/ui/index.js.map +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.d.ts +46 -0
- package/lib/ir/core/analysisSpectra.d.ts.map +1 -0
- package/lib/ir/core/analysisSpectra.js +187 -0
- package/lib/ir/core/analysisSpectra.js.map +1 -0
- package/lib/ir/core/assignBands.d.ts +83 -0
- package/lib/ir/core/assignBands.d.ts.map +1 -0
- package/lib/ir/core/assignBands.js +83 -0
- package/lib/ir/core/assignBands.js.map +1 -0
- package/lib/ir/core/bandAssignments.d.ts +47 -0
- package/lib/ir/core/bandAssignments.d.ts.map +1 -0
- package/lib/ir/core/bandAssignments.js +305 -0
- package/lib/ir/core/bandAssignments.js.map +1 -0
- package/lib/ir/core/bandLabelPlan.d.ts +93 -0
- package/lib/ir/core/bandLabelPlan.d.ts.map +1 -0
- package/lib/ir/core/bandLabelPlan.js +104 -0
- package/lib/ir/core/bandLabelPlan.js.map +1 -0
- package/lib/ir/core/detectIrFormat.d.ts +23 -0
- package/lib/ir/core/detectIrFormat.d.ts.map +1 -0
- package/lib/ir/core/detectIrFormat.js +133 -0
- package/lib/ir/core/detectIrFormat.js.map +1 -0
- package/lib/ir/core/downloadSpectra.d.ts +26 -0
- package/lib/ir/core/downloadSpectra.d.ts.map +1 -0
- package/lib/ir/core/downloadSpectra.js +37 -0
- package/lib/ir/core/downloadSpectra.js.map +1 -0
- package/lib/ir/core/fromJcamp.d.ts +35 -0
- package/lib/ir/core/fromJcamp.d.ts.map +1 -0
- package/lib/ir/core/fromJcamp.js +48 -0
- package/lib/ir/core/fromJcamp.js.map +1 -0
- package/lib/ir/core/fromSpc.d.ts +30 -0
- package/lib/ir/core/fromSpc.d.ts.map +1 -0
- package/lib/ir/core/fromSpc.js +40 -0
- package/lib/ir/core/fromSpc.js.map +1 -0
- package/lib/ir/core/index.d.ts +51 -0
- package/lib/ir/core/index.d.ts.map +1 -0
- package/lib/ir/core/index.js +35 -0
- package/lib/ir/core/index.js.map +1 -0
- package/lib/ir/core/irBand.d.ts +45 -0
- package/lib/ir/core/irBand.d.ts.map +1 -0
- package/lib/ir/core/irBand.js +30 -0
- package/lib/ir/core/irBand.js.map +1 -0
- package/lib/ir/core/irCommands.d.ts +168 -0
- package/lib/ir/core/irCommands.d.ts.map +1 -0
- package/lib/ir/core/irCommands.js +94 -0
- package/lib/ir/core/irCommands.js.map +1 -0
- package/lib/ir/core/irDomain.d.ts +63 -0
- package/lib/ir/core/irDomain.d.ts.map +1 -0
- package/lib/ir/core/irDomain.js +136 -0
- package/lib/ir/core/irDomain.js.map +1 -0
- package/lib/ir/core/irEditorApi.d.ts +42 -0
- package/lib/ir/core/irEditorApi.d.ts.map +1 -0
- package/lib/ir/core/irEditorApi.js +10 -0
- package/lib/ir/core/irEditorApi.js.map +1 -0
- package/lib/ir/core/irFormat.d.ts +42 -0
- package/lib/ir/core/irFormat.d.ts.map +1 -0
- package/lib/ir/core/irFormat.js +51 -0
- package/lib/ir/core/irFormat.js.map +1 -0
- package/lib/ir/core/irMode.d.ts +160 -0
- package/lib/ir/core/irMode.d.ts.map +1 -0
- package/lib/ir/core/irMode.js +175 -0
- package/lib/ir/core/irMode.js.map +1 -0
- package/lib/ir/core/irReducer.d.ts +101 -0
- package/lib/ir/core/irReducer.d.ts.map +1 -0
- package/lib/ir/core/irReducer.js +207 -0
- package/lib/ir/core/irReducer.js.map +1 -0
- package/lib/ir/core/irSidePanels.d.ts +22 -0
- package/lib/ir/core/irSidePanels.d.ts.map +1 -0
- package/lib/ir/core/irSidePanels.js +12 -0
- package/lib/ir/core/irSidePanels.js.map +1 -0
- package/lib/ir/core/irSpectrum.d.ts +140 -0
- package/lib/ir/core/irSpectrum.d.ts.map +1 -0
- package/lib/ir/core/irSpectrum.js +34 -0
- package/lib/ir/core/irSpectrum.js.map +1 -0
- package/lib/ir/core/irState.d.ts +119 -0
- package/lib/ir/core/irState.d.ts.map +1 -0
- package/lib/ir/core/irState.js +92 -0
- package/lib/ir/core/irState.js.map +1 -0
- package/lib/ir/core/loadIrSpectra.d.ts +36 -0
- package/lib/ir/core/loadIrSpectra.d.ts.map +1 -0
- package/lib/ir/core/loadIrSpectra.js +44 -0
- package/lib/ir/core/loadIrSpectra.js.map +1 -0
- package/lib/ir/core/nearestBand.d.ts +35 -0
- package/lib/ir/core/nearestBand.d.ts.map +1 -0
- package/lib/ir/core/nearestBand.js +47 -0
- package/lib/ir/core/nearestBand.js.map +1 -0
- package/lib/ir/core/pickBands.d.ts +70 -0
- package/lib/ir/core/pickBands.d.ts.map +1 -0
- package/lib/ir/core/pickBands.js +125 -0
- package/lib/ir/core/pickBands.js.map +1 -0
- package/lib/ir/core/spectrumJcamp.d.ts +58 -0
- package/lib/ir/core/spectrumJcamp.d.ts.map +1 -0
- package/lib/ir/core/spectrumJcamp.js +156 -0
- package/lib/ir/core/spectrumJcamp.js.map +1 -0
- package/lib/ir/core/toIrSpectrum.d.ts +59 -0
- package/lib/ir/core/toIrSpectrum.d.ts.map +1 -0
- package/lib/ir/core/toIrSpectrum.js +56 -0
- package/lib/ir/core/toIrSpectrum.js.map +1 -0
- package/lib/ir/ui/BandMarks.d.ts +52 -0
- package/lib/ir/ui/BandMarks.d.ts.map +1 -0
- package/lib/ir/ui/BandMarks.js +71 -0
- package/lib/ir/ui/BandMarks.js.map +1 -0
- package/lib/ir/ui/BandsPanel.d.ts +31 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -0
- package/lib/ir/ui/BandsPanel.js +94 -0
- package/lib/ir/ui/BandsPanel.js.map +1 -0
- package/lib/ir/ui/IrAboutDialog.d.ts +18 -0
- package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -0
- package/lib/ir/ui/IrAboutDialog.js +32 -0
- package/lib/ir/ui/IrAboutDialog.js.map +1 -0
- package/lib/ir/ui/IrCanvas.d.ts +38 -0
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -0
- package/lib/ir/ui/IrCanvas.js +41 -0
- package/lib/ir/ui/IrCanvas.js.map +1 -0
- package/lib/ir/ui/IrChart.d.ts +28 -0
- package/lib/ir/ui/IrChart.d.ts.map +1 -0
- package/lib/ir/ui/IrChart.js +114 -0
- package/lib/ir/ui/IrChart.js.map +1 -0
- package/lib/ir/ui/IrCommandProvider.d.ts +15 -0
- package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -0
- package/lib/ir/ui/IrCommandProvider.js +14 -0
- package/lib/ir/ui/IrCommandProvider.js.map +1 -0
- package/lib/ir/ui/IrCommandTooltip.d.ts +16 -0
- package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -0
- package/lib/ir/ui/IrCommandTooltip.js +22 -0
- package/lib/ir/ui/IrCommandTooltip.js.map +1 -0
- package/lib/ir/ui/IrDocumentationDialog.d.ts +18 -0
- package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -0
- package/lib/ir/ui/IrDocumentationDialog.js +68 -0
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -0
- package/lib/ir/ui/IrEditor.d.ts +60 -0
- package/lib/ir/ui/IrEditor.d.ts.map +1 -0
- package/lib/ir/ui/IrEditor.js +42 -0
- package/lib/ir/ui/IrEditor.js.map +1 -0
- package/lib/ir/ui/IrHeader.d.ts +13 -0
- package/lib/ir/ui/IrHeader.d.ts.map +1 -0
- package/lib/ir/ui/IrHeader.js +21 -0
- package/lib/ir/ui/IrHeader.js.map +1 -0
- package/lib/ir/ui/IrLogo.d.ts +20 -0
- package/lib/ir/ui/IrLogo.d.ts.map +1 -0
- package/lib/ir/ui/IrLogo.js +17 -0
- package/lib/ir/ui/IrLogo.js.map +1 -0
- package/lib/ir/ui/IrPointerTracker.d.ts +29 -0
- package/lib/ir/ui/IrPointerTracker.d.ts.map +1 -0
- package/lib/ir/ui/IrPointerTracker.js +47 -0
- package/lib/ir/ui/IrPointerTracker.js.map +1 -0
- package/lib/ir/ui/IrShell.d.ts +25 -0
- package/lib/ir/ui/IrShell.d.ts.map +1 -0
- package/lib/ir/ui/IrShell.js +178 -0
- package/lib/ir/ui/IrShell.js.map +1 -0
- package/lib/ir/ui/IrSidePanel.d.ts +26 -0
- package/lib/ir/ui/IrSidePanel.d.ts.map +1 -0
- package/lib/ir/ui/IrSidePanel.js +39 -0
- package/lib/ir/ui/IrSidePanel.js.map +1 -0
- package/lib/ir/ui/IrStateProvider.d.ts +19 -0
- package/lib/ir/ui/IrStateProvider.d.ts.map +1 -0
- package/lib/ir/ui/IrStateProvider.js +16 -0
- package/lib/ir/ui/IrStateProvider.js.map +1 -0
- package/lib/ir/ui/IrStatusBar.d.ts +14 -0
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -0
- package/lib/ir/ui/IrStatusBar.js +48 -0
- package/lib/ir/ui/IrStatusBar.js.map +1 -0
- package/lib/ir/ui/IrToolbar.d.ts +18 -0
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -0
- package/lib/ir/ui/IrToolbar.js +32 -0
- package/lib/ir/ui/IrToolbar.js.map +1 -0
- package/lib/ir/ui/IrTraces.d.ts +63 -0
- package/lib/ir/ui/IrTraces.d.ts.map +1 -0
- package/lib/ir/ui/IrTraces.js +72 -0
- package/lib/ir/ui/IrTraces.js.map +1 -0
- package/lib/ir/ui/MetadataPanel.d.ts +15 -0
- package/lib/ir/ui/MetadataPanel.d.ts.map +1 -0
- package/lib/ir/ui/MetadataPanel.js +49 -0
- package/lib/ir/ui/MetadataPanel.js.map +1 -0
- package/lib/ir/ui/SpectraPanel.d.ts +20 -0
- package/lib/ir/ui/SpectraPanel.d.ts.map +1 -0
- package/lib/ir/ui/SpectraPanel.js +42 -0
- package/lib/ir/ui/SpectraPanel.js.map +1 -0
- package/lib/ir/ui/SpectrumRow.d.ts +26 -0
- package/lib/ir/ui/SpectrumRow.d.ts.map +1 -0
- package/lib/ir/ui/SpectrumRow.js +41 -0
- package/lib/ir/ui/SpectrumRow.js.map +1 -0
- package/lib/ir/ui/index.d.ts +56 -0
- package/lib/ir/ui/index.d.ts.map +1 -0
- package/lib/ir/ui/index.js +36 -0
- package/lib/ir/ui/index.js.map +1 -0
- package/lib/ir/ui/irActions.d.ts +52 -0
- package/lib/ir/ui/irActions.d.ts.map +1 -0
- package/lib/ir/ui/irActions.js +62 -0
- package/lib/ir/ui/irActions.js.map +1 -0
- package/lib/ir/ui/irChartProps.d.ts +116 -0
- package/lib/ir/ui/irChartProps.d.ts.map +1 -0
- package/lib/ir/ui/irChartProps.js +14 -0
- package/lib/ir/ui/irChartProps.js.map +1 -0
- package/lib/ir/ui/irCommandContext.d.ts +35 -0
- package/lib/ir/ui/irCommandContext.d.ts.map +1 -0
- package/lib/ir/ui/irCommandContext.js +44 -0
- package/lib/ir/ui/irCommandContext.js.map +1 -0
- package/lib/ir/ui/irStateContext.d.ts +26 -0
- package/lib/ir/ui/irStateContext.d.ts.map +1 -0
- package/lib/ir/ui/irStateContext.js +37 -0
- package/lib/ir/ui/irStateContext.js.map +1 -0
- package/lib/ir/ui/useIrEditor.d.ts +51 -0
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -0
- package/lib/ir/ui/useIrEditor.js +88 -0
- package/lib/ir/ui/useIrEditor.js.map +1 -0
- package/lib/ir/ui/useIrPointer.d.ts +66 -0
- package/lib/ir/ui/useIrPointer.d.ts.map +1 -0
- package/lib/ir/ui/useIrPointer.js +53 -0
- package/lib/ir/ui/useIrPointer.js.map +1 -0
- package/lib/ir/ui/useIrShortcuts.d.ts +24 -0
- package/lib/ir/ui/useIrShortcuts.d.ts.map +1 -0
- package/lib/ir/ui/useIrShortcuts.js +73 -0
- package/lib/ir/ui/useIrShortcuts.js.map +1 -0
- package/lib/ir/ui/useIrZoom.d.ts +51 -0
- package/lib/ir/ui/useIrZoom.d.ts.map +1 -0
- package/lib/ir/ui/useIrZoom.js +46 -0
- package/lib/ir/ui/useIrZoom.js.map +1 -0
- package/lib/ir.d.ts +13 -0
- package/lib/ir.d.ts.map +1 -0
- package/lib/ir.js +13 -0
- package/lib/ir.js.map +1 -0
- package/lib/locales/de.json +3 -0
- package/lib/locales/en.json +3 -0
- package/lib/locales/es.json +3 -0
- package/lib/locales/fr.json +3 -0
- package/lib/panel/core/dialogStyles.d.ts +13 -0
- package/lib/panel/core/dialogStyles.d.ts.map +1 -0
- package/lib/panel/core/dialogStyles.js +11 -0
- package/lib/panel/core/dialogStyles.js.map +1 -0
- package/lib/panel/core/index.d.ts +19 -0
- package/lib/panel/core/index.d.ts.map +1 -0
- package/lib/panel/core/index.js +18 -0
- package/lib/panel/core/index.js.map +1 -0
- package/lib/panel/core/isEditingField.d.ts +17 -0
- package/lib/panel/core/isEditingField.d.ts.map +1 -0
- package/lib/panel/core/isEditingField.js +25 -0
- package/lib/panel/core/isEditingField.js.map +1 -0
- package/lib/panel/core/panelStyles.d.ts +242 -0
- package/lib/panel/core/panelStyles.d.ts.map +1 -0
- package/lib/panel/core/panelStyles.js +228 -0
- package/lib/panel/core/panelStyles.js.map +1 -0
- package/lib/panel/core/rowSpacers.d.ts +38 -0
- package/lib/panel/core/rowSpacers.d.ts.map +1 -0
- package/lib/panel/core/rowSpacers.js +31 -0
- package/lib/panel/core/rowSpacers.js.map +1 -0
- package/lib/panel/core/statusBar.d.ts +44 -0
- package/lib/panel/core/statusBar.d.ts.map +1 -0
- package/lib/panel/core/statusBar.js +40 -0
- package/lib/panel/core/statusBar.js.map +1 -0
- package/lib/panel/core/textFilter.d.ts +22 -0
- package/lib/panel/core/textFilter.d.ts.map +1 -0
- package/lib/panel/core/textFilter.js +32 -0
- package/lib/panel/core/textFilter.js.map +1 -0
- package/lib/panel/core/yieldToPainting.d.ts +17 -0
- package/lib/panel/core/yieldToPainting.d.ts.map +1 -0
- package/lib/panel/core/yieldToPainting.js +21 -0
- package/lib/panel/core/yieldToPainting.js.map +1 -0
- package/lib/panel/ui/AboutDialogFrame.d.ts +36 -0
- package/lib/panel/ui/AboutDialogFrame.d.ts.map +1 -0
- package/lib/panel/ui/AboutDialogFrame.js +43 -0
- package/lib/panel/ui/AboutDialogFrame.js.map +1 -0
- package/lib/panel/ui/ClearButton.d.ts +28 -0
- package/lib/panel/ui/ClearButton.d.ts.map +1 -0
- package/lib/panel/ui/ClearButton.js +23 -0
- package/lib/panel/ui/ClearButton.js.map +1 -0
- package/lib/panel/ui/DocumentationDialogFrame.d.ts +39 -0
- package/lib/panel/ui/DocumentationDialogFrame.d.ts.map +1 -0
- package/lib/panel/ui/DocumentationDialogFrame.js +29 -0
- package/lib/panel/ui/DocumentationDialogFrame.js.map +1 -0
- package/lib/panel/ui/FilterInput.d.ts +31 -0
- package/lib/panel/ui/FilterInput.d.ts.map +1 -0
- package/lib/panel/ui/FilterInput.js +23 -0
- package/lib/panel/ui/FilterInput.js.map +1 -0
- package/lib/panel/ui/HelpLabel.d.ts +24 -0
- package/lib/panel/ui/HelpLabel.d.ts.map +1 -0
- package/lib/panel/ui/HelpLabel.js +23 -0
- package/lib/panel/ui/HelpLabel.js.map +1 -0
- package/lib/panel/ui/PanelMessage.d.ts +41 -0
- package/lib/panel/ui/PanelMessage.d.ts.map +1 -0
- package/lib/panel/ui/PanelMessage.js +30 -0
- package/lib/panel/ui/PanelMessage.js.map +1 -0
- package/lib/panel/ui/PanelRail.d.ts +41 -0
- package/lib/panel/ui/PanelRail.d.ts.map +1 -0
- package/lib/panel/ui/PanelRail.js +12 -0
- package/lib/panel/ui/PanelRail.js.map +1 -0
- package/lib/panel/ui/Section.d.ts +25 -0
- package/lib/panel/ui/Section.d.ts.map +1 -0
- package/lib/panel/ui/Section.js +41 -0
- package/lib/panel/ui/Section.js.map +1 -0
- package/lib/panel/ui/SidePanelStack.d.ts +62 -0
- package/lib/panel/ui/SidePanelStack.d.ts.map +1 -0
- package/lib/panel/ui/SidePanelStack.js +40 -0
- package/lib/panel/ui/SidePanelStack.js.map +1 -0
- package/lib/panel/ui/SpectrumColorSwatch.d.ts +33 -0
- package/lib/panel/ui/SpectrumColorSwatch.d.ts.map +1 -0
- package/lib/panel/ui/SpectrumColorSwatch.js +76 -0
- package/lib/panel/ui/SpectrumColorSwatch.js.map +1 -0
- package/lib/panel/ui/index.d.ts +37 -0
- package/lib/panel/ui/index.d.ts.map +1 -0
- package/lib/panel/ui/index.js +24 -0
- package/lib/panel/ui/index.js.map +1 -0
- package/lib/panel/ui/useConfirmOnEnter.d.ts +19 -0
- package/lib/panel/ui/useConfirmOnEnter.d.ts.map +1 -0
- package/lib/panel/ui/useConfirmOnEnter.js +64 -0
- package/lib/panel/ui/useConfirmOnEnter.js.map +1 -0
- package/lib/panel/ui/useFilterBox.d.ts +23 -0
- package/lib/panel/ui/useFilterBox.d.ts.map +1 -0
- package/lib/panel/ui/useFilterBox.js +22 -0
- package/lib/panel/ui/useFilterBox.js.map +1 -0
- package/lib/panel/ui/useVirtualRows.d.ts +46 -0
- package/lib/panel/ui/useVirtualRows.d.ts.map +1 -0
- package/lib/panel/ui/useVirtualRows.js +56 -0
- package/lib/panel/ui/useVirtualRows.js.map +1 -0
- package/lib/panel/ui/useVirtualWindowRows.d.ts +40 -0
- package/lib/panel/ui/useVirtualWindowRows.d.ts.map +1 -0
- package/lib/panel/ui/useVirtualWindowRows.js +65 -0
- package/lib/panel/ui/useVirtualWindowRows.js.map +1 -0
- package/lib/structure/core/conformerBoltzmann.d.ts +56 -0
- package/lib/structure/core/conformerBoltzmann.d.ts.map +1 -0
- package/lib/structure/core/conformerBoltzmann.js +96 -0
- package/lib/structure/core/conformerBoltzmann.js.map +1 -0
- package/lib/structure/core/conformerEnergy.d.ts +69 -0
- package/lib/structure/core/conformerEnergy.d.ts.map +1 -0
- package/lib/structure/core/conformerEnergy.js +47 -0
- package/lib/structure/core/conformerEnergy.js.map +1 -0
- package/lib/structure/core/index.d.ts +3 -0
- package/lib/structure/core/index.d.ts.map +1 -1
- package/lib/structure/core/index.js +2 -0
- package/lib/structure/core/index.js.map +1 -1
- package/lib/structure/ui/ConformerTable.d.ts +73 -0
- package/lib/structure/ui/ConformerTable.d.ts.map +1 -0
- package/lib/structure/ui/ConformerTable.js +259 -0
- package/lib/structure/ui/ConformerTable.js.map +1 -0
- package/lib/structure/ui/conformerColumns.d.ts +30 -0
- package/lib/structure/ui/conformerColumns.d.ts.map +1 -0
- package/lib/structure/ui/conformerColumns.js +37 -0
- package/lib/structure/ui/conformerColumns.js.map +1 -0
- package/lib/ui.d.ts +5 -0
- package/lib/ui.d.ts.map +1 -1
- package/lib/ui.js +3 -0
- package/lib/ui.js.map +1 -1
- package/package.json +8 -1
- package/src/chart/core/axisLabels.ts +117 -0
- package/src/chart/core/boxLayout.ts +126 -0
- package/src/chart/core/chartAxisScale.ts +92 -10
- package/src/chart/core/chartDomain.ts +185 -0
- package/src/chart/core/chartGeometry.ts +159 -0
- package/src/chart/core/chartPane.ts +10 -0
- package/src/chart/core/chartScale.ts +7 -4
- package/src/chart/core/chartTheme.ts +161 -0
- package/src/chart/core/chartViewport.ts +40 -13
- package/src/chart/core/guidePlacement.ts +66 -0
- package/src/chart/core/index.ts +121 -2
- package/src/chart/core/labelStack.ts +72 -0
- package/src/chart/core/legendBox.ts +263 -0
- package/src/chart/core/selectionGeometry.ts +68 -0
- package/src/chart/core/spectrumColor.ts +129 -0
- package/src/chart/core/stackCapacity.ts +162 -0
- package/src/chart/core/svgPoint.ts +77 -0
- package/src/chart/core/tracePath.ts +228 -0
- package/src/chart/core/trackerReadout.ts +78 -0
- package/src/chart/core/viewTransform.ts +287 -0
- package/src/chart/core/zoomDomain.ts +235 -0
- package/src/chart/ui/Axes.tsx +361 -0
- package/src/chart/ui/AxisGuide.tsx +187 -0
- package/src/chart/ui/ChartStack.tsx +130 -0
- package/src/chart/ui/ChartTracker.tsx +101 -0
- package/src/chart/ui/PlotCaption.tsx +108 -0
- package/src/chart/ui/SelectionRect.tsx +52 -0
- package/src/chart/ui/TraceLegend.tsx +193 -0
- package/src/chart/ui/chartGestures.ts +270 -0
- package/src/chart/ui/chartStackLevel.tsx +210 -0
- package/src/chart/ui/chartSurface.ts +66 -0
- package/src/chart/ui/index.ts +35 -0
- package/src/chart/ui/useChartPointer.ts +223 -0
- package/src/chart/ui/useChartSize.ts +115 -0
- package/src/chart/ui/useChartWindow.ts +240 -0
- package/src/chart/ui/useChartZoom.ts +255 -0
- package/src/chart/ui/useWheelListener.ts +62 -0
- package/src/chrome/ui/AccountButton.tsx +185 -0
- package/src/chrome/ui/index.ts +2 -0
- package/src/clipboard/core/copyPng.ts +20 -0
- package/src/clipboard/core/index.ts +1 -0
- package/src/clipboard/ui/ClickToCopy.tsx +9 -1
- package/src/core.ts +1 -0
- package/src/download/core/exportStyles.ts +20 -0
- package/src/download/core/imageResolution.ts +118 -0
- package/src/download/core/index.ts +34 -0
- package/src/download/core/pictureExport.ts +207 -0
- package/src/download/core/stackedDrawing.ts +108 -0
- package/src/download/core/svgBounds.ts +80 -0
- package/src/download/core/svgNamespace.ts +9 -0
- package/src/download/core/svgToPng.ts +121 -0
- package/src/download/core/svgToString.ts +95 -0
- package/src/download/ui/ExportDialogFrame.tsx +86 -0
- package/src/download/ui/ExportImageDialog.tsx +91 -0
- package/src/download/ui/ExportNameField.tsx +148 -0
- package/src/download/ui/ExportPictureSection.tsx +142 -0
- package/src/download/ui/index.ts +11 -0
- package/src/download/ui/useDrawingBox.ts +37 -0
- package/src/error/core/describeSource.ts +18 -0
- package/src/error/core/index.ts +1 -0
- package/src/help/ui/HelpBody.tsx +41 -2
- package/src/help/ui/index.ts +6 -1
- package/src/ir/core/analysisSpectra.ts +231 -0
- package/src/ir/core/assignBands.ts +144 -0
- package/src/ir/core/bandAssignments.ts +329 -0
- package/src/ir/core/bandLabelPlan.ts +194 -0
- package/src/ir/core/detectIrFormat.ts +139 -0
- package/src/ir/core/downloadSpectra.ts +57 -0
- package/src/ir/core/fromJcamp.ts +70 -0
- package/src/ir/core/fromSpc.ts +61 -0
- package/src/ir/core/index.ts +113 -0
- package/src/ir/core/irBand.ts +57 -0
- package/src/ir/core/irCommands.ts +154 -0
- package/src/ir/core/irDomain.ts +163 -0
- package/src/ir/core/irEditorApi.ts +44 -0
- package/src/ir/core/irFormat.ts +57 -0
- package/src/ir/core/irMode.ts +203 -0
- package/src/ir/core/irReducer.ts +273 -0
- package/src/ir/core/irSidePanels.ts +20 -0
- package/src/ir/core/irSpectrum.ts +155 -0
- package/src/ir/core/irState.ts +173 -0
- package/src/ir/core/loadIrSpectra.ts +79 -0
- package/src/ir/core/nearestBand.ts +57 -0
- package/src/ir/core/pickBands.ts +181 -0
- package/src/ir/core/spectrumJcamp.ts +178 -0
- package/src/ir/core/toIrSpectrum.ts +102 -0
- package/src/ir/ui/BandMarks.tsx +166 -0
- package/src/ir/ui/BandsPanel.tsx +271 -0
- package/src/ir/ui/IrAboutDialog.tsx +121 -0
- package/src/ir/ui/IrCanvas.tsx +91 -0
- package/src/ir/ui/IrChart.tsx +215 -0
- package/src/ir/ui/IrCommandProvider.tsx +32 -0
- package/src/ir/ui/IrCommandTooltip.tsx +36 -0
- package/src/ir/ui/IrDocumentationDialog.tsx +174 -0
- package/src/ir/ui/IrEditor.tsx +99 -0
- package/src/ir/ui/IrHeader.tsx +39 -0
- package/src/ir/ui/IrLogo.tsx +49 -0
- package/src/ir/ui/IrPointerTracker.tsx +102 -0
- package/src/ir/ui/IrShell.tsx +285 -0
- package/src/ir/ui/IrSidePanel.tsx +78 -0
- package/src/ir/ui/IrStateProvider.tsx +32 -0
- package/src/ir/ui/IrStatusBar.tsx +97 -0
- package/src/ir/ui/IrToolbar.tsx +102 -0
- package/src/ir/ui/IrTraces.tsx +134 -0
- package/src/ir/ui/MetadataPanel.tsx +88 -0
- package/src/ir/ui/SpectraPanel.tsx +114 -0
- package/src/ir/ui/SpectrumRow.tsx +127 -0
- package/src/ir/ui/index.ts +56 -0
- package/src/ir/ui/irActions.ts +103 -0
- package/src/ir/ui/irChartProps.ts +118 -0
- package/src/ir/ui/irCommandContext.tsx +62 -0
- package/src/ir/ui/irStateContext.ts +48 -0
- package/src/ir/ui/useIrEditor.ts +139 -0
- package/src/ir/ui/useIrPointer.ts +109 -0
- package/src/ir/ui/useIrShortcuts.ts +95 -0
- package/src/ir/ui/useIrZoom.ts +86 -0
- package/src/ir.ts +13 -0
- package/src/locales/de.json +3 -0
- package/src/locales/en.json +3 -0
- package/src/locales/es.json +3 -0
- package/src/locales/fr.json +3 -0
- package/src/panel/core/dialogStyles.ts +11 -0
- package/src/panel/core/index.ts +47 -0
- package/src/panel/core/isEditingField.ts +23 -0
- package/src/panel/core/panelStyles.ts +248 -0
- package/src/panel/core/rowSpacers.ts +50 -0
- package/src/panel/core/statusBar.ts +48 -0
- package/src/panel/core/textFilter.ts +33 -0
- package/src/panel/core/yieldToPainting.ts +20 -0
- package/src/panel/ui/AboutDialogFrame.tsx +100 -0
- package/src/panel/ui/ClearButton.tsx +42 -0
- package/src/panel/ui/DocumentationDialogFrame.tsx +86 -0
- package/src/panel/ui/FilterInput.tsx +60 -0
- package/src/panel/ui/HelpLabel.tsx +43 -0
- package/src/panel/ui/PanelMessage.tsx +64 -0
- package/src/panel/ui/PanelRail.tsx +64 -0
- package/src/panel/ui/Section.tsx +66 -0
- package/src/panel/ui/SidePanelStack.tsx +109 -0
- package/src/panel/ui/SpectrumColorSwatch.tsx +119 -0
- package/src/panel/ui/index.ts +47 -0
- package/src/panel/ui/useConfirmOnEnter.ts +68 -0
- package/src/panel/ui/useFilterBox.ts +35 -0
- package/src/panel/ui/useVirtualRows.ts +82 -0
- package/src/panel/ui/useVirtualWindowRows.ts +86 -0
- package/src/structure/core/conformerBoltzmann.ts +102 -0
- package/src/structure/core/conformerEnergy.ts +97 -0
- package/src/structure/core/index.ts +15 -0
- package/src/structure/ui/ConformerTable.tsx +429 -0
- package/src/structure/ui/conformerColumns.ts +55 -0
- package/src/ui.ts +13 -0
- package/styles/chrome.css +55 -0
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Keeping the labels above the peaks apart from one another.
|
|
3
|
+
*
|
|
4
|
+
* An annotated spectrum wants a box over every peak it explains, and an
|
|
5
|
+
* isotopologue cluster puts four of them within a few pixels. Sliding them
|
|
6
|
+
* apart is most of the job, and the leader line back to the stick is what says
|
|
7
|
+
* which peak a box belongs to — so a box a little out of place is still
|
|
8
|
+
* readable.
|
|
9
|
+
*
|
|
10
|
+
* A box slid *far* out of place is not. Spacing a crowd out marches the last of
|
|
11
|
+
* them across the whole plot, where it comes to rest over peaks it says nothing
|
|
12
|
+
* about, with a leader long enough to be read as pointing at one of them. Those
|
|
13
|
+
* are dropped, and only those: a mark still sits on every annotated peak, so
|
|
14
|
+
* the fragment is not one the chemist concludes the spectrum lacks — it is one
|
|
15
|
+
* whose picture is a zoom away.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
import type { NumberArray } from 'cheminfo-types';
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Slide overlapping boxes apart, keeping every one of them inside the plot.
|
|
22
|
+
*
|
|
23
|
+
* Two sweeps, and the order of the clamps is the whole behaviour. The first
|
|
24
|
+
* sweep runs left to right and pushes each box far enough past its neighbour to
|
|
25
|
+
* clear it, which piles the crowding up against the right edge; the second runs
|
|
26
|
+
* back the other way, pulling that pile inside the right bound and spacing it
|
|
27
|
+
* out leftwards again.
|
|
28
|
+
*
|
|
29
|
+
* The left bound is then applied last, after the spacing, and so beats it. A
|
|
30
|
+
* cluster too wide for the room it is in therefore ends with its leftmost boxes
|
|
31
|
+
* overlapping rather than with one of them hanging off the plot — an overlap is
|
|
32
|
+
* two labels a reader can still pick apart with the leader lines, while a box
|
|
33
|
+
* outside the plot is clipped away and reads as an annotation that was never
|
|
34
|
+
* made.
|
|
35
|
+
* @param centres - Where each box would like to be centred, in pixels; any
|
|
36
|
+
* order, and the result comes back in that same order.
|
|
37
|
+
* @param bounds - `[from, to]` in pixels that no box may extend beyond.
|
|
38
|
+
* @param width - How wide every box is.
|
|
39
|
+
* @param gap - The clear space wanted between two neighbouring boxes.
|
|
40
|
+
* @param maximumDrift - How far a box may be slid from where it wanted to be
|
|
41
|
+
* before it is dropped instead, in pixels. Defaults to two whole box steps.
|
|
42
|
+
* @returns The centre each box was actually given, `NaN` for one that was slid
|
|
43
|
+
* too far and dropped.
|
|
44
|
+
*/
|
|
45
|
+
export function layoutAnnotationBoxes(
|
|
46
|
+
centres: NumberArray,
|
|
47
|
+
bounds: readonly [number, number],
|
|
48
|
+
width: number,
|
|
49
|
+
gap: number,
|
|
50
|
+
maximumDrift = (width + gap) * MAXIMUM_DRIFT_STEPS,
|
|
51
|
+
): Float64Array {
|
|
52
|
+
const count = centres.length;
|
|
53
|
+
const placed = new Float64Array(count);
|
|
54
|
+
if (count === 0) return placed;
|
|
55
|
+
|
|
56
|
+
const half = width / 2;
|
|
57
|
+
const minimumCentre = bounds[0] + half;
|
|
58
|
+
const maximumCentre = bounds[1] - half;
|
|
59
|
+
const step = width + gap;
|
|
60
|
+
const order = ascendingOrder(centres);
|
|
61
|
+
|
|
62
|
+
let previous = Number.NEGATIVE_INFINITY;
|
|
63
|
+
for (let position = 0; position < count; position++) {
|
|
64
|
+
const index = order[position] as number;
|
|
65
|
+
let centre = Math.min(
|
|
66
|
+
Math.max(centres[index] as number, minimumCentre),
|
|
67
|
+
maximumCentre,
|
|
68
|
+
);
|
|
69
|
+
if (centre < previous + step) centre = previous + step;
|
|
70
|
+
placed[index] = centre;
|
|
71
|
+
previous = centre;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let next = Number.POSITIVE_INFINITY;
|
|
75
|
+
for (let position = count - 1; position >= 0; position--) {
|
|
76
|
+
const index = order[position] as number;
|
|
77
|
+
let centre = placed[index] as number;
|
|
78
|
+
if (centre > maximumCentre) centre = maximumCentre;
|
|
79
|
+
if (centre > next - step) centre = next - step;
|
|
80
|
+
if (centre < minimumCentre) centre = minimumCentre;
|
|
81
|
+
placed[index] = centre;
|
|
82
|
+
next = centre;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// A picture that has been slid too far from the peak it explains is worse
|
|
86
|
+
// than no picture: it hangs over a peak it says nothing about, and the leader
|
|
87
|
+
// back to its own is long enough to be read as pointing at something else.
|
|
88
|
+
// Those are dropped rather than drawn, and the mark on the peak still says
|
|
89
|
+
// the annotation is there.
|
|
90
|
+
for (let index = 0; index < count; index++) {
|
|
91
|
+
const wanted = centres[index] as number;
|
|
92
|
+
if (Math.abs((placed[index] as number) - wanted) > maximumDrift) {
|
|
93
|
+
placed[index] = Number.NaN;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
return placed;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* How far a picture may be slid from its peak, counted in whole box steps.
|
|
101
|
+
*
|
|
102
|
+
* Two: a box may be pushed past two neighbours and still be read as belonging
|
|
103
|
+
* to the peak under it, which is what a cluster of three peaks needs. Past that
|
|
104
|
+
* the leader is longer than the box is wide and reaches across other peaks, so
|
|
105
|
+
* the picture reads as answering for one of them instead.
|
|
106
|
+
*/
|
|
107
|
+
export const MAXIMUM_DRIFT_STEPS = 2;
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The indices of the boxes, ordered by where they want to be.
|
|
111
|
+
*
|
|
112
|
+
* The sweeps only make sense left to right, and the caller's order is whatever
|
|
113
|
+
* the annotations came in — usually by mass, but a second producer's marks are
|
|
114
|
+
* appended rather than merged.
|
|
115
|
+
* @param centres - Where each box would like to be centred.
|
|
116
|
+
* @returns The indices, ascending by centre.
|
|
117
|
+
*/
|
|
118
|
+
function ascendingOrder(centres: NumberArray): Uint32Array {
|
|
119
|
+
const order = new Uint32Array(centres.length);
|
|
120
|
+
for (let index = 0; index < centres.length; index++) {
|
|
121
|
+
order[index] = index;
|
|
122
|
+
}
|
|
123
|
+
return order.toSorted(
|
|
124
|
+
(first, second) => (centres[first] as number) - (centres[second] as number),
|
|
125
|
+
);
|
|
126
|
+
}
|
|
@@ -12,6 +12,15 @@ const COMFORTABLE_LABEL = 6;
|
|
|
12
12
|
const STEP_10 = Math.sqrt(50);
|
|
13
13
|
const STEP_5 = Math.sqrt(10);
|
|
14
14
|
const STEP_2 = Math.SQRT2;
|
|
15
|
+
/**
|
|
16
|
+
* How far a fraction may sit above 1, 2 or 5 and still count as being on it.
|
|
17
|
+
*
|
|
18
|
+
* `span / count` is computed in floating point, so a window that ought to give
|
|
19
|
+
* a step of exactly one lands a hair above it — `1.0000000000000002` — and an
|
|
20
|
+
* exact comparison would take the next step up and halve the number of ticks
|
|
21
|
+
* for no visible reason.
|
|
22
|
+
*/
|
|
23
|
+
const STEP_EPSILON = 1e-9;
|
|
15
24
|
|
|
16
25
|
/** A niced axis: its domain, its ticks, and the labels they are written with. */
|
|
17
26
|
export interface ChartAxisScale {
|
|
@@ -29,6 +38,22 @@ export interface ChartAxisScale {
|
|
|
29
38
|
readonly labels: readonly string[];
|
|
30
39
|
}
|
|
31
40
|
|
|
41
|
+
/**
|
|
42
|
+
* How the step is chosen when an even division lands between two nice ones.
|
|
43
|
+
*
|
|
44
|
+
* - `nearest` — take whichever of 1, 2 or 5 the division is closest to, which
|
|
45
|
+
* puts the tick count near what was asked for from either side.
|
|
46
|
+
* - `atMost` — always take the larger, so the count asked for is a budget the
|
|
47
|
+
* axis never exceeds.
|
|
48
|
+
*
|
|
49
|
+
* The difference is not cosmetic. A figure asking for about five ticks wants
|
|
50
|
+
* them spaced as evenly as the numbers allow, and one either way costs it
|
|
51
|
+
* nothing. An axis in a two-hundred-pixel panel has worked its count out from
|
|
52
|
+
* the room it has and the width of a label, so one tick more than it asked for
|
|
53
|
+
* is two labels touching.
|
|
54
|
+
*/
|
|
55
|
+
export type ChartAxisStep = 'nearest' | 'atMost';
|
|
56
|
+
|
|
32
57
|
/** How an axis is divided. */
|
|
33
58
|
export interface ChartAxisScaleOptions {
|
|
34
59
|
/**
|
|
@@ -39,10 +64,15 @@ export interface ChartAxisScaleOptions {
|
|
|
39
64
|
/**
|
|
40
65
|
* Whether to widen the domain outward to whole steps, so the axis ends on a
|
|
41
66
|
* labelled tick. Turn it off when the domain is already exact — a share that
|
|
42
|
-
* must end at 100
|
|
67
|
+
* must end at 100%, or a window a reader dragged out for themselves.
|
|
43
68
|
* @default true
|
|
44
69
|
*/
|
|
45
70
|
nice?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* How the step is chosen. See {@link ChartAxisStep}.
|
|
73
|
+
* @default 'nearest'
|
|
74
|
+
*/
|
|
75
|
+
step?: ChartAxisStep;
|
|
46
76
|
}
|
|
47
77
|
|
|
48
78
|
/**
|
|
@@ -68,11 +98,34 @@ export function chartAxisScale(
|
|
|
68
98
|
max: number,
|
|
69
99
|
options: ChartAxisScaleOptions = {},
|
|
70
100
|
): ChartAxisScale {
|
|
71
|
-
const { count = DEFAULT_COUNT, nice = true } = options;
|
|
101
|
+
const { count = DEFAULT_COUNT, nice = true, step: rounding } = options;
|
|
72
102
|
const wanted = tickCount(count);
|
|
103
|
+
// A window of one point is not a window: there is no step to read a
|
|
104
|
+
// precision off, so the single label is written at the precision its own
|
|
105
|
+
// magnitude asks for. Only when the domain is taken as given — a domain that
|
|
106
|
+
// is to be niced is opened instead, so that a constant column still draws an
|
|
107
|
+
// axis to stand on.
|
|
108
|
+
if (!nice && min === max && Number.isFinite(min)) {
|
|
109
|
+
const decimals = chartTickDecimals(Math.abs(min));
|
|
110
|
+
return {
|
|
111
|
+
domain: [min, min],
|
|
112
|
+
values: [min],
|
|
113
|
+
step: 0,
|
|
114
|
+
decimals,
|
|
115
|
+
exponent: 0,
|
|
116
|
+
labels: [chartTickLabel(min, decimals)],
|
|
117
|
+
};
|
|
118
|
+
}
|
|
73
119
|
const opened = openDomain(min, max);
|
|
74
|
-
const domain = nice
|
|
75
|
-
|
|
120
|
+
const domain = nice
|
|
121
|
+
? chartNiceDomain(opened[0], opened[1], wanted, rounding)
|
|
122
|
+
: opened;
|
|
123
|
+
const [first, last, increment] = tickSpec(
|
|
124
|
+
domain[0],
|
|
125
|
+
domain[1],
|
|
126
|
+
wanted,
|
|
127
|
+
rounding,
|
|
128
|
+
);
|
|
76
129
|
const spacing = increment < 0 ? -1 / increment : increment;
|
|
77
130
|
const step = Number.isFinite(spacing) && spacing > 0 ? spacing : 0;
|
|
78
131
|
const values = step === 0 ? [] : tickValues(first, last, increment);
|
|
@@ -93,18 +146,20 @@ export function chartAxisScale(
|
|
|
93
146
|
* @param min - One end, in either order.
|
|
94
147
|
* @param max - The other end.
|
|
95
148
|
* @param count - Roughly how many ticks the domain will carry. Defaults to `5`.
|
|
149
|
+
* @param rounding - How the step is chosen. See {@link ChartAxisStep}.
|
|
96
150
|
* @returns The widened domain, ascending.
|
|
97
151
|
*/
|
|
98
152
|
export function chartNiceDomain(
|
|
99
153
|
min: number,
|
|
100
154
|
max: number,
|
|
101
155
|
count = DEFAULT_COUNT,
|
|
156
|
+
rounding: ChartAxisStep = 'nearest',
|
|
102
157
|
): [number, number] {
|
|
103
158
|
const wanted = tickCount(count);
|
|
104
159
|
let [start, stop] = openDomain(min, max);
|
|
105
160
|
let previous = 0;
|
|
106
161
|
for (let pass = 0; pass < NICE_PASSES; pass++) {
|
|
107
|
-
const [, , increment] = tickSpec(start, stop, wanted);
|
|
162
|
+
const [, , increment] = tickSpec(start, stop, wanted, rounding);
|
|
108
163
|
if (increment === previous || !Number.isFinite(increment)) break;
|
|
109
164
|
const low = wholeStep(start, increment, true);
|
|
110
165
|
const high = wholeStep(stop, increment, false);
|
|
@@ -163,14 +218,41 @@ export function chartExponentSuffix(exponent: number): string {
|
|
|
163
218
|
|
|
164
219
|
type TickSpec = [first: number, last: number, increment: number];
|
|
165
220
|
|
|
166
|
-
|
|
221
|
+
/**
|
|
222
|
+
* The nice factor a division is closest to.
|
|
223
|
+
* @param error - The division's mantissa, between 1 and 10.
|
|
224
|
+
* @returns 1, 2, 5 or 10.
|
|
225
|
+
*/
|
|
226
|
+
function stepNearest(error: number): number {
|
|
227
|
+
if (error >= STEP_10) return 10;
|
|
228
|
+
if (error >= STEP_5) return 5;
|
|
229
|
+
if (error >= STEP_2) return 2;
|
|
230
|
+
return 1;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The smallest nice factor at or above a division, so the ticks are never
|
|
235
|
+
* closer together than asked for.
|
|
236
|
+
* @param error - The division's mantissa, between 1 and 10.
|
|
237
|
+
* @returns 1, 2, 5 or 10.
|
|
238
|
+
*/
|
|
239
|
+
function stepAtMost(error: number): number {
|
|
240
|
+
if (error <= 1 + STEP_EPSILON) return 1;
|
|
241
|
+
if (error <= 2 + STEP_EPSILON) return 2;
|
|
242
|
+
if (error <= 5 + STEP_EPSILON) return 5;
|
|
243
|
+
return 10;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
function tickSpec(
|
|
247
|
+
start: number,
|
|
248
|
+
stop: number,
|
|
249
|
+
count: number,
|
|
250
|
+
rounding: ChartAxisStep = 'nearest',
|
|
251
|
+
): TickSpec {
|
|
167
252
|
const rawStep = (stop - start) / count;
|
|
168
253
|
const power = Math.floor(Math.log10(rawStep));
|
|
169
254
|
const error = rawStep / 10 ** power;
|
|
170
|
-
|
|
171
|
-
if (error >= STEP_2) factor = 2;
|
|
172
|
-
if (error >= STEP_5) factor = 5;
|
|
173
|
-
if (error >= STEP_10) factor = 10;
|
|
255
|
+
const factor = rounding === 'atMost' ? stepAtMost(error) : stepNearest(error);
|
|
174
256
|
if (power < 0) {
|
|
175
257
|
const divisor = 10 ** -power / factor;
|
|
176
258
|
let first = Math.round(start * divisor);
|
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The window a chart is showing, which is the one thing every viewer built on
|
|
3
|
+
* this package holds in common.
|
|
4
|
+
*
|
|
5
|
+
* Two numbers on each axis and nothing else — no units, no labels, no notion of
|
|
6
|
+
* what is being measured. That absence is the point: a mass spectrum reads its
|
|
7
|
+
* x axis as m/z and an infrared spectrum reads the same two numbers as
|
|
8
|
+
* wavenumbers, so a window that named either would need converting at every
|
|
9
|
+
* boundary, and a zoom gesture would have to be written twice to do the same
|
|
10
|
+
* arithmetic.
|
|
11
|
+
*
|
|
12
|
+
* The y axis is called nothing more specific than y for the same reason. It
|
|
13
|
+
* carries intensity in one viewer, absorbance or percent transmittance in
|
|
14
|
+
* another, and the arithmetic that maps it to pixels cares only that it is a
|
|
15
|
+
* range of numbers.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/** The window a chart is showing, in data units. */
|
|
19
|
+
export interface ChartDomain {
|
|
20
|
+
/** `[min, max]` on the horizontal axis. */
|
|
21
|
+
x: [number, number];
|
|
22
|
+
/** `[min, max]` on the vertical axis, the lower bound negative in mirror mode. */
|
|
23
|
+
y: [number, number];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* How the vertical axis behaves under a gesture, where the two viewers differ.
|
|
28
|
+
*
|
|
29
|
+
* A mass spectrum is drawn as sticks standing on zero, so zero has to stay in
|
|
30
|
+
* the window however it is zoomed — a window starting at a tenth of the base
|
|
31
|
+
* peak cuts every stick off at the ankles. A continuous trace has no feet: an
|
|
32
|
+
* infrared band dragged out at 20 to 60 percent transmittance is asked about at
|
|
33
|
+
* 20 to 60 percent, and forcing 100 into the window would undo the zoom that was
|
|
34
|
+
* just asked for.
|
|
35
|
+
*
|
|
36
|
+
* The baseline is also what the wheel scales about, which is not always zero:
|
|
37
|
+
* percent transmittance runs *down* from 100, and scaling it about zero would
|
|
38
|
+
* walk the whole trace off the top of the plot instead of stretching it.
|
|
39
|
+
*/
|
|
40
|
+
export interface YAxisRules {
|
|
41
|
+
/**
|
|
42
|
+
* The value the wheel scales about, and the line a drag is judged against.
|
|
43
|
+
* @default 0
|
|
44
|
+
*/
|
|
45
|
+
baseline?: number;
|
|
46
|
+
/**
|
|
47
|
+
* Whether the baseline must stay inside the window a drag asks for — true for
|
|
48
|
+
* a stick spectrum standing on it, false for a continuous trace.
|
|
49
|
+
* @default true
|
|
50
|
+
*/
|
|
51
|
+
keepBaseline?: boolean;
|
|
52
|
+
/**
|
|
53
|
+
* Whether the features hang **down** from the baseline rather than standing up
|
|
54
|
+
* out of it.
|
|
55
|
+
*
|
|
56
|
+
* This is which side of the baseline the data is on, and it decides which way
|
|
57
|
+
* "released past the baseline" points. A mass peak and an absorbance band both
|
|
58
|
+
* stand up out of a baseline at the foot of the plot, so the gesture is a drag
|
|
59
|
+
* released *below* it. Percent transmittance hangs down from 100, which sits
|
|
60
|
+
* near the *top* — so there the gesture is a drag released above it, and asking
|
|
61
|
+
* the mass question instead would make almost every drag in the plot take the
|
|
62
|
+
* value axis with it.
|
|
63
|
+
* @default false
|
|
64
|
+
*/
|
|
65
|
+
pointsDown?: boolean;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** What the rules come to when a viewer states none of them. */
|
|
69
|
+
export const DEFAULT_Y_AXIS_RULES: Required<YAxisRules> = {
|
|
70
|
+
baseline: 0,
|
|
71
|
+
keepBaseline: true,
|
|
72
|
+
pointsDown: false,
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* What a drag across the plot zooms to.
|
|
77
|
+
*
|
|
78
|
+
* `xAxis` is the reading gesture and the default: the question a chemist asks of
|
|
79
|
+
* a spectrum is nearly always "what is between 1650 and 1750", never "what is
|
|
80
|
+
* between forty and sixty percent", so a drag narrows the horizontal axis and
|
|
81
|
+
* leaves the height alone unless it is released past the baseline.
|
|
82
|
+
*
|
|
83
|
+
* `box` is the tool: while it is chosen, the rectangle dragged out is the window,
|
|
84
|
+
* both axes at once. It is a mode rather than a modifier because it is used in
|
|
85
|
+
* runs — a baseline being examined is examined several times over — and a
|
|
86
|
+
* modifier held down through each of them is a worse gesture than a tool pressed
|
|
87
|
+
* once.
|
|
88
|
+
*
|
|
89
|
+
* The two are named apart from the whole of `DragMode` so that a chart offering
|
|
90
|
+
* nothing but zoom tools can say so in its own signature — which is what stops
|
|
91
|
+
* `select`, the one drag that moves no axis, from reaching a chart with no
|
|
92
|
+
* handler for it.
|
|
93
|
+
*/
|
|
94
|
+
export type ZoomDragMode = 'xAxis' | 'box';
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* What a drag across the plot asks for.
|
|
98
|
+
*
|
|
99
|
+
* `select` is the third and it is not a zoom at all: the rectangle swept out is
|
|
100
|
+
* handed back as a range and the window is left exactly where it was. A
|
|
101
|
+
* chromatographic peak is integrated between two retention times a chemist
|
|
102
|
+
* chose, and choosing them by dragging over them is the gesture — so the answer
|
|
103
|
+
* to it is two numbers on the horizontal axis rather than a new window, and a
|
|
104
|
+
* chart that zoomed to them as well would take the neighbouring peaks off the
|
|
105
|
+
* screen the moment the boundaries were set.
|
|
106
|
+
*
|
|
107
|
+
* It is a mode rather than a modifier for the reason `ZoomDragMode` already
|
|
108
|
+
* gives — integration is done in runs — and it is kept out of `ZoomDragMode` so
|
|
109
|
+
* that a chart offering only zoom tools, which is what the infrared toolbar
|
|
110
|
+
* hands to its `zoomGestures`, cannot be handed it by a widening nobody noticed.
|
|
111
|
+
* Handed one, that chart would sweep out a rectangle and then do nothing at all.
|
|
112
|
+
*/
|
|
113
|
+
export type DragMode = ZoomDragMode | 'select';
|
|
114
|
+
|
|
115
|
+
/** How the y axis behaves, and what a drag is taken to mean. */
|
|
116
|
+
export interface ZoomRules extends YAxisRules {
|
|
117
|
+
/**
|
|
118
|
+
* What a drag asks for.
|
|
119
|
+
* @default 'xAxis'
|
|
120
|
+
*/
|
|
121
|
+
drag?: DragMode;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Which gestures a chart answers, for a viewer that offers fewer than all of
|
|
126
|
+
* them.
|
|
127
|
+
*
|
|
128
|
+
* A gesture is worth having only where the axis it moves has somewhere to go,
|
|
129
|
+
* and that is a property of what is being measured rather than of the chart. An
|
|
130
|
+
* axis running between two ends the data fills — percent transmittance from 0 to
|
|
131
|
+
* 100 — has nothing for the wheel to scale: stretching it about its baseline
|
|
132
|
+
* pushes the trace off the plot and leaves an axis that no longer reads as
|
|
133
|
+
* percent. An axis open at one end — intensity, absorbance — has weak features
|
|
134
|
+
* lying against the baseline, and bringing those up is what the wheel is for.
|
|
135
|
+
*
|
|
136
|
+
* Saying it here, once, is what keeps a viewer from answering a gesture in one
|
|
137
|
+
* mode and quietly ignoring it in another: the whole set travels as one object
|
|
138
|
+
* from whatever knows the measurement into `useChartZoom`.
|
|
139
|
+
*/
|
|
140
|
+
export interface ZoomGestures {
|
|
141
|
+
/**
|
|
142
|
+
* What a drag across the plot asks for.
|
|
143
|
+
* @default 'xAxis'
|
|
144
|
+
*/
|
|
145
|
+
drag?: DragMode;
|
|
146
|
+
/**
|
|
147
|
+
* Whether the wheel scales the value axis about its baseline.
|
|
148
|
+
*
|
|
149
|
+
* Turned off, the wheel is left entirely alone — the page scrolls under the
|
|
150
|
+
* pointer as it does anywhere else, which is what a reader expects of a chart
|
|
151
|
+
* that does not answer the gesture.
|
|
152
|
+
* @default true
|
|
153
|
+
*/
|
|
154
|
+
wheel?: boolean;
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/** What the gestures come to when a viewer states none of them. */
|
|
158
|
+
export const DEFAULT_ZOOM_GESTURES: Required<ZoomGestures> = {
|
|
159
|
+
drag: 'xAxis',
|
|
160
|
+
wheel: true,
|
|
161
|
+
};
|
|
162
|
+
|
|
163
|
+
/**
|
|
164
|
+
* Whether two windows show the same thing, compared by their four numbers.
|
|
165
|
+
*
|
|
166
|
+
* By value and never by identity, because the fitted window is rebuilt from the
|
|
167
|
+
* spectra whenever anything about them changes — a colour, a name, a visibility
|
|
168
|
+
* — and only some of those changes move an axis. A chart that told the two
|
|
169
|
+
* apart by identity would throw the user's zoom away every time they touched
|
|
170
|
+
* the list beside it.
|
|
171
|
+
* @param current - The window in force.
|
|
172
|
+
* @param next - The window just worked out.
|
|
173
|
+
* @returns Whether both axes already run between the same bounds.
|
|
174
|
+
*/
|
|
175
|
+
export function sameChartDomain(
|
|
176
|
+
current: ChartDomain,
|
|
177
|
+
next: ChartDomain,
|
|
178
|
+
): boolean {
|
|
179
|
+
return (
|
|
180
|
+
current.x[0] === next.x[0] &&
|
|
181
|
+
current.x[1] === next.x[1] &&
|
|
182
|
+
current.y[0] === next.y[0] &&
|
|
183
|
+
current.y[1] === next.y[1]
|
|
184
|
+
);
|
|
185
|
+
}
|
|
@@ -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 (
|
|
41
|
-
|
|
42
|
-
return { offset:
|
|
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 };
|