2

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>

CQM
  • 42,592
  • 75
  • 224
  • 366
  • See https://stackoverflow.com/questions/9400615/whats-the-best-way-to-make-a-d3-js-visualisation-layout-responsive – Lars Kotthoff Jun 26 '15 at 16:33
  • @LarsKotthoff thanks! I had searched on the net for a few solutions, which were not working for my use case, and stackoverflow didn't even suggest relevant ones like that question – CQM Jun 26 '15 at 16:34

3 Answers3

2

If you add a viewBox to the svg element e.g. viewBox="0 0 960 500" you won't need to resize any children.

Robert Longson
  • 118,664
  • 26
  • 252
  • 242
  • ah I saw that but I didn't realize this benefit over modifying the html style width and height selectors, I will give this a shot! – CQM Jun 26 '15 at 14:52
  • width and height is the size of the drawing, viewBox is the size of the contents. – Robert Longson Jun 26 '15 at 14:54
  • I did this and ended up simply using the @media css attribute and declaring certain sizes – CQM Jun 27 '15 at 00:29
1

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.

quw
  • 2,844
  • 1
  • 26
  • 35
1

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.

quw
  • 2,844
  • 1
  • 26
  • 35
Himesh Aadeshara
  • 2,114
  • 16
  • 26