Slicing tool scales 1D slices with the global 2D maximum instead of the zoomed region

Aperta
#4,428 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 3 giorni

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
4/5
Tempo stimato
3-5 giorni
Idoneità per principianti
39/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Ferma
Stack tecnologico
react, typescript

Direzione di ricerca

Read src/component/2d/utilities/scale.ts and the horizontal and vertical slice chart callers named in the issue; compare how SlicingView.tsx gets the pointer position with how the current zoom domains are available. Check the related issue #3432 and the phase correction trace callers before choosing the scope. Done means slices in a zoomed region scale to visible intensities, with the maximum calculation and per render cost checked.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

Summary

When a 2D spectrum is zoomed, the 1D slices drawn by the slicing tool keep a y-scale computed from the global maximum of the whole 2D data set, ignoring the current zoom region. Peaks inside the zoomed region are therefore rendered flat / almost invisible, which makes the tool useless for weak regions.

The slice should be scaled against the visible (zoomed) region.

Evidence

slicing tool keeps the global y-scale after zooming

How to reproduce

  1. Open a 2D spectrum.
  2. Zoom into a region whose intensities are much lower than the global maximum.
  3. Activate the slicing tool and move the pointer over the zoomed region.

Actual: the 1D slices are flat lines (or barely visible bumps), because their y-scale still spans the global maximum.

Expected: the 1D slices are scaled against the visible region, so peaks inside the zoom are clearly resolved.

Root cause

src/component/2d/utilities/scale.ts (line 95):

function getMax(data: NmrData2D): number {
  let max;

  for (const { minZ, maxZ } of Object.values(data)) {
    const innerMax = Math.max(Math.abs(minZ), Math.abs(maxZ));
    if (max === undefined || max > innerMax) {
      max = innerMax;
    }
  }

  assert(typeof max === 'number');
  return max;
}

function getSliceYScale(
  data: NmrData2D,
  size: number,
  mode: SpectraDirection,
  options: SliceYScaleOptions = {},
) {
  const { margin = 10, scaleRatio = 1 } = options;
  const max = getMax(data);   // <-- whole data set, zoom is never taken into account
  size = mode === 'RTL' ? size : size / 2;
  return scaleLinear([0, max * scaleRatio] as number[], [size - margin, margin]);
}

getMax only reads minZ / maxZ, which are precomputed over the entire matrix, and none of the callers pass the current xDomain / yDomain:

  • src/component/2d/1d-tracer/HorizontalSliceChart.tsx:31
  • src/component/2d/1d-tracer/VerticalSliceChart.tsx:34

The same helper is also used by the phase-correction traces (src/component/2d/1d-tracer/phase-correction-traces/SpectrumPhaseTrace.tsx:41,56), so they share the behaviour.

SlicingView.tsx already computes the slice for the pointed position (getSlice(spectrum, { x: scale2dX.invert(x), y: scale2dY.invert(y) })) but the y-scale of the rendered slice is still global.

Suggested fix

Make the slice y-scale aware of the visible region, e.g. pass the current zoom domain (or the displayed sub-matrix) into getSliceYScale and compute the max from that window instead of from minZ / maxZ of the whole data set.

Two related details worth checking while in there:

  • if (max === undefined || max > innerMax) keeps the smallest of the per-block maxima (max > innerMax looks inverted if a true maximum is intended).
  • getSliceYScale is called on every render with data from spectrum.data; deriving the zoomed max will need to be memoized to avoid recomputing it per pointer move.

Related

Same defect as #3432 ("slicing tool should adapt the slice with respect to the zoom region", opened 2025-04-15). Recorded separately with fresh evidence and the root cause above; feel free to close one of them as a duplicate.

Environment

  • nmrium 3.1.0, commit 5989ec6d
Lingua principale
TypeScript
Stelle
84
Fork
35
Merge medio
4g 23h
PR unite (30g)
7

Preparare l'ambiente

Questo progetto non fornisce container di sviluppo, Dockerfile né guida per i contributori, quindi l'ambiente è a tuo carico: parti dal suo README e consulta la nostra guida al primo contributo per i passaggi generali.

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di cheminfo/nmrium

Tutte le issue di cheminfo/nmrium

Issue simili

Altre issue su TypeScript

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.