admin管理员组

文章数量:1278823

Using react, I'm displaying the following

<g>
  <rect x={x} y={y} width={width} height={height} />
  <text x={x + width / 2} y={y + height / 2 + 7} textAnchor="middle">
    {someText}
  </text>
</g>

But given the value of width, I want to show or hide my <text> element. Or, I want my text element to behave with overflow: ellipsis if the text element is wider than width.

Ie, if width = 100 and the width of my <text> element = 200, then display 50% of <text> and append ... to someText.

Browsing through mozilla documentation and some svg documentation I'm not finding obvious.

What would be the most clever and efficient way to go about doing this?

Using react, I'm displaying the following

<g>
  <rect x={x} y={y} width={width} height={height} />
  <text x={x + width / 2} y={y + height / 2 + 7} textAnchor="middle">
    {someText}
  </text>
</g>

But given the value of width, I want to show or hide my <text> element. Or, I want my text element to behave with overflow: ellipsis if the text element is wider than width.

Ie, if width = 100 and the width of my <text> element = 200, then display 50% of <text> and append ... to someText.

Browsing through mozilla documentation and some svg documentation I'm not finding obvious.

What would be the most clever and efficient way to go about doing this?

Share Improve this question edited Feb 25 at 18:18 gh0st asked Feb 24 at 22:31 gh0stgh0st 1,7224 gold badges28 silver badges63 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

SVG doesn't have built-in support for overflow: ellipsis, but you can achieve the same effect by measuring the text width and truncating it if necessary.

import React, { useState, useEffect, useRef } from "react";

const TruncatedText = ({ x, y, width, height, someText }) => {
  const textRef = useRef(null);
  const [displayText, setDisplayText] = useState(someText);

  useEffect(() => {
    if (textRef.current) {
      const textWidth = textRef.current.getBBox().width; 
      if (textWidth > width) {
        let truncated = someText;
        while (textRef.current.getBBox().width > width && truncated.length > 0) {
          truncated = truncated.slice(0, -1); // Remove last character
          setDisplayText(truncated + "...");
        }
      }
    }
  }, [someText, width]);

  return (
    <g>
      <rect x={x} y={y} width={width} height={height} fill="lightgray" />
      {displayText && (
        <text ref={textRef} x={x + width / 2} y={y + height / 2 + 7} textAnchor="middle">
          {displayText}
        </text>
      )}
    </g>
  );
};

export default TruncatedText;

If you want to completely hide the text when it doesn't fit, just wrap the in a condition:

{displayText.length > 3 && (
  <text ref={textRef} x={x + width / 2} y={y + height / 2 + 7} textAnchor="middle">
    {displayText}
  </text>
)}

本文标签: javascriptHow do I hideshow a lttextgt element within ltggt given a sibling elements widthStack Overflow