1 | var r = 960 / 2, |
---|
2 | splines = []; |
---|
3 | |
---|
4 | var cluster = d3.layout.cluster() |
---|
5 | .size([360, r - 120]) |
---|
6 | .sort(null) |
---|
7 | .value(function(d) { return d.size; }); |
---|
8 | |
---|
9 | var bundle = d3.layout.bundle(); |
---|
10 | |
---|
11 | var line = d3.svg.line.radial() |
---|
12 | .interpolate("bundle") |
---|
13 | .tension(.85) |
---|
14 | .radius(function(d) { return d.y; }) |
---|
15 | .angle(function(d) { return d.x / 180 * Math.PI; }); |
---|
16 | |
---|
17 | var vis = d3.select("#chart").append("svg:svg") |
---|
18 | .attr("width", r * 2) |
---|
19 | .attr("height", r * 2) |
---|
20 | .append("svg:g") |
---|
21 | .attr("transform", "translate(" + r + "," + r + ")"); |
---|
22 | |
---|
23 | d3.json("../data/flare-imports.json", function(classes) { |
---|
24 | var nodes = cluster.nodes(packages.root(classes)), |
---|
25 | links = packages.imports(nodes); |
---|
26 | |
---|
27 | vis.selectAll("path.link") |
---|
28 | .data(splines = bundle(links)) |
---|
29 | .enter().append("svg:path") |
---|
30 | .attr("class", "link") |
---|
31 | .attr("d", line); |
---|
32 | |
---|
33 | vis.selectAll("g.node") |
---|
34 | .data(nodes.filter(function(n) { return !n.children; })) |
---|
35 | .enter().append("svg:g") |
---|
36 | .attr("class", "node") |
---|
37 | .attr("transform", function(d) { return "rotate(" + (d.x - 90) + ")translate(" + d.y + ")"; }) |
---|
38 | .append("svg:text") |
---|
39 | .attr("dx", function(d) { return d.x < 180 ? 8 : -8; }) |
---|
40 | .attr("dy", ".31em") |
---|
41 | .attr("text-anchor", function(d) { return d.x < 180 ? "start" : "end"; }) |
---|
42 | .attr("transform", function(d) { return d.x < 180 ? null : "rotate(180)"; }) |
---|
43 | .text(function(d) { return d.key; }); |
---|
44 | }); |
---|
45 | |
---|
46 | d3.select(window).on("mousemove", function() { |
---|
47 | vis.selectAll("path.link") |
---|
48 | .data(splines) |
---|
49 | .attr("d", line.tension(Math.min(1, d3.event.clientX / 960))); |
---|
50 | }); |
---|