Skip to content

Commit

Permalink
feat: zoom out based on defined axis domain preferences
Browse files Browse the repository at this point in the history
Define the axis domain (x-axis for one-dimension spectra and x-axis, y-axis for two-dimension spectra) from the spectra panel preferences. Once it is defined, use Shift + f to zoom out.

close #3024
  • Loading branch information
hamed-musallam committed Apr 26, 2024
1 parent 59c49f4 commit 29a412a
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 15 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.

4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@
"ml-tree-similarity": "^2.2.0",
"multiplet-analysis": "^2.1.2",
"nmr-correlation": "^2.3.3",
"nmr-load-save": "0.30.0",
"nmr-load-save": "0.30.1-pre.1714163234",
"nmr-processing": "^12.2.0",
"nmredata": "^0.9.9",
"numeral": "^2.0.6",
Expand Down Expand Up @@ -152,4 +152,4 @@
"vite": "^5.2.10",
"vitest": "^1.5.2"
}
}
}
14 changes: 14 additions & 0 deletions src/component/EventsTrackers/KeysListenerTracker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { useModal } from '../elements/popup/Modal';
import { HighlightEventSource, useHighlightData } from '../highlight/index';
import { useCheckToolsVisibility } from '../hooks/useCheckToolsVisibility';
import useExport from '../hooks/useExport';
import { usePanelPreferences } from '../hooks/usePanelPreferences';
import useToolsFunctions from '../hooks/useToolsFunctions';
import SaveAsModal from '../modal/SaveAsModal';
import { options } from '../toolbar/ToolTypes';
Expand Down Expand Up @@ -50,6 +51,7 @@ function KeysListenerTracker(props: KeysListenerTrackerProps) {
const isToolVisible = useCheckToolsVisibility();

const { highlight, remove } = useHighlightData();
const { axisDomain } = usePanelPreferences('spectra', activeTab);

const mouseIsOverDisplayer = useRef(false);
useEffect(() => {
Expand Down Expand Up @@ -439,6 +441,17 @@ function KeysListenerTracker(props: KeysListenerTrackerProps) {
default:
}
}

if (e.shiftKey) {
switch (e.key) {
case 'F': {
dispatch({ type: 'SET_AXIS_DOMAIN', payload: { axisDomain } });
break;
}
default:
}
}

if (e.shiftKey && (e.metaKey || e.ctrlKey)) {
switch (e.key) {
case 's':
Expand All @@ -457,6 +470,7 @@ function KeysListenerTracker(props: KeysListenerTrackerProps) {
[
alignSpectraVerticallyHandler,
allow1DTool,
axisDomain,
changeDisplayViewModeHandler,
dispatch,
handleChangeOption,
Expand Down
98 changes: 90 additions & 8 deletions src/component/panels/SpectraPanel/SpectraPreferences.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import styled from '@emotion/styled';
import { Formik, FormikProps } from 'formik';
import { PanelsPreferences, Workspace } from 'nmr-load-save';
import {
Expand All @@ -12,7 +13,11 @@ import * as Yup from 'yup';

import { useChartData } from '../../context/ChartContext';
import { usePreferences } from '../../context/PreferencesContext';
import { GroupPane, GroupPaneStyle } from '../../elements/GroupPane';
import { InputStyle } from '../../elements/Input';
import Label from '../../elements/Label';
import { Scroller } from '../../elements/Scroller';
import FormikInput from '../../elements/formik/FormikInput';
import useNucleus from '../../hooks/useNucleus';
import { usePanelPreferencesByNuclei } from '../../hooks/usePanelPreferences';
import { convertPathArrayToString } from '../../utility/convertPathArrayToString';
Expand All @@ -22,6 +27,22 @@ import { PreferencesContainer } from '../extra/preferences/PreferencesContainer'

import { SpectraColumnsManager } from './base/SpectraColumnsManager';

const groupPaneStyle: GroupPaneStyle = {
header: {
color: 'black',
fontSize: '12px',
padding: '5px',
backgroundColor: '#f8f8f8',
},
container: {
paddingBottom: '10px',
},
};

const inputStyle: InputStyle = {
input: { padding: '5px' },
};

function validationColumns(obj) {
const validationObject = {};
for (const key of Object.keys(obj.nuclei)) {
Expand Down Expand Up @@ -160,14 +181,17 @@ function SpectraPreferences(props, ref: any) {
{nuclei?.map((n) => (
<Scroller.Item key={n} elementKey={n}>
<NucleusGroup nucleus={n}>
<SpectraColumnsManager
nucleus={n}
onAdd={handleAdd}
onDelete={handleDelete}
mapOnChangeValue={mapOnChangeValueHandler}
mapValue={mapValue}
datalist={datalist}
/>
<GroupPane text="General" style={groupPaneStyle}>
<SpectraColumnsManager
nucleus={n}
onAdd={handleAdd}
onDelete={handleDelete}
mapOnChangeValue={mapOnChangeValueHandler}
mapValue={mapValue}
datalist={datalist}
/>
</GroupPane>
<AxisPreferences nucleus={n} />
</NucleusGroup>
</Scroller.Item>
))}
Expand All @@ -177,4 +201,62 @@ function SpectraPreferences(props, ref: any) {
);
}

interface AxisPreferencesProps {
nucleus: string;
}

const Container = styled.div`
display: flex;
`;

function AxisPreferences(props: AxisPreferencesProps) {
const { nucleus } = props;

if (nucleus.split(',').length === 1) {
return (
<GroupPane text="X axis" style={groupPaneStyle}>
<AxisFields nucleus={nucleus} axis="x" />
</GroupPane>
);
}

return (
<>
<GroupPane text="X axis " style={groupPaneStyle}>
<AxisFields nucleus={nucleus} axis="x" />
</GroupPane>
<GroupPane text="Y axis " style={groupPaneStyle}>
<AxisFields nucleus={nucleus} axis="y" />
</GroupPane>
</>
);
}

interface AxisFieldsProps extends AxisPreferencesProps {
axis: 'x' | 'y';
}

function AxisFields(props: AxisFieldsProps) {
const { nucleus, axis } = props;

return (
<Container>
<Label title="From:">
<FormikInput
type="number"
style={inputStyle}
name={`nuclei.${nucleus}.axisDomain.${axis}.from`}
/>
</Label>
<Label title="To:" style={{ label: { paddingLeft: '5px' } }}>
<FormikInput
type="number"
style={inputStyle}
name={`nuclei.${nucleus}.axisDomain.${axis}.to`}
/>
</Label>
</Container>
);
}

export default memo(forwardRef(SpectraPreferences));
1 change: 1 addition & 0 deletions src/component/reducer/IgnoreActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ const ignoreActions = new Set<Partial<Action['type']>>([
'SET_ONE_DIMENSION_PIVOT_POINT',
'SET_TWO_DIMENSION_PIVOT_POINT',
'SET_DIMENSIONS',
'SET_AXIS_DOMAIN',
'SET_X_DOMAIN',
'SET_Y_DOMAIN',
'SET_ZOOM',
Expand Down
2 changes: 2 additions & 0 deletions src/component/reducer/Reducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,8 @@ function innerSpectrumReducer(draft: Draft<State>, action: Action) {
action,
);

case 'SET_AXIS_DOMAIN':
return DomainActions.handleSetDomain(draft, action);
case 'SET_X_DOMAIN':
return DomainActions.handleSetXDomain(draft, action);
case 'SET_Y_DOMAIN':
Expand Down
27 changes: 26 additions & 1 deletion src/component/reducer/actions/DomainActions.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { NmrData2DFt, NmrData2DFid } from 'cheminfo-types';
import { extent } from 'd3';
import { Draft } from 'immer';
import { Spectrum1D, Spectrum2D } from 'nmr-load-save';
import { Spectrum1D, Spectrum2D, XYAxisDomain } from 'nmr-load-save';

import { get1DDataXY } from '../../../data/data1d/Spectrum1D/get1DDataXY';
import { isSpectrum2D } from '../../../data/data2d/Spectrum2D';
Expand All @@ -12,6 +12,10 @@ import { getActiveSpectra } from '../helper/getActiveSpectra';
import { getActiveSpectrum } from '../helper/getActiveSpectrum';
import { ActionType } from '../types/ActionType';

type SetAxisDomainAction = ActionType<
'SET_AXIS_DOMAIN',
{ axisDomain?: XYAxisDomain }
>;
type SetXDomainAction = ActionType<
'SET_X_DOMAIN',
{ xDomain: [number, number] }
Expand All @@ -25,6 +29,7 @@ type MoveXAxisAction = ActionType<'MOVE', { shiftX: number; shiftY: number }>;
export type DomainActions =
| SetXDomainAction
| SetYDomainAction
| SetAxisDomainAction
| MoveXAxisAction;

function getActiveData(draft: Draft<State>): Spectrum1D[] {
Expand Down Expand Up @@ -271,6 +276,25 @@ function handleSetYDomain(draft: Draft<State>, action: SetYDomainAction) {
draft.yDomain = yDomain;
addToBrushHistory(draft, { xDomain: draft.xDomain, yDomain });
}
//action
function handleSetDomain(draft: Draft<State>, action: SetAxisDomainAction) {
const { axisDomain: { x, y } = {} } = action.payload;
const {
originDomain: { xDomain, yDomain },
displayerMode,
} = draft;
const x1 = x?.from || xDomain[0];
const x2 = x?.to || xDomain[1];
const y1 = y?.from || yDomain[0];
const y2 = y?.to || yDomain[1];

if (displayerMode === '1D') {
draft.xDomain = [x1, x2];
} else {
draft.xDomain = [x1, x2];
draft.yDomain = [y1, y2];
}
}

function handleMoveOverXAxis(draft: Draft<State>, action: MoveXAxisAction) {
const { shiftX, shiftY } = action.payload;
Expand Down Expand Up @@ -311,4 +335,5 @@ export {
handleSetXDomain,
handleSetYDomain,
handleMoveOverXAxis,
handleSetDomain,
};
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const getSpectraDefaultValues = (
nucleus?: string,
): PanelsPreferences['spectra'] => {
const preferences: SpectraNucleusPreferences = {
axisDomain: {},
columns: [
{
name: 'visible',
Expand Down

0 comments on commit 29a412a

Please sign in to comment.