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. This example works with d3.js v4 and v6


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>

<!DOCTYPE html>
<meta charset="utf-8">
        
<!-- Load d3.js -->
<script src="https://d3js.org/d3.v6.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>
<script>

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

// append the svg object to the body of the page
const 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").then( function(data) {

  // Create the cluster layout:
  const 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:
  const root = d3.hierarchy(data, function(d) {
      return d.children;
  });
  cluster(root);

  // Features of the links between nodes:
  const 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())
    .join('path')
      .attr("d", linksGenerator)
      .style("fill", 'none')
      .attr("stroke", '#ccc')


  // Add a circle for each node.
  svg.selectAll("g")
      .data(root.descendants())
      .join("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 →