Skip to content

Instantly share code, notes, and snippets.

@dianaow
Created March 30, 2019 07:04
Show Gist options
  • Save dianaow/3716f28e2c663376a3cf0103e480eb30 to your computer and use it in GitHub Desktop.
Save dianaow/3716f28e2c663376a3cf0103e480eb30 to your computer and use it in GitHub Desktop.
Template: Responsive visualization
license: mit

Responsive starter code from Curran Kelleher, with code explanation written by me.

Before i discovered Curran's concise method, i had my own method of creating responsive visualizations, as compared below. I prefer Curran's method as it neatly encapsulates variables in a single function.

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; }
.div1, .div2 { position: absolute; margin-top: 20px; }
.div2 { top: 50vh; }
</style>
</head>
<body>
<div class='outer'>
<div class="div1"></div>
<div class="div2"></div>
</div>
<script>
function ResponsiveComponent1(container,props) {
const { width, height } = props;
// trick: use the general update pattern
// create a single element
// need to assign it to new variable to make it be the merged enter-update selection (use let because 'svg' is reassigned in next line)
let svg = container.selectAll('svg').data([null])
svg = svg.enter().append('svg') // will only append an svg element on first invocation of function
.merge(svg) // update selection
.attr('width', width)
.attr('height', height);
const rect = svg.selectAll('rect').data([null]);
rect
.enter().append('rect')
.attr('rx', 100) // round rect corners to better check responsive accuracy. set 'rx' attribute before merge because it is constant and does not depend on props
.merge(rect)
.attr('width', width)
.attr('height', height);
}
function ResponsiveComponent2(svg, rect, props) {
const { width, height } = props;
svg.attr('width', width)
.attr('height', height);
rect.attr('rx', 100)
.attr('width', width)
.attr('height', height);
}
function renderMethod1() {
const body = d3.select('.div1');
ResponsiveComponent1(body, {
width: document.body.clientWidth,
height: document.body.clientHeight*0.4
});
}
// create rect element once before function invocation
const svg2 = d3.select('.div2').append('svg')
const rect2 = svg2.append('rect')
function renderMethod2() {
ResponsiveComponent2(svg2, rect2, {
width: document.body.clientWidth,
height: document.body.clientHeight*0.4
})
}
renderMethod1();
renderMethod2();
window.addEventListener('resize', renderMethod1);
window.addEventListener('resize', renderMethod2);
</script>
</body>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment