J'essaie d'obtenir la largeur d'un tas d'éléments text
que j'ai créés avec d3.js
Voici comment je les crée:
var nodesText = svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d.name;
})
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return 45;
});
J'utilise ensuite la largeur pour créer rectangles
la même taille que les cases text
var nodes = svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return 25;
})
.attr("width", function(d, i) {
//To Do: find width of each text element, after it has been generated
var textWidth = svg.selectAll("text")
.each(function () {
return d3.select(this.getComputedTextLength());
});
console.log(textWidth);
return textWidth;
})
.attr("height", function(d) {
return 30;
})
J'ai essayé d'utiliser la méthode Bbox de ici mais je ne la comprends pas vraiment. Je pense que la sélection de l'élément réel est l'endroit où je me trompe vraiment.
Je voudrais faire la longueur des données d'origine:
var nodesText = svg.selectAll("text")
.data(dataset)
.enter()
.append("text")
.text(function(d) {
return d.name;
})
.attr("x", function(d, i) {
return i * (w / dataset.length);
})
.attr("y", function(d) {
return 45;
})
.each(function(d) {
d.width = this.getBBox().width;
});
et plus tard
var nodes = svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("width", function(d) { return d.width; });
Vous pouvez utiliser getBoundingClientRect()
Exemple:
.style('top', function (d) {
var currElemHeight = this.getBoundingClientRect().height;
}
edit: semble plus approprié pour les éléments HTML. pour les éléments SVG, vous pouvez utiliser getBBbox () à la place.
d3.selectAll
renvoie un sélection. Vous pouvez obtenir chacun des éléments en parcourant le tableau dans la propriété _groups
. Lorsque vous déterminez la largeur d'un rectangle, vous pouvez utiliser son index pour obtenir l'élément de texte correspondant:
.attr('width', function (d, i) {
var textSelection = d3.selectAll('text');
return textSelection._groups[0][i].getComputedTextLength();
});
La propriété _groups
de la sélection de d3 a une liste de nœuds à [0]
. Cette liste contient tous les éléments} sélectionnés, auxquels vous pouvez accéder par index. Il est important que vous obteniez le SVG element pour pouvoir utiliser la méthode getComputedTextLength
.
Vous pouvez également envisager de créer d'abord les éléments rect
, puis les éléments text
, puis de revenir aux rectangles pour modifier l'attribut width
, de sorte que les éléments text
soient au-dessus des rectangles (au cas où vous voudriez remplir les rectangles avec la couleur).
Mettre à jour:
Cependant, il est généralement préférable de ne pas accéder à _groups
. Un moyen plus sûr d'obtenir la largeur de l'élément de texte correspondant serait:
.attr('width', function (d, i) {
return d3.selectAll('text').filter(function (d, j) { return i === j; })
.node().getComputedTextLength();
});
Utiliser node
récupère en toute sécurité l'élément et le filtre trouvera l'élément de texte qui correspond à l'index.