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