Reputation: 129
I'm using d3.js library to create SVG charts. I use the width of the SVG element to determine the x.range, x-axis, ...)
<svg id="etendues" style="display:inline-block;width: calc( 100% - 501px);min-height:300px;float:left;"></svg>
...
let margin = {top: 20, right: 20, bottom: 20, left: 40};
let width = parseInt(d3.select('#etendues').style("width")) - margin.left - margin.right;
Everything was working as intended with d3.js 4.7.4. as d3.select('#etendues').style("width")
was returning the 'calculated' width of the element in pixels (also worked nicely on resize event).
However, since version 4.9 the behaviour of the selection.style method has changed.
"Change selection.style to return the inline style, if present."
d3.select('#etendues').style("width")
now returns 'calc( 100% - 501px)'
which is the textual inline style of the element which is not usable in my case (it works if I set an inline width style in pixels, but I don't want that).
Is there a workaround to obtain the old behaviour of getting the real calculated width in pixels of the element ?
Upvotes: 2
Views: 1858
Reputation: 66123
You can simply access the DOM node of the element using d3's selection.node
(i.e. d3.select(...).node()
), and then use window.getComputedStyle(elem).getPropertyValue(<prop>)
to get the computed width1, 2. In your case, you can:
const etendues = d3.select('#etendues').node();
window.getComputedStyle(etendues).getPropertyValue('width')
, orwindow.getComputedStyle(etendues).width
Just remember to use parseInt()
, since it will return a pixel value--you are already doing that though, so all is good :)
To wrap it up, you can use the following code:
const etendues = d3.select('#etendues').node();
let margin = {top: 20, right: 20, bottom: 20, left: 40};
let width = parseInt(window.getComputedStyle(etendues).width) - margin.left - margin.right;
Here is a slightly modified proof-of-concept example, meant to simply log the retrieved width to console:
const etendues = d3.select('#etendues').node();
console.log(parseInt(window.getComputedStyle(etendues).width));
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/4.9.1/d3.min.js"></script>
<svg id="etendues" style="display:inline-block;width: calc( 100% - 501px);min-height:300px;float:left;"></svg>
References to MDN docs:
Upvotes: 4