Skip to content

Commit a6098c8

Browse files
fix: correct rendering of 1D traces over the 2D (#3870)
* fix: correct rendering of 1D traces over the 2D * refactor: 2d footer * chore: throw error when function is invoked outside the 2D nucleus context * refactor: traces spectra for atom assignments
1 parent c1d1df9 commit a6098c8

9 files changed

Lines changed: 148 additions & 148 deletions

File tree

src/component/2d/FooterBanner.tsx

Lines changed: 78 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { Spectrum1D } from '@zakodium/nmrium-core';
21
import { xFindClosestIndex } from 'ml-spectra-processing';
32
import { Fragment, useMemo } from 'react';
43
import { MF } from 'react-mf';
@@ -16,13 +15,14 @@ import { useActiveSpectrum } from '../hooks/useActiveSpectrum.js';
1615
import { useFormatNumberByNucleus } from '../hooks/useFormatNumberByNucleus.js';
1716
import { options } from '../toolbar/ToolTypes.js';
1817

18+
import type { Spectrum1DTraces } from './useTracesSpectra.ts';
1919
import type { Get2DDimensionLayoutReturn } from './utilities/DimensionLayout.js';
2020
import { LAYOUT, getLayoutID } from './utilities/DimensionLayout.js';
2121
import { get1DYScale, get2DXScale, get2DYScale } from './utilities/scale.js';
2222

2323
interface FooterBannerProps {
2424
layout: Get2DDimensionLayoutReturn;
25-
data1D: Spectrum1D[];
25+
data1D: Spectrum1DTraces;
2626
}
2727

2828
export default function FooterBanner(props: FooterBannerProps) {
@@ -54,153 +54,128 @@ export default function FooterBanner(props: FooterBannerProps) {
5454

5555
const nuclei = activeTab.split(',');
5656
const [formatX, formatY] = useFormatNumberByNucleus(nuclei);
57+
const hasTraces = data1D.x || data1D.y;
5758

5859
const scaleX = useMemo(() => {
59-
if (data1D.length === 0) {
60-
return get2DXScale({ width, margin, xDomain, mode });
60+
if (selectedTool === options.slicing.id || !trackID) {
61+
return null;
6162
}
62-
if (selectedTool !== options.slicing.id) {
63-
switch (trackID) {
64-
case LAYOUT.top:
65-
case LAYOUT.main: {
66-
return get2DXScale({ width, margin, xDomain, mode });
67-
}
68-
case LAYOUT.left: {
69-
return get2DYScale({ height, margin, yDomain });
70-
}
71-
default:
72-
return null;
73-
}
63+
64+
if (!hasTraces || trackID === 'MAIN' || trackID === 'TOP') {
65+
return get2DXScale({ width, margin, xDomain, mode });
7466
}
75-
return null;
67+
68+
return get2DYScale({ height, margin, yDomain });
7669
}, [
77-
data1D,
78-
height,
79-
margin,
70+
hasTraces,
8071
selectedTool,
81-
trackID,
8272
width,
73+
margin,
8374
xDomain,
84-
yDomain,
8575
mode,
76+
trackID,
77+
height,
78+
yDomain,
8679
]);
8780

8881
const scaleY = useMemo(() => {
89-
if (data1D.length === 0) {
82+
if (selectedTool === options.slicing.id || !trackID) {
83+
return null;
84+
}
85+
86+
if (!hasTraces || trackID === 'MAIN') {
9087
return get2DYScale({ height, margin, yDomain });
9188
}
92-
if (selectedTool !== options.slicing.id) {
93-
switch (trackID) {
94-
case LAYOUT.main: {
95-
return get2DYScale({ height, margin, yDomain });
96-
}
97-
case LAYOUT.top: {
98-
return data1D[0]
99-
? get1DYScale(yDomains[data1D[0].id], margin.top)
100-
: null;
101-
}
102-
case LAYOUT.left: {
103-
return data1D[1]
104-
? get1DYScale(yDomains[data1D[1].id], margin.left)
105-
: null;
106-
}
107-
default:
108-
return null;
109-
}
89+
90+
if (trackID === 'TOP') {
91+
return data1D.x ? get1DYScale(yDomains[data1D.x.id], margin.top) : null;
11092
}
111-
return null;
112-
}, [data1D, height, margin, selectedTool, trackID, yDomain, yDomains]);
11393

94+
return data1D.y ? get1DYScale(yDomains[data1D.y.id], margin.left) : null;
95+
}, [
96+
data1D.x,
97+
data1D.y,
98+
hasTraces,
99+
height,
100+
margin,
101+
selectedTool,
102+
trackID,
103+
yDomain,
104+
yDomains,
105+
]);
114106
if (
115107
!activeSpectrum ||
116108
!position ||
117109
position.y < 10 ||
118110
position.x < 10 ||
119111
position.x > width - margin.right ||
120-
position.y > height - margin.bottom ||
121-
!data1D
112+
position.y > height - margin.bottom
122113
) {
123114
return <FooterContainer />;
124115
}
125116
const getRealYValue = (coordinate: any) => {
126-
let index: number | null = null;
117+
let axis: 'x' | 'y' | null = null;
127118
if (trackID === LAYOUT.top) {
128-
index = 0;
119+
axis = 'x';
129120
} else if (trackID === LAYOUT.left) {
130-
index = 1;
121+
axis = 'y';
131122
}
132-
if (index != null && scaleX != null && data1D[index]) {
133-
const datum = get1DDataXY(data1D[index]);
134-
const xIndex = xFindClosestIndex(datum.x, scaleX.invert(coordinate));
135-
return datum.y[xIndex];
123+
const spectrum = axis && data1D[axis];
124+
125+
if (!scaleX || !spectrum) {
126+
return 1;
136127
}
137-
return 1;
128+
129+
const datum = get1DDataXY(spectrum);
130+
const xIndex = xFindClosestIndex(datum.x, scaleX.invert(coordinate));
131+
return datum.y[xIndex];
138132
};
139133

140134
const getXValue = (x: number | null = null) => {
141-
if (scaleX != null) {
142-
switch (trackID) {
143-
case LAYOUT.main:
144-
case LAYOUT.top: {
145-
return scaleX.invert(x || position.x);
146-
}
147-
case LAYOUT.left: {
148-
return scaleX.invert(x || position.y);
149-
}
150-
default:
151-
return 0;
152-
}
135+
if (!scaleX || !trackID) return 0;
136+
137+
if (trackID === 'MAIN') {
138+
return scaleX.invert(x || position.y);
153139
}
154-
return 0;
140+
// return if the trackID = "MAIN" | "TOP"
141+
return scaleX.invert(x || position.x);
155142
};
156143

157144
const getYValue = () => {
158-
if (scaleY != null) {
159-
switch (trackID) {
160-
case LAYOUT.main:
161-
case LAYOUT.top: {
162-
return scaleY.invert(position.y);
163-
}
164-
case LAYOUT.left: {
165-
return scaleY.invert(position.x);
166-
}
167-
default:
168-
return 0;
169-
}
145+
if (!scaleY || !trackID) return 0;
146+
147+
if (trackID === 'LEFT') {
148+
return scaleY.invert(position.x);
170149
}
171-
return 0;
150+
151+
return scaleY.invert(position.y);
172152
};
173153

174154
const getRation = () => {
175-
switch (trackID) {
176-
case LAYOUT.top: {
177-
return (
178-
(getRealYValue(startX) / (getRealYValue(endX) || Number.MIN_VALUE)) *
179-
100
180-
).toFixed(2);
181-
}
182-
case LAYOUT.left: {
183-
return (
184-
(getRealYValue(startY) / (getRealYValue(endY) || Number.MIN_VALUE)) *
185-
100
186-
).toFixed(2);
187-
}
188-
default:
189-
return 0;
155+
if (!trackID || trackID === 'MAIN') return 0;
156+
157+
if (trackID === 'TOP') {
158+
return (
159+
(getRealYValue(startX) / (getRealYValue(endX) || Number.MIN_VALUE)) *
160+
100
161+
).toFixed(2);
190162
}
163+
164+
// tracKId = "LEFT"
165+
return (
166+
(getRealYValue(startY) / (getRealYValue(endY) || Number.MIN_VALUE)) *
167+
100
168+
).toFixed(2);
191169
};
192170

193171
const getDeltaX = () => {
194-
switch (trackID) {
195-
case LAYOUT.top: {
196-
return (getXValue(startX) - getXValue(endX)).toPrecision(6);
197-
}
198-
case LAYOUT.left: {
199-
return (getXValue(startY) - getXValue(endY)).toPrecision(6);
200-
}
201-
default:
202-
return 0;
172+
if (!trackID || trackID === 'MAIN') return 0;
173+
174+
if (trackID === 'TOP') {
175+
return (getXValue(startX) - getXValue(endX)).toPrecision(6);
203176
}
177+
178+
return (getXValue(startY) - getXValue(endY)).toPrecision(6);
204179
};
205180

206181
const getLabel = (label2d: any, label1d: any, nucleus: any) => {

src/component/2d/SVGContent2D.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
import type { Spectrum1D } from '@zakodium/nmrium-core';
2-
31
import { ClipPathContainer } from '../1d-2d/components/ClipPathContainer.js';
42
import SpectrumInfoBlock from '../1d-2d/components/SpectrumInfoBlock.js';
53
import { ShareDataProvider } from '../context/ShareDataContext.js';
@@ -8,12 +6,13 @@ import XAxis from './XAxis.js';
86
import YAxis from './YAxis.js';
97
import { FidContainer } from './fid/FidContainer.js';
108
import { FTContainer } from './ft/FTContainer.js';
9+
import type { Spectrum1DTraces } from './useTracesSpectra.ts';
1110
import { SignalsGuideLines } from './zones/SignalsGuideLines.js';
1211
import Zones from './zones/Zones.js';
1312
import ZonesAssignmentsLabels from './zones/ZonesAssignmentsLabels.js';
1413

1514
interface Chart2DProps {
16-
spectra?: Spectrum1D[];
15+
spectra: Spectrum1DTraces;
1716
}
1817

1918
export function SVGContent2D({ spectra }: Chart2DProps) {

src/component/2d/Viewer2D.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,15 +65,15 @@ function Viewer2D(props: Viewer2DProps) {
6565
<XYLabelPointer data1D={spectrumData} layout={DIMENSION} />
6666

6767
<>
68-
{spectrumData[0] && (
68+
{spectrumData.x && (
6969
<BrushXY
7070
axis="X"
7171
dimensionBorder={DIMENSION.TOP}
7272
height={margin.top}
7373
margin={{ ...margin, top: 0, bottom: 0 }}
7474
/>
7575
)}
76-
{spectrumData[1] && (
76+
{spectrumData.y && (
7777
<BrushXY
7878
axis="Y"
7979
dimensionBorder={DIMENSION.LEFT}

src/component/2d/ft/FTContainer.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
1-
import type { Spectrum1D } from '@zakodium/nmrium-core';
2-
31
import { isFt2DSpectrum } from '../../../data/data2d/Spectrum2D/isSpectrum2D.js';
42
import { ClipPathContainer } from '../../1d-2d/components/ClipPathContainer.js';
53
import useSpectrum from '../../hooks/useSpectrum.js';
64
import Left1DChart from '../1d-tracer/Left1DChart.js';
75
import Top1DChart from '../1d-tracer/Top1DChart.js';
6+
import type { Spectrum1DTraces } from '../useTracesSpectra.ts';
87

98
import Contours from './Contours.js';
109

1110
interface FTContainerProps {
12-
spectra?: Spectrum1D[];
11+
spectra: Spectrum1DTraces;
1312
}
1413

1514
export function FTContainer(props: FTContainerProps) {
@@ -23,8 +22,8 @@ export function FTContainer(props: FTContainerProps) {
2322

2423
return (
2524
<>
26-
{spectra?.[0] && <Top1DChart data={spectra[0]} />}
27-
{spectra?.[1] && <Left1DChart data={spectra[1]} />}
25+
{spectra.x && <Top1DChart data={spectra.x} />}
26+
{spectra.y && <Left1DChart data={spectra.y} />}
2827
<ClipPathContainer>
2928
<Contours />
3029
</ClipPathContainer>

src/component/2d/tools/XYLabelPointer.tsx

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import type { Spectrum1D } from '@zakodium/nmrium-core';
21
import type { CSSProperties } from 'react';
32
import { useMemo } from 'react';
43

@@ -7,6 +6,7 @@ import { useMouseTracker } from '../../EventsTrackers/MouseTracker.js';
76
import { useChartData } from '../../context/ChartContext.js';
87
import { useActiveSpectrum } from '../../hooks/useActiveSpectrum.js';
98
import { useFormatNumberByNucleus } from '../../hooks/useFormatNumberByNucleus.js';
9+
import type { Spectrum1DTraces } from '../useTracesSpectra.ts';
1010
import type { Get2DDimensionLayoutReturn } from '../utilities/DimensionLayout.js';
1111
import { LAYOUT, getLayoutID } from '../utilities/DimensionLayout.js';
1212
import { get1DYScale, useScale2DX, useScale2DY } from '../utilities/scale.js';
@@ -24,7 +24,7 @@ const style: CSSProperties = {
2424

2525
interface XYLabelPointerProps {
2626
layout: Get2DDimensionLayoutReturn;
27-
data1D: Spectrum1D[];
27+
data1D: Spectrum1DTraces;
2828
}
2929

3030
export default function XYLabelPointer(props: XYLabelPointerProps) {
@@ -53,9 +53,10 @@ export default function XYLabelPointer(props: XYLabelPointerProps) {
5353
const [formatX, formatY] = useFormatNumberByNucleus(nuclei);
5454
const scale2DX = useScale2DX();
5555
const scale2DY = useScale2DY();
56+
const hasTraces = data1D.x || data1D.y;
5657

5758
const scaleX = useMemo(() => {
58-
if (!activeSpectrum || data1D.length === 0) {
59+
if (!activeSpectrum || !hasTraces) {
5960
return scale2DX;
6061
}
6162

@@ -70,32 +71,32 @@ export default function XYLabelPointer(props: XYLabelPointerProps) {
7071
default:
7172
return null;
7273
}
73-
}, [activeSpectrum, data1D, scale2DX, scale2DY, trackID]);
74+
}, [activeSpectrum, hasTraces, scale2DX, scale2DY, trackID]);
7475

7576
const scaleY = useMemo(() => {
76-
if (!activeSpectrum || data1D.length === 0) {
77+
if (!activeSpectrum || !hasTraces) {
7778
return scale2DY;
7879
}
7980
switch (trackID) {
8081
case LAYOUT.main: {
8182
return scale2DY;
8283
}
8384
case LAYOUT.top: {
84-
return data1D[0]
85-
? get1DYScale(yDomains[data1D[0].id], margin.top)
86-
: null;
85+
return data1D.x ? get1DYScale(yDomains[data1D.x.id], margin.top) : null;
8786
}
8887
case LAYOUT.left: {
89-
return data1D[1]
90-
? get1DYScale(yDomains[data1D[1].id], margin.left)
88+
return data1D.y
89+
? get1DYScale(yDomains[data1D.y.id], margin.left)
9190
: null;
9291
}
9392
default:
9493
return null;
9594
}
9695
}, [
9796
activeSpectrum,
98-
data1D,
97+
data1D.x,
98+
data1D.y,
99+
hasTraces,
99100
margin.left,
100101
margin.top,
101102
scale2DY,

0 commit comments

Comments
 (0)