toolkit/javascript/d3/examples/chord/chord-flare.html
author Nicolas Sauret <nicolas.sauret@iri.centrepompidou.fr>
Tue, 15 Apr 2014 17:46:09 +0200
changeset 48 1b2dffb4ac2b
parent 47 c0b4a8b5a012
permissions -rw-r--r--
add wiki (wikimd) delete publication (bootstrap)

<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-type" content="text/html; charset=utf-8">
    <title>Chord Diagram</title>
    <script type="text/javascript" src="../../d3.js"></script>
    <script type="text/javascript" src="../../d3.layout.js"></script>
    <style type="text/css">

body {
  font: 10px sans-serif;
}

path.chord {
  fill-opacity: .67;
}

    </style>
  </head>
  <body>
    <script type="text/javascript">

var r1 = 960 / 2,
    r0 = r1 - 120;

var fill = d3.scale.category20c();

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

var arc = d3.svg.arc()
    .innerRadius(r0)
    .outerRadius(r0 + 20);

var svg = d3.select("body").append("svg:svg")
    .attr("width", r1 * 2)
    .attr("height", r1 * 2)
  .append("svg:g")
    .attr("transform", "translate(" + r1 + "," + r1 + ")");

d3.json("../data/flare-imports.json", function(imports) {
  var indexByName = {},
      nameByIndex = {},
      matrix = [],
      n = 0;

  // Returns the Flare package name for the given class name.
  function name(name) {
    return name.substring(0, name.lastIndexOf(".")).substring(6);
  }

  // Compute a unique index for each package name.
  imports.forEach(function(d) {
    d = name(d.name);
    if (!(d in indexByName)) {
      nameByIndex[n] = d;
      indexByName[d] = n++;
    }
  });

  // Construct a square matrix counting package imports.
  imports.forEach(function(d) {
    var source = indexByName[name(d.name)],
        row = matrix[source];
    if (!row) {
     row = matrix[source] = [];
     for (var i = -1; ++i < n;) row[i] = 0;
    }
    d.imports.forEach(function(d) { row[indexByName[name(d)]]++; });
  });

  chord.matrix(matrix);

  var g = svg.selectAll("g.group")
      .data(chord.groups)
    .enter().append("svg:g")
      .attr("class", "group");

  g.append("svg:path")
      .style("fill", function(d) { return fill(d.index); })
      .style("stroke", function(d) { return fill(d.index); })
      .attr("d", arc);

  g.append("svg:text")
      .each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; })
      .attr("dy", ".35em")
      .attr("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; })
      .attr("transform", function(d) {
        return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")"
            + "translate(" + (r0 + 26) + ")"
            + (d.angle > Math.PI ? "rotate(180)" : "");
      })
      .text(function(d) { return nameByIndex[d.index]; });

  svg.selectAll("path.chord")
      .data(chord.chords)
    .enter().append("svg:path")
      .attr("class", "chord")
      .style("stroke", function(d) { return d3.rgb(fill(d.source.index)).darker(); })
      .style("fill", function(d) { return fill(d.source.index); })
      .attr("d", d3.svg.chord().radius(r0));

});

    </script>
  </body>
</html>