Reputation: 44278
I need my SVG in a webpage to dynamically resize based on window size, or to have multiple hardcoded widths and heights.
I am using the D3 library.
My problem is that it isn't just the SVG tag that needs a different canvas size, it is the children elements such as a rect
tag and g
tag that also need to resize or be completely re-rendered
How would this be done?
I realize I could listen to window resizing with
d3.select(window).on('resize', resize);
with my resize function doing all the logic, but exactly how and what width/heights to choose (or calculate) is beyond me
<div class="svg-container">
<svg width="960" height="500" preserveAspectRatio="xMidYMid" class="svg-content">
<defs>
<clipPath id="clip-upper">
<rect id="rect-clip-upper" width="960" height="305" x="-480" y="-305"> </rect>
</clipPath>
<clipPath id="clip-lower">
<rect id="rect-clip-lower" width="960" height="195" x="-480" y="0"></rect>
</clipPath>
</defs>
<g clip-path="url(#clip-upper)" transform="translate(480,305)"></g>
<g clip-path="url(#clip-lower)" transform="translate(480,305)"></g>
</svg>
Upvotes: 2
Views: 951
Reputation: 2131
Hi SVG it self suggest "Salable vector graphics" so it is responsive by nature so for that you just need to use "viewBox" attribute of <svg>
element. with your perspective use.
Upvotes: 1
Reputation: 2854
Instead of hardcoding a width, make it dependent upon the width of the parent of the svg. E.g.
width = svgParent[0][0].clientWidth - margin.left - margin.right;
height = svgParent[0][0].clientHeight - margin.top - margin.bottom;
Make sure that all your widths, heights, and positions are either calculated from data (in which case d3 will handle it) or relate to width/height in some way. Then, in your resize handler, just call child.attr("width", newWidth)
, child.attr("x", newX)
, etc. on all elements you want to resize.
If you're using axes, set the range to your new width value and call the axis function again (i.e. svg.select(".x.axis").call(xAxis)
). If you are using zoom or other similar features, you'll have to call them again.
Upvotes: 1
Reputation: 124249
If you add a viewBox to the svg element e.g. viewBox="0 0 960 500" you won't need to resize any children.
Upvotes: 2