import styled from '@emotion/styled';
import type { ActiveSpectrum, Spectrum1D } from '@zakodium/nmrium-core';
import { xFindClosestIndex } from 'ml-spectra-processing';
import { memo } from 'react';
import { BsCursor } from 'react-icons/bs';
import { IoPulseSharp } from 'react-icons/io5';
import { get1DDataXY } from '../../data/data1d/Spectrum1D/get1DDataXY.js';
import { useBrushTracker } from '../EventsTrackers/BrushTracker.js';
import { useMouseTracker } from '../EventsTrackers/MouseTracker.js';
import { useChartData } from '../context/ChartContext.js';
import { useScaleChecked } from '../context/ScaleContext.js';
import { FooterContainer, InfoItem } from '../elements/Footer.js';
import { useActiveSpectrum } from '../hooks/useActiveSpectrum.js';
import { useFormatNumberByNucleus } from '../hooks/useFormatNumberByNucleus.js';
import useSpectrum from '../hooks/useSpectrum.js';
import { useInsetOptions } from './inset/InsetProvider.js';
const FlexInfoItem = styled(InfoItem)`
align-items: center;
`;
const InfoBlock = styled(InfoItem)`
white-space: nowrap;
`;
const Separator = styled.div`
border-left: 2px solid gray;
height: 10px;
margin: 0 10px;
width: 1px;
`;
interface FooterBannerInnerProps {
margin: {
top: number;
left: number;
right: number;
bottom: number;
};
width: number;
height: number;
activeSpectrum: ActiveSpectrum | null;
spectrum: Spectrum1D;
activeTab: string;
}
function FooterBannerInner({
margin,
width,
height,
activeSpectrum,
spectrum,
activeTab,
}: FooterBannerInnerProps) {
const position = useMouseTracker();
const { startX, endX, step, mouseButton } = useBrushTracker();
const { scaleX } = useScaleChecked();
const format = useFormatNumberByNucleus(activeTab);
const isInset = useInsetOptions();
if (isInset) {
return null;
}
if (
!position ||
position.y < margin.top ||
position.x < margin.left ||
position.x > width - margin.right ||
position.y > height - margin.bottom
) {
return ;
}
function getXIndex(xPosition: number) {
if (spectrum) {
const data = get1DDataXY(spectrum);
return xFindClosestIndex(data.x, scaleX().invert(xPosition));
}
return 0;
}
function getYValue(xPosition: number) {
if (spectrum) {
const data = get1DDataXY(spectrum);
const xIndex = getXIndex(xPosition);
return data.y[xIndex];
}
return 1;
}
const isBrushing = step === 'brushing' && mouseButton === 'main';
return (
đť›…:
{format(scaleX().invert(position.x))}
ppm
{activeSpectrum && spectrum?.info?.originFrequency && (
<>
(
{format(
scaleX().invert(position.x) * spectrum?.info?.originFrequency,
'hz',
)}
Hz
)
,
Index:
{getXIndex(position.x)}
>
)}
{isBrushing && (
Δppm:
{(scaleX().invert(startX) - scaleX().invert(endX)).toPrecision(6)}
)}
{activeSpectrum && (
{spectrum?.info?.originFrequency && isBrushing && (
ΔHz:
{(
(scaleX().invert(startX) - scaleX().invert(endX)) *
spectrum?.info?.originFrequency
).toPrecision(5)}
)}
{isBrushing && (
ratio :
{(
(getYValue(startX) / (getYValue(endX) || Number.MIN_VALUE)) *
100
).toFixed(2)}
%
)}
)}
{activeSpectrum && (
Intensity:
{format(getYValue(position.x))}
)}
);
}
const MemoizedFooterBanner = memo(FooterBannerInner);
export default function FooterBanner() {
const {
margin,
width,
height,
view: {
spectra: { activeTab },
},
} = useChartData();
const activeSpectrum = useActiveSpectrum();
const spectrum = useSpectrum(null) as Spectrum1D;
return (
);
}