D3.js v4.9 Get the estimated width of the selected item
I am using d3.js library to create SVG diagrams. I am using the width of the SVG element to define 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 worked as intended with d3.js 4.7.4. as it was d3.select('#etendues').style("width")
returning the "calculated" width of the element in pixels (also worked fine on a resize event).
However, since version 4.9 , the behavior 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 text inline style of the element, which cannot be used in my case (it works if I set the style of the line width in pixels, but I don't want that).
Is there a workaround for getting the old behavior of getting the actual calculated width in pixels of an element?
source to share
You can just access the DOM node of the element using d3 selection.node
(i.e. d3.select(...).node()
) and then use window.getComputedStyle(elem).getPropertyValue(<prop>)
to get the calculated width 1 , 2 . In your case, you can:
- Save the link i.e.
const etendues = d3.select('#etendues').node();
- Get width using inline JS:
-
window.getComputedStyle(etendues).getPropertyValue('width')
, or -
window.getComputedStyle(etendues).width
-
Don't forget to use parseInt()
, as it will return the pixel value - you are already doing that, so it's okay :)
To complete it, 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;
Below is a slightly modified example of a proof-of-concept designed to easily extract the resulting width to the 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>
Links to MDN docs:
source to share