Building a lightweight, flexible D3.js dashboard (Part 3 of 3)

Posted on August 23, 2012 by Eric Benjamin Seufert

Part 1
Part 2

(The full sourcecode for the below example can be found here, and an interactive example can be found here. Click Open in a new Window to see all graphs in their pre-determined sizes)

The riveting conclusion! The last two posts in this series introduced D3.js and established the structure of a D3.js dashboard. This post will extend that foundation by creating a multi-dimensional (ie more than one country) dataset that can be browsed through a console.

The first thing we must do is add more data to the dataset; for this example, we’ll add data for two additional countries: Finland and Estonia. The getData function adds another dimension to the data array when looping through the JSON object to accommodate multiple countries.

As in the last post, data is an array of arrays: each element of data contains an array, which in turn contains the name of the country as the first element and objects containing a day of data each as individual elements.

We’ll next have to add functionality to identify the countries in the dataset and build a selection console containing toggle-able controls for showing the data for them. We’ll create two functions: buildConsole and getCountries. buildConsole will construct the menu through which countries can be added and removed from the graph objects; getCountries will identify which countries are selected and return a list of them whenever the console is changed.

Note that buildConsole sets whichever country is first in our dataset to visible by default.

The next functionality we’ll have to add is a cloning mechanism for the data array. Arrays of simple data objects can be copied; arrays containing arrays or objects are always passed by reference. Since we’ll be aggregating and de-aggregating metric, we need to always pass a copy of the original data array whenever a user re-configures the console. To do this, we’ll create two functions: cloneMetric and cloneData. cloneMetric creates a clone of a single metric (ie one element of the data array — in our case, one country). cloneData iterates through the data array and clones each of its elements.

Now we’ll need a function that can aggregate metrics over multiple dimensions (countries). We’ll create a function called aggregateMetric, which takes the list of selected countries from the console (provided by getCountries) and a copy of the data array and combines the counts for each country selected. The function then runs the createAverages function from the last post to build aggregated metrics like the retention metrics and session length and average session count.

Note that aggregateMetrics returns a single metric, not the entire data array.

The last functionality we lack is a function to reset the visualization object each time a user changes the console. We’ll create a function called resetCharts which takes a copy of the data array, builds the country list, aggregates the metrics, clears the visualization div, and then builds the graphs we want using the buildLineChart function we wrote last time.

To tie this all together, we’ll modify the document.ready function to accommodate our new functions. Upon document.ready, we’ll create out dataset, build the console, reset the charts (which also builds the charts), and then establish some functionality for when the console (which is contained within the “country-selector” div) is changed.

While the examples in this series of posts have been simple, I hope they have illustrated the power and flexibility of dashboards created with D3.js. Not only is D3.js as a dashboard platform infinitely customizable, it’s also cheap, requiring about the same amount of time to create as a dashboard as in a visualization tool once a framework has been established. I genuinely think D3.js is the way forward for start-up analytics, especially given the ubiquity of JSON streams and the strength of enterprise Javascript expertise most start-ups possess.