react-cheminfo 0.65.0 → 0.66.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 +11 -6
- package/lib/i18n/core/chromeCatalog.d.ts +1 -1
- package/lib/i18n/core/chromeCatalog.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.d.ts +23 -6
- package/lib/ir/core/analysisSpectra.d.ts.map +1 -1
- package/lib/ir/core/analysisSpectra.js.map +1 -1
- package/lib/ir/core/bandLabelPlan.d.ts.map +1 -1
- package/lib/ir/core/bandLabelPlan.js +11 -6
- package/lib/ir/core/bandLabelPlan.js.map +1 -1
- package/lib/ir/core/index.d.ts +13 -9
- package/lib/ir/core/index.d.ts.map +1 -1
- package/lib/ir/core/index.js +9 -6
- package/lib/ir/core/index.js.map +1 -1
- package/lib/ir/core/irBand.d.ts +45 -14
- package/lib/ir/core/irBand.d.ts.map +1 -1
- package/lib/ir/core/irBand.js +28 -6
- package/lib/ir/core/irBand.js.map +1 -1
- 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 +11 -1
- package/lib/ir/core/irCommands.js.map +1 -1
- package/lib/ir/core/irDomain.d.ts +4 -3
- package/lib/ir/core/irDomain.d.ts.map +1 -1
- package/lib/ir/core/irDomain.js +10 -7
- package/lib/ir/core/irDomain.js.map +1 -1
- package/lib/ir/core/irFormat.d.ts +14 -2
- package/lib/ir/core/irFormat.d.ts.map +1 -1
- package/lib/ir/core/irFormat.js +33 -4
- package/lib/ir/core/irFormat.js.map +1 -1
- package/lib/ir/core/irMode.d.ts +35 -8
- package/lib/ir/core/irMode.d.ts.map +1 -1
- package/lib/ir/core/irMode.js +38 -10
- package/lib/ir/core/irMode.js.map +1 -1
- package/lib/ir/core/irReducer.d.ts +0 -28
- package/lib/ir/core/irReducer.d.ts.map +1 -1
- package/lib/ir/core/irReducer.js +1 -24
- package/lib/ir/core/irReducer.js.map +1 -1
- package/lib/ir/core/irSpectrum.d.ts +52 -26
- package/lib/ir/core/irSpectrum.d.ts.map +1 -1
- package/lib/ir/core/irSpectrum.js +21 -15
- package/lib/ir/core/irSpectrum.js.map +1 -1
- package/lib/ir/core/irState.d.ts +40 -2
- package/lib/ir/core/irState.d.ts.map +1 -1
- package/lib/ir/core/irState.js +38 -1
- package/lib/ir/core/irState.js.map +1 -1
- package/lib/ir/core/irTechnique.d.ts +94 -0
- package/lib/ir/core/irTechnique.d.ts.map +1 -0
- package/lib/ir/core/irTechnique.js +87 -0
- package/lib/ir/core/irTechnique.js.map +1 -0
- package/lib/ir/core/irTechniqueCommands.d.ts +26 -0
- package/lib/ir/core/irTechniqueCommands.d.ts.map +1 -0
- package/lib/ir/core/irTechniqueCommands.js +68 -0
- package/lib/ir/core/irTechniqueCommands.js.map +1 -0
- package/lib/ir/core/pickBands.d.ts +6 -5
- package/lib/ir/core/pickBands.d.ts.map +1 -1
- package/lib/ir/core/pickBands.js +49 -26
- package/lib/ir/core/pickBands.js.map +1 -1
- package/lib/ir/core/ramanBands.d.ts +30 -0
- package/lib/ir/core/ramanBands.d.ts.map +1 -0
- package/lib/ir/core/ramanBands.js +83 -0
- package/lib/ir/core/ramanBands.js.map +1 -0
- package/lib/ir/core/spectrumJcamp.d.ts +10 -5
- package/lib/ir/core/spectrumJcamp.d.ts.map +1 -1
- package/lib/ir/core/spectrumJcamp.js +63 -15
- package/lib/ir/core/spectrumJcamp.js.map +1 -1
- package/lib/ir/core/toIrSpectrum.d.ts.map +1 -1
- package/lib/ir/core/toIrSpectrum.js +17 -2
- package/lib/ir/core/toIrSpectrum.js.map +1 -1
- package/lib/ir/ui/BandRow.d.ts +30 -0
- package/lib/ir/ui/BandRow.d.ts.map +1 -0
- package/lib/ir/ui/BandRow.js +42 -0
- package/lib/ir/ui/BandRow.js.map +1 -0
- package/lib/ir/ui/BandsPanel.d.ts +4 -0
- package/lib/ir/ui/BandsPanel.d.ts.map +1 -1
- package/lib/ir/ui/BandsPanel.js +14 -59
- package/lib/ir/ui/BandsPanel.js.map +1 -1
- package/lib/ir/ui/IrAboutDialog.d.ts +7 -0
- package/lib/ir/ui/IrAboutDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrAboutDialog.js +16 -3
- package/lib/ir/ui/IrAboutDialog.js.map +1 -1
- package/lib/ir/ui/IrCanvas.d.ts.map +1 -1
- package/lib/ir/ui/IrCanvas.js +2 -2
- package/lib/ir/ui/IrCanvas.js.map +1 -1
- package/lib/ir/ui/IrChart.d.ts +2 -1
- package/lib/ir/ui/IrChart.d.ts.map +1 -1
- package/lib/ir/ui/IrChart.js +18 -21
- package/lib/ir/ui/IrChart.js.map +1 -1
- package/lib/ir/ui/IrCommandProvider.d.ts +7 -0
- package/lib/ir/ui/IrCommandProvider.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandProvider.js +2 -2
- package/lib/ir/ui/IrCommandProvider.js.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.d.ts +7 -0
- package/lib/ir/ui/IrCommandTooltip.d.ts.map +1 -1
- package/lib/ir/ui/IrCommandTooltip.js +3 -2
- package/lib/ir/ui/IrCommandTooltip.js.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts +8 -1
- package/lib/ir/ui/IrDocumentationDialog.d.ts.map +1 -1
- package/lib/ir/ui/IrDocumentationDialog.js +30 -7
- package/lib/ir/ui/IrDocumentationDialog.js.map +1 -1
- package/lib/ir/ui/IrEditor.d.ts +3 -1
- package/lib/ir/ui/IrEditor.d.ts.map +1 -1
- package/lib/ir/ui/IrEditor.js +3 -20
- package/lib/ir/ui/IrEditor.js.map +1 -1
- package/lib/ir/ui/IrHeader.d.ts.map +1 -1
- package/lib/ir/ui/IrHeader.js +5 -1
- package/lib/ir/ui/IrHeader.js.map +1 -1
- package/lib/ir/ui/IrLogo.d.ts +11 -3
- package/lib/ir/ui/IrLogo.d.ts.map +1 -1
- package/lib/ir/ui/IrLogo.js +14 -5
- package/lib/ir/ui/IrLogo.js.map +1 -1
- package/lib/ir/ui/IrShell.d.ts.map +1 -1
- package/lib/ir/ui/IrShell.js +23 -56
- package/lib/ir/ui/IrShell.js.map +1 -1
- package/lib/ir/ui/IrStatusBar.d.ts +3 -2
- package/lib/ir/ui/IrStatusBar.d.ts.map +1 -1
- package/lib/ir/ui/IrStatusBar.js +14 -9
- package/lib/ir/ui/IrStatusBar.js.map +1 -1
- package/lib/ir/ui/IrToolbar.d.ts +3 -0
- package/lib/ir/ui/IrToolbar.d.ts.map +1 -1
- package/lib/ir/ui/IrToolbar.js +10 -3
- package/lib/ir/ui/IrToolbar.js.map +1 -1
- package/lib/ir/ui/IrTraces.d.ts +4 -1
- package/lib/ir/ui/IrTraces.d.ts.map +1 -1
- package/lib/ir/ui/IrTraces.js +2 -0
- package/lib/ir/ui/IrTraces.js.map +1 -1
- package/lib/ir/ui/RamanEditor.d.ts +46 -0
- package/lib/ir/ui/RamanEditor.d.ts.map +1 -0
- package/lib/ir/ui/RamanEditor.js +17 -0
- package/lib/ir/ui/RamanEditor.js.map +1 -0
- package/lib/ir/ui/SpectraPanel.d.ts.map +1 -1
- package/lib/ir/ui/SpectraPanel.js +2 -2
- package/lib/ir/ui/SpectraPanel.js.map +1 -1
- package/lib/ir/ui/SpectrumRow.d.ts +7 -0
- package/lib/ir/ui/SpectrumRow.d.ts.map +1 -1
- package/lib/ir/ui/SpectrumRow.js +4 -5
- package/lib/ir/ui/SpectrumRow.js.map +1 -1
- package/lib/ir/ui/VibrationalEditor.d.ts +48 -0
- package/lib/ir/ui/VibrationalEditor.d.ts.map +1 -0
- package/lib/ir/ui/VibrationalEditor.js +31 -0
- package/lib/ir/ui/VibrationalEditor.js.map +1 -0
- package/lib/ir/ui/bandsTsv.d.ts +19 -0
- package/lib/ir/ui/bandsTsv.d.ts.map +1 -0
- package/lib/ir/ui/bandsTsv.js +38 -0
- package/lib/ir/ui/bandsTsv.js.map +1 -0
- package/lib/ir/ui/irChartProps.d.ts +14 -4
- package/lib/ir/ui/irChartProps.d.ts.map +1 -1
- package/lib/ir/ui/irChartProps.js +3 -2
- package/lib/ir/ui/irChartProps.js.map +1 -1
- package/lib/ir/ui/irCommandContext.d.ts +8 -0
- package/lib/ir/ui/irCommandContext.d.ts.map +1 -1
- package/lib/ir/ui/irCommandContext.js +14 -3
- package/lib/ir/ui/irCommandContext.js.map +1 -1
- package/lib/ir/ui/useIrEditor.d.ts +3 -3
- package/lib/ir/ui/useIrEditor.d.ts.map +1 -1
- package/lib/ir/ui/useIrEditor.js +13 -4
- package/lib/ir/ui/useIrEditor.js.map +1 -1
- package/lib/ir/ui/useIrHandle.d.ts +14 -0
- package/lib/ir/ui/useIrHandle.d.ts.map +1 -0
- package/lib/ir/ui/useIrHandle.js +39 -0
- package/lib/ir/ui/useIrHandle.js.map +1 -0
- package/lib/ir/ui/useIrText.d.ts +40 -0
- package/lib/ir/ui/useIrText.d.ts.map +1 -0
- package/lib/ir/ui/useIrText.js +118 -0
- package/lib/ir/ui/useIrText.js.map +1 -0
- package/lib/ir/ui/useIrZoom.d.ts +7 -0
- package/lib/ir/ui/useIrZoom.d.ts.map +1 -1
- package/lib/ir/ui/useIrZoom.js +5 -4
- package/lib/ir/ui/useIrZoom.js.map +1 -1
- package/lib/ir/ui/useValueAxisZoom.d.ts +20 -0
- package/lib/ir/ui/useValueAxisZoom.d.ts.map +1 -0
- package/lib/ir/ui/useValueAxisZoom.js +54 -0
- package/lib/ir/ui/useValueAxisZoom.js.map +1 -0
- package/lib/ir.d.ts +3 -0
- package/lib/ir.d.ts.map +1 -1
- package/lib/ir.js +3 -0
- package/lib/ir.js.map +1 -1
- package/lib/locales/de.json +20 -1
- package/lib/locales/en.json +20 -1
- package/lib/locales/es.json +20 -1
- package/lib/locales/fr.json +20 -1
- package/lib/locales/it.json +20 -1
- package/lib/raman.d.ts +16 -0
- package/lib/raman.d.ts.map +1 -0
- package/lib/raman.js +12 -0
- package/lib/raman.js.map +1 -0
- package/package.json +2 -1
- package/src/ir/core/analysisSpectra.ts +26 -10
- package/src/ir/core/bandLabelPlan.ts +21 -10
- package/src/ir/core/index.ts +25 -5
- package/src/ir/core/irBand.ts +52 -14
- package/src/ir/core/irCommands.ts +15 -1
- package/src/ir/core/irDomain.ts +9 -7
- package/src/ir/core/irFormat.ts +39 -6
- package/src/ir/core/irMode.ts +42 -10
- package/src/ir/core/irReducer.ts +1 -49
- package/src/ir/core/irSpectrum.ts +59 -30
- package/src/ir/core/irState.ts +67 -2
- package/src/ir/core/irTechnique.ts +115 -0
- package/src/ir/core/irTechniqueCommands.ts +82 -0
- package/src/ir/core/pickBands.ts +63 -28
- package/src/ir/core/ramanBands.ts +105 -0
- package/src/ir/core/spectrumJcamp.ts +65 -16
- package/src/ir/core/toIrSpectrum.ts +20 -2
- package/src/ir/ui/BandRow.tsx +107 -0
- package/src/ir/ui/BandsPanel.tsx +32 -125
- package/src/ir/ui/IrAboutDialog.tsx +69 -28
- package/src/ir/ui/IrCanvas.tsx +2 -1
- package/src/ir/ui/IrChart.tsx +20 -24
- package/src/ir/ui/IrCommandProvider.tsx +10 -3
- package/src/ir/ui/IrCommandTooltip.tsx +11 -2
- package/src/ir/ui/IrDocumentationDialog.tsx +99 -55
- package/src/ir/ui/IrEditor.tsx +5 -36
- package/src/ir/ui/IrHeader.tsx +10 -3
- package/src/ir/ui/IrLogo.tsx +28 -9
- package/src/ir/ui/IrShell.tsx +27 -75
- package/src/ir/ui/IrStatusBar.tsx +17 -12
- package/src/ir/ui/IrToolbar.tsx +26 -15
- package/src/ir/ui/IrTraces.tsx +5 -1
- package/src/ir/ui/RamanEditor.tsx +53 -0
- package/src/ir/ui/SpectraPanel.tsx +2 -1
- package/src/ir/ui/SpectrumRow.tsx +14 -5
- package/src/ir/ui/VibrationalEditor.tsx +94 -0
- package/src/ir/ui/bandsTsv.ts +46 -0
- package/src/ir/ui/irChartProps.ts +14 -4
- package/src/ir/ui/irCommandContext.tsx +18 -3
- package/src/ir/ui/useIrEditor.ts +20 -8
- package/src/ir/ui/useIrHandle.ts +51 -0
- package/src/ir/ui/useIrText.ts +170 -0
- package/src/ir/ui/useIrZoom.ts +12 -3
- package/src/ir/ui/useValueAxisZoom.ts +67 -0
- package/src/ir.ts +3 -0
- package/src/locales/de.json +20 -1
- package/src/locales/en.json +20 -1
- package/src/locales/es.json +20 -1
- package/src/locales/fr.json +20 -1
- package/src/locales/it.json +20 -1
- package/src/raman.ts +19 -0
package/src/ir/ui/IrLogo.tsx
CHANGED
|
@@ -1,24 +1,37 @@
|
|
|
1
|
+
import type { IrTechnique } from '../core/irTechnique.ts';
|
|
2
|
+
|
|
3
|
+
import { useIrText } from './useIrText.ts';
|
|
4
|
+
|
|
1
5
|
export interface IrLogoProps {
|
|
2
6
|
/**
|
|
3
7
|
* How big to draw it, in pixels.
|
|
4
8
|
* @default 16
|
|
5
9
|
*/
|
|
6
10
|
size?: number;
|
|
11
|
+
/**
|
|
12
|
+
* What the spectra were measured with, which decides which way the bands
|
|
13
|
+
* point.
|
|
14
|
+
* @default 'infrared'
|
|
15
|
+
*/
|
|
16
|
+
technique?: IrTechnique;
|
|
7
17
|
}
|
|
8
18
|
|
|
9
19
|
/**
|
|
10
|
-
* The viewer's mark: three bands
|
|
20
|
+
* The viewer's mark: three bands meeting a baseline.
|
|
11
21
|
*
|
|
12
22
|
* Drawn from the domain's own primitives rather than being a picture of a chart —
|
|
13
23
|
* a transmittance baseline near the top with a strong band, a medium one and a
|
|
14
24
|
* weak one dropping out of it, which is what an infrared spectrum looks like at a
|
|
15
|
-
* glance and what nothing else looks like.
|
|
16
|
-
*
|
|
25
|
+
* glance and what nothing else looks like. A Raman spectrum's bands stand up from
|
|
26
|
+
* a baseline near the foot instead, so its mark is the same three bands rising.
|
|
27
|
+
* Three elements, because that is what survives 16 pixels.
|
|
17
28
|
* @param props - Component props.
|
|
18
29
|
* @returns The mark, as SVG.
|
|
19
30
|
*/
|
|
20
31
|
export function IrLogo(props: IrLogoProps) {
|
|
21
|
-
const { size = 16 } = props;
|
|
32
|
+
const { size = 16, technique = 'infrared' } = props;
|
|
33
|
+
const { mark } = useIrText(technique);
|
|
34
|
+
const { baseline, bands } = MARKS[technique];
|
|
22
35
|
|
|
23
36
|
return (
|
|
24
37
|
<svg
|
|
@@ -26,19 +39,19 @@ export function IrLogo(props: IrLogoProps) {
|
|
|
26
39
|
height={size}
|
|
27
40
|
viewBox="0 0 16 16"
|
|
28
41
|
role="img"
|
|
29
|
-
aria-label=
|
|
42
|
+
aria-label={mark}
|
|
30
43
|
>
|
|
31
|
-
{/* The baseline
|
|
44
|
+
{/* The baseline: high up where 100 % transmittance runs, low for Raman. */}
|
|
32
45
|
<path
|
|
33
|
-
d=
|
|
46
|
+
d={baseline}
|
|
34
47
|
fill="none"
|
|
35
48
|
stroke="#94a3b8"
|
|
36
49
|
strokeWidth={1}
|
|
37
50
|
strokeLinecap="round"
|
|
38
51
|
/>
|
|
39
|
-
{/* Three bands
|
|
52
|
+
{/* Three bands meeting it, strong, medium, weak. */}
|
|
40
53
|
<path
|
|
41
|
-
d=
|
|
54
|
+
d={bands}
|
|
42
55
|
fill="none"
|
|
43
56
|
stroke="#0072b2"
|
|
44
57
|
strokeWidth={2}
|
|
@@ -47,3 +60,9 @@ export function IrLogo(props: IrLogoProps) {
|
|
|
47
60
|
</svg>
|
|
48
61
|
);
|
|
49
62
|
}
|
|
63
|
+
|
|
64
|
+
/** The two strokes of each technique's mark. */
|
|
65
|
+
const MARKS: Record<IrTechnique, { baseline: string; bands: string }> = {
|
|
66
|
+
infrared: { baseline: 'M1 3H15', bands: 'M3 3V13M8 3V8.5M12.5 3V6' },
|
|
67
|
+
raman: { baseline: 'M1 13H15', bands: 'M3 13V3M8 13V7.5M12.5 13V10' },
|
|
68
|
+
};
|
package/src/ir/ui/IrShell.tsx
CHANGED
|
@@ -1,11 +1,5 @@
|
|
|
1
1
|
import type { Ref } from 'react';
|
|
2
|
-
import {
|
|
3
|
-
useCallback,
|
|
4
|
-
useId,
|
|
5
|
-
useImperativeHandle,
|
|
6
|
-
useMemo,
|
|
7
|
-
useState,
|
|
8
|
-
} from 'react';
|
|
2
|
+
import { useId, useMemo, useState } from 'react';
|
|
9
3
|
import { SplitPane, useFullscreen } from 'react-science/ui';
|
|
10
4
|
|
|
11
5
|
import { sanitizeFileName } from '../../download/core/sanitizeFileName.ts';
|
|
@@ -13,12 +7,12 @@ import { useFigureDownload } from '../../download/ui/useFigureDownload.tsx';
|
|
|
13
7
|
import { PanelRail } from '../../panel/ui/PanelRail.tsx';
|
|
14
8
|
import type { IrBand } from '../core/irBand.ts';
|
|
15
9
|
import type { IrCommandHandlers } from '../core/irCommands.ts';
|
|
16
|
-
import {
|
|
17
|
-
import
|
|
18
|
-
import { otherIrMode, yAxisRules } from '../core/irMode.ts';
|
|
10
|
+
import type { IrEditorHandle } from '../core/irEditorApi.ts';
|
|
11
|
+
import { otherIrMode } from '../core/irMode.ts';
|
|
19
12
|
import { irSidePanels } from '../core/irSidePanels.ts';
|
|
20
|
-
import type {
|
|
13
|
+
import type { IrSpectrum } from '../core/irSpectrum.ts';
|
|
21
14
|
import { DEFAULT_SIDE_PANEL } from '../core/irState.ts';
|
|
15
|
+
import { irCommandOffered } from '../core/irTechniqueCommands.ts';
|
|
22
16
|
|
|
23
17
|
import { IrAboutDialog } from './IrAboutDialog.tsx';
|
|
24
18
|
import { IrCanvas } from './IrCanvas.tsx';
|
|
@@ -28,7 +22,9 @@ import { IrHeader } from './IrHeader.tsx';
|
|
|
28
22
|
import { IrSidePanel } from './IrSidePanel.tsx';
|
|
29
23
|
import { IrToolbar } from './IrToolbar.tsx';
|
|
30
24
|
import { useIrActions, useIrEditorState } from './irStateContext.ts';
|
|
25
|
+
import { useIrHandle } from './useIrHandle.ts';
|
|
31
26
|
import { useIrShortcuts } from './useIrShortcuts.ts';
|
|
27
|
+
import { useValueAxisZoom } from './useValueAxisZoom.ts';
|
|
32
28
|
|
|
33
29
|
export interface IrShellProps {
|
|
34
30
|
/**
|
|
@@ -58,8 +54,8 @@ export function IrShell(props: IrShellProps) {
|
|
|
58
54
|
const { state, visibleSpectra, selectedSpectrum } = useIrEditorState();
|
|
59
55
|
const actions = useIrActions();
|
|
60
56
|
const { toggle: toggleFullScreen } = useFullscreen();
|
|
61
|
-
const { openPanelIds, tool
|
|
62
|
-
const { mode, pickBands, showAssignments } = state.settings;
|
|
57
|
+
const { openPanelIds, tool } = state.view;
|
|
58
|
+
const { mode, pickBands, showAssignments, technique } = state.settings;
|
|
63
59
|
|
|
64
60
|
const [isAboutOpen, setIsAboutOpen] = useState(false);
|
|
65
61
|
const [isDocumentationOpen, setIsDocumentationOpen] = useState(false);
|
|
@@ -79,27 +75,7 @@ export function IrShell(props: IrShellProps) {
|
|
|
79
75
|
// times a second.
|
|
80
76
|
const [highlight, setHighlight] = useState<IrBand | null>(null);
|
|
81
77
|
|
|
82
|
-
|
|
83
|
-
* ChartScale the value axis by a factor, about the baseline the mode hangs from.
|
|
84
|
-
* @param factor - Above one to zoom out.
|
|
85
|
-
*/
|
|
86
|
-
const scaleValueAxis = useCallback(
|
|
87
|
-
(factor: number) => {
|
|
88
|
-
const shown = domain ?? fullDomain(visibleSpectra, mode);
|
|
89
|
-
// Asked of the mode rather than written out again here: the baseline a
|
|
90
|
-
// value axis is scaled about is `irMode`'s to know, and a second copy of
|
|
91
|
-
// it is a second thing to get wrong.
|
|
92
|
-
const { baseline = 0 } = yAxisRules(mode);
|
|
93
|
-
actions.setDomain({
|
|
94
|
-
x: shown.x,
|
|
95
|
-
y: [
|
|
96
|
-
baseline + (shown.y[0] - baseline) * factor,
|
|
97
|
-
baseline + (shown.y[1] - baseline) * factor,
|
|
98
|
-
],
|
|
99
|
-
});
|
|
100
|
-
},
|
|
101
|
-
[actions, domain, visibleSpectra, mode],
|
|
102
|
-
);
|
|
78
|
+
const { zoomIn, zoomOut } = useValueAxisZoom();
|
|
103
79
|
|
|
104
80
|
const commands = useMemo<IrCommandHandlers>(
|
|
105
81
|
() => ({
|
|
@@ -108,13 +84,18 @@ export function IrShell(props: IrShellProps) {
|
|
|
108
84
|
fullScreen: toggleFullScreen,
|
|
109
85
|
readTool: () => actions.setTool('read'),
|
|
110
86
|
boxTool: () => actions.setTool(tool === 'box' ? 'read' : 'box'),
|
|
111
|
-
zoomIn
|
|
112
|
-
zoomOut
|
|
87
|
+
zoomIn,
|
|
88
|
+
zoomOut,
|
|
113
89
|
resetZoom: () => actions.resetDomain(),
|
|
114
|
-
|
|
90
|
+
// A command the technique does not offer has no handler, so its key
|
|
91
|
+
// stays with the page.
|
|
92
|
+
toggleMode: irCommandOffered(technique, 'toggleMode')
|
|
93
|
+
? () => actions.setSettings({ mode: otherIrMode(mode, technique) })
|
|
94
|
+
: undefined,
|
|
115
95
|
togglePicking: () => actions.setSettings({ pickBands: !pickBands }),
|
|
116
|
-
toggleAssignments: ()
|
|
117
|
-
actions.setSettings({ showAssignments: !showAssignments })
|
|
96
|
+
toggleAssignments: irCommandOffered(technique, 'toggleAssignments')
|
|
97
|
+
? () => actions.setSettings({ showAssignments: !showAssignments })
|
|
98
|
+
: undefined,
|
|
118
99
|
exportImage: () => setFigureOpen(!isFigureOpen),
|
|
119
100
|
clear: () => actions.clear(),
|
|
120
101
|
}),
|
|
@@ -122,9 +103,11 @@ export function IrShell(props: IrShellProps) {
|
|
|
122
103
|
actions,
|
|
123
104
|
tool,
|
|
124
105
|
mode,
|
|
106
|
+
technique,
|
|
125
107
|
pickBands,
|
|
126
108
|
showAssignments,
|
|
127
|
-
|
|
109
|
+
zoomIn,
|
|
110
|
+
zoomOut,
|
|
128
111
|
toggleFullScreen,
|
|
129
112
|
isFigureOpen,
|
|
130
113
|
setFigureOpen,
|
|
@@ -137,28 +120,7 @@ export function IrShell(props: IrShellProps) {
|
|
|
137
120
|
// again.
|
|
138
121
|
const [root, setRoot] = useState<HTMLElement | null>(null);
|
|
139
122
|
useIrShortcuts(root, commands);
|
|
140
|
-
|
|
141
|
-
useImperativeHandle(
|
|
142
|
-
handle,
|
|
143
|
-
(): IrEditorHandle => ({
|
|
144
|
-
getSpectra: () => state.data.spectra,
|
|
145
|
-
setSpectra: (spectra) => actions.setSpectra(spectra),
|
|
146
|
-
addSpectra: (spectra) => actions.addSpectra(spectra),
|
|
147
|
-
clear: () => actions.clear(),
|
|
148
|
-
setDomain: (next) => actions.setDomain(next),
|
|
149
|
-
resetDomain: () => actions.resetDomain(),
|
|
150
|
-
zoomToWavenumber: (wavenumber, options: ZoomToBandOptions = {}) => {
|
|
151
|
-
const { width = DEFAULT_FRAME_WIDTH } = options;
|
|
152
|
-
const shown: IrDomain = domain ?? fullDomain(visibleSpectra, mode);
|
|
153
|
-
actions.setDomain({
|
|
154
|
-
x: [wavenumber - width / 2, wavenumber + width / 2],
|
|
155
|
-
y: shown.y,
|
|
156
|
-
});
|
|
157
|
-
},
|
|
158
|
-
selectSpectrum: (id) => actions.selectSpectrum(id),
|
|
159
|
-
}),
|
|
160
|
-
[state.data.spectra, actions, domain, visibleSpectra, mode],
|
|
161
|
-
);
|
|
123
|
+
useIrHandle(handle);
|
|
162
124
|
|
|
163
125
|
/**
|
|
164
126
|
* Open or close the side, as the splitter is dragged shut and back open.
|
|
@@ -175,7 +137,7 @@ export function IrShell(props: IrShellProps) {
|
|
|
175
137
|
}
|
|
176
138
|
|
|
177
139
|
return (
|
|
178
|
-
<IrCommandProvider handlers={commands}>
|
|
140
|
+
<IrCommandProvider handlers={commands} technique={technique}>
|
|
179
141
|
{/* `tabIndex` so a click anywhere in the viewer makes this the target the
|
|
180
142
|
shortcuts are heard on: keys are delivered to whatever holds the caret,
|
|
181
143
|
and an SVG never does. */}
|
|
@@ -221,27 +183,17 @@ export function IrShell(props: IrShellProps) {
|
|
|
221
183
|
<IrAboutDialog
|
|
222
184
|
isOpen={isAboutOpen}
|
|
223
185
|
onClose={() => setIsAboutOpen(false)}
|
|
186
|
+
technique={technique}
|
|
224
187
|
/>
|
|
225
188
|
<IrDocumentationDialog
|
|
226
189
|
isOpen={isDocumentationOpen}
|
|
227
190
|
onClose={() => setIsDocumentationOpen(false)}
|
|
191
|
+
technique={technique}
|
|
228
192
|
/>
|
|
229
193
|
</IrCommandProvider>
|
|
230
194
|
);
|
|
231
195
|
}
|
|
232
196
|
|
|
233
|
-
/**
|
|
234
|
-
* What one press of zoom in or out is worth.
|
|
235
|
-
*
|
|
236
|
-
* A fifth, which is about what one notch of a mouse wheel does — so the button
|
|
237
|
-
* and the wheel feel like the same gesture at two speeds rather than two
|
|
238
|
-
* different ones.
|
|
239
|
-
*/
|
|
240
|
-
const ZOOM_STEP = 1.2;
|
|
241
|
-
|
|
242
|
-
/** How wide a window a host gets when it asks to frame a band without saying. */
|
|
243
|
-
const DEFAULT_FRAME_WIDTH = 200;
|
|
244
|
-
|
|
245
197
|
/**
|
|
246
198
|
* What a picture of the chart is called.
|
|
247
199
|
*
|
|
@@ -8,18 +8,21 @@ import {
|
|
|
8
8
|
statusSpacerStyle as spacerStyle,
|
|
9
9
|
} from '../../panel/core/statusBar.ts';
|
|
10
10
|
import { countAssigned } from '../core/assignBands.ts';
|
|
11
|
-
import {
|
|
12
|
-
import { boxZoomOnly
|
|
11
|
+
import { formatWavenumberRange } from '../core/irFormat.ts';
|
|
12
|
+
import { boxZoomOnly } from '../core/irMode.ts';
|
|
13
|
+
import { IR_TECHNIQUE_RULES } from '../core/irTechnique.ts';
|
|
13
14
|
|
|
14
15
|
import { useIrEditorState } from './irStateContext.ts';
|
|
16
|
+
import { useIrText } from './useIrText.ts';
|
|
15
17
|
|
|
16
18
|
/**
|
|
17
19
|
* The one line under the chart: what is drawn, what was found, what went wrong.
|
|
18
20
|
*
|
|
19
21
|
* Everything in it is derived, so it is the cheapest place in the viewer to
|
|
20
22
|
* answer "did that work" — how many spectra are drawn of those open, how many
|
|
21
|
-
* bands the picking found and how many the table had something to say about
|
|
22
|
-
* the range the selected spectrum
|
|
23
|
+
* bands the picking found and how many the table had something to say about
|
|
24
|
+
* (where the table covers the technique), and the range the selected spectrum
|
|
25
|
+
* covers, in the order its axis is read.
|
|
23
26
|
*
|
|
24
27
|
* The refusal is last and is the only red in the shell, so the eye that has just
|
|
25
28
|
* pressed something and seen nothing happen lands on the reason.
|
|
@@ -30,12 +33,14 @@ export function IrStatusBar() {
|
|
|
30
33
|
useIrEditorState();
|
|
31
34
|
const { spectra } = state.data;
|
|
32
35
|
const { error, tool } = state.view;
|
|
33
|
-
const { mode, pickBands } = state.settings;
|
|
36
|
+
const { mode, pickBands, technique } = state.settings;
|
|
37
|
+
const { reverseX, assignments } = IR_TECHNIQUE_RULES[technique];
|
|
38
|
+
const text = useIrText(technique);
|
|
34
39
|
|
|
35
40
|
const range =
|
|
36
|
-
selectedSpectrum === null
|
|
37
|
-
?
|
|
38
|
-
:
|
|
41
|
+
selectedSpectrum === null
|
|
42
|
+
? ''
|
|
43
|
+
: formatWavenumberRange(selectedSpectrum.wavenumber, reverseX);
|
|
39
44
|
|
|
40
45
|
return (
|
|
41
46
|
<div style={barStyle}>
|
|
@@ -45,7 +50,7 @@ export function IrStatusBar() {
|
|
|
45
50
|
: `${countLabel(visibleSpectra.length, 'spectrum', 'spectra')} drawn of ${spectra.length}`}
|
|
46
51
|
</span>
|
|
47
52
|
|
|
48
|
-
<span style={itemStyle}>{
|
|
53
|
+
<span style={itemStyle}>{text.yTitle(mode)}</span>
|
|
49
54
|
|
|
50
55
|
{selectedSpectrum === null ? null : (
|
|
51
56
|
<span style={nameStyle} title={selectedSpectrum.name}>
|
|
@@ -53,12 +58,12 @@ export function IrStatusBar() {
|
|
|
53
58
|
</span>
|
|
54
59
|
)}
|
|
55
60
|
|
|
56
|
-
{range ===
|
|
61
|
+
{range === '' ? null : <span style={mutedStyle}>{range}</span>}
|
|
57
62
|
|
|
58
63
|
{pickBands && assigned.length > 0 ? (
|
|
59
64
|
<span style={itemStyle}>
|
|
60
|
-
{countLabel(assigned.length, 'band', 'bands')}
|
|
61
|
-
{countAssigned(assigned)} assigned
|
|
65
|
+
{countLabel(assigned.length, 'band', 'bands')}
|
|
66
|
+
{assignments ? `, ${countAssigned(assigned)} assigned` : null}
|
|
62
67
|
</span>
|
|
63
68
|
) : null}
|
|
64
69
|
|
package/src/ir/ui/IrToolbar.tsx
CHANGED
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
import { Toolbar } from 'react-science/ui';
|
|
2
2
|
|
|
3
3
|
import type { FigureDownloadState } from '../../download/ui/useFigureDownload.tsx';
|
|
4
|
-
import { boxZoomOnly } from '../core/irMode.ts';
|
|
4
|
+
import { bandsPointDown, boxZoomOnly } from '../core/irMode.ts';
|
|
5
|
+
import { defaultIrMode } from '../core/irTechnique.ts';
|
|
6
|
+
import { irCommandOffered } from '../core/irTechniqueCommands.ts';
|
|
5
7
|
|
|
6
8
|
import { useIrCommandProps } from './irCommandContext.tsx';
|
|
7
9
|
import { useIrEditorState } from './irStateContext.ts';
|
|
10
|
+
import { useIrText } from './useIrText.ts';
|
|
8
11
|
|
|
9
12
|
/** What {@link IrToolbar} needs. */
|
|
10
13
|
export interface IrToolbarProps {
|
|
@@ -29,6 +32,9 @@ export interface IrToolbarProps {
|
|
|
29
32
|
* drag on that axis is a rectangle, so both buttons go dead with the square zoom
|
|
30
33
|
* lit. Showing `read` as available there would offer a gesture the chart does not
|
|
31
34
|
* make, and showing it as *active* would name the wrong one.
|
|
35
|
+
*
|
|
36
|
+
* A button whose command the technique does not offer is not drawn: a Raman
|
|
37
|
+
* spectrum has a single value axis and no assignment to name.
|
|
32
38
|
* @param props - Component props.
|
|
33
39
|
* @returns The toolbar.
|
|
34
40
|
*/
|
|
@@ -38,7 +44,8 @@ export function IrToolbar(props: IrToolbarProps) {
|
|
|
38
44
|
const command = useIrCommandProps();
|
|
39
45
|
const { spectra } = state.data;
|
|
40
46
|
const { domain, tool } = state.view;
|
|
41
|
-
const { mode, pickBands, showAssignments } = state.settings;
|
|
47
|
+
const { mode, pickBands, showAssignments, technique } = state.settings;
|
|
48
|
+
const text = useIrText(technique);
|
|
42
49
|
|
|
43
50
|
const isEmpty = spectra.length === 0;
|
|
44
51
|
// The popover opens the panel itself, so the command's own click is left out.
|
|
@@ -49,7 +56,7 @@ export function IrToolbar(props: IrToolbarProps) {
|
|
|
49
56
|
// `collapse`, not the default `wrap`: a wrapping vertical toolbar measures
|
|
50
57
|
// itself and writes the result back as an inline width, so in a row short of
|
|
51
58
|
// space it settles at half an icon and stays there.
|
|
52
|
-
<Toolbar vertical overflow="collapse" aria-label=
|
|
59
|
+
<Toolbar vertical overflow="collapse" aria-label={text.tools}>
|
|
53
60
|
<Toolbar.Item
|
|
54
61
|
icon="trash"
|
|
55
62
|
intent="danger"
|
|
@@ -83,24 +90,28 @@ export function IrToolbar(props: IrToolbarProps) {
|
|
|
83
90
|
disabled={domain === null}
|
|
84
91
|
/>
|
|
85
92
|
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
{irCommandOffered(technique, 'toggleMode') ? (
|
|
94
|
+
<Toolbar.Item
|
|
95
|
+
icon={bandsPointDown(mode) ? 'arrow-down' : 'arrow-up'}
|
|
96
|
+
active={mode !== defaultIrMode(technique)}
|
|
97
|
+
{...command('toggleMode')}
|
|
98
|
+
disabled={isEmpty}
|
|
99
|
+
/>
|
|
100
|
+
) : null}
|
|
92
101
|
<Toolbar.Item
|
|
93
102
|
icon="locate"
|
|
94
103
|
active={pickBands}
|
|
95
104
|
{...command('togglePicking')}
|
|
96
105
|
disabled={selectedSpectrum === null}
|
|
97
106
|
/>
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
107
|
+
{irCommandOffered(technique, 'toggleAssignments') ? (
|
|
108
|
+
<Toolbar.Item
|
|
109
|
+
icon="label"
|
|
110
|
+
active={showAssignments}
|
|
111
|
+
{...command('toggleAssignments')}
|
|
112
|
+
disabled={!pickBands || selectedSpectrum === null}
|
|
113
|
+
/>
|
|
114
|
+
) : null}
|
|
104
115
|
|
|
105
116
|
{/* What the chart looks like right now is what a figure is of — the
|
|
106
117
|
window it was dragged to, the way up it is being read, the
|
package/src/ir/ui/IrTraces.tsx
CHANGED
|
@@ -26,7 +26,10 @@ export interface IrTracesProps {
|
|
|
26
26
|
* the *high* end, the opposite of what every other chart's does.
|
|
27
27
|
*/
|
|
28
28
|
xDomain: readonly [number, number];
|
|
29
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* The wavenumber axis as it is currently zoomed, running right to left for
|
|
31
|
+
* infrared.
|
|
32
|
+
*/
|
|
30
33
|
xScale: ChartScale;
|
|
31
34
|
/** The value axis as it is currently zoomed. */
|
|
32
35
|
yScale: ChartScale;
|
|
@@ -85,6 +88,7 @@ export function IrTraces(props: IrTracesProps): ReactElement {
|
|
|
85
88
|
for (const spectrum of spectra) {
|
|
86
89
|
if (!spectrum.visible) continue;
|
|
87
90
|
const trace = traceOf(spectrum, mode);
|
|
91
|
+
if (trace === undefined) continue;
|
|
88
92
|
const { x, y } = xyReduce(trace, { from, to, nbPoints: wanted });
|
|
89
93
|
const d = profilePath(x, y, xScale, yScale);
|
|
90
94
|
if (d !== '') drawn.push({ id: spectrum.id, color: spectrum.color, d });
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { Ref } from 'react';
|
|
2
|
+
|
|
3
|
+
import type { IrEditorHandle } from '../core/irEditorApi.ts';
|
|
4
|
+
import type { IrSidePanelId } from '../core/irSidePanels.ts';
|
|
5
|
+
import type { IrSpectrum } from '../core/irSpectrum.ts';
|
|
6
|
+
|
|
7
|
+
import { VibrationalEditor } from './VibrationalEditor.tsx';
|
|
8
|
+
|
|
9
|
+
/** The handle a host drives a Raman viewer through: the infrared one's. */
|
|
10
|
+
export type RamanEditorHandle = IrEditorHandle;
|
|
11
|
+
|
|
12
|
+
export interface RamanEditorProps {
|
|
13
|
+
/**
|
|
14
|
+
* The spectra to open on, each carrying its `intensity`. Read when the viewer
|
|
15
|
+
* opens and never again: what is on the chart belongs to the viewer from then
|
|
16
|
+
* on. The `ref` handle is how spectra arrive afterwards.
|
|
17
|
+
* @default []
|
|
18
|
+
*/
|
|
19
|
+
data?: IrSpectrum[];
|
|
20
|
+
/**
|
|
21
|
+
* Called whenever the spectra open change — one loaded, one closed, the chart
|
|
22
|
+
* cleared — with the spectra now open. Not called for a zoom, a selection, a
|
|
23
|
+
* rename or a colour.
|
|
24
|
+
* @default undefined
|
|
25
|
+
*/
|
|
26
|
+
onChange?: (spectra: IrSpectrum[]) => void;
|
|
27
|
+
/**
|
|
28
|
+
* The side panels open to begin with.
|
|
29
|
+
* @default DEFAULT_SIDE_PANELS
|
|
30
|
+
*/
|
|
31
|
+
defaultPanelIds?: IrSidePanelId[];
|
|
32
|
+
/**
|
|
33
|
+
* The handle a host drives the viewer through: take these spectra, frame this
|
|
34
|
+
* Raman shift, select that one.
|
|
35
|
+
* @default undefined
|
|
36
|
+
*/
|
|
37
|
+
ref?: Ref<RamanEditorHandle>;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* A Raman spectrum viewer: the infrared viewer's shell, panels, gestures and
|
|
42
|
+
* export, changed only where Raman is physically different.
|
|
43
|
+
*
|
|
44
|
+
* The spectra are read as intensity, their one value axis, so there is no mode
|
|
45
|
+
* to choose; the Raman shift runs from low at the left to high at the right;
|
|
46
|
+
* the bands are picked as maxima of intensity; and the infrared correlation
|
|
47
|
+
* table is not asked what a band might be.
|
|
48
|
+
* @param props - Component props.
|
|
49
|
+
* @returns The viewer.
|
|
50
|
+
*/
|
|
51
|
+
export function RamanEditor(props: RamanEditorProps) {
|
|
52
|
+
return <VibrationalEditor technique="raman" {...props} />;
|
|
53
|
+
}
|
|
@@ -37,7 +37,7 @@ export function SpectraPanel() {
|
|
|
37
37
|
const actions = useIrActions();
|
|
38
38
|
const { spectra } = state.data;
|
|
39
39
|
const { selectedId } = state.view;
|
|
40
|
-
const { mode } = state.settings;
|
|
40
|
+
const { mode, technique } = state.settings;
|
|
41
41
|
|
|
42
42
|
const selected = spectra.find((spectrum) => spectrum.id === selectedId);
|
|
43
43
|
const allDrawn = spectra.every((spectrum) => spectrum.visible);
|
|
@@ -96,6 +96,7 @@ export function SpectraPanel() {
|
|
|
96
96
|
<SpectrumRow
|
|
97
97
|
key={spectrum.id}
|
|
98
98
|
spectrum={spectrum}
|
|
99
|
+
technique={technique}
|
|
99
100
|
selected={spectrum.id === selectedId}
|
|
100
101
|
onSelect={() => actions.selectSpectrum(spectrum.id)}
|
|
101
102
|
onToggle={() =>
|
|
@@ -1,12 +1,20 @@
|
|
|
1
1
|
import { Button } from 'react-science/ui';
|
|
2
2
|
|
|
3
3
|
import { SpectrumColorSwatch } from '../../panel/ui/SpectrumColorSwatch.tsx';
|
|
4
|
-
import {
|
|
4
|
+
import { formatWavenumberRange } from '../core/irFormat.ts';
|
|
5
5
|
import type { IrSpectrum } from '../core/irSpectrum.ts';
|
|
6
|
+
import type { IrTechnique } from '../core/irTechnique.ts';
|
|
7
|
+
import { IR_TECHNIQUE_RULES } from '../core/irTechnique.ts';
|
|
6
8
|
|
|
7
9
|
export interface SpectrumRowProps {
|
|
8
10
|
/** The spectrum the row is about. */
|
|
9
11
|
spectrum: IrSpectrum;
|
|
12
|
+
/**
|
|
13
|
+
* What it was measured with, which decides the order its range is written
|
|
14
|
+
* in: high to low for infrared, low to high for Raman.
|
|
15
|
+
* @default 'infrared'
|
|
16
|
+
*/
|
|
17
|
+
technique?: IrTechnique;
|
|
10
18
|
/** Whether the panels are about it. */
|
|
11
19
|
selected: boolean;
|
|
12
20
|
/** Point the panels at it. */
|
|
@@ -31,6 +39,7 @@ export interface SpectrumRowProps {
|
|
|
31
39
|
export function SpectrumRow(props: SpectrumRowProps) {
|
|
32
40
|
const {
|
|
33
41
|
spectrum,
|
|
42
|
+
technique = 'infrared',
|
|
34
43
|
selected,
|
|
35
44
|
onSelect,
|
|
36
45
|
onToggle,
|
|
@@ -40,10 +49,10 @@ export function SpectrumRow(props: SpectrumRowProps) {
|
|
|
40
49
|
onRename,
|
|
41
50
|
} = props;
|
|
42
51
|
|
|
43
|
-
const range =
|
|
44
|
-
spectrum.wavenumber
|
|
45
|
-
|
|
46
|
-
|
|
52
|
+
const range = formatWavenumberRange(
|
|
53
|
+
spectrum.wavenumber,
|
|
54
|
+
IR_TECHNIQUE_RULES[technique].reverseX,
|
|
55
|
+
);
|
|
47
56
|
|
|
48
57
|
return (
|
|
49
58
|
<div
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type { Ref } from 'react';
|
|
2
|
+
import { RootLayout } from 'react-science/ui';
|
|
3
|
+
|
|
4
|
+
import type { IrEditorHandle } from '../core/irEditorApi.ts';
|
|
5
|
+
import type { IrSidePanelId } from '../core/irSidePanels.ts';
|
|
6
|
+
import type { IrMode, IrSpectrum } from '../core/irSpectrum.ts';
|
|
7
|
+
import type { IrTechnique } from '../core/irTechnique.ts';
|
|
8
|
+
|
|
9
|
+
import { IrShell } from './IrShell.tsx';
|
|
10
|
+
import { IrStateProvider } from './IrStateProvider.tsx';
|
|
11
|
+
import { useIrEditor } from './useIrEditor.ts';
|
|
12
|
+
|
|
13
|
+
export interface VibrationalEditorProps {
|
|
14
|
+
/**
|
|
15
|
+
* What the spectra were measured with. Read when the viewer opens and fixed
|
|
16
|
+
* from then on: it decides the value axes, the direction and name of the
|
|
17
|
+
* wavenumber axis, and whether the correlation table is asked about a band.
|
|
18
|
+
*/
|
|
19
|
+
technique: IrTechnique;
|
|
20
|
+
/**
|
|
21
|
+
* The spectra to open on. Read when the viewer opens and never again.
|
|
22
|
+
* @default []
|
|
23
|
+
*/
|
|
24
|
+
data?: IrSpectrum[];
|
|
25
|
+
/**
|
|
26
|
+
* Called whenever the spectra open change, with the spectra now open.
|
|
27
|
+
* @default undefined
|
|
28
|
+
*/
|
|
29
|
+
onChange?: (spectra: IrSpectrum[]) => void;
|
|
30
|
+
/**
|
|
31
|
+
* Which value axis to open in; one the technique does not offer opens its
|
|
32
|
+
* first instead.
|
|
33
|
+
* @default the technique's first
|
|
34
|
+
*/
|
|
35
|
+
mode?: IrMode;
|
|
36
|
+
/**
|
|
37
|
+
* The side panels open to begin with.
|
|
38
|
+
* @default DEFAULT_SIDE_PANELS
|
|
39
|
+
*/
|
|
40
|
+
defaultPanelIds?: IrSidePanelId[];
|
|
41
|
+
/**
|
|
42
|
+
* The handle a host drives the viewer through.
|
|
43
|
+
* @default undefined
|
|
44
|
+
*/
|
|
45
|
+
ref?: Ref<IrEditorHandle>;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* The viewer `IrEditor` and `RamanEditor` both are: one shell, one set of
|
|
50
|
+
* panels and gestures, with what differs between the techniques read from
|
|
51
|
+
* `IR_TECHNIQUE_RULES` rather than written into either.
|
|
52
|
+
* @param props - Component props.
|
|
53
|
+
* @returns The viewer.
|
|
54
|
+
*/
|
|
55
|
+
export function VibrationalEditor(props: VibrationalEditorProps) {
|
|
56
|
+
const {
|
|
57
|
+
technique,
|
|
58
|
+
data = NO_SPECTRA,
|
|
59
|
+
onChange,
|
|
60
|
+
mode,
|
|
61
|
+
defaultPanelIds,
|
|
62
|
+
ref,
|
|
63
|
+
} = props;
|
|
64
|
+
|
|
65
|
+
const editor = useIrEditor({
|
|
66
|
+
spectra: data,
|
|
67
|
+
settings: { technique, ...(mode === undefined ? {} : { mode }) },
|
|
68
|
+
panelIds: defaultPanelIds,
|
|
69
|
+
onChange,
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
return (
|
|
73
|
+
<IrStateProvider editor={editor}>
|
|
74
|
+
{/* `react-science`'s own root: it holds the element the browser is asked
|
|
75
|
+
to show full screen, points Blueprint's portals at that element so
|
|
76
|
+
dialogs and tooltips are not left behind in `document.body`, and paints
|
|
77
|
+
the backdrop white. Above the shell rather than inside it, so the shell
|
|
78
|
+
can ask whether it is full screen and offer the way out. */}
|
|
79
|
+
<RootLayout style={rootLayoutStyle}>
|
|
80
|
+
<IrShell handle={ref} />
|
|
81
|
+
</RootLayout>
|
|
82
|
+
</IrStateProvider>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The viewer fills what it is given, and its own children scroll rather than
|
|
88
|
+
* push: `react-science` lays its root out as a column of full width and height,
|
|
89
|
+
* and a flex column with no `minHeight` grows past its parent instead.
|
|
90
|
+
*/
|
|
91
|
+
const rootLayoutStyle = { minHeight: 0 } as const;
|
|
92
|
+
|
|
93
|
+
/** What a viewer opens on when it is handed nothing, kept stable for the memo. */
|
|
94
|
+
const NO_SPECTRA: IrSpectrum[] = [];
|