Skip to content

Commit 335ca66

Browse files
feat: display spectrum label in stack mode
1 parent 67bedcc commit 335ca66

8 files changed

Lines changed: 135 additions & 2 deletions

File tree

src/component/1d/LinesSeries.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { useVerticalAlign } from '../hooks/useVerticalAlign.js';
1010
import { useVisibleSpectra1D } from '../hooks/use_visible_spectra_1d.ts';
1111

1212
import Line from './Line.js';
13+
import { SpectrumLabel } from './SpectrumLabel.tsx';
1314
import { useInsetOptions } from './inset/InsetProvider.js';
1415

1516
const BOX_SIZE = 10;
@@ -31,6 +32,7 @@ function LinesSeries() {
3132
<g className="spectra">
3233
{spectra.map((d, i) => (
3334
<g key={d.id}>
35+
<SpectrumLabel index={i} spectrum={d} />
3436
<Line display={d.display} id={d.id} data={get1DDataXY(d)} index={i} />
3537
<HeadlightRectStackMode spectrumID={d.id} index={i} />
3638
</g>

src/component/1d/SpectrumLabel.tsx

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import type { SpectraTableColumn, Spectrum } from '@zakodium/nmrium-core';
2+
import dlv from 'dlv';
3+
4+
import { useChartData } from '../context/ChartContext.tsx';
5+
import { useScaleChecked } from '../context/ScaleContext.tsx';
6+
import { usePanelPreferences } from '../hooks/usePanelPreferences.ts';
7+
import { useVerticalAlign } from '../hooks/useVerticalAlign.ts';
8+
9+
export function SpectrumLabel({
10+
index,
11+
spectrum,
12+
}: {
13+
index: number;
14+
spectrum: Spectrum;
15+
}) {
16+
const { spectraBottomMargin, shiftY } = useScaleChecked();
17+
const {
18+
height,
19+
margin,
20+
toolOptions: { selectedTool },
21+
view: {
22+
spectra: { activeTab },
23+
},
24+
} = useChartData();
25+
const { columns, enableSpectraLabel } = usePanelPreferences(
26+
'spectra',
27+
activeTab,
28+
);
29+
const verticalAlign = useVerticalAlign();
30+
31+
if (
32+
verticalAlign !== 'stack' ||
33+
selectedTool !== 'zoom' ||
34+
!Array.isArray(columns) ||
35+
columns.length === 0 ||
36+
!enableSpectraLabel
37+
) {
38+
return null;
39+
}
40+
41+
const innerHeight = height - margin.bottom - spectraBottomMargin;
42+
const label = getSpectrumLabel(columns, spectrum);
43+
44+
return (
45+
<text
46+
dy={-5}
47+
fontSize={12}
48+
transform={`translate(${margin.left},${innerHeight - shiftY * index})`}
49+
>
50+
{label}
51+
</text>
52+
);
53+
}
54+
55+
function getSpectrumLabel(
56+
columns: SpectraTableColumn[],
57+
spectrum: Spectrum,
58+
): string {
59+
return columns
60+
.filter((column) => column.isSpectrumLabel)
61+
.map((column) => (column.jpath ? dlv(spectrum, column.jpath, '') : ''))
62+
.join(', ');
63+
}

src/component/panels/SpectraPanel/SpectraPanelHeader.tsx

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,19 @@ import { SvgNmrResetScale, SvgNmrSameTop } from 'cheminfo-font';
77
import { memo, useCallback } from 'react';
88
import { FaCreativeCommonsSamplingPlus } from 'react-icons/fa';
99
import { IoColorPaletteOutline } from 'react-icons/io5';
10-
import { MdFormatColorFill } from 'react-icons/md';
10+
import { MdFormatColorFill, MdOutlineFormatColorText } from 'react-icons/md';
1111

1212
import { useChartData } from '../../context/ChartContext.js';
1313
import { useDispatch } from '../../context/DispatchContext.js';
1414
import { usePreferences } from '../../context/PreferencesContext.js';
1515
import { useToaster } from '../../context/ToasterContext.js';
1616
import { useAlert } from '../../elements/Alert.js';
1717
import { useActiveSpectra } from '../../hooks/useActiveSpectra.js';
18+
import { usePanelPreferences } from '../../hooks/usePanelPreferences.ts';
1819
import useSpectrum from '../../hooks/useSpectrum.js';
1920
import { useToggleSpectraVisibility } from '../../hooks/useToggleSpectraVisibility.js';
2021
import type { DisplayerMode } from '../../reducer/Reducer.js';
22+
import { booleanToString } from '../../utility/booleanToString.ts';
2123
import { getSpectraByNucleus } from '../../utility/getSpectraByNucleus.js';
2224
import type { ToolbarItemProps } from '../header/DefaultPanelHeader.js';
2325
import DefaultPanelHeader from '../header/DefaultPanelHeader.js';
@@ -60,7 +62,9 @@ function SpectraPanelHeaderInner({
6062
const dispatch = useDispatch();
6163
const {
6264
current: { spectraColors },
65+
dispatch: dispatchPreferences,
6366
} = usePreferences();
67+
const { enableSpectraLabel } = usePanelPreferences('spectra', activeTab);
6468

6569
const handleDelete = useCallback(() => {
6670
alert.showAlert({
@@ -116,6 +120,14 @@ function SpectraPanelHeaderInner({
116120
payload: {},
117121
});
118122
}
123+
124+
function toggleSpectraLabelHandler() {
125+
dispatchPreferences({
126+
type: 'TOGGLE_SPECTRA_LABEL',
127+
payload: { nucleus: activeTab },
128+
});
129+
}
130+
119131
const hasActiveSpectra = activeSpectra && activeSpectra?.length > 0;
120132
const spectraLengthPerTab = getSpectraByNucleus(activeTab, data)?.length;
121133
const { getToggleVisibilityButtons } = useToggleSpectraVisibility(
@@ -168,6 +180,12 @@ function SpectraPanelHeaderInner({
168180
tooltip: 'Distinct spectra recoloring',
169181
onClick: distinctReColorSpectraHandler,
170182
},
183+
{
184+
icon: <MdOutlineFormatColorText />,
185+
tooltip: `${booleanToString(!enableSpectraLabel)} spectra label`,
186+
active: enableSpectraLabel,
187+
onClick: toggleSpectraLabelHandler,
188+
},
171189
]);
172190

173191
return (

src/component/panels/SpectraPanel/SpectraPreferences.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ function SpectraPreferences(props: object, ref: Ref<any>) {
129129
jpath: [],
130130
label: '',
131131
visible: true,
132+
isSpectrumLabel: false,
132133
},
133134
...columns.slice(index),
134135
];

src/component/panels/SpectraPanel/base/SpectraColumnsManager.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ export function SpectraColumnsManager({
115115
/>
116116
),
117117
},
118+
{
119+
Header: 'spectrum label',
120+
style: { width: '30px', textAlign: 'center' },
121+
Cell: ({ row }: CellProps<SpectraTableColumn>) => (
122+
<Checkbox
123+
style={{ margin: 0 }}
124+
{...register(getObjectKey(nucleus, row.index, 'isSpectrumLabel'))}
125+
/>
126+
),
127+
},
118128
{
119129
Header: '',
120130
style: { width: '65px' },
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import type { Draft } from 'immer';
2+
3+
import type {
4+
PreferencesState,
5+
ToggleSpectraLabelAction,
6+
} from '../preferencesReducer.js';
7+
import { getActiveWorkspace } from '../utilities/getActiveWorkspace.js';
8+
9+
export function toggleSpectraLabel(
10+
draft: Draft<PreferencesState>,
11+
action: ToggleSpectraLabelAction,
12+
) {
13+
if (action.payload) {
14+
const currentWorkspacePreferences = getActiveWorkspace(draft);
15+
16+
const { nucleus } = action.payload;
17+
const nucleusPreferences =
18+
currentWorkspacePreferences.panels.spectra?.nuclei[nucleus];
19+
20+
if (!nucleusPreferences) {
21+
return;
22+
}
23+
24+
nucleusPreferences.enableSpectraLabel =
25+
!nucleusPreferences.enableSpectraLabel;
26+
}
27+
}

src/component/reducer/preferences/panelsPreferencesDefaultValues.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,21 +33,25 @@ const getSpectraDefaultValues = (
3333
label: 'Spectrum Name',
3434
jpath: ['info', 'name'],
3535
visible: true,
36+
isSpectrumLabel: true,
3637
},
3738
{
3839
label: 'Solvent',
3940
jpath: ['info', 'solvent'],
4041
visible: true,
42+
isSpectrumLabel: false,
4143
},
4244
{
4345
jpath: ['info', 'pulseSequence'],
4446
label: 'Pulse',
4547
visible: true,
48+
isSpectrumLabel: false,
4649
},
4750
{
4851
jpath: ['info', 'experiment'],
4952
label: 'Experiment',
5053
visible: true,
54+
isSpectrumLabel: false,
5155
},
5256
{
5357
name: 'color',
@@ -56,6 +60,7 @@ const getSpectraDefaultValues = (
5660
visible: true,
5761
},
5862
],
63+
enableSpectraLabel: true,
5964
};
6065

6166
return getPreferences(preferences, nucleus);

src/component/reducer/preferences/preferencesReducer.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ import { setWorkspace } from './actions/setWorkspace.js';
5757
import { toggleInformationBlock } from './actions/toggleInformationBlock.js';
5858
import { toggleOpenSplitPanel } from './actions/toggleOpenSplitPanel.js';
5959
import { togglePanel } from './actions/togglePanel.js';
60+
import { toggleSpectraLabel } from './actions/toggleSpectraLabel.ts';
6061
import { mapWorkspaces } from './utilities/mapWorkspaces.js';
6162

6263
const LOCAL_STORAGE_SETTINGS_KEY = 'nmr-general-settings';
@@ -91,6 +92,10 @@ export type SetPanelsPreferencesAction = ActionType<
9192
'SET_PANELS_PREFERENCES',
9293
{ key: keyof PanelsPreferences; value: any }
9394
>;
95+
export type ToggleSpectraLabelAction = ActionType<
96+
'TOGGLE_SPECTRA_LABEL',
97+
{ nucleus: string }
98+
>;
9499

95100
export type SetWorkspaceAction = ActionType<
96101
'SET_WORKSPACE',
@@ -196,6 +201,7 @@ export type PreferencesActions =
196201
| InitPreferencesAction
197202
| SetPreferencesAction
198203
| SetPanelsPreferencesAction
204+
| ToggleSpectraLabelAction
199205
| SetWorkspaceAction
200206
| WorkspaceAction
201207
| AddWorkspaceAction
@@ -345,7 +351,8 @@ function innerPreferencesReducer(
345351
return changeDefaultMoleculeSettings(draft, action);
346352
case 'TOGGLE_SPLIT_PANEL':
347353
return toggleOpenSplitPanel(draft, action);
348-
354+
case 'TOGGLE_SPECTRA_LABEL':
355+
return toggleSpectraLabel(draft, action);
349356
default:
350357
return draft;
351358
}

0 commit comments

Comments
 (0)