import React, { useRef, useEffect } from 'react' import * as d3 from 'd3-selection' interface TextField { text: string setLineCount?: (a: number) => void align: string lineHeight: number maxAnnotationWidth?: number } export const TextField = ({ text, align, lineHeight, maxAnnotationWidth = 150, setLineCount }: TextField) => { const textnode = useRef(null) useEffect(() => { const splitedText = text.split(/\s+/) const targetText = d3.select(textnode.current) const testEL = document.createElement('svg') let testTextEL = document.createElement('svg') testTextEL = testEL.appendChild(testTextEL) const testSVG = d3.select(testEL) const testText = testSVG.append('text') const textInLines: string[][] = [] let line: string[] = [] document.body.appendChild(testEL) for (let i = 0; i < splitedText.length; i++) { line.push(splitedText[i]) testText.html(line.join(' ')) const currentWidth = testTextEL.getBoundingClientRect().width if (currentWidth > maxAnnotationWidth) { line.pop() textInLines.push(line) line = [splitedText[i]] } } textInLines.push(line) testSVG.remove() if (setLineCount) setLineCount(textInLines.length) targetText.html('') for (let i = 0; i < textInLines.length; i++) { targetText .append('tspan') .attr('x', 0) .attr('dy', i === 0 ? 0 : lineHeight) .html(textInLines[i].join(' ')) } }, []) return ( ) }