|
//////////////////////////////////////////////////////////// |
|
//////////////////////// Set-Up //////////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
var margin = {left:90, top:90, right:90, bottom:90}, |
|
width = Math.min(window.innerWidth, 700) - margin.left - margin.right, |
|
height = Math.min(window.innerWidth, 700) - margin.top - margin.bottom, |
|
innerRadius = Math.min(width, height) * .39, |
|
outerRadius = innerRadius * 1.1; |
|
|
|
var Names = ["Black Widow","Captain America","Hawkeye","the Hulk","Iron Man","Thor"], |
|
colors = ["#301E1E", "#083E77", "#342350", "#567235", "#8B161C", "#DF7C00"], |
|
opacityDefault = 0.8; |
|
|
|
var matrix = [ |
|
[0,4,3,2,5,2], //Black Widow |
|
[4,0,3,2,4,3], //Captain America |
|
[3,3,0,2,3,3], //Hawkeye |
|
[2,2,2,0,3,3], //The Hulk |
|
[5,4,3,3,0,2], //Iron Man |
|
[2,3,3,3,2,0], //Thor |
|
]; |
|
|
|
//////////////////////////////////////////////////////////// |
|
/////////// Create scale and layout functions ////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
var colors = d3.scale.ordinal() |
|
.domain(d3.range(Names.length)) |
|
.range(colors); |
|
|
|
var chord = d3.layout.chord() |
|
.padding(.15) |
|
.sortChords(d3.descending) |
|
.matrix(matrix); |
|
|
|
var arc = d3.svg.arc() |
|
.innerRadius(innerRadius*1.01) |
|
.outerRadius(outerRadius); |
|
|
|
var path = d3.svg.chord() |
|
.radius(innerRadius); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////////// Create SVG ////////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
var svg = d3.select("#chart").append("svg") |
|
.attr("width", width + margin.left + margin.right) |
|
.attr("height", height + margin.top + margin.bottom) |
|
.append("g") |
|
.attr("transform", "translate(" + (width/2 + margin.left) + "," + (height/2 + margin.top) + ")"); |
|
|
|
//////////////////////////////////////////////////////////// |
|
/////////////// Create the gradient fills ////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
//Function to create the unique id for each chord gradient |
|
function getGradID(d){ return "linkGrad-" + d.source.index + "-" + d.target.index; } |
|
|
|
//Create the gradients definitions for each chord |
|
var grads = svg.append("defs").selectAll("linearGradient") |
|
.data(chord.chords()) |
|
.enter().append("linearGradient") |
|
//Create the unique ID for this specific source-target pairing |
|
.attr("id", getGradID) |
|
.attr("gradientUnits", "userSpaceOnUse") |
|
//Find the location where the source chord starts |
|
.attr("x1", function(d,i) { return innerRadius * Math.cos((d.source.endAngle-d.source.startAngle)/2 + d.source.startAngle - Math.PI/2); }) |
|
.attr("y1", function(d,i) { return innerRadius * Math.sin((d.source.endAngle-d.source.startAngle)/2 + d.source.startAngle - Math.PI/2); }) |
|
//Find the location where the target chord starts |
|
.attr("x2", function(d,i) { return innerRadius * Math.cos((d.target.endAngle-d.target.startAngle)/2 + d.target.startAngle - Math.PI/2); }) |
|
.attr("y2", function(d,i) { return innerRadius * Math.sin((d.target.endAngle-d.target.startAngle)/2 + d.target.startAngle - Math.PI/2); }) |
|
|
|
//Set the starting color (at 0%) |
|
grads.append("stop") |
|
.attr("offset", "0%") |
|
.attr("stop-color", function(d){ return colors(d.source.index); }); |
|
|
|
//Set the ending color (at 100%) |
|
grads.append("stop") |
|
.attr("offset", "100%") |
|
.attr("stop-color", function(d){ return colors(d.target.index); }); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Draw outer Arcs ///////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
var outerArcs = svg.selectAll("g.group") |
|
.data(chord.groups) |
|
.enter().append("g") |
|
.attr("class", "group") |
|
.on("mouseover", fade(.1)) |
|
.on("mouseout", fade(opacityDefault)); |
|
|
|
outerArcs.append("path") |
|
.style("fill", function(d) { return colors(d.index); }) |
|
.attr("d", arc); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////////// Append Names //////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
//Append the label names on the outside |
|
outerArcs.append("text") |
|
.each(function(d) { d.angle = (d.startAngle + d.endAngle) / 2; }) |
|
.attr("dy", ".35em") |
|
.attr("class", "titles") |
|
.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(" + (outerRadius + 10) + ")" |
|
+ (d.angle > Math.PI ? "rotate(180)" : ""); |
|
}) |
|
.text(function(d,i) { return Names[i]; }); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Draw inner chords /////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
svg.selectAll("path.chord") |
|
.data(chord.chords) |
|
.enter().append("path") |
|
.attr("class", "chord") |
|
//change the fill to reference the unique gradient ID of the source-target combination |
|
.style("fill", function(d){ return "url(#" + getGradID(d) + ")"; }) |
|
.style("opacity", opacityDefault) |
|
.attr("d", path); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Extra Functions ///////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
//Returns an event handler for fading a given chord group. |
|
function fade(opacity) { |
|
return function(d,i) { |
|
svg.selectAll("path.chord") |
|
.filter(function(d) { return d.source.index != i && d.target.index != i; }) |
|
.transition() |
|
.style("opacity", opacity); |
|
}; |
|
}//fade |