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
Add ellipses to overflowing text in SVG?
提问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 foreignObject
to 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);
回答by Akhil A
If you write CSS it won't work on . Instead of that write logic and append '...' in string.
如果您编写 CSS,它将无法在 . 而不是那种写逻辑并在字符串中附加“...”。