CSS 向 SVG 中的溢出文本添加省略号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15975440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-29 22:26:16  来源:igfitidea点击:

Add ellipses to overflowing text in SVG?

cssd3.jssvg

提问by Richard

I'm using D3.js. I'd like to find an SVG equivalent to this CSS class, which adds ellipses if text flows out of its containing div:

我正在使用D3.js. 我想找到一个等同于这个 CSS 类的 SVG,如果文本从其包含的 div 流出,它会添加省略号:

.ai-ellipsis {
  display: block;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  -o-text-overflow: ellipsis;
  -moz-binding: url(<q>assets/xml/ellipsis.xml#ellipsis</q>);
}

This is my SVG:

这是我的SVG:

<g class="bar" transform="translate(0,39)">
    <text class="label" x="-3" y="6.5" dy=".35em" text-anchor="start">Construction</text>    
    <rect height="13" width="123"></rect>
</g>

It's generated as follows:

它的生成如下:

barEnter.append("text").attr("class", "label")
        .attr("x", -3).attr("y", function() { return y.rangeBand() / 2})
        .attr("dy", ".35em").attr("text-anchor", "start")
        .text(function(d) {
            return d.Name;
        });

Currently the text is overflowing and overlapping the rect element.

当前文本溢出并与 rect 元素重叠。

Is there any way I can say "if text is more than a certain width, crop it and add ellipses"?

有什么办法可以说“如果文本超过特定宽度,则对其进行裁剪并添加省略号”?

采纳答案by Lars Kotthoff

I am not aware of an equivalent CSS class for SVG, but you can use foreignObjectto embed HTML in SVG. This gives you access to this functionality and is more flexible in general (e.g. you can do automatic line breaking easily).

我不知道 SVG 的等效 CSS 类,但您可以使用foreignObject将 HTML 嵌入到 SVG 中。这使您可以访问此功能,并且通常更灵活(例如,您可以轻松地进行自动换行)。

See herefor a complete example.

有关完整示例,请参见此处

回答by user2846569

a wrapper function for overflowing text:

用于溢出文本的包装函数:

    function wrap() {
        var self = d3.select(this),
            textLength = self.node().getComputedTextLength(),
            text = self.text();
        while (textLength > (width - 2 * padding) && text.length > 0) {
            text = text.slice(0, -1);
            self.text(text + '...');
            textLength = self.node().getComputedTextLength();
        }
    } 

usage:

用法:

text.append('tspan').text(function(d) { return d.name; }).each(wrap);

回答by c9s

This function does not depend on d3:

此函数不依赖于 d3:

function textEllipsis(el, text, width) {
  if (typeof el.getSubStringLength !== "undefined") {
    el.textContent = text;
    var len = text.length;
    while (el.getSubStringLength(0, len--) > width) {
        el.textContent = text.slice(0, len) + "...";
    }
  } else if (typeof el.getComputedTextLength !== "undefined") {
    while (el.getComputedTextLength() > width) {
      text = text.slice(0,-1);
      el.textContent = text + "...";
    }
  } else {
    // the last fallback
    while (el.getBBox().width > width) {
      text = text.slice(0,-1);
      // we need to update the textContent to update the boundary width
      el.textContent = text + "...";
    }
  }
}

回答by C. Draghici

function trimText(text, threshold) {
    if (text.length <= threshold) return text;
    return text.substr(0, threshold).concat("...");
}

Use this function to set the SVG node text. The value for the threshold (eg. 20) depends on you. This means that you will display up to 20 characters from your node text. All the texts grater than 20 characters will be trim and display "..." at the end of the trim text.

使用此函数设置 SVG 节点文本。阈值的值(例如 20)取决于您。这意味着您将显示节点文本中最多 20 个字符。所有大于 20 个字符的文本将被修剪并在修剪文本的末尾显示“...”。

Usage eg. :

用法例如。:

var self = this;
nodeText.text(x => self.trimText(x.name, 20)) // nodeText is the text element of the SVG node

回答by Mauro Colella

Just an update on the wrap function proposed by user2846569. getComputedTextLength()tends to be really slow, so...

只是对 user2846569 提出的 wrap 函数的更新。getComputedTextLength()往往很慢,所以......

EDIT

编辑

I diligently applied the advice by user2846569and made a version with "binary" search, with some calibration and parametrized precision.

我认真地应用了user2846569的建议,并制作了一个带有“二进制”搜索的版本,具有一定的校准和参数化精度。

'use strict';

var width = 2560;

d3.select('svg').attr('width', width);

// From http://stackoverflow.com/questions/10726909/random-alpha-numeric-string-in-javascript
function randomString(length, chars) {
    var result = '';
    for (var i = length; i > 0; --i)
        result += chars[Math.floor(Math.random() * chars.length)];
    return result;
}

function wrap() {
    var self = d3.select(this),
        textWidth = self.node().getComputedTextLength(),    // Width of text in pixel.
        initialText = self.text(),                          // Initial text.
        textLength = initialText.length,                    // Length of text in characters.
        text = initialText,
        precision = 10, //textWidth / width,                // Adjustable precision.
        maxIterations = 100; // width;                      // Set iterations limit.

    while (maxIterations > 0 && text.length > 0 && Math.abs(width - textWidth) > precision) {

        text = /*text.slice(0,-1); =*/(textWidth >= width) ? text.slice(0, -textLength * 0.15) : initialText.slice(0, textLength * 1.15);
        self.text(text + '...');
        textWidth = self.node().getComputedTextLength();
        textLength = text.length;
        maxIterations--;
    }
    console.log(width - textWidth);
}

var g = d3.select('g');

g.append('text').append('tspan').text(function(d) {
    return randomString(width, 'a');
}).each(wrap);

View on JSFiddle.

在 JSFiddle 上查看。

回答by Akhil A

If you write CSS it won't work on . Instead of that write logic and append '...' in string.

如果您编写 CSS,它将无法在 . 而不是那种写逻辑并在字符串中附加“...”。