Interactive chord diagram in d3.js





This is a graph done in d3.js. Visit the chord diagram section of the d3.js gallery for more examples. This example works with d3.js v4 and v6


Histogram section
|

This is a very basic chord diagram made using d3.js. The data comes from here. It uses the histogram function d3. And here are a few more things about it. It uses the histogram function d3. And here are a few more things about it. here is the code building the figure. Remember it is interactive.

<!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>

<!-- Create a div for the tooltip -->
<div id="tooltip"></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>

<!-- Create a div for the tooltip -->
<div id="tooltip"></div>

<script>

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

// create a matrix
var matrix = [
  [11975,  5871, 8916, 2868],
  [ 1951, 10048, 2060, 6171],
  [ 8010, 16145, 8090, 8045],
  [ 1013,   990,  940, 6907]
];
var names = ["A", "B", "C", "D"]

// 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 inner part of the circle
svg
  .datum(res)
  .append("g")
  .selectAll("g")
  .data(function(d) { return d.groups; })
  .enter()
  .append("g")
  .append("path")
    .style("fill", "grey")
    .style("stroke", "black")
    .attr("d", d3.arc()
      .innerRadius(230)
      .outerRadius(240)
    )

// Add a tooltip div. Here I define the general feature of the tooltip: stuff that do not depend on the data point.
// Its opacity is set to 0: we don't see it by default.
var tooltip = d3.select("#my_dataviz")
  .append("div")
  .style("opacity", 0)
  .attr("class", "tooltip")
  .style("background-color", "white")
  .style("border", "solid")
  .style("border-width", "1px")
  .style("border-radius", "5px")
  .style("padding", "10px")

// A function that change this tooltip when the user hover a point.
// Its opacity is set to 1: we can now see it. Plus it set the text and position of tooltip depending on the datapoint (d)
var showTooltip = function(d) {
  tooltip
    .style("opacity", 1)
    .html("Source: " + names[d.source.index] + "<br>Target: " + names[d.target.index])
    .style("left", (d3.event.pageX + 15) + "px")
    .style("top", (d3.event.pageY - 28) + "px")
}

// A function that change this tooltip when the leaves a point: just need to set opacity to 0 again
var hideTooltip = function(d) {
  tooltip
    .transition()
    .duration(1000)
    .style("opacity", 0)
}

// 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(220)
    )
    .style("fill", "#69b3a2")
    .style("stroke", "black")
  .on("mouseover", showTooltip )
  .on("mouseleave", hideTooltip )

</script>
<script>

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

// create a matrix
const matrix = [
  [11975,  5871, 8916, 2868],
  [ 1951, 10048, 2060, 6171],
  [ 8010, 16145, 8090, 8045],
  [ 1013,   990,  940, 6907]
];
const names = ["A", "B", "C", "D"]

// 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 inner part of the circle
svg
  .datum(res)
  .append("g")
  .selectAll("g")
  .data(d => d.groups)
  .join("g")
  .append("path")
    .style("fill", "grey")
    .style("stroke", "black")
    .attr("d", d3.arc()
      .innerRadius(230)
      .outerRadius(240)
    )

// Add a tooltip div. Here I define the general feature of the tooltip: stuff that do not depend on the data point.
// Its opacity is set to 0: we don't see it by default.
const tooltip = d3.select("#my_dataviz")
  .append("div")
  .style("opacity", 0)
  .attr("class", "tooltip")
  .style("background-color", "white")
  .style("border", "solid")
  .style("border-width", "1px")
  .style("border-radius", "5px")
  .style("padding", "10px")

// A function that change this tooltip when the user hover a point.
// Its opacity is set to 1: we can now see it. Plus it set the text and position of tooltip depending on the datapoint (d)
const showTooltip = function(event, d) {
  tooltip
    .style("opacity", 1)
    .html("Source: " + names[d.source.index] + "<br>Target: " + names[d.target.index])
    .style("left", (event.x)/2+300 + "px")
    .style("top", (event.y)/2+500 + "px")
}

// A function that change this tooltip when the leaves a point: just need to set opacity to 0 again
var hideTooltip = function(event, d) {
  tooltip
    .transition()
    //.duration(1000)
    .style("opacity", 0)
}

// Add the links between groups
svg
  .datum(res)
  .append("g")
  .selectAll("path")
  .data(d => d)
  .join("path")
    .attr("d", d3.ribbon()
      .radius(220)
    )
    .style("fill", "#69b3a2")
    .style("stroke", "black")
  .on("mouseover", showTooltip )
  .on("mouseleave", hideTooltip )

</script>

Related blocks

  • Chord Diagram - link

  • The basis of tooltip -

  • ll



Contact

This document is a work in progress analysis by Yan Holtz. Any feedback is highly encouraged. You can fill an issue on Github, drop me a message on Twitter, or send an email pasting yan.holtz.data with gmail.com.

Github Twitter