Most basic radial dendrogram in d3.js





This post describes how to build a very basic radial dendrogram with d3.js. Three levels of hierarchy are drawn. You can see many other examples in the dendrogram section of the gallery.


Dendrogram section

Steps:

  • Input dataset is a hierarchy: CEO is over boss 1 and boss 2 that are over 8 employees. See data here.

  • See here to get this kind of input format from an usual table.

  • Two crucial functions are used to build the dendrogram layout: d3.cluster() and d3.hierarchy(). See the d3-hierarchy documentation to learn more about it.

  • Once we know where the nodes are located, links are drawn thanks to the linkRadial() function to get this smooth shape. Read more about shape helpers here.
<!DOCTYPE html>
<meta charset="utf-8">

<!-- Load d3.js -->
<script src="https://d3js.org/d3.v4.js"></script>

<!-- Create a div where the graph will take place -->
<div id="my_dataviz"></div>

<script>

// set the dimensions and margins of the graph
var width = 460
var height = 460
var radius = width / 2 // radius of the dendrogram

// append the svg object to the body of the page
var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + radius + "," + radius + ")");

// read json data
d3.json("https://raw.githubusercontent.com/holtzy/D3-graph-gallery/master/DATA/data_dendrogram.json", function(data) {

  // Create the cluster layout:
  var cluster = d3.cluster()
    .size([360, radius - 60]);  // 360 means whole circle. radius - 60 means 60 px of margin around dendrogram

  // Give the data to this cluster layout:
  var root = d3.hierarchy(data, function(d) {
      return d.children;
  });
  cluster(root);

  // Features of the links between nodes:
  var linksGenerator = d3.linkRadial()
      .angle(function(d) { return d.x / 180 * Math.PI; })
      .radius(function(d) { return d.y; });

  // Add the links between nodes:
  svg.selectAll('path')
    .data(root.links())
    .enter()
    .append('path')
      .attr("d", linksGenerator)
      .style("fill", 'none')
      .attr("stroke", '#ccc')


  // Add a circle for each node.
  svg.selectAll("g")
      .data(root.descendants())
      .enter()
      .append("g")
      .attr("transform", function(d) {
          return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")";
      })
      .append("circle")
        .attr("r", 7)
        .style("fill", "#69b3a2")
        .attr("stroke", "black")
        .style("stroke-width", 2)

})

</script>

Related blocks →