Muster the cluster!

Another type of similar diagram is a dendrogram, which uses D3's cluster layout and puts all leaf nodes of a tree at the same depth. Let's create that now. Comment out the westerosChart.init() line in main.js and add this beneath it:

westerosChart.init('cluster', 'data/GoT-lineages-screentimes.json');

Go back to chapter6/index and add the following:

westerosChart.cluster = function Cluster(_data) { 
const data = getMajorHouses(_data);
const stratify = d3.stratify()
.parentId(d => d.fatherLabel)
.id(d => d.itemLabel);

const root = stratify(data);

fixateColors(houseNames(root), 'id');

const layout = d3.cluster()
.size([
this.innerWidth - 150,
this.innerHeight,
]);

const links = layout(root)
.descendants()
.slice(1);
}

This should look familiar already--we get our data, create a stratify generator, then use it on our data. We then create a cluster layout, give it a size (though, here we subtract 150 pixels for the legend), then generate the links using layout.descendants().

Still in westerosChart.cluster, add the following:

  const line = d3.line().curve(d3.curveBasis); 

this.container.selectAll('.link')
.data(links)
.enter()
.append('path')
.attr('fill', 'none')
.attr('stroke', 'lightblue')
.attr('d', d => line([
[d.y, d.x],
[(d.y + d.parent.y) / 2, d.x],
[(d.y + d.parent.y) / 2, d.parent.x],
[d.parent.y, d.parent.x]],
));

This is the same path, drawing bit of code from before, except we've swapped the x and y values so that it displays horizontally instead of vertically.

Next, add circles for the nodes:

  const nodes = this.container.selectAll('.node') 
.data(root.descendants())
.enter()
.append('circle')
.classed('node', true)
.attr('r', 5)
.attr('fill', getHouseColor)
.attr('cx', d => d.y)
.attr('cy', d => d.x);

Then, add a legend:

  const l = legend 
.legendColor()
.scale(color);

this.container
.append('g')
.attr('id', 'legend')
.attr('transform', `translate(${this.innerWidth - 100}, 0)`)
.call(l);

Lastly, call the tooltip factory, and we're done!:

  nodes.call(tooltip(d => d.data.itemLabel, this.container));

Click on save, and you'll get something like this:

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset