react-cheminfo 0.69.0 → 0.71.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 +70 -2
- package/lib/about/core/providers.d.ts +6 -0
- package/lib/about/core/providers.d.ts.map +1 -1
- package/lib/about/core/providers.js +7 -0
- package/lib/about/core/providers.js.map +1 -1
- package/lib/about/ui/AboutProvidedBy.js +34 -0
- package/lib/about/ui/AboutProvidedBy.js.map +1 -1
- package/lib/chart/ui/useChartPointer.d.ts +9 -1
- package/lib/chart/ui/useChartPointer.d.ts.map +1 -1
- package/lib/chart/ui/useChartPointer.js +11 -3
- package/lib/chart/ui/useChartPointer.js.map +1 -1
- package/lib/credits/core/credits.d.ts +41 -0
- package/lib/credits/core/credits.d.ts.map +1 -1
- package/lib/credits/core/credits.js +50 -0
- package/lib/credits/core/credits.js.map +1 -1
- package/lib/download/core/drawingMarkup.d.ts +8 -1
- package/lib/download/core/drawingMarkup.d.ts.map +1 -1
- package/lib/download/core/drawingMarkup.js +13 -1
- package/lib/download/core/drawingMarkup.js.map +1 -1
- package/lib/download/core/figurePng.d.ts +14 -0
- package/lib/download/core/figurePng.d.ts.map +1 -1
- package/lib/download/core/figurePng.js +21 -6
- package/lib/download/core/figurePng.js.map +1 -1
- package/lib/download/core/figureSvg.d.ts.map +1 -1
- package/lib/download/core/figureSvg.js +5 -3
- package/lib/download/core/figureSvg.js.map +1 -1
- package/lib/download/core/figureTarget.d.ts +13 -0
- package/lib/download/core/figureTarget.d.ts.map +1 -1
- package/lib/download/core/figureTarget.js +25 -5
- package/lib/download/core/figureTarget.js.map +1 -1
- package/lib/download/core/svgBounds.d.ts +15 -0
- package/lib/download/core/svgBounds.d.ts.map +1 -1
- package/lib/download/core/svgBounds.js +20 -0
- package/lib/download/core/svgBounds.js.map +1 -1
- package/lib/download/core/svgToPng.d.ts.map +1 -1
- package/lib/download/core/svgToPng.js +4 -2
- package/lib/download/core/svgToPng.js.map +1 -1
- package/lib/format/core/relativeTime.d.ts +8 -3
- package/lib/format/core/relativeTime.d.ts.map +1 -1
- package/lib/format/core/relativeTime.js +19 -7
- package/lib/format/core/relativeTime.js.map +1 -1
- package/lib/host/core/connectHost.d.ts +25 -34
- package/lib/host/core/connectHost.d.ts.map +1 -1
- package/lib/host/core/connectHost.js +43 -89
- package/lib/host/core/connectHost.js.map +1 -1
- package/lib/host/core/hostOutputs.d.ts +58 -0
- package/lib/host/core/hostOutputs.d.ts.map +1 -0
- package/lib/host/core/hostOutputs.js +151 -0
- package/lib/host/core/hostOutputs.js.map +1 -0
- package/lib/host/core/index.d.ts +9 -3
- package/lib/host/core/index.d.ts.map +1 -1
- package/lib/host/core/index.js +4 -1
- package/lib/host/core/index.js.map +1 -1
- package/lib/host/core/irKinds.d.ts +124 -0
- package/lib/host/core/irKinds.d.ts.map +1 -0
- package/lib/host/core/irKinds.js +46 -0
- package/lib/host/core/irKinds.js.map +1 -0
- package/lib/host/core/kinds.d.ts +13 -5
- package/lib/host/core/kinds.d.ts.map +1 -1
- package/lib/host/core/kinds.js +11 -5
- package/lib/host/core/kinds.js.map +1 -1
- package/lib/host/core/protocol.d.ts +50 -7
- package/lib/host/core/protocol.d.ts.map +1 -1
- package/lib/host/core/protocol.js +10 -6
- package/lib/host/core/protocol.js.map +1 -1
- package/lib/host/core/selectInputs.d.ts +37 -0
- package/lib/host/core/selectInputs.d.ts.map +1 -0
- package/lib/host/core/selectInputs.js +110 -0
- package/lib/host/core/selectInputs.js.map +1 -0
- package/lib/host/testing/sciPeaks.d.ts +31 -0
- package/lib/host/testing/sciPeaks.d.ts.map +1 -1
- package/lib/host/testing/sciPeaks.js +73 -0
- package/lib/host/testing/sciPeaks.js.map +1 -1
- package/lib/host/testing/standInHost.d.ts +9 -1
- package/lib/host/testing/standInHost.d.ts.map +1 -1
- package/lib/host/testing/standInHost.js +19 -1
- package/lib/host/testing/standInHost.js.map +1 -1
- package/lib/host/ui/useHostConnection.d.ts +13 -5
- package/lib/host/ui/useHostConnection.d.ts.map +1 -1
- package/lib/host/ui/useHostConnection.js +4 -3
- package/lib/host/ui/useHostConnection.js.map +1 -1
- package/lib/host-testing.d.ts +2 -2
- package/lib/host-testing.d.ts.map +1 -1
- package/lib/host-testing.js +2 -2
- package/lib/host-testing.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/handPicking.d.ts +58 -0
- package/lib/ir/core/handPicking.d.ts.map +1 -0
- package/lib/ir/core/handPicking.js +130 -0
- package/lib/ir/core/handPicking.js.map +1 -0
- package/lib/ir/core/index.d.ts +3 -0
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +3 -0
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBandState.d.ts +57 -0
- package/lib/ir/core/irBandState.d.ts.map +1 -0
- package/lib/ir/core/irBandState.js +119 -0
- package/lib/ir/core/irBandState.js.map +1 -0
- package/lib/ir/core/irCommands.d.ts +11 -0
- package/lib/ir/core/irCommands.d.ts.map +1 -1
- package/lib/ir/core/irCommands.js +6 -0
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irPeaks.d.ts +28 -0
- package/lib/ir/core/irPeaks.d.ts.map +1 -0
- package/lib/ir/core/irPeaks.js +66 -0
- package/lib/ir/core/irPeaks.js.map +1 -0
- package/lib/ir/core/irReducer.d.ts +8 -0
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +15 -32
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +15 -0
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +9 -6
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +10 -6
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/pickBands.d.ts +14 -0
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +39 -33
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +9 -1
- package/lib/ir/core/ramanBands.d.ts.map +1 -1
- package/lib/ir/core/ramanBands.js +2 -2
- package/lib/ir/core/ramanBands.js.map +1 -1
- package/lib/ir/core/spectrumBands.d.ts +46 -0
- package/lib/ir/core/spectrumBands.d.ts.map +1 -0
- package/lib/ir/core/spectrumBands.js +98 -0
- package/lib/ir/core/spectrumBands.js.map +1 -0
- package/lib/ir/ui/BandRow.d.ts +5 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -1
- package/lib/ir/ui/BandRow.js +4 -3
- package/lib/ir/ui/BandRow.js.map +1 -1
- package/lib/ir/ui/BandsPanel.d.ts +5 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +36 -16
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/BandsToolbar.d.ts +9 -0
- package/lib/ir/ui/BandsToolbar.d.ts.map +1 -0
- package/lib/ir/ui/BandsToolbar.js +61 -0
- package/lib/ir/ui/BandsToolbar.js.map +1 -0
- package/lib/ir/ui/IrCanvas.d.ts +2 -1
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +19 -5
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +8 -1
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +4 -2
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +6 -0
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +1 -1
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +4 -3
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +5 -4
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +2 -1
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -1
- package/lib/ir/ui/VibrationalEditor.js.map +1 -1
- package/lib/ir/ui/irActions.d.ts +5 -0
- package/lib/ir/ui/irActions.d.ts.map +1 -1
- package/lib/ir/ui/irActions.js +6 -0
- package/lib/ir/ui/irActions.js.map +1 -1
- package/lib/ir/ui/irChartProps.d.ts +4 -1
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.d.ts +5 -11
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +17 -18
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/locales/de.json +63 -0
- package/lib/locales/en.json +63 -0
- package/lib/locales/es.json +63 -0
- package/lib/locales/fr.json +63 -0
- package/lib/locales/it.json +63 -0
- package/lib/mass/core/analyseSpectrum.d.ts +85 -0
- package/lib/mass/core/analyseSpectrum.d.ts.map +1 -0
- package/lib/mass/core/analyseSpectrum.js +101 -0
- package/lib/mass/core/analyseSpectrum.js.map +1 -0
- package/lib/mass/core/ascendingTrace.d.ts +24 -0
- package/lib/mass/core/ascendingTrace.d.ts.map +1 -0
- package/lib/mass/core/ascendingTrace.js +57 -0
- package/lib/mass/core/ascendingTrace.js.map +1 -0
- package/lib/mass/core/centroidPeaks.d.ts +77 -0
- package/lib/mass/core/centroidPeaks.d.ts.map +1 -0
- package/lib/mass/core/centroidPeaks.js +62 -0
- package/lib/mass/core/centroidPeaks.js.map +1 -0
- package/lib/mass/core/detectMassFormat.d.ts +24 -0
- package/lib/mass/core/detectMassFormat.d.ts.map +1 -0
- package/lib/mass/core/detectMassFormat.js +105 -0
- package/lib/mass/core/detectMassFormat.js.map +1 -0
- package/lib/mass/core/downloadSpectra.d.ts +24 -0
- package/lib/mass/core/downloadSpectra.d.ts.map +1 -0
- package/lib/mass/core/downloadSpectra.js +35 -0
- package/lib/mass/core/downloadSpectra.js.map +1 -0
- package/lib/mass/core/fromJcamp.d.ts +46 -0
- package/lib/mass/core/fromJcamp.d.ts.map +1 -0
- package/lib/mass/core/fromJcamp.js +123 -0
- package/lib/mass/core/fromJcamp.js.map +1 -0
- package/lib/mass/core/fromText.d.ts +30 -0
- package/lib/mass/core/fromText.d.ts.map +1 -0
- package/lib/mass/core/fromText.js +39 -0
- package/lib/mass/core/fromText.js.map +1 -0
- package/lib/mass/core/index.d.ts +70 -0
- package/lib/mass/core/index.d.ts.map +1 -0
- package/lib/mass/core/index.js +42 -0
- package/lib/mass/core/index.js.map +1 -0
- package/lib/mass/core/jcampTechnique.d.ts +38 -0
- package/lib/mass/core/jcampTechnique.d.ts.map +1 -0
- package/lib/mass/core/jcampTechnique.js +70 -0
- package/lib/mass/core/jcampTechnique.js.map +1 -0
- package/lib/mass/core/labelStackBox.d.ts +49 -0
- package/lib/mass/core/labelStackBox.d.ts.map +1 -0
- package/lib/mass/core/labelStackBox.js +44 -0
- package/lib/mass/core/labelStackBox.js.map +1 -0
- package/lib/mass/core/labelledPeaks.d.ts +79 -0
- package/lib/mass/core/labelledPeaks.d.ts.map +1 -0
- package/lib/mass/core/labelledPeaks.js +74 -0
- package/lib/mass/core/labelledPeaks.js.map +1 -0
- package/lib/mass/core/loadMassSpectra.d.ts +57 -0
- package/lib/mass/core/loadMassSpectra.d.ts.map +1 -0
- package/lib/mass/core/loadMassSpectra.js +45 -0
- package/lib/mass/core/loadMassSpectra.js.map +1 -0
- package/lib/mass/core/loadedMassSpectrum.d.ts +42 -0
- package/lib/mass/core/loadedMassSpectrum.d.ts.map +1 -0
- package/lib/mass/core/loadedMassSpectrum.js +15 -0
- package/lib/mass/core/loadedMassSpectrum.js.map +1 -0
- package/lib/mass/core/massCommands.d.ts +170 -0
- package/lib/mass/core/massCommands.d.ts.map +1 -0
- package/lib/mass/core/massCommands.js +95 -0
- package/lib/mass/core/massCommands.js.map +1 -0
- package/lib/mass/core/massDomain.d.ts +121 -0
- package/lib/mass/core/massDomain.d.ts.map +1 -0
- package/lib/mass/core/massDomain.js +179 -0
- package/lib/mass/core/massDomain.js.map +1 -0
- package/lib/mass/core/massEditorApi.d.ts +65 -0
- package/lib/mass/core/massEditorApi.d.ts.map +1 -0
- package/lib/mass/core/massEditorApi.js +10 -0
- package/lib/mass/core/massEditorApi.js.map +1 -0
- package/lib/mass/core/massFormat.d.ts +78 -0
- package/lib/mass/core/massFormat.d.ts.map +1 -0
- package/lib/mass/core/massFormat.js +168 -0
- package/lib/mass/core/massFormat.js.map +1 -0
- package/lib/mass/core/massMeta.d.ts +85 -0
- package/lib/mass/core/massMeta.d.ts.map +1 -0
- package/lib/mass/core/massMeta.js +182 -0
- package/lib/mass/core/massMeta.js.map +1 -0
- package/lib/mass/core/massReducer.d.ts +82 -0
- package/lib/mass/core/massReducer.d.ts.map +1 -0
- package/lib/mass/core/massReducer.js +163 -0
- package/lib/mass/core/massReducer.js.map +1 -0
- package/lib/mass/core/massResolution.d.ts +92 -0
- package/lib/mass/core/massResolution.d.ts.map +1 -0
- package/lib/mass/core/massResolution.js +126 -0
- package/lib/mass/core/massResolution.js.map +1 -0
- package/lib/mass/core/massSidePanels.d.ts +28 -0
- package/lib/mass/core/massSidePanels.d.ts.map +1 -0
- package/lib/mass/core/massSidePanels.js +12 -0
- package/lib/mass/core/massSidePanels.js.map +1 -0
- package/lib/mass/core/massSpectrum.d.ts +206 -0
- package/lib/mass/core/massSpectrum.d.ts.map +1 -0
- package/lib/mass/core/massSpectrum.js +41 -0
- package/lib/mass/core/massSpectrum.js.map +1 -0
- package/lib/mass/core/massState.d.ts +145 -0
- package/lib/mass/core/massState.d.ts.map +1 -0
- package/lib/mass/core/massState.js +102 -0
- package/lib/mass/core/massState.js.map +1 -0
- package/lib/mass/core/massStateEdits.d.ts +51 -0
- package/lib/mass/core/massStateEdits.d.ts.map +1 -0
- package/lib/mass/core/massStateEdits.js +90 -0
- package/lib/mass/core/massStateEdits.js.map +1 -0
- package/lib/mass/core/massSummary.d.ts +77 -0
- package/lib/mass/core/massSummary.d.ts.map +1 -0
- package/lib/mass/core/massSummary.js +174 -0
- package/lib/mass/core/massSummary.js.map +1 -0
- package/lib/mass/core/mzDecimalsSetting.d.ts +36 -0
- package/lib/mass/core/mzDecimalsSetting.d.ts.map +1 -0
- package/lib/mass/core/mzDecimalsSetting.js +42 -0
- package/lib/mass/core/mzDecimalsSetting.js.map +1 -0
- package/lib/mass/core/nearestPeak.d.ts +75 -0
- package/lib/mass/core/nearestPeak.d.ts.map +1 -0
- package/lib/mass/core/nearestPeak.js +99 -0
- package/lib/mass/core/nearestPeak.js.map +1 -0
- package/lib/mass/core/peakLabelLines.d.ts +77 -0
- package/lib/mass/core/peakLabelLines.d.ts.map +1 -0
- package/lib/mass/core/peakLabelLines.js +54 -0
- package/lib/mass/core/peakLabelLines.js.map +1 -0
- package/lib/mass/core/peakLabelPlan.d.ts +109 -0
- package/lib/mass/core/peakLabelPlan.d.ts.map +1 -0
- package/lib/mass/core/peakLabelPlan.js +143 -0
- package/lib/mass/core/peakLabelPlan.js.map +1 -0
- package/lib/mass/core/peakTable.d.ts +54 -0
- package/lib/mass/core/peakTable.d.ts.map +1 -0
- package/lib/mass/core/peakTable.js +53 -0
- package/lib/mass/core/peakTable.js.map +1 -0
- package/lib/mass/core/resolutionOf.d.ts +60 -0
- package/lib/mass/core/resolutionOf.d.ts.map +1 -0
- package/lib/mass/core/resolutionOf.js +84 -0
- package/lib/mass/core/resolutionOf.js.map +1 -0
- package/lib/mass/core/scanFilter.d.ts +25 -0
- package/lib/mass/core/scanFilter.d.ts.map +1 -0
- package/lib/mass/core/scanFilter.js +107 -0
- package/lib/mass/core/scanFilter.js.map +1 -0
- package/lib/mass/core/spectrumJcamp.d.ts +47 -0
- package/lib/mass/core/spectrumJcamp.d.ts.map +1 -0
- package/lib/mass/core/spectrumJcamp.js +167 -0
- package/lib/mass/core/spectrumJcamp.js.map +1 -0
- package/lib/mass/core/toMassSpectrum.d.ts +67 -0
- package/lib/mass/core/toMassSpectrum.d.ts.map +1 -0
- package/lib/mass/core/toMassSpectrum.js +78 -0
- package/lib/mass/core/toMassSpectrum.js.map +1 -0
- package/lib/mass/core/traceIcon.d.ts +82 -0
- package/lib/mass/core/traceIcon.d.ts.map +1 -0
- package/lib/mass/core/traceIcon.js +66 -0
- package/lib/mass/core/traceIcon.js.map +1 -0
- package/lib/mass/core/writtenResolution.d.ts +40 -0
- package/lib/mass/core/writtenResolution.d.ts.map +1 -0
- package/lib/mass/core/writtenResolution.js +77 -0
- package/lib/mass/core/writtenResolution.js.map +1 -0
- package/lib/mass/ui/MassAboutDialog.d.ts +16 -0
- package/lib/mass/ui/MassAboutDialog.d.ts.map +1 -0
- package/lib/mass/ui/MassAboutDialog.js +44 -0
- package/lib/mass/ui/MassAboutDialog.js.map +1 -0
- package/lib/mass/ui/MassCanvas.d.ts +46 -0
- package/lib/mass/ui/MassCanvas.d.ts.map +1 -0
- package/lib/mass/ui/MassCanvas.js +84 -0
- package/lib/mass/ui/MassCanvas.js.map +1 -0
- package/lib/mass/ui/MassChart.d.ts +21 -0
- package/lib/mass/ui/MassChart.d.ts.map +1 -0
- package/lib/mass/ui/MassChart.js +139 -0
- package/lib/mass/ui/MassChart.js.map +1 -0
- package/lib/mass/ui/MassCommandProvider.d.ts +15 -0
- package/lib/mass/ui/MassCommandProvider.d.ts.map +1 -0
- package/lib/mass/ui/MassCommandProvider.js +14 -0
- package/lib/mass/ui/MassCommandProvider.js.map +1 -0
- package/lib/mass/ui/MassCommandTooltip.d.ts +16 -0
- package/lib/mass/ui/MassCommandTooltip.d.ts.map +1 -0
- package/lib/mass/ui/MassCommandTooltip.js +22 -0
- package/lib/mass/ui/MassCommandTooltip.js.map +1 -0
- package/lib/mass/ui/MassDocumentationDialog.d.ts +18 -0
- package/lib/mass/ui/MassDocumentationDialog.d.ts.map +1 -0
- package/lib/mass/ui/MassDocumentationDialog.js +70 -0
- package/lib/mass/ui/MassDocumentationDialog.js.map +1 -0
- package/lib/mass/ui/MassEditor.d.ts +78 -0
- package/lib/mass/ui/MassEditor.d.ts.map +1 -0
- package/lib/mass/ui/MassEditor.js +42 -0
- package/lib/mass/ui/MassEditor.js.map +1 -0
- package/lib/mass/ui/MassHeader.d.ts +12 -0
- package/lib/mass/ui/MassHeader.d.ts.map +1 -0
- package/lib/mass/ui/MassHeader.js +20 -0
- package/lib/mass/ui/MassHeader.js.map +1 -0
- package/lib/mass/ui/MassLogo.d.ts +21 -0
- package/lib/mass/ui/MassLogo.d.ts.map +1 -0
- package/lib/mass/ui/MassLogo.js +36 -0
- package/lib/mass/ui/MassLogo.js.map +1 -0
- package/lib/mass/ui/MassPointerTracker.d.ts +44 -0
- package/lib/mass/ui/MassPointerTracker.d.ts.map +1 -0
- package/lib/mass/ui/MassPointerTracker.js +29 -0
- package/lib/mass/ui/MassPointerTracker.js.map +1 -0
- package/lib/mass/ui/MassShell.d.ts +29 -0
- package/lib/mass/ui/MassShell.d.ts.map +1 -0
- package/lib/mass/ui/MassShell.js +133 -0
- package/lib/mass/ui/MassShell.js.map +1 -0
- package/lib/mass/ui/MassSidePanel.d.ts +32 -0
- package/lib/mass/ui/MassSidePanel.d.ts.map +1 -0
- package/lib/mass/ui/MassSidePanel.js +44 -0
- package/lib/mass/ui/MassSidePanel.js.map +1 -0
- package/lib/mass/ui/MassStateProvider.d.ts +19 -0
- package/lib/mass/ui/MassStateProvider.d.ts.map +1 -0
- package/lib/mass/ui/MassStateProvider.js +16 -0
- package/lib/mass/ui/MassStateProvider.js.map +1 -0
- package/lib/mass/ui/MassStatusBar.d.ts +15 -0
- package/lib/mass/ui/MassStatusBar.d.ts.map +1 -0
- package/lib/mass/ui/MassStatusBar.js +50 -0
- package/lib/mass/ui/MassStatusBar.js.map +1 -0
- package/lib/mass/ui/MassToolbar.d.ts +24 -0
- package/lib/mass/ui/MassToolbar.d.ts.map +1 -0
- package/lib/mass/ui/MassToolbar.js +36 -0
- package/lib/mass/ui/MassToolbar.js.map +1 -0
- package/lib/mass/ui/MetadataPanel.d.ts +35 -0
- package/lib/mass/ui/MetadataPanel.d.ts.map +1 -0
- package/lib/mass/ui/MetadataPanel.js +100 -0
- package/lib/mass/ui/MetadataPanel.js.map +1 -0
- package/lib/mass/ui/MzDecimalsMenu.d.ts +28 -0
- package/lib/mass/ui/MzDecimalsMenu.d.ts.map +1 -0
- package/lib/mass/ui/MzDecimalsMenu.js +40 -0
- package/lib/mass/ui/MzDecimalsMenu.js.map +1 -0
- package/lib/mass/ui/PeakLabels.d.ts +93 -0
- package/lib/mass/ui/PeakLabels.d.ts.map +1 -0
- package/lib/mass/ui/PeakLabels.js +91 -0
- package/lib/mass/ui/PeakLabels.js.map +1 -0
- package/lib/mass/ui/PeakTable.d.ts +34 -0
- package/lib/mass/ui/PeakTable.d.ts.map +1 -0
- package/lib/mass/ui/PeakTable.js +49 -0
- package/lib/mass/ui/PeakTable.js.map +1 -0
- package/lib/mass/ui/PeaksPanel.d.ts +31 -0
- package/lib/mass/ui/PeaksPanel.d.ts.map +1 -0
- package/lib/mass/ui/PeaksPanel.js +53 -0
- package/lib/mass/ui/PeaksPanel.js.map +1 -0
- package/lib/mass/ui/SpectraPanel.d.ts +17 -0
- package/lib/mass/ui/SpectraPanel.d.ts.map +1 -0
- package/lib/mass/ui/SpectraPanel.js +76 -0
- package/lib/mass/ui/SpectraPanel.js.map +1 -0
- package/lib/mass/ui/SpectrumRow.d.ts +26 -0
- package/lib/mass/ui/SpectrumRow.d.ts.map +1 -0
- package/lib/mass/ui/SpectrumRow.js +141 -0
- package/lib/mass/ui/SpectrumRow.js.map +1 -0
- package/lib/mass/ui/SpectrumTrace.d.ts +46 -0
- package/lib/mass/ui/SpectrumTrace.d.ts.map +1 -0
- package/lib/mass/ui/SpectrumTrace.js +68 -0
- package/lib/mass/ui/SpectrumTrace.js.map +1 -0
- package/lib/mass/ui/index.d.ts +69 -0
- package/lib/mass/ui/index.d.ts.map +1 -0
- package/lib/mass/ui/index.js +42 -0
- package/lib/mass/ui/index.js.map +1 -0
- package/lib/mass/ui/massActions.d.ts +52 -0
- package/lib/mass/ui/massActions.d.ts.map +1 -0
- package/lib/mass/ui/massActions.js +62 -0
- package/lib/mass/ui/massActions.js.map +1 -0
- package/lib/mass/ui/massChartProps.d.ts +128 -0
- package/lib/mass/ui/massChartProps.d.ts.map +1 -0
- package/lib/mass/ui/massChartProps.js +14 -0
- package/lib/mass/ui/massChartProps.js.map +1 -0
- package/lib/mass/ui/massCommandContext.d.ts +36 -0
- package/lib/mass/ui/massCommandContext.d.ts.map +1 -0
- package/lib/mass/ui/massCommandContext.js +45 -0
- package/lib/mass/ui/massCommandContext.js.map +1 -0
- package/lib/mass/ui/massHostPanels.d.ts +48 -0
- package/lib/mass/ui/massHostPanels.d.ts.map +1 -0
- package/lib/mass/ui/massHostPanels.js +41 -0
- package/lib/mass/ui/massHostPanels.js.map +1 -0
- package/lib/mass/ui/massStateContext.d.ts +26 -0
- package/lib/mass/ui/massStateContext.d.ts.map +1 -0
- package/lib/mass/ui/massStateContext.js +37 -0
- package/lib/mass/ui/massStateContext.js.map +1 -0
- package/lib/mass/ui/useIntensityZoom.d.ts +20 -0
- package/lib/mass/ui/useIntensityZoom.d.ts.map +1 -0
- package/lib/mass/ui/useIntensityZoom.js +42 -0
- package/lib/mass/ui/useIntensityZoom.js.map +1 -0
- package/lib/mass/ui/useMassEditor.d.ts +52 -0
- package/lib/mass/ui/useMassEditor.d.ts.map +1 -0
- package/lib/mass/ui/useMassEditor.js +93 -0
- package/lib/mass/ui/useMassEditor.js.map +1 -0
- package/lib/mass/ui/useMassFiles.d.ts +22 -0
- package/lib/mass/ui/useMassFiles.d.ts.map +1 -0
- package/lib/mass/ui/useMassFiles.js +71 -0
- package/lib/mass/ui/useMassFiles.js.map +1 -0
- package/lib/mass/ui/useMassHandle.d.ts +15 -0
- package/lib/mass/ui/useMassHandle.d.ts.map +1 -0
- package/lib/mass/ui/useMassHandle.js +35 -0
- package/lib/mass/ui/useMassHandle.js.map +1 -0
- package/lib/mass/ui/useMassPointer.d.ts +70 -0
- package/lib/mass/ui/useMassPointer.d.ts.map +1 -0
- package/lib/mass/ui/useMassPointer.js +57 -0
- package/lib/mass/ui/useMassPointer.js.map +1 -0
- package/lib/mass/ui/useMassShortcuts.d.ts +21 -0
- package/lib/mass/ui/useMassShortcuts.d.ts.map +1 -0
- package/lib/mass/ui/useMassShortcuts.js +66 -0
- package/lib/mass/ui/useMassShortcuts.js.map +1 -0
- package/lib/mass/ui/useMassSide.d.ts +27 -0
- package/lib/mass/ui/useMassSide.d.ts.map +1 -0
- package/lib/mass/ui/useMassSide.js +45 -0
- package/lib/mass/ui/useMassSide.js.map +1 -0
- package/lib/mass/ui/useMassZoom.d.ts +92 -0
- package/lib/mass/ui/useMassZoom.d.ts.map +1 -0
- package/lib/mass/ui/useMassZoom.js +65 -0
- package/lib/mass/ui/useMassZoom.js.map +1 -0
- package/lib/mass.d.ts +16 -0
- package/lib/mass.d.ts.map +1 -0
- package/lib/mass.js +16 -0
- package/lib/mass.js.map +1 -0
- package/lib/panel/ui/PanelRail.d.ts.map +1 -1
- package/lib/panel/ui/PanelRail.js +6 -1
- package/lib/panel/ui/PanelRail.js.map +1 -1
- package/lib/slides/ui/slideSanitizeSchema.d.ts +3 -2
- package/lib/slides/ui/slideSanitizeSchema.d.ts.map +1 -1
- package/lib/slides/ui/slideSanitizeSchema.js +82 -2
- package/lib/slides/ui/slideSanitizeSchema.js.map +1 -1
- package/package.json +6 -1
- package/src/about/core/providers.ts +7 -0
- package/src/about/ui/AboutProvidedBy.tsx +49 -0
- package/src/chart/ui/useChartPointer.ts +18 -4
- package/src/credits/core/credits.ts +53 -0
- package/src/download/core/drawingMarkup.ts +18 -1
- package/src/download/core/figurePng.ts +21 -8
- package/src/download/core/figureSvg.ts +5 -2
- package/src/download/core/figureTarget.ts +28 -3
- package/src/download/core/svgBounds.ts +21 -0
- package/src/download/core/svgToPng.ts +3 -4
- package/src/format/core/relativeTime.ts +29 -7
- package/src/host/core/connectHost.ts +77 -120
- package/src/host/core/hostOutputs.ts +197 -0
- package/src/host/core/index.ts +13 -7
- package/src/host/core/irKinds.ts +92 -0
- package/src/host/core/kinds.ts +16 -6
- package/src/host/core/protocol.ts +50 -8
- package/src/host/core/selectInputs.ts +145 -0
- package/src/host/testing/sciPeaks.ts +140 -0
- package/src/host/testing/standInHost.ts +30 -5
- package/src/host/ui/useHostConnection.ts +17 -8
- package/src/host-testing.ts +4 -0
- package/src/ir/core/handPicking.ts +154 -0
- package/src/ir/core/index.ts +14 -0
- package/src/ir/core/irBandState.ts +155 -0
- package/src/ir/core/irCommands.ts +7 -0
- package/src/ir/core/irPeaks.ts +79 -0
- package/src/ir/core/irReducer.ts +27 -34
- package/src/ir/core/irSpectrum.ts +16 -0
- package/src/ir/core/irState.ts +15 -8
- package/src/ir/core/pickBands.ts +46 -39
- package/src/ir/core/ramanBands.ts +2 -2
- package/src/ir/core/spectrumBands.ts +113 -0
- package/src/ir/ui/BandRow.tsx +20 -2
- package/src/ir/ui/BandsPanel.tsx +46 -88
- package/src/ir/ui/BandsToolbar.tsx +152 -0
- package/src/ir/ui/IrCanvas.tsx +22 -11
- package/src/ir/ui/IrChart.tsx +10 -1
- package/src/ir/ui/IrDocumentationDialog.tsx +7 -0
- package/src/ir/ui/IrEditor.tsx +4 -2
- package/src/ir/ui/IrShell.tsx +5 -0
- package/src/ir/ui/IrStatusBar.tsx +4 -1
- package/src/ir/ui/IrToolbar.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +2 -1
- package/src/ir/ui/irActions.ts +11 -0
- package/src/ir/ui/irChartProps.ts +4 -1
- package/src/ir/ui/useIrEditor.ts +21 -21
- package/src/locales/de.json +63 -0
- package/src/locales/en.json +63 -0
- package/src/locales/es.json +63 -0
- package/src/locales/fr.json +63 -0
- package/src/locales/it.json +63 -0
- package/src/mass/core/analyseSpectrum.ts +191 -0
- package/src/mass/core/ascendingTrace.ts +62 -0
- package/src/mass/core/centroidPeaks.ts +114 -0
- package/src/mass/core/detectMassFormat.ts +113 -0
- package/src/mass/core/downloadSpectra.ts +52 -0
- package/src/mass/core/fromJcamp.ts +151 -0
- package/src/mass/core/fromText.ts +58 -0
- package/src/mass/core/index.ts +194 -0
- package/src/mass/core/jcampTechnique.ts +87 -0
- package/src/mass/core/labelStackBox.ts +75 -0
- package/src/mass/core/labelledPeaks.ts +135 -0
- package/src/mass/core/loadMassSpectra.ts +86 -0
- package/src/mass/core/loadedMassSpectrum.ts +43 -0
- package/src/mass/core/massCommands.ts +156 -0
- package/src/mass/core/massDomain.ts +229 -0
- package/src/mass/core/massEditorApi.ts +68 -0
- package/src/mass/core/massFormat.ts +187 -0
- package/src/mass/core/massMeta.ts +239 -0
- package/src/mass/core/massReducer.ts +232 -0
- package/src/mass/core/massResolution.ts +169 -0
- package/src/mass/core/massSidePanels.ts +27 -0
- package/src/mass/core/massSpectrum.ts +220 -0
- package/src/mass/core/massState.ts +206 -0
- package/src/mass/core/massStateEdits.ts +104 -0
- package/src/mass/core/massSummary.ts +213 -0
- package/src/mass/core/mzDecimalsSetting.ts +52 -0
- package/src/mass/core/nearestPeak.ts +130 -0
- package/src/mass/core/peakLabelLines.ts +112 -0
- package/src/mass/core/peakLabelPlan.ts +246 -0
- package/src/mass/core/peakTable.ts +82 -0
- package/src/mass/core/resolutionOf.ts +100 -0
- package/src/mass/core/scanFilter.ts +119 -0
- package/src/mass/core/spectrumJcamp.ts +186 -0
- package/src/mass/core/toMassSpectrum.ts +126 -0
- package/src/mass/core/traceIcon.ts +105 -0
- package/src/mass/core/writtenResolution.ts +81 -0
- package/src/mass/ui/MassAboutDialog.tsx +89 -0
- package/src/mass/ui/MassCanvas.tsx +170 -0
- package/src/mass/ui/MassChart.tsx +266 -0
- package/src/mass/ui/MassCommandProvider.tsx +34 -0
- package/src/mass/ui/MassCommandTooltip.tsx +36 -0
- package/src/mass/ui/MassDocumentationDialog.tsx +136 -0
- package/src/mass/ui/MassEditor.tsx +130 -0
- package/src/mass/ui/MassHeader.tsx +38 -0
- package/src/mass/ui/MassLogo.tsx +84 -0
- package/src/mass/ui/MassPointerTracker.tsx +72 -0
- package/src/mass/ui/MassShell.tsx +237 -0
- package/src/mass/ui/MassSidePanel.tsx +107 -0
- package/src/mass/ui/MassStateProvider.tsx +32 -0
- package/src/mass/ui/MassStatusBar.tsx +108 -0
- package/src/mass/ui/MassToolbar.tsx +120 -0
- package/src/mass/ui/MetadataPanel.tsx +201 -0
- package/src/mass/ui/MzDecimalsMenu.tsx +86 -0
- package/src/mass/ui/PeakLabels.tsx +242 -0
- package/src/mass/ui/PeakTable.tsx +199 -0
- package/src/mass/ui/PeaksPanel.tsx +182 -0
- package/src/mass/ui/SpectraPanel.tsx +153 -0
- package/src/mass/ui/SpectrumRow.tsx +246 -0
- package/src/mass/ui/SpectrumTrace.tsx +119 -0
- package/src/mass/ui/index.ts +69 -0
- package/src/mass/ui/massActions.ts +109 -0
- package/src/mass/ui/massChartProps.ts +130 -0
- package/src/mass/ui/massCommandContext.tsx +65 -0
- package/src/mass/ui/massHostPanels.ts +71 -0
- package/src/mass/ui/massStateContext.ts +48 -0
- package/src/mass/ui/useIntensityZoom.ts +55 -0
- package/src/mass/ui/useMassEditor.ts +156 -0
- package/src/mass/ui/useMassFiles.ts +91 -0
- package/src/mass/ui/useMassHandle.ts +58 -0
- package/src/mass/ui/useMassPointer.ts +120 -0
- package/src/mass/ui/useMassShortcuts.ts +85 -0
- package/src/mass/ui/useMassSide.ts +63 -0
- package/src/mass/ui/useMassZoom.ts +157 -0
- package/src/mass.ts +16 -0
- package/src/panel/ui/PanelRail.tsx +5 -1
- package/src/slides/ui/slideSanitizeSchema.ts +86 -2
- package/styles/chrome.css +7 -0
- package/styles/slides.css +47 -0
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import type { CSSProperties, ReactElement } from 'react';
|
|
2
|
+
import { useMemo } from 'react';
|
|
3
|
+
|
|
4
|
+
import type { PlotRect } from '../../chart/core/chartGeometry.ts';
|
|
5
|
+
import type { ChartScale } from '../../chart/core/chartScale.ts';
|
|
6
|
+
import {
|
|
7
|
+
CHART_COLORS,
|
|
8
|
+
CHART_FONT,
|
|
9
|
+
LABEL_HALO,
|
|
10
|
+
LABEL_QUIET,
|
|
11
|
+
PEAK_LABEL,
|
|
12
|
+
} from '../../chart/core/chartTheme.ts';
|
|
13
|
+
import type { HoveredPeak } from '../core/labelStackBox.ts';
|
|
14
|
+
import type { MassSpectrum } from '../core/massSpectrum.ts';
|
|
15
|
+
import type { PeakLabelLineKind } from '../core/peakLabelLines.ts';
|
|
16
|
+
import { planPeakLabels } from '../core/peakLabelPlan.ts';
|
|
17
|
+
|
|
18
|
+
export interface PeakLabelsProps {
|
|
19
|
+
/**
|
|
20
|
+
* The spectrum whose peaks are labelled. Hand it the same one that was drawn:
|
|
21
|
+
* a mirrored half is drawn normalised, and labels computed from the spectrum
|
|
22
|
+
* as measured would float above sticks of another height.
|
|
23
|
+
*/
|
|
24
|
+
spectrum: MassSpectrum;
|
|
25
|
+
/** Where the plot sits, which is what a stack may not be pushed out of. */
|
|
26
|
+
plot: PlotRect;
|
|
27
|
+
/** The m/z axis as it is currently zoomed. */
|
|
28
|
+
xScale: ChartScale;
|
|
29
|
+
/**
|
|
30
|
+
* The intensity axis as it is currently zoomed. Reflect it and the labels
|
|
31
|
+
* follow the sticks downwards — together with `below`, which turns the stacks
|
|
32
|
+
* over.
|
|
33
|
+
*/
|
|
34
|
+
yScale: ChartScale;
|
|
35
|
+
/**
|
|
36
|
+
* How many peaks are labelled at most, the most intense first.
|
|
37
|
+
* @default DEFAULT_LABEL_LIMIT
|
|
38
|
+
*/
|
|
39
|
+
limit?: number;
|
|
40
|
+
/**
|
|
41
|
+
* Whether a peak whose charge was established says so.
|
|
42
|
+
* @default false
|
|
43
|
+
*/
|
|
44
|
+
showCharges?: boolean;
|
|
45
|
+
/**
|
|
46
|
+
* How many decimals the masses on screen are written with.
|
|
47
|
+
* @default 4
|
|
48
|
+
*/
|
|
49
|
+
mzDecimals?: number;
|
|
50
|
+
/**
|
|
51
|
+
* What explains each peak, keyed as `peakKey` keys it — the name a host
|
|
52
|
+
* writes on top of a stack.
|
|
53
|
+
* @default undefined
|
|
54
|
+
*/
|
|
55
|
+
annotationLabels?: ReadonlyMap<string, string>;
|
|
56
|
+
/**
|
|
57
|
+
* Whether the stacks hang under the sticks rather than standing over them,
|
|
58
|
+
* which is what the lower half of a mirrored pair wants.
|
|
59
|
+
* @default false
|
|
60
|
+
*/
|
|
61
|
+
below?: boolean;
|
|
62
|
+
/**
|
|
63
|
+
* The ink the stacks are written in — worth passing the spectrum's own colour
|
|
64
|
+
* on a chart holding several, where an unattributed m/z belongs to any of them.
|
|
65
|
+
* @default the theme's label colour
|
|
66
|
+
*/
|
|
67
|
+
color?: string;
|
|
68
|
+
/**
|
|
69
|
+
* What one unit of the measured intensity is written as.
|
|
70
|
+
* @default 1
|
|
71
|
+
*/
|
|
72
|
+
intensityScale?: number;
|
|
73
|
+
/**
|
|
74
|
+
* Called with the peak whose stack the pointer is resting on, `null` when it
|
|
75
|
+
* leaves. Without it the stacks answer no pointer at all.
|
|
76
|
+
* @default undefined
|
|
77
|
+
*/
|
|
78
|
+
onHover?: (peak: HoveredPeak | null) => void;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* The tops of the best peaks of one spectrum, and what each of them reads.
|
|
83
|
+
*
|
|
84
|
+
* Two things drawn together because they are one claim: a short mark on the tip
|
|
85
|
+
* of the picked peak, and the numbers written over it. The mark is the half that
|
|
86
|
+
* matters when the continuous trace is the one on screen — the centroid is then
|
|
87
|
+
* not drawn at all, and a stack of numbers floating over a peak shape says which
|
|
88
|
+
* region was picked but never which point of it, which is the number the stack
|
|
89
|
+
* is quoting. With the mark on the tip the two agree by construction.
|
|
90
|
+
*
|
|
91
|
+
* Which peaks are labelled is `planPeakLabels`'s to decide, and it follows the
|
|
92
|
+
* zoom: a survey of the whole spectrum labels its base peak and a few others,
|
|
93
|
+
* and the same spectrum zoomed onto one cluster labels every line in it. Every
|
|
94
|
+
* line is haloed and none of them is boxed: a number over a peak is written
|
|
95
|
+
* over whatever the plot has there, and the halo clears a hairline of chart from
|
|
96
|
+
* around each glyph, where a filled box would hide the very data it is about.
|
|
97
|
+
*
|
|
98
|
+
* The numbers take no pointer event; the room they occupy does, as one
|
|
99
|
+
* transparent rectangle per stack, and only when somebody asked for it — so a
|
|
100
|
+
* stack can be interrogated without becoming a control, while the crosshair
|
|
101
|
+
* underneath goes on following the pointer.
|
|
102
|
+
* @param props - Component props.
|
|
103
|
+
* @returns The marks and the labels, as SVG.
|
|
104
|
+
*/
|
|
105
|
+
export function PeakLabels(props: PeakLabelsProps): ReactElement {
|
|
106
|
+
const {
|
|
107
|
+
spectrum,
|
|
108
|
+
plot,
|
|
109
|
+
xScale,
|
|
110
|
+
yScale,
|
|
111
|
+
limit,
|
|
112
|
+
showCharges = false,
|
|
113
|
+
mzDecimals,
|
|
114
|
+
annotationLabels,
|
|
115
|
+
below = false,
|
|
116
|
+
color = CHART_COLORS.labelText,
|
|
117
|
+
intensityScale = 1,
|
|
118
|
+
onHover,
|
|
119
|
+
} = props;
|
|
120
|
+
|
|
121
|
+
const plans = useMemo(
|
|
122
|
+
() =>
|
|
123
|
+
planPeakLabels({
|
|
124
|
+
spectrum,
|
|
125
|
+
plot,
|
|
126
|
+
xScale,
|
|
127
|
+
yScale,
|
|
128
|
+
showCharges,
|
|
129
|
+
below,
|
|
130
|
+
intensityScale,
|
|
131
|
+
...(limit === undefined ? {} : { limit }),
|
|
132
|
+
...(mzDecimals === undefined ? {} : { mzDecimals }),
|
|
133
|
+
...(annotationLabels === undefined ? {} : { annotationLabels }),
|
|
134
|
+
}),
|
|
135
|
+
[
|
|
136
|
+
spectrum,
|
|
137
|
+
plot,
|
|
138
|
+
xScale,
|
|
139
|
+
yScale,
|
|
140
|
+
limit,
|
|
141
|
+
showCharges,
|
|
142
|
+
mzDecimals,
|
|
143
|
+
annotationLabels,
|
|
144
|
+
below,
|
|
145
|
+
intensityScale,
|
|
146
|
+
],
|
|
147
|
+
);
|
|
148
|
+
|
|
149
|
+
// Every picked peak is marked; only the ones that kept their room are
|
|
150
|
+
// written, since a stack over a peak whose neighbour took the room would be
|
|
151
|
+
// written across that neighbour's.
|
|
152
|
+
const written = useMemo(
|
|
153
|
+
() => plans.filter((plan) => Number.isFinite(plan.labelX)),
|
|
154
|
+
[plans],
|
|
155
|
+
);
|
|
156
|
+
|
|
157
|
+
const stackStyle = useMemo(
|
|
158
|
+
() => ({ fill: color, fontSize: CHART_FONT.label, ...LABEL_HALO }),
|
|
159
|
+
[color],
|
|
160
|
+
);
|
|
161
|
+
const markStyle = useMemo(() => ({ stroke: color }), [color]);
|
|
162
|
+
|
|
163
|
+
return (
|
|
164
|
+
<g>
|
|
165
|
+
{/* Its own group, because the stroke that draws a mark would outline every
|
|
166
|
+
glyph of a label sharing the group with it. */}
|
|
167
|
+
<g pointerEvents="none" style={markStyle}>
|
|
168
|
+
{plans.map((plan) => (
|
|
169
|
+
<line
|
|
170
|
+
key={plan.key}
|
|
171
|
+
x1={plan.tipX}
|
|
172
|
+
y1={plan.tipY}
|
|
173
|
+
x2={plan.tipX}
|
|
174
|
+
y2={
|
|
175
|
+
below
|
|
176
|
+
? plan.tipY - PEAK_LABEL.topMark
|
|
177
|
+
: plan.tipY + PEAK_LABEL.topMark
|
|
178
|
+
}
|
|
179
|
+
/>
|
|
180
|
+
))}
|
|
181
|
+
</g>
|
|
182
|
+
<g pointerEvents="none" style={stackStyle}>
|
|
183
|
+
{written.map((plan) => (
|
|
184
|
+
<text key={plan.key} textAnchor="middle">
|
|
185
|
+
{plan.lines.map((line, index) => (
|
|
186
|
+
<tspan
|
|
187
|
+
key={line.kind}
|
|
188
|
+
x={plan.labelX}
|
|
189
|
+
y={plan.baselines[index]}
|
|
190
|
+
style={LINE_STYLES[line.kind]}
|
|
191
|
+
>
|
|
192
|
+
{line.text}
|
|
193
|
+
</tspan>
|
|
194
|
+
))}
|
|
195
|
+
</text>
|
|
196
|
+
))}
|
|
197
|
+
</g>
|
|
198
|
+
{onHover === undefined
|
|
199
|
+
? null
|
|
200
|
+
: written.map((plan) => (
|
|
201
|
+
<rect
|
|
202
|
+
key={plan.key}
|
|
203
|
+
x={plan.box.x}
|
|
204
|
+
y={plan.box.y}
|
|
205
|
+
width={plan.box.width}
|
|
206
|
+
height={plan.box.height}
|
|
207
|
+
fill="transparent"
|
|
208
|
+
onPointerEnter={() =>
|
|
209
|
+
onHover({
|
|
210
|
+
key: plan.key,
|
|
211
|
+
mz: plan.peak.x,
|
|
212
|
+
intensity: plan.peak.y,
|
|
213
|
+
charge: plan.peak.charge,
|
|
214
|
+
x: plan.labelX,
|
|
215
|
+
// A card hangs off the edge of the stack facing away from the
|
|
216
|
+
// stick, so it never covers the peak it is about.
|
|
217
|
+
y: below ? plan.box.y + plan.box.height : plan.box.y,
|
|
218
|
+
})
|
|
219
|
+
}
|
|
220
|
+
onPointerLeave={() => onHover(null)}
|
|
221
|
+
/>
|
|
222
|
+
))}
|
|
223
|
+
</g>
|
|
224
|
+
);
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* How each line of a stack is set.
|
|
229
|
+
*
|
|
230
|
+
* Four numbers in one ink and one weight are four things said at once, and the
|
|
231
|
+
* eye has to read all of them to find the one it came for. So the stack is
|
|
232
|
+
* graded instead: the name of what the peak is carries the weight, because it is
|
|
233
|
+
* the only line that is an answer rather than a measurement; the m/z is written
|
|
234
|
+
* plain, which is what a chemist is nearly always reading; and the charge and
|
|
235
|
+
* the intensity are let back towards the paper.
|
|
236
|
+
*/
|
|
237
|
+
const LINE_STYLES: Record<PeakLabelLineKind, CSSProperties> = {
|
|
238
|
+
annotation: { fontWeight: 600 },
|
|
239
|
+
charge: { fillOpacity: LABEL_QUIET },
|
|
240
|
+
mz: {},
|
|
241
|
+
intensity: { fillOpacity: LABEL_QUIET },
|
|
242
|
+
};
|
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { memo, useMemo, useRef } from 'react';
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
panelCellStyle,
|
|
5
|
+
panelColumnButtonStyle,
|
|
6
|
+
panelNumberCellStyle,
|
|
7
|
+
panelScrollAreaStyle,
|
|
8
|
+
panelStickyHeaderStyle,
|
|
9
|
+
panelTableStyle,
|
|
10
|
+
} from '../../panel/core/panelStyles.ts';
|
|
11
|
+
import { useVirtualRows } from '../../panel/ui/useVirtualRows.ts';
|
|
12
|
+
import type { MassPeakObject } from '../core/centroidPeaks.ts';
|
|
13
|
+
import { formatIntensity, formatMz } from '../core/massFormat.ts';
|
|
14
|
+
|
|
15
|
+
/** Which column the rows are read in the order of. */
|
|
16
|
+
export type PeakSortKey = 'mz' | 'intensity';
|
|
17
|
+
|
|
18
|
+
export interface PeakTableProps {
|
|
19
|
+
/** The peaks to list, in increasing m/z. */
|
|
20
|
+
peaks: readonly MassPeakObject[];
|
|
21
|
+
/** How many decimals the masses are written with. */
|
|
22
|
+
mzDecimals: number;
|
|
23
|
+
/**
|
|
24
|
+
* Which column the rows are in the order of: m/z ascending, which is how a
|
|
25
|
+
* spectrum is read, or intensity descending, which is how its base peak and
|
|
26
|
+
* its neighbours are found.
|
|
27
|
+
*/
|
|
28
|
+
sortKey: PeakSortKey;
|
|
29
|
+
/** Order the rows by a column. */
|
|
30
|
+
onSort: (key: PeakSortKey) => void;
|
|
31
|
+
/** The m/z of the peak the pointer is resting on, `null` for none. */
|
|
32
|
+
highlightMz: number | null;
|
|
33
|
+
/** Told which peak a row the pointer rests on is, `null` when it leaves. */
|
|
34
|
+
onHighlight: (mz: number | null) => void;
|
|
35
|
+
/** Frame a peak on the chart. */
|
|
36
|
+
onPick: (mz: number) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* The peaks, one row each, under a header that sorts them.
|
|
41
|
+
*
|
|
42
|
+
* Only the rows in view are drawn: a table opened onto a whole Orbitrap scan is
|
|
43
|
+
* a thousand rows, and every one of them would otherwise be laid out again on
|
|
44
|
+
* every hover of the chart beside it.
|
|
45
|
+
* @param props - Component props.
|
|
46
|
+
* @returns The table.
|
|
47
|
+
*/
|
|
48
|
+
export function PeakTable(props: PeakTableProps) {
|
|
49
|
+
const {
|
|
50
|
+
peaks,
|
|
51
|
+
mzDecimals,
|
|
52
|
+
sortKey,
|
|
53
|
+
onSort,
|
|
54
|
+
highlightMz,
|
|
55
|
+
onHighlight,
|
|
56
|
+
onPick,
|
|
57
|
+
} = props;
|
|
58
|
+
const scrollRef = useRef<HTMLDivElement>(null);
|
|
59
|
+
|
|
60
|
+
const ordered = useMemo(
|
|
61
|
+
() =>
|
|
62
|
+
sortKey === 'mz'
|
|
63
|
+
? peaks
|
|
64
|
+
: peaks.toSorted((first, second) => second.y - first.y),
|
|
65
|
+
[peaks, sortKey],
|
|
66
|
+
);
|
|
67
|
+
const rows = useVirtualRows(scrollRef, ordered.length, ROW_HEIGHT);
|
|
68
|
+
const showsCharge = useMemo(
|
|
69
|
+
() => peaks.some((peak) => peak.charge !== 0),
|
|
70
|
+
[peaks],
|
|
71
|
+
);
|
|
72
|
+
|
|
73
|
+
return (
|
|
74
|
+
<div ref={scrollRef} style={panelScrollAreaStyle}>
|
|
75
|
+
<table style={panelTableStyle}>
|
|
76
|
+
<thead>
|
|
77
|
+
<tr>
|
|
78
|
+
<th style={panelStickyHeaderStyle}>
|
|
79
|
+
<button
|
|
80
|
+
type="button"
|
|
81
|
+
style={panelColumnButtonStyle}
|
|
82
|
+
onClick={() => onSort('mz')}
|
|
83
|
+
>
|
|
84
|
+
m/z{sortKey === 'mz' ? ' ▲' : ''}
|
|
85
|
+
</button>
|
|
86
|
+
</th>
|
|
87
|
+
<th style={panelStickyHeaderStyle}>
|
|
88
|
+
<button
|
|
89
|
+
type="button"
|
|
90
|
+
style={panelColumnButtonStyle}
|
|
91
|
+
onClick={() => onSort('intensity')}
|
|
92
|
+
>
|
|
93
|
+
intensity{sortKey === 'intensity' ? ' ▼' : ''}
|
|
94
|
+
</button>
|
|
95
|
+
</th>
|
|
96
|
+
{showsCharge ? (
|
|
97
|
+
<th style={panelStickyHeaderStyle}>
|
|
98
|
+
<span style={panelColumnButtonStyle}>z</span>
|
|
99
|
+
</th>
|
|
100
|
+
) : null}
|
|
101
|
+
</tr>
|
|
102
|
+
</thead>
|
|
103
|
+
<tbody onPointerLeave={() => onHighlight(null)}>
|
|
104
|
+
{rows.before > 0 ? <tr style={{ height: rows.before }} /> : null}
|
|
105
|
+
{rows.indices.map((index) => {
|
|
106
|
+
const peak = ordered[index] as MassPeakObject;
|
|
107
|
+
return (
|
|
108
|
+
<PeakRow
|
|
109
|
+
key={peak.x}
|
|
110
|
+
index={index}
|
|
111
|
+
peak={peak}
|
|
112
|
+
mzDecimals={mzDecimals}
|
|
113
|
+
showsCharge={showsCharge}
|
|
114
|
+
isHighlighted={peak.x === highlightMz}
|
|
115
|
+
measure={rows.measure}
|
|
116
|
+
onHighlight={onHighlight}
|
|
117
|
+
onPick={onPick}
|
|
118
|
+
/>
|
|
119
|
+
);
|
|
120
|
+
})}
|
|
121
|
+
{rows.after > 0 ? <tr style={{ height: rows.after }} /> : null}
|
|
122
|
+
</tbody>
|
|
123
|
+
</table>
|
|
124
|
+
</div>
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
interface PeakRowProps {
|
|
129
|
+
/** Where the row sits in the list, which is how its height is found again. */
|
|
130
|
+
index: number;
|
|
131
|
+
/** The peak. */
|
|
132
|
+
peak: MassPeakObject;
|
|
133
|
+
/** How many decimals the mass is written with. */
|
|
134
|
+
mzDecimals: number;
|
|
135
|
+
/** Whether the charge column is drawn. */
|
|
136
|
+
showsCharge: boolean;
|
|
137
|
+
/** Whether the pointer is resting on this peak, here or on the chart. */
|
|
138
|
+
isHighlighted: boolean;
|
|
139
|
+
/** Reports the row's height. */
|
|
140
|
+
measure: (node: HTMLElement | null) => void;
|
|
141
|
+
/** Told the peak's m/z when the pointer comes to rest on the row. */
|
|
142
|
+
onHighlight: (mz: number | null) => void;
|
|
143
|
+
/** Frames the peak on the chart. */
|
|
144
|
+
onPick: (mz: number) => void;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* One peak. Memoised, because a hover on the chart moves the highlight and only
|
|
149
|
+
* the row it left and the row it reached have anything new to draw.
|
|
150
|
+
*/
|
|
151
|
+
const PeakRow = memo(function PeakRow(props: PeakRowProps) {
|
|
152
|
+
const {
|
|
153
|
+
index,
|
|
154
|
+
peak,
|
|
155
|
+
mzDecimals,
|
|
156
|
+
showsCharge,
|
|
157
|
+
isHighlighted,
|
|
158
|
+
measure,
|
|
159
|
+
onHighlight,
|
|
160
|
+
onPick,
|
|
161
|
+
} = props;
|
|
162
|
+
return (
|
|
163
|
+
<tr
|
|
164
|
+
ref={measure}
|
|
165
|
+
data-index={index}
|
|
166
|
+
style={isHighlighted ? highlightedRowStyle : rowStyle}
|
|
167
|
+
title="Click to frame this peak on the chart"
|
|
168
|
+
// Reachable by Tab as well as by the pointer: framing a peak is the one
|
|
169
|
+
// thing a row does, and a keyboard has to be able to ask for it.
|
|
170
|
+
tabIndex={0}
|
|
171
|
+
onPointerEnter={() => onHighlight(peak.x)}
|
|
172
|
+
onFocus={() => onHighlight(peak.x)}
|
|
173
|
+
onClick={() => onPick(peak.x)}
|
|
174
|
+
onKeyDown={(event) => {
|
|
175
|
+
if (event.key !== 'Enter' && event.key !== ' ') return;
|
|
176
|
+
event.preventDefault();
|
|
177
|
+
onPick(peak.x);
|
|
178
|
+
}}
|
|
179
|
+
>
|
|
180
|
+
<td style={panelCellStyle}>{formatMz(peak.x, mzDecimals)}</td>
|
|
181
|
+
<td style={panelNumberCellStyle}>
|
|
182
|
+
{formatIntensity(peak.y, mzDecimals)}
|
|
183
|
+
</td>
|
|
184
|
+
{showsCharge ? (
|
|
185
|
+
<td style={panelNumberCellStyle}>
|
|
186
|
+
{peak.charge === 0 ? '' : peak.charge}
|
|
187
|
+
</td>
|
|
188
|
+
) : null}
|
|
189
|
+
</tr>
|
|
190
|
+
);
|
|
191
|
+
});
|
|
192
|
+
|
|
193
|
+
/** What one row is worth before one has been measured. */
|
|
194
|
+
const ROW_HEIGHT = 18;
|
|
195
|
+
|
|
196
|
+
const rowStyle = { cursor: 'pointer' } as const;
|
|
197
|
+
|
|
198
|
+
/** The row of the peak being looked at, wherever it was pointed at. */
|
|
199
|
+
const highlightedRowStyle = { ...rowStyle, background: '#e8f1fb' } as const;
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
2
|
+
import { SelectedTotal, Toolbar } from 'react-science/ui';
|
|
3
|
+
|
|
4
|
+
import { useCopyToClipboard } from '../../clipboard/ui/useCopyToClipboard.ts';
|
|
5
|
+
import {
|
|
6
|
+
panelBodyStyle,
|
|
7
|
+
panelEmptyStyle,
|
|
8
|
+
panelStyle,
|
|
9
|
+
panelToolbarCountStyle,
|
|
10
|
+
panelToolbarStyle,
|
|
11
|
+
} from '../../panel/core/panelStyles.ts';
|
|
12
|
+
import { mzFrame } from '../core/massDomain.ts';
|
|
13
|
+
import {
|
|
14
|
+
PEAK_TABLE_LIMIT,
|
|
15
|
+
PEAK_TABLE_THRESHOLD,
|
|
16
|
+
peakTableRows,
|
|
17
|
+
peakTableToTsv,
|
|
18
|
+
} from '../core/peakTable.ts';
|
|
19
|
+
|
|
20
|
+
import { MzDecimalsMenu } from './MzDecimalsMenu.tsx';
|
|
21
|
+
import type { PeakSortKey } from './PeakTable.tsx';
|
|
22
|
+
import { PeakTable } from './PeakTable.tsx';
|
|
23
|
+
import { useMassCommandProps } from './massCommandContext.tsx';
|
|
24
|
+
import { useMassActions, useMassEditorState } from './massStateContext.ts';
|
|
25
|
+
|
|
26
|
+
export interface PeaksPanelProps {
|
|
27
|
+
/**
|
|
28
|
+
* The m/z of the peak the pointer is resting on, wherever it was hovered.
|
|
29
|
+
* @default null
|
|
30
|
+
*/
|
|
31
|
+
highlightMz?: number | null;
|
|
32
|
+
/**
|
|
33
|
+
* Told which peak a row the pointer rests on is, `null` when it leaves.
|
|
34
|
+
* @default undefined
|
|
35
|
+
*/
|
|
36
|
+
onHighlight?: (mz: number | null) => void;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* What is actually in the selected spectrum, peak by peak.
|
|
41
|
+
*
|
|
42
|
+
* The centroid rather than the profile, because the centroid is what every
|
|
43
|
+
* number downstream is computed from — a profile lists the dozens of points one
|
|
44
|
+
* ion's peak shape covers, and none of them is the ion. For a profile these are
|
|
45
|
+
* the peaks the picking found in it.
|
|
46
|
+
*
|
|
47
|
+
* The window is the chart's by default: zoom into a cluster and the question
|
|
48
|
+
* becomes what is in *that* cluster, and a table that went on listing every row
|
|
49
|
+
* would have to be searched for the answer the chart is already pointing at. A
|
|
50
|
+
* floor of a hundredth of the base peak leaves the baseline out, and both are a
|
|
51
|
+
* toggle away. Resting on a row lights the peak on the chart, and clicking one
|
|
52
|
+
* frames it there.
|
|
53
|
+
* @param props - Component props.
|
|
54
|
+
* @returns The panel.
|
|
55
|
+
*/
|
|
56
|
+
export function PeaksPanel(props: PeaksPanelProps) {
|
|
57
|
+
const { highlightMz = null, onHighlight } = props;
|
|
58
|
+
const {
|
|
59
|
+
state,
|
|
60
|
+
visibleSpectra,
|
|
61
|
+
selectedSpectrum,
|
|
62
|
+
mzDecimals,
|
|
63
|
+
autoMzDecimals,
|
|
64
|
+
} = useMassEditorState();
|
|
65
|
+
const actions = useMassActions();
|
|
66
|
+
const command = useMassCommandProps();
|
|
67
|
+
const { domain } = state.view;
|
|
68
|
+
const { showLabels, showCharges } = state.settings;
|
|
69
|
+
|
|
70
|
+
const [inWindow, setInWindow] = useState(true);
|
|
71
|
+
const [withFloor, setWithFloor] = useState(true);
|
|
72
|
+
const [sortKey, setSortKey] = useState<PeakSortKey>('mz');
|
|
73
|
+
const { copied, copy } = useCopyToClipboard();
|
|
74
|
+
|
|
75
|
+
const peaks = useMemo(
|
|
76
|
+
() =>
|
|
77
|
+
selectedSpectrum === null
|
|
78
|
+
? []
|
|
79
|
+
: peakTableRows(selectedSpectrum, {
|
|
80
|
+
domain: inWindow ? domain : null,
|
|
81
|
+
threshold: withFloor ? PEAK_TABLE_THRESHOLD : 0,
|
|
82
|
+
}),
|
|
83
|
+
[selectedSpectrum, inWindow, domain, withFloor],
|
|
84
|
+
);
|
|
85
|
+
|
|
86
|
+
// Stable across a pointer move, so the memoised rows survive one.
|
|
87
|
+
const onPick = useCallback(
|
|
88
|
+
(mz: number) => actions.setDomain(mzFrame(mz, visibleSpectra, domain)),
|
|
89
|
+
[actions, visibleSpectra, domain],
|
|
90
|
+
);
|
|
91
|
+
const highlight = useCallback(
|
|
92
|
+
(mz: number | null) => onHighlight?.(mz),
|
|
93
|
+
[onHighlight],
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
const total = selectedSpectrum?.centroid.x.length ?? 0;
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<div style={panelStyle}>
|
|
100
|
+
<div style={panelToolbarStyle}>
|
|
101
|
+
<Toolbar aria-label="Peaks">
|
|
102
|
+
<Toolbar.Item
|
|
103
|
+
icon="zoom-to-fit"
|
|
104
|
+
active={inWindow}
|
|
105
|
+
tooltip="Only the peaks the chart is showing"
|
|
106
|
+
aria-label="Only the peaks the chart is showing"
|
|
107
|
+
onClick={() => setInWindow(!inWindow)}
|
|
108
|
+
/>
|
|
109
|
+
<Toolbar.Item
|
|
110
|
+
icon="filter"
|
|
111
|
+
active={withFloor}
|
|
112
|
+
tooltip="Leave out the peaks under 1 % of the base peak"
|
|
113
|
+
aria-label="Leave out the peaks under 1 % of the base peak"
|
|
114
|
+
onClick={() => setWithFloor(!withFloor)}
|
|
115
|
+
/>
|
|
116
|
+
<Toolbar.Item
|
|
117
|
+
icon="label"
|
|
118
|
+
active={showLabels}
|
|
119
|
+
{...command('toggleLabels')}
|
|
120
|
+
/>
|
|
121
|
+
<Toolbar.Item
|
|
122
|
+
icon="numerical"
|
|
123
|
+
active={showCharges}
|
|
124
|
+
{...command('toggleCharges')}
|
|
125
|
+
/>
|
|
126
|
+
<MzDecimalsMenu
|
|
127
|
+
setting={state.settings.mzDecimals}
|
|
128
|
+
autoDecimals={autoMzDecimals}
|
|
129
|
+
onChange={(setting) => actions.setSettings({ mzDecimals: setting })}
|
|
130
|
+
/>
|
|
131
|
+
<Toolbar.Item
|
|
132
|
+
icon={copied ? 'tick' : 'duplicate'}
|
|
133
|
+
tooltip="Copy the rows as tab-separated text"
|
|
134
|
+
aria-label="Copy the rows as tab-separated text"
|
|
135
|
+
disabled={peaks.length === 0}
|
|
136
|
+
onClick={() => void copy(peakTableToTsv(peaks, mzDecimals))}
|
|
137
|
+
/>
|
|
138
|
+
</Toolbar>
|
|
139
|
+
<div
|
|
140
|
+
style={panelToolbarCountStyle}
|
|
141
|
+
title={`${peaks.length} of the ${total} peaks of this spectrum listed`}
|
|
142
|
+
>
|
|
143
|
+
<SelectedTotal count={peaks.length} total={total} />
|
|
144
|
+
</div>
|
|
145
|
+
</div>
|
|
146
|
+
|
|
147
|
+
<div style={panelBodyStyle}>
|
|
148
|
+
{selectedSpectrum === null ? (
|
|
149
|
+
<p style={panelEmptyStyle}>
|
|
150
|
+
No spectrum is selected. Click one in the Spectra panel and its
|
|
151
|
+
peaks are listed here.
|
|
152
|
+
</p>
|
|
153
|
+
) : peaks.length === 0 ? (
|
|
154
|
+
<p style={panelEmptyStyle}>
|
|
155
|
+
No peak stands in the window above the floor. Zoom out, or switch
|
|
156
|
+
the window or the floor off in the toolbar.
|
|
157
|
+
</p>
|
|
158
|
+
) : (
|
|
159
|
+
<>
|
|
160
|
+
{peaks.length === PEAK_TABLE_LIMIT ? (
|
|
161
|
+
<p style={noteStyle}>
|
|
162
|
+
The {PEAK_TABLE_LIMIT} most intense peaks are listed. Zoom in to
|
|
163
|
+
list the rest.
|
|
164
|
+
</p>
|
|
165
|
+
) : null}
|
|
166
|
+
<PeakTable
|
|
167
|
+
peaks={peaks}
|
|
168
|
+
mzDecimals={mzDecimals}
|
|
169
|
+
sortKey={sortKey}
|
|
170
|
+
onSort={setSortKey}
|
|
171
|
+
highlightMz={highlightMz}
|
|
172
|
+
onHighlight={highlight}
|
|
173
|
+
onPick={onPick}
|
|
174
|
+
/>
|
|
175
|
+
</>
|
|
176
|
+
)}
|
|
177
|
+
</div>
|
|
178
|
+
</div>
|
|
179
|
+
);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
const noteStyle = { margin: 0, fontSize: 11, opacity: 0.7 } as const;
|