Reputation: 59336
I need to know exactly the width and height for an arbitrary g
element in my SVG
because I need to draw a selection marker around it once the user has clicked it.
What I've seen in the internet is something like: d3.select("myG").style("width")
. The problem is that the element will not always have an explicit width attribute set. For instance, when I create a circle inside the g
, it will have the radious (r
) set instead of the width. Even if I use the window.getComputedStyle
method on a circle
, it will return "auto".
Is there a way to calculate the width of an arbitrary svg
selement in D3
?
Thank you.
Upvotes: 141
Views: 136034
Reputation: 2970
Use even less code by just calling clientWidth directly:
const element = d3.select('yourElementIdOrClass');
const width = element.node().clientWidth;
Upvotes: 1
Reputation: 8509
Once I faced with the issue when I did not know which the element currently stored in my variable (svg or html) but I needed to get it width and height. I created this function and want to share it:
function computeDimensions(selection) {
var dimensions = null;
var node = selection.node();
if (node instanceof SVGGraphicsElement) { // check if node is svg element
dimensions = node.getBBox();
} else { // else is html element
dimensions = node.getBoundingClientRect();
}
console.log(dimensions);
return dimensions;
}
Little demo in the hidden snippet below. We handle click on the blue div and on the red svg circle with the same function.
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>
Upvotes: 3
Reputation: 6925
.getBoundingClientRect() returns the size of an element and its position relative to the viewport.We can easily get following
Example :
var element = d3.select('.elementClassName').node();
element.getBoundingClientRect().width;
Upvotes: 42
Reputation: 6192
Using something like selection.node().getBBox()
you get values like
{
height: 5,
width: 5,
y: 50,
x: 20
}
Use selection.node().getBoundingClientRect()
Upvotes: 274