D3.js: Как получить вычисленную ширину и высоту для произвольного элемента?
Мне нужно точно знать ширину и высоту для произвольного элемента g
в моем SVG
, потому что мне нужно нарисовать маркер выделения, когда пользователь щелкнул его.
То, что я видел в Интернете, это что-то вроде: d3.select("myG").style("width")
. Проблема в том, что элемент не всегда будет иметь атрибут ширины явной ширины. Например, когда я создаю круг внутри g
, он будет иметь вместо него ширину (r
). Даже если я использую метод window.getComputedStyle
на circle
, он вернет "авто".
Есть ли способ вычислить ширину произвольного сегмента SVG
в D3
?
Спасибо.
Ответы
Ответ 1
Для элементов SVG
Используя что-то вроде selection.node().getBBox()
, вы получаете такие значения, как
{
height: 5,
width: 5,
y: 50,
x: 20
}
Для элементов HTML
Используйте selection.node().getBoundingClientRect()
Ответ 2
.getBoundingClientRect() возвращает размер элемента и его позицию относительно окна просмотра. Мы можем легко получить следующий
- влево, вправо
- верх, внизу
- высота, ширина
Пример:
var element = d3.select('.elementClassName').node();
element.getBoundingClientRect().width;
Ответ 3
Как только я столкнулся с проблемой, когда я не знал, какой элемент хранится в моей переменной (svg или html), но мне нужно было получить ее ширину и высоту. Я создал эту функцию и хочу поделиться ею:
function computeDimensions(selection) {
var dimensions = null;
var node = selection.node();
if (node instanceof SVGElement) { // check if node is svg element
dimensions = node.getBBox();
} else { // else is html element
dimensions = node.getBoundingClientRect();
}
console.log(dimensions);
return dimensions;
}
Маленькая демонстрация в скрытом фрагменте ниже. Мы обрабатываем щелчок на синем div и на круге красного SVG с той же функцией.
var svg = d3.select('svg')
.attr('width', 50)
.attr('height', 50);
function computeDimensions(selection) {
var dimensions = null;
var node = selection.node();
if (node instanceof SVGElement) {
dimensions = node.getBBox();
} else {
dimensions = node.getBoundingClientRect();
}
console.clear();
console.log(dimensions);
return dimensions;
}
var circle = svg
.append("circle")
.attr("r", 20)
.attr("cx", 30)
.attr("cy", 30)
.attr("fill", "red")
.on("click", function() { computeDimensions(circle); });
var div = d3.selectAll("div").on("click", function() { computeDimensions(div) });
* {
margin: 0;
padding: 0;
border: 0;
}
body {
background: #ffd;
}
.div {
display: inline-block;
background-color: blue;
margin-right: 30px;
width: 30px;
height: 30px;
}
<h3>
Click on blue div block or svg circle
</h3>
<svg></svg>
<div class="div"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.11.0/d3.min.js"></script>