Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | 22x 22x 22x | import * as React from 'react'; import { select } from 'd3-selection'; interface ITextboxProps { text: string; width: number; x: number; y: number; lineHeight: number; textAnchor?: 'start' | 'middle' | 'end'; fontSize?: string; fill?: string; } export const Textbox: React.FunctionComponent<ITextboxProps> = props => { const textElementRef: React.RefObject<SVGTextElement> = React.useRef(null); const wrapWords = () => { Iif (!textElementRef.current) { return; } const text = select(textElementRef.current); const words = props.text.split(/\s+/); let line: string[] = []; let tspan = text.append<SVGTSpanElement>('tspan'); let numLines = 0; words.forEach(word => { line.push(word); tspan.text(line.join(' ')); const node = tspan.node(); Iif (node && node.getComputedTextLength() > props.width && line.length > 1) { numLines++; line.pop(); tspan.text(line.join(' ')); line = [word]; tspan = text.append<SVGTSpanElement>('tspan').text(word).attr('dy', props.lineHeight).attr('x', props.x); } }); // bottom aligns text text.attr('dy', -numLines * props.lineHeight); return () => { text.selectAll('tspan').remove(); }; }; React.useEffect(wrapWords); const { lineHeight, ...rest } = props; return <text ref={textElementRef} {...rest} />; }; |