11import styled from '@emotion/styled' ;
2- import type { BoundingBox } from '@zakodium/nmrium-core' ;
3- import { rangesToACS } from 'nmr-processing' ;
4- import { useEffect , useState } from 'react' ;
2+ import type { BoundingBox , TextStyle } from '@zakodium/nmrium-core' ;
3+ import { useEffect , useMemo , useState } from 'react' ;
54import { BsArrowsMove } from 'react-icons/bs' ;
65import { FaTimes } from 'react-icons/fa' ;
76import { Rnd } from 'react-rnd' ;
7+ import { SVGStyledText } from 'react-science/ui' ;
88
9- import { isSpectrum1D } from '../../data/data1d/Spectrum1D/isSpectrum1D.js ' ;
9+ import { isSpectrum1D } from '../../data/data1d/Spectrum1D/index.ts ' ;
1010import { useChartData } from '../context/ChartContext.js' ;
1111import { useDispatch } from '../context/DispatchContext.js' ;
1212import { useGlobal } from '../context/GlobalContext.js' ;
1313import type { ActionsButtonsPopoverProps } from '../elements/ActionsButtonsPopover.js' ;
1414import { ActionsButtonsPopover } from '../elements/ActionsButtonsPopover.js' ;
15- import { useActiveNucleusTab } from '../hooks/useActiveNucleusTab.ts' ;
16- import { usePanelPreferences } from '../hooks/usePanelPreferences.js' ;
1715import { useSVGUnitConverter } from '../hooks/useSVGUnitConverter.js' ;
18- import useSpectraByActiveNucleus from '../hooks/useSpectraPerNucleus.js' ;
1916import { useTextMetrics } from '../hooks/useTextMetrics.ts' ;
2017import { useCheckExportStatus } from '../hooks/useViewportSize.js' ;
18+ import { useACSSettings } from '../hooks/use_acs_settings.ts' ;
19+ import { usePublicationStrings } from '../hooks/use_publication_strings.ts' ;
2120
2221const ReactRnd = styled ( Rnd ) `
2322 border: 1px solid transparent;
@@ -36,11 +35,17 @@ interface UseWrapSVGTextParams {
3635 text : string ;
3736 width : number ;
3837 fontSize : number ;
38+ fontStyle : string | undefined ;
39+ fontWeight : string | undefined ;
3940}
4041
4142function useWrapSVGText ( params : UseWrapSVGTextParams ) {
42- const { text, width, fontSize } = params ;
43- const { getTextWidth } = useTextMetrics ( fontSize ) ;
43+ const { text, width, fontSize, fontStyle, fontWeight } = params ;
44+ const { getTextWidth } = useTextMetrics ( {
45+ labelSize : fontSize ,
46+ labelStyle : fontStyle ,
47+ labelWeight : fontWeight ,
48+ } ) ;
4449
4550 const formattedText = text
4651 . replaceAll ( / < s u p > (?< n > .* ?) < \/ s u p > / g, '++$1++ ' )
@@ -73,28 +78,36 @@ function useWrapSVGText(params: UseWrapSVGTextParams) {
7378
7479interface PublicationTextProps {
7580 text : string ;
81+ textStyle : TextStyle ;
7682 fontSize ?: number ;
7783 width : number ;
7884 padding ?: number ;
7985}
8086
8187function PublicationText ( props : PublicationTextProps ) {
82- const { fontSize = 12 , padding = 10 , width, text } = props ;
88+ const { text, width } = props ;
89+ const textStyle = {
90+ ...props . textStyle ,
91+ fontSize : props . textStyle . fontSize ?? props . fontSize ?? 12 ,
92+ } ;
93+ const { fontSize = textStyle . fontSize , padding = 10 } = props ;
8394 const boxWidth = width - padding * 2 ;
8495
8596 const { lineHeight, lines } = useWrapSVGText ( {
8697 width : boxWidth ,
8798 fontSize,
99+ fontStyle : textStyle . fontStyle ,
100+ fontWeight : textStyle . fontWeight ,
88101 text,
89102 } ) ;
90103
91104 return (
92105 < g transform = { `translate(${ padding } ${ padding } )` } >
93106 { lines . map ( ( line , lineIndex ) => (
94- < text
107+ < SVGStyledText
95108 // eslint-disable-next-line react/no-array-index-key
96109 key = { lineIndex }
97- fontSize = { fontSize }
110+ { ... textStyle }
98111 fontFamily = "Arial"
99112 y = { lineIndex * lineHeight }
100113 dominantBaseline = "hanging"
@@ -119,7 +132,7 @@ function PublicationText(props: PublicationTextProps) {
119132 return < tspan key = { wordIndex } > { word } </ tspan > ;
120133 }
121134 } ) }
122- </ text >
135+ </ SVGStyledText >
123136 ) ) }
124137 </ g >
125138 ) ;
@@ -129,16 +142,18 @@ interface DraggablePublicationStringProps {
129142 value : string ;
130143 bonding : BoundingBox ;
131144 spectrumKey : string ;
145+ nucleus : string | undefined ;
132146}
133147
134148function DraggablePublicationString ( props : DraggablePublicationStringProps ) {
135- const { value, bonding : externalBounding , spectrumKey } = props ;
149+ const { value, bonding : externalBounding , spectrumKey, nucleus } = props ;
136150 const dispatch = useDispatch ( ) ;
137151 const { viewerRef } = useGlobal ( ) ;
138152 const [ bounding , setBounding ] = useState < BoundingBox > ( externalBounding ) ;
139153 const [ isMoveActive , setIsMoveActive ] = useState ( false ) ;
140154 const { percentToPixel, pixelToPercent } = useSVGUnitConverter ( ) ;
141155 const isExportProcessStart = useCheckExportStatus ( ) ;
156+ const acsOptions = useACSSettings ( nucleus ) ;
142157
143158 useEffect ( ( ) => {
144159 setBounding ( { ...externalBounding } ) ;
@@ -254,7 +269,11 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
254269 if ( isExportProcessStart ) {
255270 return (
256271 < g transform = { `translate(${ x } ${ y } )` } >
257- < PublicationText text = { value } width = { width } />
272+ < PublicationText
273+ text = { value }
274+ width = { width }
275+ textStyle = { acsOptions . textStyle }
276+ />
258277 </ g >
259278 ) ;
260279 }
@@ -298,51 +317,35 @@ function DraggablePublicationString(props: DraggablePublicationStringProps) {
298317 y = { y }
299318 >
300319 < svg width = { width } height = { 'auto' } xmlns = "http://www.w3.org/2000/svg" >
301- < PublicationText text = { value } width = { width } />
320+ < PublicationText
321+ text = { value }
322+ width = { width }
323+ textStyle = { acsOptions . textStyle }
324+ />
302325 </ svg >
303326 </ ActionsButtonsPopover >
304327 </ ReactRnd >
305328 ) ;
306329}
307330
308- function usePublicationString ( ) {
309- const spectra = useSpectraByActiveNucleus ( ) ;
310- const activeTab = useActiveNucleusTab ( ) ;
311- const rangesPreferences = usePanelPreferences ( 'ranges' , activeTab ) ;
312-
313- const output : Record < string , string > = { } ;
314-
315- for ( const spectrum of spectra ) {
316- if ( ! isSpectrum1D ( spectrum ) ) {
317- continue ;
318- }
319- const { id : spectrumKey , info, ranges } = spectrum ;
320-
321- if ( ! Array . isArray ( ranges ?. values ) || ranges . values . length === 0 ) {
322- continue ;
323- }
324-
325- const { originFrequency : observedFrequency , nucleus } = info ;
326-
327- const value = rangesToACS ( ranges . values , {
328- nucleus, // '19f'
329- deltaFormat : rangesPreferences . deltaPPM . format ,
330- couplingFormat : rangesPreferences . coupling . format ,
331- observedFrequency, //400
332- } ) ;
333-
334- output [ spectrumKey ] = value ;
335- }
336-
337- return output ;
338- }
339-
340331export function FloatPublicationString ( ) {
341- const publicationString = usePublicationString ( ) ;
332+ const publicationString = usePublicationStrings ( ) ;
342333 const {
334+ data : spectra ,
343335 view : { ranges } ,
344336 } = useChartData ( ) ;
345- const options = Object . entries ( ranges ) ;
337+ const options = useMemo ( ( ) => Object . entries ( ranges ) , [ ranges ] ) ;
338+ const spectraToNucleusMap = useMemo ( ( ) => {
339+ const map = new Map < string , string > ( ) ;
340+
341+ for ( const spectrum of spectra ) {
342+ if ( ! isSpectrum1D ( spectrum ) ) continue ;
343+ const { nucleus } = spectrum . info ;
344+ map . set ( spectrum . id , nucleus ) ;
345+ }
346+
347+ return map ;
348+ } , [ spectra ] ) ;
346349
347350 return options . map ( ( [ spectrumKey , viewOptions ] ) => {
348351 const { showPublicationString, publicationStringBounding } = viewOptions ;
@@ -352,6 +355,7 @@ export function FloatPublicationString() {
352355 < DraggablePublicationString
353356 key = { spectrumKey }
354357 spectrumKey = { spectrumKey }
358+ nucleus = { spectraToNucleusMap . get ( spectrumKey ) }
355359 bonding = { publicationStringBounding }
356360 value = { publicationString [ spectrumKey ] }
357361 />
0 commit comments