Skip to content

Commit

Permalink
feat: improve database (#3102)
Browse files Browse the repository at this point in the history
* feat: use independent vertical scaling for previewing database spectrum

* feat: toggle database spectrum

* fix: verical scale

* fix: keep the horizontal zoom when add/remove spectrum from database
  • Loading branch information
hamed-musallam committed Jul 2, 2024
1 parent e0394d9 commit d33a9f0
Show file tree
Hide file tree
Showing 8 changed files with 145 additions and 56 deletions.
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"multiplet-analysis": "^2.1.2",
"nmr-correlation": "^2.3.3",
"nmr-load-save": "^0.34.2",
"nmr-processing": "^12.4.0",
"nmr-processing": "^12.5.0",
"nmredata": "^0.9.11",
"numeral": "^2.0.6",
"openchemlib": "^8.14.0",
Expand Down
38 changes: 17 additions & 21 deletions src/component/1d/database/DatabaseSpectrum.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { extent } from 'd3';
import throttle from 'lodash/throttle';
import { readFromWebSource, Spectrum1D } from 'nmr-load-save';
import { useCallback, useContext, useEffect, useRef, useState } from 'react';
Expand All @@ -7,14 +8,12 @@ import { useScaleChecked } from '../../context/ScaleContext';
import { useToaster } from '../../context/ToasterContext';
import { HighlightEventSource, useHighlightData } from '../../highlight';
import { usePanelPreferences } from '../../hooks/usePanelPreferences';
import { useVerticalAlign } from '../../hooks/useVerticalAlign';
import { spinnerContext } from '../../loader/SpinnerContext';
import { PathBuilder } from '../../utility/PathBuilder';
import { getYScale } from '../utilities/scale';
import { getYScaleWithRation } from '../utilities/scale';

function DatabaseSpectrum() {
const { displayerKey, height, yDomain, yDomains, margin } = useChartData();
const verticalAlign = useVerticalAlign();
const { displayerKey, height, margin } = useChartData();
const [path, setPath] = useState<string>();
const [isLoading, setLoading] = useState<boolean>(false);
const { highlight } = useHighlightData();
Expand All @@ -26,23 +25,18 @@ function DatabaseSpectrum() {
const getSpinner = useContext(spinnerContext);

const scaleY = useCallback(
() =>
getYScale({
height,
margin: { top: margin.top, bottom: margin.bottom + marginBottom },
verticalAlign,
(yDomain: number[]) =>
getYScaleWithRation({
yDomain,
yDomains,
height,
margin: {
...margin,
bottom: margin.bottom + marginBottom,
top: margin.top,
},
scaleRatio: 1,
}),
[
verticalAlign,
height,
margin.bottom,
margin.top,
marginBottom,
yDomain,
yDomains,
],
[height, margin, marginBottom],
);

const loadSpectrum = useRef(
Expand All @@ -57,9 +51,11 @@ function DatabaseSpectrum() {
const spectrum = data?.spectra?.[0] || null;
if (spectrum) {
const pathBuilder = new PathBuilder();
const finalScaleX = scaleX();
const finalScaleY = scaleY();
const { x, re: y } = (spectrum as Spectrum1D).data;
const yDomain = extent(y) as number[];
const finalScaleX = scaleX();
const finalScaleY = scaleY(yDomain);

pathBuilder.moveTo(finalScaleX(x[0]), finalScaleY(y[0]));
for (let i = 1; i < x.length; i++) {
pathBuilder.lineTo(finalScaleX(x[i]), finalScaleY(y[i]));
Expand Down
31 changes: 27 additions & 4 deletions src/component/panels/databasePanel/DatabasePanel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -257,8 +257,12 @@ function DatabasePanelInner({
const resurrectHandler = useCallback(
(rowData) => {
const { index, baseURL, jcampURL: jcampRelativeURL } = rowData;
const { ranges, solvent, names = [] } = result.data[index];

const {
ranges,
solvent,
names = [],
id: spectrumID,
} = result.data[index];
if (jcampRelativeURL) {
const url = new URL(jcampRelativeURL, baseURL);
setTimeout(async () => {
Expand All @@ -269,9 +273,9 @@ function DatabasePanelInner({
const { data } = await readFromWebSource({
entries: [{ baseURL: url.origin, relativePath: url.pathname }],
});

const spectrum = data?.spectra?.[0] || null;
if (spectrum && isSpectrum1D(spectrum)) {
if (spectrum && isSpectrum1D(spectrum) && spectrumID) {
spectrum.id = spectrumID;
dispatch({
type: 'RESURRECTING_SPECTRUM_FROM_JCAMP',
payload: { ranges, spectrum },
Expand Down Expand Up @@ -318,9 +322,27 @@ function DatabasePanelInner({
},
[result, toaster],
);
const removeHandler = useCallback(
(row) => {
const { spectrumID: id } = row;
if (!id) {
return;
}

dispatch({
type: 'DELETE_SPECTRA',
payload: {
id,
domainOptions: { isYDomainShared: false, updateYDomain: false },
},
});
},
[dispatch],
);
const searchByStructureHandler = (idCodeValue: string) => {
setIdCode(idCodeValue);
};

return (
<div
css={[
Expand Down Expand Up @@ -373,6 +395,7 @@ function DatabasePanelInner({
data={tableData}
totalCount={result.data.length}
onAdd={resurrectHandler}
onRemove={removeHandler}
onSave={saveHandler}
/>
) : (
Expand Down
72 changes: 55 additions & 17 deletions src/component/panels/databasePanel/DatabaseTable.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
/** @jsxImportSource @emotion/react */
import { Classes } from '@blueprintjs/core';
import lodashGet from 'lodash/get';
import { useMemo, memo, CSSProperties } from 'react';
import { ResponsiveChart } from 'react-d3-utils';
import { FaDownload, FaPlus } from 'react-icons/fa';
import { FaDownload, FaMinus, FaPlus } from 'react-icons/fa';
import { IdcodeSvgRenderer, SmilesSvgRenderer } from 'react-ocl/full';
import { Button } from 'react-science/ui';

import { PrepareDataResult } from '../../../data/data1d/database';
import Button from '../../elements/Button';
import { ColumnWrapper } from '../../elements/ColumnWrapper';
import ReactTable from '../../elements/ReactTable/ReactTable';
import addCustomColumn, {
CustomColumn,
} from '../../elements/ReactTable/utility/addCustomColumn';
import { HighlightEventSource } from '../../highlight';
import { usePanelPreferences } from '../../hooks/usePanelPreferences';
import useSpectraByActiveNucleus from '../../hooks/useSpectraPerNucleus';
import { formatNumber } from '../../utility/formatNumber';

interface DatabaseTableProps {
data: any;
interface ToggleEvent {
onAdd: (row: any) => void;
onRemove: (row: any) => void;
}
interface DatabaseTableProps extends ToggleEvent {
data: any;
onSave: (row: any) => void;
totalCount: number;
}
Expand Down Expand Up @@ -160,6 +165,7 @@ const databaseTableColumns = (
function DatabaseTable({
data,
onAdd,
onRemove,
onSave,
totalCount,
}: DatabaseTableProps) {
Expand All @@ -185,29 +191,29 @@ function DatabaseTable({
<ColumnWrapper
style={{ display: 'flex', justifyContent: 'space-evenly' }}
>
<Button.Done
style={{ padding: '0.25rem', fontSize: '0.7rem' }}
fill="outline"
onClick={() => onAdd(row.original)}
>
<FaPlus />
</Button.Done>
<ToggleBtn
onAdd={onAdd}
onRemove={onRemove}
data={row.original}
/>

{databasePreferences?.allowSaveAsNMRium && (
<Button.Action
style={{ padding: '0.25rem', fontSize: '0.7rem' }}
fill="outline"
<Button
small
outlined
tooltipProps={{ content: '', disabled: true }}
onClick={() => onSave(row.original)}
disabled={!jcampURL}
>
<FaDownload />
</Button.Action>
<FaDownload className={Classes.ICON} />
</Button>
)}
</ColumnWrapper>
);
},
},
],
[databasePreferences?.allowSaveAsNMRium, onAdd, onSave],
[databasePreferences?.allowSaveAsNMRium, onAdd, onRemove, onSave],
);

const tableColumns = useMemo(() => {
Expand Down Expand Up @@ -235,4 +241,36 @@ function DatabaseTable({
);
}

interface ToggleBtnProps extends ToggleEvent {
data: PrepareDataResult;
}

export function ToggleBtn(props: ToggleBtnProps) {
const { onAdd, onRemove, data } = props;
const spectra = useSpectraByActiveNucleus();
const isAdded = spectra.some((spectrum) => spectrum.id === data.spectrumID);

return (
<Button
small
intent={isAdded ? 'danger' : 'success'}
outlined
tooltipProps={{ content: '', disabled: true }}
onClick={() => {
if (isAdded) {
onRemove(data);
} else {
onAdd(data);
}
}}
>
{isAdded ? (
<FaMinus className={Classes.ICON} />
) : (
<FaPlus className={Classes.ICON} />
)}
</Button>
);
}

export default memo(DatabaseTable);
37 changes: 32 additions & 5 deletions src/component/reducer/actions/DatabaseActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {
} from '../../../data/data1d/Spectrum1D/ranges/generateSpectrumFromRanges';
import { State } from '../Reducer';
import { setZoom } from '../helper/Zoom1DManager';
import zoomHistoryManager from '../helper/ZoomHistoryManager';
import { ActionType } from '../types/ActionType';

import { setDomain } from './DomainActions';
Expand Down Expand Up @@ -46,8 +47,22 @@ function handleResurrectSpectrumFromJcamp(
};

draft.data.push(spectrum);
setDomain(draft);

setDomain(draft, { isYDomainShared: false });

//rescale the vertical zoom
setZoom(draft, { scale: 0.8, spectrumID: spectrum.id });

//keep the last horizontal zoom
const zoomHistory = zoomHistoryManager(
draft.zoom.history,
draft.view.spectra.activeTab,
);
const zoomValue = zoomHistory.getLast();
if (zoomValue) {
draft.xDomain = zoomValue.xDomain;
draft.yDomain = zoomValue.yDomain;
}
}

function handleResurrectSpectrumFromRanges(
Expand All @@ -56,10 +71,22 @@ function handleResurrectSpectrumFromRanges(
) {
const { ranges, info } = action.payload;
const datum = generateSpectrumFromRanges(ranges, info, draft.usedColors);
if (datum) {
draft.data.push(datum);
setDomain(draft, { isYDomainShared: false });
setZoom(draft, { scale: 0.8, spectrumID: datum.id });
if (!datum) return;

draft.data.push(datum);
setDomain(draft, { isYDomainShared: false });
//rescale the vertical zoom
setZoom(draft, { scale: 0.8, spectrumID: datum.id });

//keep the last horizontal zoom
const zoomHistory = zoomHistoryManager(
draft.zoom.history,
draft.view.spectra.activeTab,
);
const zoomValue = zoomHistory.getLast();
if (zoomValue) {
draft.xDomain = zoomValue.xDomain;
draft.yDomain = zoomValue.yDomain;
}
}

Expand Down
6 changes: 4 additions & 2 deletions src/component/reducer/actions/SpectraActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ import {
import { getActiveSpectrum } from '../helper/getActiveSpectrum';
import { ActionType } from '../types/ActionType';

import { setDomain, setMode } from './DomainActions';
import { SetDomainOptions, setDomain, setMode } from './DomainActions';
import { rollbackSpectrumByFilter } from './FiltersActions';
import {
setTab,
Expand Down Expand Up @@ -96,6 +96,7 @@ type DeleteSpectraAction = ActionType<
'DELETE_SPECTRA',
{
id?: string;
domainOptions?: SetDomainOptions;
}
>;
type AddMissingProjectionAction = ActionType<
Expand Down Expand Up @@ -470,7 +471,7 @@ function handleChangeSpectrumSetting(
//action
function handleDeleteSpectra(draft: Draft<State>, action: DeleteSpectraAction) {
const state = original(draft) as State;
const { id: spectraId } = action?.payload || {};
const { id: spectraId, domainOptions } = action?.payload || {};
if (spectraId) {
const index = state.data.findIndex((d) => d.id === spectraId);
draft.data.splice(index, 1);
Expand All @@ -489,6 +490,7 @@ function handleDeleteSpectra(draft: Draft<State>, action: DeleteSpectraAction) {
setActiveTab(draft, {
tab: draft.view.spectra.activeTab,
refreshActiveTab: true,
domainOptions,
});
}

Expand Down
Loading

0 comments on commit d33a9f0

Please sign in to comment.