1 | // From http://mkweb.bcgsc.ca/circos/guide/tables/ |
---|
2 | var chord = d3.layout.chord() |
---|
3 | .padding(.05) |
---|
4 | .sortSubgroups(d3.descending) |
---|
5 | .matrix([ |
---|
6 | [11975, 5871, 8916, 2868], |
---|
7 | [ 1951, 10048, 2060, 6171], |
---|
8 | [ 8010, 16145, 8090, 8045], |
---|
9 | [ 1013, 990, 940, 6907] |
---|
10 | ]); |
---|
11 | |
---|
12 | var w = 600, |
---|
13 | h = 600, |
---|
14 | r0 = Math.min(w, h) * .41, |
---|
15 | r1 = r0 * 1.1; |
---|
16 | |
---|
17 | var fill = d3.scale.ordinal() |
---|
18 | .domain(d3.range(4)) |
---|
19 | .range(["#000000", "#FFDD89", "#957244", "#F26223"]); |
---|
20 | |
---|
21 | var svg = d3.select("#chart") |
---|
22 | .append("svg:svg") |
---|
23 | .attr("width", w) |
---|
24 | .attr("height", h) |
---|
25 | .append("svg:g") |
---|
26 | .attr("transform", "translate(" + w / 2 + "," + h / 2 + ")"); |
---|
27 | |
---|
28 | svg.append("svg:g") |
---|
29 | .selectAll("path") |
---|
30 | .data(chord.groups) |
---|
31 | .enter().append("svg:path") |
---|
32 | .style("fill", function(d) { return fill(d.index); }) |
---|
33 | .style("stroke", function(d) { return fill(d.index); }) |
---|
34 | .attr("d", d3.svg.arc().innerRadius(r0).outerRadius(r1)) |
---|
35 | .on("mouseover", fade(.1)) |
---|
36 | .on("mouseout", fade(1)); |
---|
37 | |
---|
38 | var ticks = svg.append("svg:g") |
---|
39 | .selectAll("g") |
---|
40 | .data(chord.groups) |
---|
41 | .enter().append("svg:g") |
---|
42 | .selectAll("g") |
---|
43 | .data(groupTicks) |
---|
44 | .enter().append("svg:g") |
---|
45 | .attr("transform", function(d) { |
---|
46 | return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" |
---|
47 | + "translate(" + r1 + ",0)"; |
---|
48 | }); |
---|
49 | |
---|
50 | ticks.append("svg:line") |
---|
51 | .attr("x1", 1) |
---|
52 | .attr("y1", 0) |
---|
53 | .attr("x2", 5) |
---|
54 | .attr("y2", 0) |
---|
55 | .style("stroke", "#000"); |
---|
56 | |
---|
57 | ticks.append("svg:text") |
---|
58 | .attr("x", 8) |
---|
59 | .attr("dy", ".35em") |
---|
60 | .attr("text-anchor", function(d) { |
---|
61 | return d.angle > Math.PI ? "end" : null; |
---|
62 | }) |
---|
63 | .attr("transform", function(d) { |
---|
64 | return d.angle > Math.PI ? "rotate(180)translate(-16)" : null; |
---|
65 | }) |
---|
66 | .text(function(d) { return d.label; }); |
---|
67 | |
---|
68 | svg.append("svg:g") |
---|
69 | .attr("class", "chord") |
---|
70 | .selectAll("path") |
---|
71 | .data(chord.chords) |
---|
72 | .enter().append("svg:path") |
---|
73 | .style("fill", function(d) { return fill(d.target.index); }) |
---|
74 | .attr("d", d3.svg.chord().radius(r0)) |
---|
75 | .style("opacity", 1); |
---|
76 | |
---|
77 | /** Returns an array of tick angles and labels, given a group. */ |
---|
78 | function groupTicks(d) { |
---|
79 | var k = (d.endAngle - d.startAngle) / d.value; |
---|
80 | return d3.range(0, d.value, 1000).map(function(v, i) { |
---|
81 | return { |
---|
82 | angle: v * k + d.startAngle, |
---|
83 | label: i % 5 ? null : v / 1000 + "k" |
---|
84 | }; |
---|
85 | }); |
---|
86 | } |
---|
87 | |
---|
88 | /** Returns an event handler for fading a given chord group. */ |
---|
89 | function fade(opacity) { |
---|
90 | return function(g, i) { |
---|
91 | svg.selectAll("g.chord path") |
---|
92 | .filter(function(d) { |
---|
93 | return d.source.index != i && d.target.index != i; |
---|
94 | }) |
---|
95 | .transition() |
---|
96 | .style("opacity", opacity); |
---|
97 | }; |
---|
98 | } |
---|