Получить ширину текстового элемента SVG d3.js после его создания.
Я пытаюсь получить ширину связки элементов text
, которые я создал с помощью d3.js
Вот как я их создаю:
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;
});
Затем я использую ширину для создания rectangles
того же размера, что и теги 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;
})
Я попробовал использовать метод Bbox от здесь, но я этого не понимаю. Я думаю, что выбор фактического элемента - это то, где я ошибаюсь.
Ответы
Ответ 1
Я бы сделал длину части исходных данных:
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;
});
а затем позже
var nodes = svg.selectAll("rect")
.data(dataset)
.enter()
.append("rect")
.attr("width", function(d) { return d.width; });
Ответ 2
Вы можете использовать getBoundingClientRect()
Пример:
.style('top', function (d) {
var currElemHeight = this.getBoundingClientRect().height;
}
edit: похоже, что он более подходит для элементов HTML. для элементов SVG вы можете использовать getBBbox().
Ответ 3
d3.selectAll
возвращает выбор. Вы можете получить каждый из элементов, перемещаясь по массиву в свойстве _groups
. Когда вы определяете ширину прямоугольника, вы можете использовать его индекс для получения соответствующего текстового элемента:
.attr('width', function (d, i) {
var textSelection = d3.selectAll('text');
return textSelection._groups[0][i].getComputedTextLength();
});
Свойство _groups
для выбора d3 имеет список узлов в [0]
. Этот список содержит все выбранные элементы, к которым вы можете получить доступ по индексу. Важно, чтобы вы получили элемент SVG, чтобы вы могли использовать метод getComputedTextLength
.
Вы также можете сначала рассмотреть элементы rect
, затем элементы text
, а затем вернуться к прямоугольникам, чтобы отредактировать атрибут width
, чтобы элементы text
находились поверх прямоугольники (если вы хотите заполнить прямоугольники цветом).
Update:
Обычно предпочитают, чтобы вы не обращались к _groups
, поэтому более безопасный способ получить соответствующую ширину текстового элемента:
.attr('width', function (d, i) {
return d3.selectAll('text').filter(function (d, j) { return i === j; })
.node().getComputedTextLength();
});
Использование node
безопасно извлекает элемент, а фильтр найдет текстовый элемент, который соответствует индексу.