我想得到的文本 Package 在下面的D3树,使而不是
Foo is not a long word
字符串
每一行都被绕成
Foo is
not a
long word
型
我试着把文本变成一个'foreignObject'而不是一个文本对象,文本确实会换行,但它不会在树动画上移动,而是全部分组在左手角。
代码位于
http://jsfiddle.net/mikeyai/X43X5/1/
JavaScript:
var width = 960,
height = 500;
var tree = d3.layout.tree()
.size([width - 20, height - 20]);
var root = {},
nodes = tree(root);
root.parent = root;
root.px = root.x;
root.py = root.y;
var diagonal = d3.svg.diagonal();
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(10,10)");
var node = svg.selectAll(".node"),
link = svg.selectAll(".link");
var duration = 750,
timer = setInterval(update, duration);
function update() {
if (nodes.length >= 500) return clearInterval(timer);
// Add a new node to a random parent.
var n = {id: nodes.length},
p = nodes[Math.random() * nodes.length | 0];
if (p.children) p.children.push(n); else p.children = [n];
nodes.push(n);
// Recompute the layout and data join.
node = node.data(tree.nodes(root), function(d) { return d.id; });
link = link.data(tree.links(nodes), function(d) { return d.source.id + "-" + d.target.id; });
// Add entering nodes in the parent’s old position.
node.enter().append("text")
.attr("class", "node")
.attr("x", function(d) { return d.parent.px; })
.attr("y", function(d) { return d.parent.py; })
.text('Foo is not a long word');
// Add entering links in the parent’s old position.
link.enter().insert("path", ".node")
.attr("class", "link")
.attr("d", function(d) {
var o = {x: d.source.px, y: d.source.py};
return diagonal({source: o, target: o});
});
// Transition nodes and links to their new positions.
var t = svg.transition()
.duration(duration);
t.selectAll(".link")
.attr("d", diagonal);
t.selectAll(".node")
.attr("x", function(d) { return d.px = d.x; })
.attr("y", function(d) { return d.py = d.y; });
}
型
6条答案
按热度按时间pgpifvop1#
您可以修改Mike Bostock's "Wrapping Long Labels" example以将
<tspan>
元素添加到<text>
节点。要向节点添加换行文本,需要进行两项主要更改。我没有深入研究在过渡期间让文本更新其位置,但这应该不难添加。第一个是添加一个函数
wrap
,基于上例中的函数。wrap
将负责添加<tspan>
元素,以使您的文本适合特定的宽度:字符串
第二个变化是,不是设置每个节点的文本,而是需要为每个节点调用
wrap
:型
2sbarzqh2#
如果您愿意添加另一个JS库,则可以使用D3plus,这是一个D3插件。它具有内置的text wrapping功能。它甚至支持填充和调整文本大小来填充可用空间。
字符串
我用过了这肯定比自己计算 Package 好。
有another d3 plugin可用于文本 Package ,但我从来没有使用过它,所以我不能说它的有用性。
y53ybaqx3#
如果你使用的是React,你可以使用的库是@visx/text。它公开了一个更强大的SVG文本元素,支持
width
参数。字符串
enyaitl34#
您还可以通过使用
foreignObject
在SVG中使用纯HTML元素。例如,我使用以下代码将HTML
div
附加到svg对象。字符串
结果:
型
如果样式是静态的,也可以使用
.attr('class', 'classname')
而不是所有的.style(...)
调用,并通过样式表插入样式。Source(and more info/options)from this SO answer .
ar7v8xwq5#
这是一种使用d3 plus进行文本换行的方法。这对我来说真的很容易,而且到目前为止可以在所有浏览器中使用
字符串
ikfrs5lh6#
你可以用这个函数来换行
字符串
在函数内部,它使用text.each()方法迭代选择中的每个文本元素,并分别应用 Package 逻辑。
它使用D3的d3.select(this)来选择迭代中的当前文本元素。
它使用.split(/\s+/)方法将文本元素的内容拆分为单词。/\s+/正则表达式用于通过空格(空格和换行符)分割文本。然后调用reverse()方法来颠倒单词的顺序。
它使用.filter((q)=> q)过滤掉任何空单词。此步骤对于文本中存在连续空格或前导/尾随空格的情况非常有用,因为它可以确保删除空单词。
lineHeight变量用于设置换行文本所需的行高。可以调整此值以控制行间距。
分别使用.attr(“y”)和.attr(“x”)检索文本元素的当前y和x属性。这些属性定义文本元素的初始位置。
dy变量设置为0,这意味着文本沿着y轴没有初始偏移。
使用.append(“tspan”)在文本元素中创建一个临时tspan元素。这个tspan元素用于计算文本的长度,而不需要实际修改内容。
使用.text(null)将text元素的文本内容设置为null,从而有效地清除内容。
tspan元素的x、y和dy属性设置为初始位置和偏移值。
此时,换行的设置已经完成,函数已经准备好处理单词并换行文本。
while循环中的其余代码负责实际的文本换行逻辑。它迭代words数组中的每个单词,并将其追加到当前tspan元素,同时测量其长度。
如果当前tspan的长度超过了指定的宽度,则通过创建一个新的tspan元素来开始一个新行。如果文本长度大于容器右侧或左侧的可用空间,则调整tspan元素的x属性以使文本适合可用空间。
在函数结束时,文本内容已经被换行,并且可能已经创建了多个tspan元素来容纳换行的行。