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,235 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The window a gesture asks for, where each viewer's own fitting holds the one
|
|
3
|
+
* the data asks for.
|
|
4
|
+
*
|
|
5
|
+
* Nothing here touches React or the DOM: a drag arrives as two corners in the
|
|
6
|
+
* user units of the SVG, a wheel as a factor, and each leaves as a window — so
|
|
7
|
+
* what a gesture does to a chart can be read, and tested, without one being on
|
|
8
|
+
* screen.
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import { clamp } from '../../format/core/clamp.ts';
|
|
12
|
+
|
|
13
|
+
import type { ChartDomain, ZoomRules } from './chartDomain.ts';
|
|
14
|
+
import { DEFAULT_Y_AXIS_RULES } from './chartDomain.ts';
|
|
15
|
+
import type { PlotRect } from './chartGeometry.ts';
|
|
16
|
+
import type { ChartScale } from './chartScale.ts';
|
|
17
|
+
import { chartPixel, chartValue } from './chartScale.ts';
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* How far the pointer has to travel before a press counts as a gesture rather
|
|
21
|
+
* than as a click, in user units of the SVG.
|
|
22
|
+
*
|
|
23
|
+
* Across the x axis it is what decides whether there is a window at all: below
|
|
24
|
+
* this the gesture is a click that happened to wobble — which is most clicks
|
|
25
|
+
* made on a trackpad — and zooming to it would leave a window a fraction of a
|
|
26
|
+
* data unit wide, from which the only way back is the double click nobody knows
|
|
27
|
+
* about yet. `chartGestures.ts` asks the same question of the vertical travel
|
|
28
|
+
* before it calls a release a click, since a drag of one pixel across and three
|
|
29
|
+
* hundred down went somewhere.
|
|
30
|
+
*/
|
|
31
|
+
export const MINIMUM_DRAG = 4;
|
|
32
|
+
|
|
33
|
+
/** The two corners of a drag, in the user units of the SVG. */
|
|
34
|
+
export interface DragBox {
|
|
35
|
+
/** Where the press landed, horizontally. */
|
|
36
|
+
fromX: number;
|
|
37
|
+
/** Where it landed vertically. */
|
|
38
|
+
fromY: number;
|
|
39
|
+
/** Where the pointer is now, horizontally. */
|
|
40
|
+
toX: number;
|
|
41
|
+
/** Where it is vertically. */
|
|
42
|
+
toY: number;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/** The drag as it is being made, for the preview rectangle to be drawn from. */
|
|
46
|
+
export interface ZoomSelection extends DragBox {
|
|
47
|
+
/**
|
|
48
|
+
* Whether letting go here would take the y axis with it, which is what the
|
|
49
|
+
* rectangle changes shape to say.
|
|
50
|
+
*/
|
|
51
|
+
zoomsYAxis: boolean;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* The drag as the preview rectangle needs it.
|
|
56
|
+
*
|
|
57
|
+
* The answer the rectangle changes shape on is worked out once, here, rather
|
|
58
|
+
* than by the rectangle itself — so what the preview promises and what letting
|
|
59
|
+
* go actually does are the same test rather than two that have to agree.
|
|
60
|
+
*
|
|
61
|
+
* A `select` drag is therefore always a band, however far past the baseline it
|
|
62
|
+
* strays: its answer is two numbers on one axis, so a preview that grew into a
|
|
63
|
+
* rectangle would promise a height nobody is ever told about.
|
|
64
|
+
* @param drag - The drag being made, `null` when none is.
|
|
65
|
+
* @param yScale - The y axis as it is currently zoomed.
|
|
66
|
+
* @param rules - How the y axis behaves and what a drag means, defaulting to a
|
|
67
|
+
* stick spectrum read by dragging its horizontal axis.
|
|
68
|
+
* @returns The selection to draw, `null` when there is no drag.
|
|
69
|
+
*/
|
|
70
|
+
export function zoomSelection(
|
|
71
|
+
drag: DragBox | null,
|
|
72
|
+
yScale: ChartScale,
|
|
73
|
+
rules: ZoomRules = {},
|
|
74
|
+
): ZoomSelection | null {
|
|
75
|
+
if (drag === null) return null;
|
|
76
|
+
const {
|
|
77
|
+
baseline = DEFAULT_Y_AXIS_RULES.baseline,
|
|
78
|
+
pointsDown = DEFAULT_Y_AXIS_RULES.pointsDown,
|
|
79
|
+
drag: mode = 'xAxis',
|
|
80
|
+
} = rules;
|
|
81
|
+
return {
|
|
82
|
+
fromX: drag.fromX,
|
|
83
|
+
fromY: drag.fromY,
|
|
84
|
+
toX: drag.toX,
|
|
85
|
+
toY: drag.toY,
|
|
86
|
+
// The box tool takes the height always, so the preview is a rectangle from
|
|
87
|
+
// the first pixel of the gesture rather than a full-height band that
|
|
88
|
+
// suddenly becomes one; a select drag never takes it at all.
|
|
89
|
+
zoomsYAxis:
|
|
90
|
+
mode === 'box' ||
|
|
91
|
+
(mode !== 'select' &&
|
|
92
|
+
releasedBeyondBaseline(drag.toY, yScale, baseline, pointsDown)),
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* Whether a drag let go here asks for the y axis as well.
|
|
98
|
+
*
|
|
99
|
+
* The baseline, not the bottom of the plot: on a mirrored chart zero runs across
|
|
100
|
+
* the middle, so a drag that dips into the reflected half has crossed it, and on
|
|
101
|
+
* an ordinary chart the same test means the pointer went below the axis and out
|
|
102
|
+
* into the margin. One rule, two gestures that both read as "and take the height
|
|
103
|
+
* with you".
|
|
104
|
+
*
|
|
105
|
+
* **Which way "past" points depends on which side of the baseline the data is
|
|
106
|
+
* on**, which is what `pointsDown` says. Features that stand up out of a
|
|
107
|
+
* baseline at the foot of the plot — mass sticks, absorbance bands — are passed
|
|
108
|
+
* by going below it. Percent transmittance hangs down from 100, which sits near
|
|
109
|
+
* the top of the plot, so there the gesture is a drag released *above* the
|
|
110
|
+
* baseline; asking the other question would answer yes almost everywhere in the
|
|
111
|
+
* plot and make every ordinary drag take the value axis with it.
|
|
112
|
+
* @param pointerY - Where the pointer is, in user units of the SVG.
|
|
113
|
+
* @param yScale - The y axis as it is currently zoomed.
|
|
114
|
+
* @param baseline - The value the gesture is judged against. Defaults to `0`.
|
|
115
|
+
* @param pointsDown - Whether the data hangs below the baseline. Defaults to
|
|
116
|
+
* `false`.
|
|
117
|
+
* @returns Whether the y axis comes along.
|
|
118
|
+
*/
|
|
119
|
+
export function releasedBeyondBaseline(
|
|
120
|
+
pointerY: number,
|
|
121
|
+
yScale: ChartScale,
|
|
122
|
+
baseline = DEFAULT_Y_AXIS_RULES.baseline,
|
|
123
|
+
pointsDown = DEFAULT_Y_AXIS_RULES.pointsDown,
|
|
124
|
+
): boolean {
|
|
125
|
+
const atBaseline = chartPixel(yScale, baseline);
|
|
126
|
+
// SVG counts pixels downwards, so "above the baseline" is the smaller pixel.
|
|
127
|
+
return pointsDown ? pointerY < atBaseline : pointerY > atBaseline;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/**
|
|
131
|
+
* The window a drag asks for, or `null` when it asks for nothing.
|
|
132
|
+
*
|
|
133
|
+
* Both corners are pulled back inside the plot before they are read, so a drag
|
|
134
|
+
* that ran out over the axis labels — which is how the y axis is asked for in
|
|
135
|
+
* the first place — zooms to the edge of the data rather than to whatever lies
|
|
136
|
+
* under the margin.
|
|
137
|
+
*
|
|
138
|
+
* Whether the baseline is kept in the window is the one thing that differs
|
|
139
|
+
* between viewers, and `YAxisRules` is where they say so. A stick spectrum keeps
|
|
140
|
+
* it: sticks are drawn from it, and a window starting at a tenth of the base
|
|
141
|
+
* peak would cut every one of them off at the ankles. A continuous trace does
|
|
142
|
+
* not: a band dragged out between two absorbances is asked about between those
|
|
143
|
+
* two absorbances.
|
|
144
|
+
* @param current - The window in force, kept on the axis that is not asked for.
|
|
145
|
+
* @param drag - The two corners, in user units of the SVG.
|
|
146
|
+
* @param plot - Where the plot sits inside the SVG.
|
|
147
|
+
* @param xScale - The x axis as it is currently zoomed.
|
|
148
|
+
* @param yScale - The y axis as it is currently zoomed.
|
|
149
|
+
* @param rules - How the y axis behaves and what a drag means, defaulting to a
|
|
150
|
+
* stick spectrum read by dragging its horizontal axis.
|
|
151
|
+
* @returns The window to show, `null` when the drag was too short to be one.
|
|
152
|
+
*/
|
|
153
|
+
export function zoomedDomain(
|
|
154
|
+
current: ChartDomain,
|
|
155
|
+
drag: DragBox,
|
|
156
|
+
plot: PlotRect,
|
|
157
|
+
xScale: ChartScale,
|
|
158
|
+
yScale: ChartScale,
|
|
159
|
+
rules: ZoomRules = {},
|
|
160
|
+
): ChartDomain | null {
|
|
161
|
+
const {
|
|
162
|
+
baseline = DEFAULT_Y_AXIS_RULES.baseline,
|
|
163
|
+
keepBaseline = DEFAULT_Y_AXIS_RULES.keepBaseline,
|
|
164
|
+
pointsDown = DEFAULT_Y_AXIS_RULES.pointsDown,
|
|
165
|
+
drag: mode = 'xAxis',
|
|
166
|
+
} = rules;
|
|
167
|
+
const fromX = clamp(drag.fromX, plot.left, plot.right);
|
|
168
|
+
const toX = clamp(drag.toX, plot.left, plot.right);
|
|
169
|
+
if (Math.abs(toX - fromX) < MINIMUM_DRAG) return null;
|
|
170
|
+
// Sorted after inverting, not before: an axis drawn right to left — an
|
|
171
|
+
// infrared spectrum runs from 4000 down to 400 — maps the leftmost pixel to
|
|
172
|
+
// the *highest* value, so taking the left edge as the lower bound would hand
|
|
173
|
+
// back a window whose ends are the wrong way round, and every scale built
|
|
174
|
+
// from it would draw the trace mirrored.
|
|
175
|
+
const firstX = chartValue(xScale, fromX);
|
|
176
|
+
const secondX = chartValue(xScale, toX);
|
|
177
|
+
const x: [number, number] = [
|
|
178
|
+
Math.min(firstX, secondX),
|
|
179
|
+
Math.max(firstX, secondX),
|
|
180
|
+
];
|
|
181
|
+
// The box tool is asked for the rectangle it was given, wherever it was let
|
|
182
|
+
// go; the reading gesture takes the height only when it crossed the baseline.
|
|
183
|
+
if (
|
|
184
|
+
mode !== 'box' &&
|
|
185
|
+
!releasedBeyondBaseline(drag.toY, yScale, baseline, pointsDown)
|
|
186
|
+
) {
|
|
187
|
+
return { x, y: current.y };
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const fromY = chartValue(yScale, clamp(drag.fromY, plot.top, plot.bottom));
|
|
191
|
+
const toY = chartValue(yScale, clamp(drag.toY, plot.top, plot.bottom));
|
|
192
|
+
// Both ends, so a baseline the data runs *down* from — 100 percent
|
|
193
|
+
// transmittance — is kept as surely as one it stands on. The box tool holds no
|
|
194
|
+
// baseline at all: a rectangle dragged round a feature is a promise about
|
|
195
|
+
// exactly that rectangle, and a viewer whose axis rules keep its baseline
|
|
196
|
+
// would otherwise see the tool quietly return a taller window than the one
|
|
197
|
+
// drawn.
|
|
198
|
+
const holdBaseline = keepBaseline && mode !== 'box';
|
|
199
|
+
const bottom = holdBaseline
|
|
200
|
+
? Math.min(baseline, fromY, toY)
|
|
201
|
+
: Math.min(fromY, toY);
|
|
202
|
+
const top = holdBaseline
|
|
203
|
+
? Math.max(baseline, fromY, toY)
|
|
204
|
+
: Math.max(fromY, toY);
|
|
205
|
+
return top > bottom ? { x, y: [bottom, top] } : { x, y: current.y };
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* The window one turn of the wheel asks for.
|
|
210
|
+
*
|
|
211
|
+
* Both bounds are scaled about the baseline rather than about the middle of the
|
|
212
|
+
* window. On a stick spectrum that keeps the foot the sticks are drawn from on
|
|
213
|
+
* the axis, and keeps a mirrored chart symmetric — scaling about the middle
|
|
214
|
+
* would send the two halves apart at different rates, so a peak of one height
|
|
215
|
+
* would mean two different intensities. On an axis running downwards from a
|
|
216
|
+
* baseline, such as percent transmittance from 100, it is what stretches the
|
|
217
|
+
* bands instead of walking the whole trace off the plot.
|
|
218
|
+
* @param current - The window in force.
|
|
219
|
+
* @param factor - What one wheel event is worth, above one to zoom out.
|
|
220
|
+
* @param baseline - The value to scale about. Defaults to `0`.
|
|
221
|
+
* @returns The window to show, `current` itself when the factor is not one a
|
|
222
|
+
* window survives.
|
|
223
|
+
*/
|
|
224
|
+
export function scaledYAxis(
|
|
225
|
+
current: ChartDomain,
|
|
226
|
+
factor: number,
|
|
227
|
+
baseline = DEFAULT_Y_AXIS_RULES.baseline,
|
|
228
|
+
): ChartDomain {
|
|
229
|
+
if (!Number.isFinite(factor) || factor <= 0) return current;
|
|
230
|
+
const y: [number, number] = [
|
|
231
|
+
baseline + (current.y[0] - baseline) * factor,
|
|
232
|
+
baseline + (current.y[1] - baseline) * factor,
|
|
233
|
+
];
|
|
234
|
+
return y[1] > y[0] ? { x: current.x, y } : current;
|
|
235
|
+
}
|
|
@@ -0,0 +1,361 @@
|
|
|
1
|
+
import type { ReactElement } from 'react';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { axisLabeller } from '../core/axisLabels.ts';
|
|
5
|
+
import type { ChartAxisScale } from '../core/chartAxisScale.ts';
|
|
6
|
+
import { chartAxisScale } from '../core/chartAxisScale.ts';
|
|
7
|
+
import type { PlotRect } from '../core/chartGeometry.ts';
|
|
8
|
+
import type { ChartScale } from '../core/chartScale.ts';
|
|
9
|
+
import { chartPixel } from '../core/chartScale.ts';
|
|
10
|
+
import { CHART_COLORS, CHART_FONT } from '../core/chartTheme.ts';
|
|
11
|
+
|
|
12
|
+
export interface AxesProps {
|
|
13
|
+
/** Where the plot sits inside the SVG. */
|
|
14
|
+
plot: PlotRect;
|
|
15
|
+
/** The window on screen, which the ticks along the bottom are chosen for. */
|
|
16
|
+
xDomain: readonly [number, number];
|
|
17
|
+
/** The window on screen, which the ticks up the side are chosen for. */
|
|
18
|
+
yDomain: readonly [number, number];
|
|
19
|
+
/**
|
|
20
|
+
* The horizontal axis as it is currently zoomed. A scale built onto a
|
|
21
|
+
* reversed pixel range is drawn reversed with no further ceremony, which is
|
|
22
|
+
* what an infrared spectrum running from 4000 down to 400 needs.
|
|
23
|
+
*/
|
|
24
|
+
xScale: ChartScale;
|
|
25
|
+
/** The vertical axis as it is currently zoomed. */
|
|
26
|
+
yScale: ChartScale;
|
|
27
|
+
/**
|
|
28
|
+
* Whether the vertical labels are written by magnitude, so the half below
|
|
29
|
+
* the rule reads `100 50 0 50 100` rather than `-100 -50 0 50 100`. What the
|
|
30
|
+
* lower half of a mirrored pair means is a second spectrum drawn downwards,
|
|
31
|
+
* never a negative value, and a minus sign in front of every one of its
|
|
32
|
+
* labels says otherwise.
|
|
33
|
+
* @default false
|
|
34
|
+
*/
|
|
35
|
+
absYTicks?: boolean;
|
|
36
|
+
/**
|
|
37
|
+
* Whether the numbers along the bottom are written.
|
|
38
|
+
*
|
|
39
|
+
* Panes stacked over one window would each repeat `2.5 5.0 7.5` and spend a
|
|
40
|
+
* tick row of height on it, so only the pane at the foot writes them. The
|
|
41
|
+
* grid and the axis line stay — they are what a peak's height is read against.
|
|
42
|
+
* @default true
|
|
43
|
+
*/
|
|
44
|
+
showXTicks?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Whether the name of the horizontal axis is written under it.
|
|
47
|
+
*
|
|
48
|
+
* Separate from `showXTicks` because the two go at different moments — a pane
|
|
49
|
+
* above the foot of a stack keeps neither, a chart in a narrow panel keeps its
|
|
50
|
+
* numbers. `xTitle` stays required either way: which pane is the foot changes.
|
|
51
|
+
* @default true
|
|
52
|
+
*/
|
|
53
|
+
showXTitle?: boolean;
|
|
54
|
+
/**
|
|
55
|
+
* What the horizontal axis is called — `m/z`, `wavenumber (cm⁻¹)`.
|
|
56
|
+
*
|
|
57
|
+
* Required rather than defaulted, because there is no name that is right for
|
|
58
|
+
* every spectrum and a default would be one viewer's units silently drawn
|
|
59
|
+
* under another's data.
|
|
60
|
+
*/
|
|
61
|
+
xTitle: string;
|
|
62
|
+
/** What the vertical axis is called — `intensity`, `absorbance`, `%T`. */
|
|
63
|
+
yTitle: string;
|
|
64
|
+
/**
|
|
65
|
+
* How much room one label along the bottom is given, in pixels.
|
|
66
|
+
*
|
|
67
|
+
* The default is the width of the widest number a spectrum axis writes — a
|
|
68
|
+
* mass at four decimals — so that a chart in a narrow panel carries three
|
|
69
|
+
* labels rather than six run together. A chart whose numbers are known to be
|
|
70
|
+
* short says so and gets more of them: a fixed axis over a few hundred mass
|
|
71
|
+
* units writes `400 600 800`, and at the default spacing a column that narrow
|
|
72
|
+
* is given a single tick, which says nothing about the range at all.
|
|
73
|
+
* @default 90
|
|
74
|
+
*/
|
|
75
|
+
xTickSpacing?: number;
|
|
76
|
+
/**
|
|
77
|
+
* How much room one label up the side is given, in pixels.
|
|
78
|
+
* @default 44
|
|
79
|
+
*/
|
|
80
|
+
yTickSpacing?: number;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* The frame the spectra are read against: two axis lines, a grid, and titles.
|
|
85
|
+
*
|
|
86
|
+
* The ticks are rules across the whole plot rather than dashes at its edge. A
|
|
87
|
+
* feature is read for its height against the ones around it — is this the base
|
|
88
|
+
* peak, is that band half of it — and a dash on the far left is a measuring
|
|
89
|
+
* stick nobody can lay across the peak they are looking at. The rules
|
|
90
|
+
* are drawn in the palest colour the theme carries and under the data band, so
|
|
91
|
+
* a grid line is never mistaken for a trace.
|
|
92
|
+
*
|
|
93
|
+
* Every number is written outside the plot, and every line inside it. That is
|
|
94
|
+
* what lets the data band be clipped without a label being cut in half, and it
|
|
95
|
+
* keeps the plot itself free for the only thing it is about.
|
|
96
|
+
*
|
|
97
|
+
* The axis pair is one L rather than a box: the top and the right of a spectrum
|
|
98
|
+
* are open, because a peak that runs out of the top is a peak the zoom has cut
|
|
99
|
+
* off, and a rule along the top would read as a ceiling the measurement stopped
|
|
100
|
+
* at.
|
|
101
|
+
*
|
|
102
|
+
* How many ticks there are follows the room there is for them — a chart in a
|
|
103
|
+
* narrow panel is given fewer, rather than the same six labels overprinting one
|
|
104
|
+
* another — and the precision each is written to comes from the step, so a
|
|
105
|
+
* window two millimass units wide is labelled to four decimals and a full scan
|
|
106
|
+
* to none. The notation is settled once per axis rather than per label, so an
|
|
107
|
+
* intensity axis running to two hundred million reads `5e+7 1e+8 1.5e+8 2e+8`
|
|
108
|
+
* and not a column of nine digits the title has to be read around.
|
|
109
|
+
* @param props - Component props.
|
|
110
|
+
* @returns The axes, as SVG.
|
|
111
|
+
*/
|
|
112
|
+
export function Axes(props: AxesProps): ReactElement {
|
|
113
|
+
const {
|
|
114
|
+
plot,
|
|
115
|
+
xDomain,
|
|
116
|
+
yDomain,
|
|
117
|
+
xScale,
|
|
118
|
+
yScale,
|
|
119
|
+
absYTicks = false,
|
|
120
|
+
showXTicks = true,
|
|
121
|
+
showXTitle = true,
|
|
122
|
+
xTitle,
|
|
123
|
+
yTitle,
|
|
124
|
+
xTickSpacing = X_TICK_SPACING,
|
|
125
|
+
yTickSpacing = Y_TICK_SPACING,
|
|
126
|
+
} = props;
|
|
127
|
+
|
|
128
|
+
const xTicks = useMemo(
|
|
129
|
+
() => spectrumAxis(xDomain, tickCount(plot.width, xTickSpacing)),
|
|
130
|
+
[xDomain, plot.width, xTickSpacing],
|
|
131
|
+
);
|
|
132
|
+
const yTicks = useMemo(
|
|
133
|
+
() => spectrumAxis(yDomain, tickCount(plot.height, yTickSpacing)),
|
|
134
|
+
[yDomain, plot.height, yTickSpacing],
|
|
135
|
+
);
|
|
136
|
+
const writeXTick = useMemo(() => axisLabeller(xTicks), [xTicks]);
|
|
137
|
+
const writeYTick = useMemo(() => axisLabeller(yTicks), [yTicks]);
|
|
138
|
+
|
|
139
|
+
const middleX = plot.left + plot.width / 2;
|
|
140
|
+
const middleY = plot.top + plot.height / 2;
|
|
141
|
+
// Beside the numbers rather than in a fixed column at the edge of the margin.
|
|
142
|
+
// One gutter holds `100` on a spectrum and `1.5e+8` on a chromatogram, and a
|
|
143
|
+
// title pinned where the wider of the two would leave it stands twenty pixels
|
|
144
|
+
// clear of the narrower — far enough to read as naming the chart rather than
|
|
145
|
+
// the axis.
|
|
146
|
+
const titleColumn = useMemo(
|
|
147
|
+
() => valueTitleColumn(yTicks.values, writeYTick, absYTicks, plot.left),
|
|
148
|
+
[yTicks, writeYTick, absYTicks, plot.left],
|
|
149
|
+
);
|
|
150
|
+
// The rule a mirrored pair is reflected in only exists while both halves are
|
|
151
|
+
// on screen; on an ordinary chart zero is the baseline and already drawn.
|
|
152
|
+
const zero = chartPixel(yScale, 0);
|
|
153
|
+
const showsZeroRule = yDomain[0] < 0 && yDomain[1] > 0;
|
|
154
|
+
|
|
155
|
+
return (
|
|
156
|
+
<g pointerEvents="none">
|
|
157
|
+
{xTicks.values.map((tick) => (
|
|
158
|
+
<line
|
|
159
|
+
key={tick}
|
|
160
|
+
x1={chartPixel(xScale, tick)}
|
|
161
|
+
y1={plot.top}
|
|
162
|
+
x2={chartPixel(xScale, tick)}
|
|
163
|
+
y2={plot.bottom}
|
|
164
|
+
style={gridStyle}
|
|
165
|
+
/>
|
|
166
|
+
))}
|
|
167
|
+
{yTicks.values.map((tick) => (
|
|
168
|
+
<line
|
|
169
|
+
key={tick}
|
|
170
|
+
x1={plot.left}
|
|
171
|
+
y1={chartPixel(yScale, tick)}
|
|
172
|
+
x2={plot.right}
|
|
173
|
+
y2={chartPixel(yScale, tick)}
|
|
174
|
+
style={gridStyle}
|
|
175
|
+
/>
|
|
176
|
+
))}
|
|
177
|
+
{showsZeroRule ? (
|
|
178
|
+
<line
|
|
179
|
+
x1={plot.left}
|
|
180
|
+
y1={zero}
|
|
181
|
+
x2={plot.right}
|
|
182
|
+
y2={zero}
|
|
183
|
+
style={zeroRuleStyle}
|
|
184
|
+
/>
|
|
185
|
+
) : null}
|
|
186
|
+
<path
|
|
187
|
+
d={`M${plot.left} ${plot.top}V${plot.bottom}H${plot.right}`}
|
|
188
|
+
fill="none"
|
|
189
|
+
style={axisStyle}
|
|
190
|
+
/>
|
|
191
|
+
{showXTicks &&
|
|
192
|
+
xTicks.values.map((tick) => (
|
|
193
|
+
<text
|
|
194
|
+
key={tick}
|
|
195
|
+
x={chartPixel(xScale, tick)}
|
|
196
|
+
y={plot.bottom + TICK_LABEL_GAP}
|
|
197
|
+
textAnchor="middle"
|
|
198
|
+
dominantBaseline="hanging"
|
|
199
|
+
style={tickStyle}
|
|
200
|
+
>
|
|
201
|
+
{writeXTick(tick)}
|
|
202
|
+
</text>
|
|
203
|
+
))}
|
|
204
|
+
{yTicks.values.map((tick) => (
|
|
205
|
+
<text
|
|
206
|
+
key={tick}
|
|
207
|
+
x={plot.left - TICK_LABEL_GAP}
|
|
208
|
+
y={chartPixel(yScale, tick)}
|
|
209
|
+
textAnchor="end"
|
|
210
|
+
dominantBaseline="central"
|
|
211
|
+
style={tickStyle}
|
|
212
|
+
>
|
|
213
|
+
{writeYTick(absYTicks ? Math.abs(tick) : tick)}
|
|
214
|
+
</text>
|
|
215
|
+
))}
|
|
216
|
+
{showXTitle && (
|
|
217
|
+
<text
|
|
218
|
+
x={middleX}
|
|
219
|
+
y={plot.bottom + TITLE_GAP}
|
|
220
|
+
textAnchor="middle"
|
|
221
|
+
dominantBaseline="hanging"
|
|
222
|
+
style={titleStyle}
|
|
223
|
+
>
|
|
224
|
+
{xTitle}
|
|
225
|
+
</text>
|
|
226
|
+
)}
|
|
227
|
+
<text
|
|
228
|
+
x={titleColumn}
|
|
229
|
+
y={middleY}
|
|
230
|
+
transform={`rotate(-90 ${titleColumn} ${middleY})`}
|
|
231
|
+
textAnchor="middle"
|
|
232
|
+
dominantBaseline="central"
|
|
233
|
+
style={titleStyle}
|
|
234
|
+
>
|
|
235
|
+
{yTitle}
|
|
236
|
+
</text>
|
|
237
|
+
</g>
|
|
238
|
+
);
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* The ticks of one axis of a chart a reader has zoomed for themselves.
|
|
243
|
+
*
|
|
244
|
+
* The window is exactly what the reader dragged out, so it is never widened to
|
|
245
|
+
* end on a round tick — an axis that jumped outward as the drag was released
|
|
246
|
+
* would show data the reader had just excluded. And the count is a budget
|
|
247
|
+
* worked out from the room the panel has, so the step is rounded up rather than
|
|
248
|
+
* to the nearest: one tick more than the room allows is two labels touching.
|
|
249
|
+
* @param domain - The window on screen, `[from, to]`.
|
|
250
|
+
* @param count - The most intervals the axis has room for.
|
|
251
|
+
* @returns The axis, divided.
|
|
252
|
+
*/
|
|
253
|
+
function spectrumAxis(
|
|
254
|
+
domain: readonly [number, number],
|
|
255
|
+
count: number,
|
|
256
|
+
): ChartAxisScale {
|
|
257
|
+
return chartAxisScale(domain[0], domain[1], {
|
|
258
|
+
count,
|
|
259
|
+
nice: false,
|
|
260
|
+
step: 'atMost',
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* How many intervals an axis of a given length has room to name.
|
|
266
|
+
*
|
|
267
|
+
* A label at a deep zoom is eight characters wide, so the spacings are the width
|
|
268
|
+
* of a label and not a fraction of the axis: a chart in a side panel then
|
|
269
|
+
* carries three labels rather than the same six run together.
|
|
270
|
+
* @param length - How long the axis is, in pixels.
|
|
271
|
+
* @param spacing - The room one label wants along it.
|
|
272
|
+
* @returns The number of intervals to aim for, never below two.
|
|
273
|
+
*/
|
|
274
|
+
function tickCount(length: number, spacing: number): number {
|
|
275
|
+
return Math.max(2, Math.round(length / spacing));
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/**
|
|
279
|
+
* Where the rotated value title stands, given the numbers it has to clear.
|
|
280
|
+
*
|
|
281
|
+
* The widest label is measured in characters rather than in pixels, because the
|
|
282
|
+
* chart has no font to measure against — `CHART_FONT` sets sizes and leaves the
|
|
283
|
+
* family to the host — and a rendered measurement would mean laying the text out
|
|
284
|
+
* and reading it back on every zoom.
|
|
285
|
+
* @param ticks - The ticks up the side, as `chartAxisScale` chose them.
|
|
286
|
+
* @param write - How this axis writes one of them.
|
|
287
|
+
* @param absolute - Whether the labels are written by magnitude, which is one
|
|
288
|
+
* character narrower on the half of a mirrored chart that runs negative.
|
|
289
|
+
* @param left - Where the plot begins, which is the far side of the gutter.
|
|
290
|
+
* @returns The column to centre the title on, never left of `TITLE_COLUMN`.
|
|
291
|
+
*/
|
|
292
|
+
function valueTitleColumn(
|
|
293
|
+
ticks: readonly number[],
|
|
294
|
+
write: (value: number) => string,
|
|
295
|
+
absolute: boolean,
|
|
296
|
+
left: number,
|
|
297
|
+
): number {
|
|
298
|
+
let widest = 0;
|
|
299
|
+
for (const tick of ticks) {
|
|
300
|
+
const width = write(absolute ? Math.abs(tick) : tick).length;
|
|
301
|
+
if (width > widest) widest = width;
|
|
302
|
+
}
|
|
303
|
+
const beside =
|
|
304
|
+
left - TICK_LABEL_GAP - widest * TICK_CHARACTER - TITLE_ASIDE - HALF_TITLE;
|
|
305
|
+
return Math.max(TITLE_COLUMN, beside);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/** Half the height of the title, which is what its rotated glyphs claim. */
|
|
309
|
+
const HALF_TITLE = CHART_FONT.title / 2;
|
|
310
|
+
|
|
311
|
+
/** The room a label wants along the bottom, at its widest. */
|
|
312
|
+
const X_TICK_SPACING = 90;
|
|
313
|
+
|
|
314
|
+
/** The room a label wants up the side. */
|
|
315
|
+
const Y_TICK_SPACING = 44;
|
|
316
|
+
|
|
317
|
+
/** The clear space between the plot and the numbers written outside it. */
|
|
318
|
+
const TICK_LABEL_GAP = 5;
|
|
319
|
+
|
|
320
|
+
/** How far under the plot the horizontal title hangs, clear of the numbers. */
|
|
321
|
+
const TITLE_GAP = 18;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* The column the rotated value title stands in when the numbers leave it no
|
|
325
|
+
* room, inside the left margin.
|
|
326
|
+
*
|
|
327
|
+
* A floor rather than the place it is written: `valueTitleColumn` puts the
|
|
328
|
+
* title beside the widest number instead, and this is where an axis whose
|
|
329
|
+
* labels fill the whole gutter pushes it back to.
|
|
330
|
+
*/
|
|
331
|
+
const TITLE_COLUMN = 8;
|
|
332
|
+
|
|
333
|
+
/** The clear space between the widest number up the side and the title. */
|
|
334
|
+
const TITLE_ASIDE = 4;
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* How wide one character of a tick label is, at the size the ticks are written.
|
|
338
|
+
*
|
|
339
|
+
* Six tenths of the type size, which is a shade wider than a digit is in any of
|
|
340
|
+
* the sans faces a host is likely to be set in — the chart sets no family of its
|
|
341
|
+
* own, so this is an estimate and is deliberately the generous one. Too wide
|
|
342
|
+
* writes the value title a pixel or two further from the numbers than it had to
|
|
343
|
+
* be; too narrow writes it over them.
|
|
344
|
+
*/
|
|
345
|
+
const TICK_CHARACTER = 0.6 * CHART_FONT.tick;
|
|
346
|
+
|
|
347
|
+
const gridStyle = { stroke: CHART_COLORS.grid } as const;
|
|
348
|
+
|
|
349
|
+
const zeroRuleStyle = { stroke: CHART_COLORS.zeroRule } as const;
|
|
350
|
+
|
|
351
|
+
const axisStyle = { stroke: CHART_COLORS.axis } as const;
|
|
352
|
+
|
|
353
|
+
const tickStyle = {
|
|
354
|
+
fill: CHART_COLORS.tick,
|
|
355
|
+
fontSize: CHART_FONT.tick,
|
|
356
|
+
} as const;
|
|
357
|
+
|
|
358
|
+
const titleStyle = {
|
|
359
|
+
fill: CHART_COLORS.title,
|
|
360
|
+
fontSize: CHART_FONT.title,
|
|
361
|
+
} as const;
|