Skip to content

Commit

Permalink
refactor: edit peaks and couplings
Browse files Browse the repository at this point in the history
  • Loading branch information
hamed-musallam committed Mar 15, 2024
1 parent 17f1648 commit 480ccaa
Show file tree
Hide file tree
Showing 5 changed files with 115 additions and 119 deletions.
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { Formik, useFormikContext } from 'formik';
import { WorkSpacePanelPreferences } from 'nmr-load-save';
import { translateMultiplet } from 'nmr-processing';
import { CSSProperties, useRef } from 'react';
import * as Yup from 'yup';

import { useChartData } from '../../../../context/ChartContext';
import Button from '../../../../elements/Button';
import FormikInput from '../../../../elements/formik/FormikInput';
import { usePanelPreferences } from '../../../../hooks/usePanelPreferences';
import { useEvent } from '../../../../utility/Events';
import { formatNumber } from '../../../../utility/formatNumber';

Expand All @@ -30,13 +31,18 @@ const styles: Record<

interface AddSignalFormTabProps {
range: any;
preferences: WorkSpacePanelPreferences['ranges'];
}

export function AddSignalFormTab(props: AddSignalFormTabProps) {
const { range, preferences } = props;
const { range } = props;
const { values, setFieldValue } = useFormikContext<any>();
const newSignalFormRef = useRef<any>();
const {
view: {
spectra: { activeTab },
},
} = useChartData();
const rangesPreferences = usePanelPreferences('ranges', activeTab);

function saveHandler(val) {
const newSignal = {
Expand Down Expand Up @@ -84,8 +90,8 @@ export function AddSignalFormTab(props: AddSignalFormTabProps) {
Edit or select a delta value of new signal in range [
{`${formatNumber(
range.from,
preferences.from.format,
)} ppm - ${formatNumber(range.to, preferences.to.format)} ppm`}
rangesPreferences.from.format,
)} ppm - ${formatNumber(range.to, rangesPreferences.to.format)} ppm`}
]:
</p>
<FormikInput
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,16 @@ const style: InputStyle = {
interface DeltaInputProps {
signal: any;
index: number;
onFocus: (element: any) => void;
}

function DeltaInput({ signal, index, onFocus }: DeltaInputProps) {
function DeltaInput({ signal, index }: DeltaInputProps) {
return (
<div style={{ display: 'flex', alignItems: 'center' }}>
<span>𝛅: </span>
<FormikInput
name={`signals.${index}.delta`}
type="number"
placeholder={'J (Hz)'}
onFocus={onFocus}
style={style}
checkErrorAfterInputTouched={false}
/>
Expand Down
27 changes: 24 additions & 3 deletions src/component/modal/editRange/forms/components/JCouplingsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ import FormikInput from '../../../../elements/formik/FormikInput';
import FormikSelect from '../../../../elements/formik/FormikSelect';
import { hasCouplingConstant } from '../../../../panels/extra/utilities/MultiplicityUtilities';
import { useEvent } from '../../../../utility/Events';
import { formatNumber } from '../../../../utility/formatNumber';
import useSpectrum from '../../../../hooks/useSpectrum';

Check warning on line 15 in src/component/modal/editRange/forms/components/JCouplingsTable.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

`../../../../hooks/useSpectrum` import should occur before import of `../../../../panels/extra/utilities/MultiplicityUtilities`
import { isSpectrum1D } from '../../../../../data/data1d/Spectrum1D';

Check warning on line 16 in src/component/modal/editRange/forms/components/JCouplingsTable.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

`../../../../../data/data1d/Spectrum1D` import should occur before import of `../../../../elements/Button`
import { useChartData } from '../../../../context/ChartContext';

Check warning on line 17 in src/component/modal/editRange/forms/components/JCouplingsTable.tsx

View workflow job for this annotation

GitHub Actions / nodejs / lint-eslint

`../../../../context/ChartContext` import should occur before import of `../../../../elements/Button`
import { usePanelPreferences } from '../../../../hooks/usePanelPreferences';

const styles: Record<'input' | 'select' | 'column', CSSProperties> = {
input: {
Expand Down Expand Up @@ -45,14 +50,22 @@ export default function JCouplingsTable(props: PeaksTableProps) {
const [lastSelectedCouplingIndex, setLastSelectedCouplingIndex] = useState<
number | null
>(null);
const spectrum = useSpectrum();
const {
view: {
spectra: { activeTab },
},
} = useChartData();
const rangesPreferences = usePanelPreferences('ranges', activeTab);

useEvent({
onClick: (options) => {
if (
`${props.index}` === values.signalIndex &&
typeof lastSelectedCouplingIndex === 'number'
) {
const x = options.xPPM;
const x = formatNumber(options.xPPM, rangesPreferences.deltaHz.format);

void setFieldValue(
getJCouplingKey(
values.signalIndex,
Expand All @@ -70,15 +83,23 @@ export default function JCouplingsTable(props: PeaksTableProps) {
} = options;
if (
`${props.index}` === values.signalIndex &&
typeof lastSelectedCouplingIndex === 'number'
typeof lastSelectedCouplingIndex === 'number' &&
isSpectrum1D(spectrum)
) {
const value = Number(
formatNumber(
Math.abs(to - from) * spectrum.info.originFrequency,
rangesPreferences.deltaHz.format,
),
);

void setFieldValue(
getJCouplingKey(
values.signalIndex,
lastSelectedCouplingIndex,
'coupling',
),
(to - from) / 2 + from,
value,
);
}
},
Expand Down
99 changes: 74 additions & 25 deletions src/component/modal/editRange/forms/components/PeaksTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,14 @@ import { CSSProperties, useCallback, useMemo, useState } from 'react';
import { FaPlus, FaRegTrashAlt } from 'react-icons/fa';
import { Toolbar } from 'react-science/ui';

import { useChartData } from '../../../../context/ChartContext';
import Button from '../../../../elements/Button';
import ReactTable, { Column } from '../../../../elements/ReactTable/ReactTable';
import FormikInput from '../../../../elements/formik/FormikInput';
import { usePanelPreferences } from '../../../../hooks/usePanelPreferences';
import useSpectrum from '../../../../hooks/useSpectrum';
import { useEvent } from '../../../../utility/Events';
import { formatNumber } from '../../../../utility/formatNumber';

const styles: Record<'input' | 'column', CSSProperties> = {
input: {
Expand All @@ -27,6 +30,16 @@ interface PeaksTableProps {
index: number;
}

function getPeakKey(signalIndex: number, peakIndex, key?: keyof Peak1D) {
const path = `signals[${signalIndex}].peaks.${peakIndex}`;

if (!key) {
return path;
}

return `${path}.${key}`;
}

export default function PeaksTable(props: PeaksTableProps) {
const { values, setFieldValue } = useFormikContext<any>();
const signal = values?.signals?.[values?.signalIndex] || {};
Expand All @@ -37,23 +50,61 @@ export default function PeaksTable(props: PeaksTableProps) {
data: { x: xArray, re },
} = spectrum;
const shiftX = getShiftX(spectrum);
const [lastSelectedPeak, setLastSelectedPeak] = useState<Peak1D | null>(null);
const [lastSelectedPeakIndex, setLastSelectedPeakIndex] = useState<
number | null
>(null);

const {
view: {
spectra: { activeTab },
},
} = useChartData();
const rangesPreferences = usePanelPreferences('ranges', activeTab);

useEvent({
onClick: (options) => {
if (`${props.index}` === values.signalIndex) {
const index = peaks.findIndex(
(peak) => peak.id === lastSelectedPeak?.id,
if (
`${props.index}` === values.signalIndex &&
typeof lastSelectedPeakIndex === 'number'
) {
const delta = formatNumber(
options.xPPM,
rangesPreferences.deltaPPM.format,
);
const xIndex = xFindClosestIndex(xArray, delta, { sorted: false });
const intensity = formatNumber(
re[xIndex],
rangesPreferences.deltaPPM.format,
);
if (index !== -1) {
const delta = options.xPPM;
const xIndex = xFindClosestIndex(xArray, delta, { sorted: false });
void setFieldValue(`signals[${values?.signalIndex}].peaks.${index}`, {
...peaks[index],
void setFieldValue(
getPeakKey(values?.signalIndex, lastSelectedPeakIndex),
{
...peaks[lastSelectedPeakIndex],
x: delta,
y: re[xIndex],
});
}
y: intensity,
},
);
}
},
onBrushEnd: (options) => {
const {
range: [from, to],
} = options;
if (
`${props.index}` === values.signalIndex &&
typeof lastSelectedPeakIndex === 'number'
) {
const value = Number(
formatNumber(
(to - from) / 2 + from,
rangesPreferences.deltaPPM.format,
),
);

void setFieldValue(
getPeakKey(values.signalIndex, lastSelectedPeakIndex, 'x'),
value,
);
}
},
});
Expand All @@ -73,30 +124,26 @@ export default function PeaksTable(props: PeaksTableProps) {
...data,
peak,
]);
setLastSelectedPeak(peak);
setLastSelectedPeakIndex(data?.length || 0);
},
[delta, re, setFieldValue, shiftX, values?.signalIndex, xArray],
);

const deleteHandler = useCallback(
(data, index: number) => {
const lastPeakIndex = data.findIndex(
(peak) => peak.id === lastSelectedPeak?.id,
);

const peaks = data.filter((_, columnIndex) => columnIndex !== index);

void setFieldValue(`signals[${values?.signalIndex}].peaks`, peaks);
if (lastPeakIndex === index) {
setLastSelectedPeak(null);
if (lastSelectedPeakIndex === index) {
setLastSelectedPeakIndex(null);
}
},
[lastSelectedPeak?.id, setFieldValue, values?.signalIndex],
[lastSelectedPeakIndex, setFieldValue, values?.signalIndex],
);

function deleteAllHandler() {
void setFieldValue(`signals[${values?.signalIndex}].peaks`, []);
setLastSelectedPeak(null);
setLastSelectedPeakIndex(null);
}

const changeDeltaHandler = useCallback(
Expand Down Expand Up @@ -175,12 +222,14 @@ export default function PeaksTable(props: PeaksTableProps) {
[changeDeltaHandler, deleteHandler, values?.signalIndex],
);

function selectRowHandler(data) {
setLastSelectedPeak((prevPeak) => (prevPeak?.id === data.id ? null : data));
function selectRowHandler(index) {
setLastSelectedPeakIndex((prevIndex) =>
prevIndex === index ? null : index,
);
}

function handleActiveRow(row) {
return row?.original.id === lastSelectedPeak?.id;
return row?.index === lastSelectedPeakIndex;
}

return (
Expand Down Expand Up @@ -210,7 +259,7 @@ export default function PeaksTable(props: PeaksTableProps) {
<ReactTable
data={peaks}
columns={COLUMNS}
onClick={(e, rowData: any) => selectRowHandler(rowData.original)}
onClick={(e, rowData: any) => selectRowHandler(rowData.index)}
activeRow={handleActiveRow}
emptyDataRowText="No peaks"
/>
Expand Down
Loading

0 comments on commit 480ccaa

Please sign in to comment.