Control colors in d3.js chord diagram





This post follows the 2 previous posts on chord diagram: most basic chord and adding labels. It shows how to attribute a color to each group of the dataset. See the chord section for more examples. This example works with d3.js v4 and v6


chord diagram section

Steps:

  • See the basic chord diagram post for an intro on chord

  • Here a vector of 4 colors is built. Then a color is called for each group based on their index.

  • Note that a color scale could have been used as well, like here.

  • Next step: interactivity.
|
<!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>

// create the svg area
var svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", 440)
    .attr("height", 440)
  .append("g")
    .attr("transform", "translate(220,220)")

// create a matrix
var matrix = [
  [0,  5871, 8916, 2868],
  [ 1951, 0, 2060, 6171],
  [ 8010, 16145, 0, 8045],
  [ 1013,   990,  940, 0]
];

// 4 groups, so create a vector of 4 colors
var colors = [ "#440154ff", "#31668dff", "#37b578ff", "#fde725ff"]

// give this matrix to d3.chord(): it will calculates all the info we need to draw arc and ribbon
var res = d3.chord()
    .padAngle(0.05)
    .sortSubgroups(d3.descending)
    (matrix)

// add the groups on the outer part of the circle
svg
  .datum(res)
  .append("g")
  .selectAll("g")
  .data(function(d) { return d.groups; })
  .enter()
  .append("g")
  .append("path")
    .style("fill", function(d,i){ return colors[i] })
    .style("stroke", "black")
    .attr("d", d3.arc()
      .innerRadius(200)
      .outerRadius(210)
    )

// Add the links between groups
svg
  .datum(res)
  .append("g")
  .selectAll("path")
  .data(function(d) { return d; })
  .enter()
  .append("path")
    .attr("d", d3.ribbon()
      .radius(200)
    )
    .style("fill", function(d){ return(colors[d.source.index]) }) // colors depend on the source group. Change to target otherwise.
    .style("stroke", "black");

</script>
<script>

// create the svg area
const svg = d3.select("#my_dataviz")
  .append("svg")
    .attr("width", 440)
    .attr("height", 440)
  .append("g")
    .attr("transform", "translate(220,220)")

// create a matrix
const matrix = [
  [0,  5871, 8916, 2868],
  [ 1951, 0, 2060, 6171],
  [ 8010, 16145, 0, 8045],
  [ 1013,   990,  940, 0]
];

// 4 groups, so create a vector of 4 colors
const colors = [ "#440154ff", "#31668dff", "#37b578ff", "#fde725ff"]

// give this matrix to d3.chord(): it will calculates all the info we need to draw arc and ribbon
const res = d3.chord()
    .padAngle(0.05)
    .sortSubgroups(d3.descending)
    (matrix)

// add the groups on the outer part of the circle
svg
  .datum(res)
  .append("g")
  .selectAll("g")
  .data(function(d) { return d.groups; })
  .join("g")
  .append("path")
    .style("fill", (d,i) => colors[i])
    .style("stroke", "black")
    .attr("d", d3.arc()
      .innerRadius(200)
      .outerRadius(210)
    )

// Add the links between groups
svg
  .datum(res)
  .append("g")
  .selectAll("path")
  .data(d => d)
  .join("path")
    .attr("d", d3.ribbon()
      .radius(200)
    )
    .style("fill", d => colors[d.source.index]) // colors depend on the source group. Change to target otherwise.
    .style("stroke", "black");

</script>

Related blocks →