howto

How to adapt a D3.js template in a web app?

June 03, 2015

D3.js is the state-of-the-art library for data visualization. Check out the gallery for stunning and beautiful examples. Happily, many visualizations are given along their source code, so that you can easily duplicate them.

For instance, let's try to replicate the parallel coordinates chart, created by Mike Bostock. This is a cool (and useful) data viz. A parallel coordinates chart allows you to quickly visualize a multi-dimensional (but relatively small) dataset: you can immediately spot out correlations across dimensions and uncover clusters. In this interactive viz, you can explore the data in depth by filtering values on each dimension with a brush tool.

Furthermore, this data viz is given with the generating D3 code and data! Let's try to replicate it in a web app.



Create a new web app

Create a new webapp. Then, import the D3 library. As a reminder, this post explains how to do this.

Finally, you need to import the data. The parallel coordinates chart is illustrated on the famous cars dataset. In your project, create the cars dataset from this CSV file. To access this data in your web app, click on the rightmost button in the editor, then click on Datasets, and select the cars dataset.

Understand the code overall structure

Many D3 code samples, given in the gallery or bl.ocks.org, have the same overall structure.

<!DOCTYPE html>
<meta charset="utf-8">
<style>
    /* CSS  code */
</style>
<body>
    <!-- HTML code -->
    <script src="http://d3js.org/d3.v3.min.js"></script>
    <script>
        // JS code
    </script>
<body>

To replicate the D3 visualizations in your web app, you will simply need to copy the CSS and HTML code in the corresponding panels of the web app editor. For the JavaScript code, it requires a little more work, as we will see promptly.

Copying the CSS code

In the parallel coordinates chart example, there is no HTML code written withing the <body> tags, and thus no HTMl code to copy in the editor. Here's the CSS code, defined within the <style>tags, that you should copy in the CSS panel of your editor.

svg {
  font: 10px sans-serif;
}

.background path {
  fill: none;
  stroke: #ccc;
  stroke-opacity: .4;
  shape-rendering: crispEdges;
}

.foreground path {
  fill: none;
  stroke: steelblue;
  stroke-opacity: .7;
}

.brush .extent {
  fill-opacity: .3;
  stroke: #fff;
  shape-rendering: crispEdges;
}

.axis line,
.axis path {
  fill: none;
  stroke: #000;
  shape-rendering: crispEdges;
}

.axis text {
  text-shadow: 0 1px 0 #fff;
  cursor: move;
}

Adapting the JS code

The trickiest part in adapting a D3 template is always to shape the data in the format required by the data viz. In the parallel coordinates charts, the data in the D3 code is represented as the cars JSON array.

But generally you do not directly have JSON data. In many D3 templates, the data is given as a csv file, while in DSS you will have to connect to your dataset (which can be stored in a great variety of format and database system).

In the D3 original code, the data is thus read from the cars.csv file:

// D3 code
d3.csv("cars.csv", function(error, cars) {
    // D3 code
};
// D3 code

Then the D3 code defined inside the d3.csv function is applied on the cars JSON array.

In our web app instead, we need to connect to data through the Dataiku JavaScript API. In order to do this, we need to slightly modify the JS code. Replace the original JS code above by

// same D3 code
function parallelCoordinatesChart(cars) {
    // same D3 code
}
// same D3 code

and copy it in the JS panel of the web app editor. In other words, keep the entire D3 code unchanged expect the call to the d3.csv function, that is replaced by defining the parallelCoordinatesChart function, which takes the cars JSON array as input.

Now, we only need to connect to the cars dataset through the dataiku JS API, in order to create the corresponding cars JSON array. Notice that, when you selected the cars datsaset in your web app, the following code was automatically added:

dataiku.fetch('PROJECTNAME.cars', function(dataFrame) {
});

where PROJECTNAME actually stands for the name of your project.

You finally need to copy the JS code defined in the dataiku.fetch below. This code creates the cars JSON array and calls the parallelCoordinatesChart function to create the chart.

dataiku.fetch('PROJECTNAME.cars', function(dataFrame) {
    var columnNames = dataFrame.getColumnNames();
    function formatData(row) {
        var out = {};
        columnNames.forEach(function (col) {
            out[col]= col==='name' ? row[col] : +row[col];
        });
        return out;
    }
  var cars = dataFrame.mapRecords(formatData);
  parallelCoordinatesChart(cars);  
});

That's it, you have a running D3 data viz in your web app!