Je voudrais que le texte soit placé sur l’arbre D3 suivant afin qu’au lieu de
Foo is not a long Word
chaque ligne est emballée à
Foo is
not a
long Word
J'ai essayé de transformer le texte en objet "foreignObject" plutôt qu'en objet texte; le texte est effectivement renvoyé à la ligne, mais il ne bouge pas dans l'animation de l'arborescence et est tout regroupé dans le coin supérieur gauche.
Code situé à
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; });
}
Vous pouvez modifier l'exemple "Enveloppe de longues étiquettes" de Mike Bostock pour ajouter des éléments <tspan>
à vos nœuds <text>
. Deux modifications majeures sont nécessaires pour ajouter du texte enveloppé à vos nœuds. Je n'ai pas cherché à faire en sorte que le texte mette à jour sa position lors des transitions, mais cela ne devrait pas être trop difficile à ajouter.
La première consiste à ajouter une fonction wrap
, basée sur la fonction dans l'exemple ci-dessus. wrap
se chargera d’ajouter des éléments <tspan>
pour adapter votre texte à une certaine largeur:
function wrap(text, width) {
text.each(function () {
var text = d3.select(this),
words = text.text().split(/\s+/).reverse(),
Word,
line = [],
lineNumber = 0,
lineHeight = 1.1, // ems
x = text.attr("x"),
y = text.attr("y"),
dy = 0, //parseFloat(text.attr("dy")),
tspan = text.text(null)
.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", dy + "em");
while (Word = words.pop()) {
line.Push(Word);
tspan.text(line.join(" "));
if (tspan.node().getComputedTextLength() > width) {
line.pop();
tspan.text(line.join(" "));
line = [Word];
tspan = text.append("tspan")
.attr("x", x)
.attr("y", y)
.attr("dy", ++lineNumber * lineHeight + dy + "em")
.text(Word);
}
}
});
}
La deuxième modification est qu'au lieu de définir le texte de chaque nœud, vous devez appeler wrap
pour chaque nœud:
// 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")
.call(wrap, 30); // wrap the text in <= 30 pixels
Une autre option, si vous souhaitez ajouter une autre librairie JS, consiste à utiliser D3plus , un addon D3. Il a intégré texte encapsulant fonctionnalité. Il prend même en charge le remplissage et le redimensionnement du texte afin de remplir l'espace disponible.
d3plus.textwrap()
.container(d3.select("#rectWrap"))
.draw();
Je l'ai utilisé. Cela vaut certainement mieux que de calculer vous-même l’emballage.
Il y a un autre plugin d3 disponible pour l'habillage de texte, mais je ne l'ai jamais utilisé, je ne peux donc pas vous parler de son utilité.
C’est un moyen de retourner un texte avec d3 plus. C'est vraiment facile pour moi et fonctionne dans tous les navigateurs dès maintenant
d3plus.textwrap()
.container(d3.select("#intellectual"))
.shape('square')
.width(370)
.height(55)
.resize(true)
.draw();