// Formatting helpers shared by the viewer components. /** Gyromagnetic ratio of 1H, Hz/T — used to express gradients in mT/m. */ export const GAMMA = 42.576e6 /** Format a time in seconds with an adaptive unit. */ export function formatTime(t: number, digits = 4): string { const a = Math.abs(t) if (a >= 1) return `${t.toFixed(digits)} s` if (a >= 1e-3) return `${(t * 1e3).toPrecision(digits)} ms` if (a === 0) return '0' return `${(t * 1e6).toPrecision(digits)} µs` } /** Tick label for a time axis where the tick spacing is `step` seconds. */ export function formatTick(t: number, step: number): string { if (step >= 0.1) return `${trimZeros(t.toFixed(2))} s` if (step >= 1e-4) return `${trimZeros((t * 1e3).toFixed(3))} ms` return `${trimZeros((t * 1e6).toFixed(2))} µs` } function trimZeros(s: string): string { return s.includes('.') ? s.replace(/\.?0+$/, '') : s } /** Gradient amplitude, Hz/m -> compact display in both unit systems. */ export function formatGrad(hzPerM: number): string { const mTm = (hzPerM / GAMMA) * 1e3 return `${(hzPerM / 1e3).toFixed(1)} kHz/m (${mTm.toFixed(2)} mT/m)` } /** Slew rate, Hz/m/s -> display in T/m/s. */ export function formatSlew(hzPerMPerS: number): string { return `${(hzPerMPerS / GAMMA).toFixed(1)} T/m/s` } export function formatNumber(v: number, digits = 6): string { if (Number.isInteger(v)) return String(v) return String(Number(v.toPrecision(digits))) }