Responsive charts with d3.js





Like every other element of a webpage, charts deserve to be responsive: their size must adapt to the device size. This post describes several approaches allowing to get this feature for d3.js charts.

Most basic example


A common pattern to make a chart responsive:


<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the chart will take place -->
<div id="div_basicResize"></div>

<script>

// Initialize a SVG area. Note that the width is not specified yet, since unknown
var Svg = d3.select("#div_basicResize")
  .append("svg")
  .attr("height", 200)

// Create dummy data
var data = [19, 13, 54, 78, 98, 120, 138]

// Add X axis. Note that we don't know the range yet, so we cannot draw it.
var x = d3.scaleLinear()
  .domain([0, 150])
var xAxis = Svg.append("g")
  .attr("transform", "translate(0,150)")

// Initialize circles. Note that the X scale is not available yet, so we cannot draw them
var myCircles = Svg
  .selectAll("circles")
  .data(data)
  .enter()
  .append("circle")
    .style("fill", "#69b2b3")
    .attr("r", 20)
    .attr("cy", 100)



// A function that finishes to draw the chart for a specific device size.
function drawChart() {

  // get the current width of the div where the chart appear, and attribute it to Svg
  currentWidth = parseInt(d3.select('#div_basicResize').style('width'), 10)
  Svg.attr("width", currentWidth)

  // Update the X scale and Axis (here the 20 is just to have a bit of margin)
  x.range([ 20, currentWidth-20 ]);
  xAxis.call(d3.axisBottom(x))

  // Add the last information needed for the circles: their X position
  myCircles
    .attr("cx", function(d){ return x(d)})
  }


// Initialize the chart
drawChart()

// Add an event listener that run the function when dimension change
window.addEventListener('resize', drawChart );


</script>

Application to an area chart


First of all, make sure you understood how this basic area chart is built with d3.js. The following example just uses the concept described above to make it responsive. Try to change the window size!

Better performance with debouncing


The most common way to add responsiveness in d3.js is to use an event listener. Here is the basic idea:

The advantage of bootstrap


Using the bootstrap grid as a workaround for responsiveness