The most D3 examples that I can find are not responsive embedded SVG. I guess the main reason for that is not to confuse the reader of a tutorial with stuff outside of D3. With the help of How to Scale SVG from Amelia Bellamy-Royds I would like to show on a minimal D3 example how to make the resulting SVG responsive.
Let us start with the following minimal example that draws a white circle on a cyan rectangle.
<div id="wrapper"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var divWrapper = d3.select("#wrapper")
.append("svg")
.attr("width", 400)
.attr("height", 200);
divWrapper.append('rect')
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#cdebeb");
divWrapper.append("circle")
.attr("cx", 200)
.attr("cy", 100)
.attr("r", 50)
.attr("fill", "#ffffff");
</script>
The HTML and JavaScript code from above will result in the following embedded SVG that is not responsive.
I will use Option 4: Use the padding-bottom Hack on a Container. There are just a few things we have to change on the example from above.
width
and height
attribute on the wrapper
viewBox
attribute instead on the wrapper
wrapper
and the containing SVG with the padding-bottom Hack<style>
#wrapper {
position: relative;
height: 0;
width: 100%;
padding: 0;
/* padding-bottom will be overwritten by JavaScript later */
padding-bottom: 100%;
}
#wrapper > svg {
position: absolute;
height: 100%;
width: 100%;
left: 0;
top: 0;
}
</style>
<div id="wrapper"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var width = 400,
height = 200,
wrapper = d3.select("#wrapper")
.attr(
"style",
"padding-bottom: " + Math.ceil(height * 100 / width) + "%"
)
.append("svg")
.attr("viewBox", "0 0 " + width + " " + height);
wrapper.append('rect')
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "#cdebeb");
wrapper.append("circle")
.attr("cx", 200)
.attr("cy", 100)
.attr("r", 50)
.attr("fill", "#ffffff");
</script>
The result should be a responsive embedded D3 SVG image.