Ich versuche, die Breite einer Reihe von text
-Elementen zu ermitteln, die ich mit d3.js erstellt habe
So erstelle ich sie:
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;
});
Ich verwende dann die Breite, um rectangles
die gleiche Größe wie die Boxen der text
zu erstellen
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;
})
Ich habe versucht, die Bbox-Methode von here zu verwenden, aber ich verstehe das nicht wirklich. Ich denke, dass die Auswahl des eigentlichen Elements darin liegt, dass ich wirklich falsch liege.
Ich würde die Länge Teil der ursprünglichen Daten machen:
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;
});
und dann später
var nodes = svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("width", function(d) { return d.width; });
Sie können getBoundingClientRect()
verwenden.
Beispiel:
.style('top', function (d) {
var currElemHeight = this.getBoundingClientRect().height;
}
edit: scheint für HTML-Elemente besser geeignet zu sein. Für SVG-Elemente können Sie stattdessen getBBbox () verwenden.
d3.selectAll
gibt eine selection zurück. Sie können jedes elements erhalten, indem Sie durch das Array in der _groups
-Eigenschaft navigieren. Wenn Sie die Breite eines Rechtecks bestimmen, können Sie dessen Index verwenden, um das entsprechende Textelement abzurufen:
.attr('width', function (d, i) {
var textSelection = d3.selectAll('text');
return textSelection._groups[0][i].getComputedTextLength();
});
Die _groups
-Eigenschaft der Auswahl von d3 verfügt über eine Liste von Knoten unter [0]
. Diese Liste enthält alle ausgewählten elements , auf die Sie per Index zugreifen können. Es ist wichtig, dass Sie das SVG Element erhalten, damit Sie die getComputedTextLength
-Methode verwenden können.
Vielleicht möchten Sie auch die rect
-Elemente erstellen, dann die text
-Elemente und dann zu den Rechtecken zurückkehren, um das width
-Attribut zu bearbeiten, sodass sich die text
-Elemente über den Rechtecken befinden (falls Sie die Rechtecke füllen möchten) mit Farbe).
Update:
In der Regel wird jedoch bevorzugt, dass Sie nicht auf _groups
zugreifen. Eine sicherere Methode zum Ermitteln der Breite des übereinstimmenden Textelements wäre:
.attr('width', function (d, i) {
return d3.selectAll('text').filter(function (d, j) { return i === j; })
.node().getComputedTextLength();
});
Wenn Sie node
verwenden, wird das Element sicher abgerufen, und der Filter findet das Textelement, das dem Index entspricht.