D3 Nest Tutorial and examples

Here is my learning process for getting to grips with nest. Discovered the d3 tests half way through which were a great help: tests

Simple one level nest

In Bl.ocks.org, click on "Open in a New Window" (bottom right) to view all the examples

Group by status

var nested_data = d3.nest()
.key(function(d) { return d.status; })
.entries(csv_data);

Simple two level nest

Group by status then priority

var nested_data = d3.nest()
.key(function(d) { return d.status; })
.key(function(d) { return d.priority; })
.entries(csv_data);

Use rollup to count leaves

The leaf level is replaced by a value at the parent level

var nested_data = d3.nest()
.key(function(d) { return d.status; })
.key(function(d) { return d.priority; })
.rollup(function(leaves) { return leaves.length; })
.entries(csv_data);

Rollup does sums as well

Can't have two rollups, but can return an object/array

var nested_data = d3.nest()
.key(function(d) { return d.status; })
.key(function(d) { return d.priority; })
.rollup(function(leaves) { return {"length": leaves.length, "total_time": d3.sum(leaves, function(d) {return parseFloat(d.time);})} })
.entries(csv_data);

Rollup everything to get a grand total of number of lines

No key

var nested_data = d3.nest()
.rollup(function(leaves) { return leaves.length; })
.entries(csv_data);

Sorting

Each level can be sorted by key - a simple ascending or descending...

var nested_data = d3.nest()
.key(function(d) { return d.status; }).sortKeys(d3.ascending)
.key(function(d) { return d.priority; }).sortKeys(function(d) { return )
.rollup(function(leaves) { return leaves.length; })
.entries(csv_data);

Sorting - custom order

Status, fortuitously, can be sorted in straing ascending order, but Priority requires a custom order. Create an list in the order you want and use indexOf to create the order comparaitor function.

var priority_order = ['MUST', "SHOULD", 'COULD', 'WISH'];
var nested_data = d3.nest()
.key(function(d) { return d.status; }).sortKeys(d3.ascending)
.key(function(d) { return d.priority; }).sortKeys(function(a,b) { return priority_order.indexOf(a) - priority_order.indexOf(b); })
.rollup(function(leaves) { return leaves.length; })
.entries(csv_data);

Sorting - sort the leaves as well

Use sortValue to sort the leaves - sort by time with smallest first

var priority_order = ['MUST', "SHOULD", 'COULD', 'WISH'];
var nested_data = d3.nest()
.key(function(d) { return d.status; }).sortKeys(d3.ascending)
.key(function(d) { return d.priority; }).sortKeys(function(a,b) { return priority_order.indexOf(a) - priority_order.indexOf(b); })
.sortValues(function(a,b) { return parseFloat(a.time) - parseFloat(b.time); } }
.entries(csv_data);

Sorting - sort the leaves as well

Use sortValue to sort the leaves - sort by person this time.

var priority_order = ['MUST', "SHOULD", 'COULD', 'WISH'];
var nested_data = d3.nest()
.key(function(d) { return d.status; }).sortKeys(d3.ascending)
.key(function(d) { return d.priority; }).sortKeys(function(a,b) { return priority_order.indexOf(a) - priority_order.indexOf(b); })
.sortValues(function(a,b) { return ((a.who < b.who)
? -1
: 1);
return 0;} )
.entries(csv_data);

Populate a Select list from csv data

Use nest to get a unique list of people then create a select from it.

var nested_data = d3.nest()
.key(function(d) { return d.who}).sortKeys(d3.ascending)
.rollup(function(leaves) { return leaves.length; })
.entries(csv_data);

var list = d3.select("#ex10").append("select")

list.selectAll("option")
.data(nested_data)
.enter()
.append("option")
.attr("value", function(d) {return d.key;})
.text(function(d) {
return d.key; });