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 ( ); }