Posted by & filed under Content - Highlights and Reviews, Programming & Development.

codeA guest post by Peter Le Bek, founder of RethinkUI, an frontend development agency based in Glasgow, UK. He tweets at @_lebek and writes code at github.com/lebek

In recent years D3.js has built a significant following: it’s now the de facto standard for web-based data visualization. Given that an important consideration when designing or building anything for the web is how it’ll behave on different devices, we’re going to look at some basic techniques that can make D3.js visualizations more responsive.

There’s an interesting twist when it comes to visualizations. Of all UI elements they’re often the first to be packaged into reusable components – the reason being that they’re often the most tedious to build. This means that in addition to considering variation between devices, we also need to consider variations in application context. The same graph component could appear in a narrow sidebar, embedded in text, or in fullscreen, and in every case this graph should capitalize on available space to present data in the most clear and understandable way.

Capitalizing on available space is as much about deciding what to put in the space as it is about scaling to fit inside it. Just scaling a visualization often leaves data drowned in labels and axes at small window sizes – a problem we’ll address by applying the idea of progressive disclosure. Starting with a very succinct version of the data at small window sizes, we progressively add complexity as the window expands.

All the code for this tutorial is available on github. The best way to understand what’s happening as we progress is to launch the demos and experiment by resizing the window.

Basic Graph

Let’s begin with a completely non-responsive line graph of the Amazon stock price (dataset).

This is a simple example, but the techniques we’ll use can be applied to any D3.js visualization.

Code | Demo

Scaling

The first step is to adjust the size of the graph to fit in the window. There are two basic ways to update the size of an existing visualization.

We can configure the SVG element to resize:

Or we can listen for a window resize event and run an update through D3.js:

The second approach is better because it allows us to fix the size of certain elements (e.g. text), while at the same time updating the overall width and height for the new window size. Here’s the update
code:

Demo

Note that there’s no need to create new scales, the existing objects can be updated. The calls to call() simply tell the axes to redraw themselves using the updated scale.

<h2

Now that our graph is scaling responsively it’s time to consider the tick labels. When we scale down to landscape mobile size the tick labels begin to overlap, and at desktop size they’re too spread out. We can fix this using the axis.ticks() function, which allows us to specify the number of ticks.

figure_1

The trick is to define this number relative to the pixel length of the axis:

Demo

This sets the number of tick marks such that there’s one every 50 pixels. We set a lower limit of 2 tick marks because in the absence of tick marks we should probably remove the axes all together – which leads us on to…

Removing the Axis

When the window size gets so small that the axes appears to fill more space than the line itself, it’s time to get rid of the axes.

Without the axes we lose the quantitative context for the line. We can fix this by marking the values at the start and end point:

This type of line graph is often referred to as a sparkline.

figure_2

Adapting the Data Resolution

We’re going to make one final improvement.

Our dataset contains 4202 data points. When the window is 400px wide we’re displaying about 10 data points per pixel (4202/400). Apart from creating unnecessary performance overhead, this overcrowding makes the line thick and difficult to read. The solution is to set the data resolution relative to the window size.

Demo

This code calculates the number of data points per pixel, in our case\~10. It then filters the data to contain every 10th point, which is a crude way to downsample the data but it works. The difference is subtle, but visible:

figure_3

Conclusion

Deciding how to display data across the array of devices and application contexts is a problem that requires some creativity, but on the technical side D3.js makes it quite easy to define and update elements according to the window size. I’ll leave you with some good examples of responsive D3.js visualizations:

Look below for some great D3.js books from Safari Books Online.

Not a subscriber? Sign up for a free trial.

Safari has the content you need

Developing a D3.js Edge is aimed at intermediate D3.js developers, so to get the most from this book you need to know some JavaScript, and you should have experience creating graphics using D3. You will also want to have a good debugger handy (Chrome Developer panel or the Firefox/Firebug combo), to help you step through the many real world examples that you’ll find in this book.
Interactive Data Visualization for the Web shows you how to create and publish your own interactive data visualization projects on the Web – even if you have little or no experience with data visualization or web development. It’s easy and fun with this practical, hands-on introduction. Author Scott Murray teaches you the fundamental concepts and methods of D3, a JavaScript library that lets you express data visually in a web browser.
Data Visualization with d3.js walks you through 20 examples. You can finally stop struggling to piece together examples you’ve found online. With this book, you will learn enough of the core concepts to conceive of and build your own visualizations from scratch.
It begins with the basics of putting lines on the screen, and builds on this foundation all the way to creating interactive animated visualizations using d3.js layouts.
Visual Storytelling with D3: An Introduction to Data Visualization in JavaScript provides readers with a strong framework of principles for making well-conceived and well-crafted infographics, as well as detailed and practical instructions for how to really wield D3, the best tool for making web infographics available. An extended example is used in the book to explain how to put theory to practical use.

Tags: D3.js, data resolution, Graph, responsive, Scaling, SVG, tick count, UI,

3 Responses to “Building Responsive Visualizations with D3.js”

  1. TomL

    Great article! I found that the charts did not resize properly in Firefox (27.0.1 Ubuntu). After some trial and error with various SO posts, the solution that worked for me was to add the following attribute to svg elements.

    svg { position:fixed; }

    Comments are welcome on whether this is a good solution.

  2. Peter Le Bek

    Good catch. My preference would be for:


    #graph {
    width: 100%;
    height: 100%;
    position: absolute;
    }

    position: absolute; will size the svg element relative to its parent so it fits anywhere.

    Thanks!

  3. adrian

    thanks for the post. what would be handy in d3 is some link with bootstrap css (or other responsive paradigm) such that one can assign “col-sm-12″ or “col-md-3″ to canvas or svg element. perhaps that is possible given the width: 100% example posted.