Home > Articles

  • Print
  • + Share This
This chapter is from the book

Draw the Chord Diagram

One of my favorite visualizations is Mike Bostock’s “Uber Rides by Neighborhood” chord diagram (https://bost.ocks.org/mike/uberdata/). This is a very good foundation for us for the task at hand. In fact, the main differences between my version and his are cosmetic. The JavaScript goes in app/assets/javascripts/departures.js.

Listing 6.1 Chord Diagram JavaScript

function makeChordChart(route) {
  var width         = 720,
      height        = 720,
      outerRadius   = Math.min(width, height) / 2 - 30,
      innerRadius   = outerRadius - 24
      formatPercent = d3.format(".1%"),
      color         = d3.scale.category20();

  var arc = d3.svg.arc()
      .innerRadius(innerRadius)
      .outerRadius(outerRadius);

  var layout = d3.layout.chord()
      .padding(.04)
      .sortSubgroups(d3.descending)
      .sortChords(d3.ascending);

  var path = d3.svg.chord()
      .radius(innerRadius);

  var svg = d3.select("#chart").append("svg")
      .attr("width", width)
      .attr("height", height)
    .append("g")
      .attr("id", "circle")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  svg.append("circle")
      .attr("r", outerRadius);

  svg.append("text")
      .attr('class', 'chart_title')
      .attr("x", 0)
      .attr("y", -340)
      .attr("text-anchor", "middle")
      .style("font-size", "16px")
      .text("American Airlines City Pairs (1999)");

  d3.json(route, function(error, data) {
    var airports = data.airports;

    // Compute the chord layout.
    layout.matrix(data.matrix);

    // Add a group per origin.
    var group = svg.selectAll(".group")
        .data(layout.groups)
      .enter().append("g")
        .attr("class", "group")
        .on("mouseover", mouseover);

    // Add a mouseover title.
    group.append("title").text(function(d, i) {
      return airports[i] + ": " + formatPercent(d.value) + " of origins"; });

    // Add the group arc.
    var groupPath = group.append("path")
        .attr("id", function(d, i) { return "group" + i; })
        .attr("d", arc)
        .style("fill", function(d, i) { return color(i); });

    // Add a text label.
    var groupText = group.append("text")
        .attr("x", 6)
        .attr("dy", 15);

    groupText.append("textPath")
        .attr("xlink:href", function(d, i) { return "#group" + i; })
        .text(function(d, i) { return airports[i]; });

    // Remove the labels that don't fit. :(
    groupText.filter(function(d, i) { return groupPath[0][i].getTotalLength() / 2 - 16 < this.getComputedTextLength(); })
        .remove();

    // Add the chords.
    var chord = svg.selectAll(".chord")
        .data(layout.chords)
      .enter().append("path")
        .attr("class", "chord")
        .style("fill", function(d) { return color(d.source.index); })
        .attr("d", path);

    // Add an elaborate mouseover title for each chord.
    chord.append("title").text(function(d) {
      return airports[d.source.index]
          + " → " + airports[d.target.index]
          + ": " + formatPercent(d.source.value)
          + "\n" + airports[d.target.index]
          + " → " + airports[d.source.index]
          + ": " + formatPercent(d.target.value);
    });
    function mouseover(d, i) {
      chord.classed("fade", function(p) {
        return p.source.index != i
            && p.target.index != i;
      });
    }
  });
}

The title is hard-coded for American Airlines. If you do explore what the city pairs for other airlines look like consider a small refactor to allow for more generic JavaScript.

The chord diagram for American Airlines flights in 1999 can be seen in Figure 6.2. It may take a few seconds to pull the data and load in the browser.

Figure 6.2

Figure 6.2 American Airlines Flights – 1999

  • + Share This
  • 🔖 Save To Your Account