|
<!DOCTYPE html> |
|
<html> |
|
<head> |
|
<meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> |
|
<title>Chord Diagram - Phone Brands</title> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<!-- jQuery --> |
|
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> |
|
<!-- Bootstrap 3 --> |
|
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css"> |
|
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script> |
|
|
|
<style> |
|
body { |
|
/*background: url(http://mbostock.github.io/d3/talk/20111018/texture-noise.png);*/ |
|
overflow: hidden; |
|
margin: 0; |
|
font-size: 14px; |
|
font-family: "Helvetica Neue", Helvetica; |
|
} |
|
|
|
#footer { |
|
position: absolute; |
|
top: 0; |
|
z-index: 1; |
|
display: block; |
|
font-size: 36px; |
|
font-weight: 300; |
|
text-shadow: 0 1px 0 #fff; |
|
top: 640px; |
|
right: 140px; |
|
text-align: right; |
|
} |
|
|
|
line { |
|
stroke: #000; |
|
stroke-width: 1.px; |
|
} |
|
|
|
.hint { |
|
position: absolute; |
|
right: 0; |
|
width: 350px; |
|
font-size: 12px; |
|
color: #999; |
|
} |
|
|
|
text { |
|
font-size: 10px; |
|
} |
|
|
|
.titles{ |
|
font-size: 14px; |
|
} |
|
|
|
path.chord { |
|
fill-opacity: .80; |
|
} |
|
</style> |
|
</head> |
|
<body> |
|
|
|
<div id="cont" class="container-fluid"> |
|
<div class="row text-center"> |
|
<div class="col-sm-12 column"><div id="chart"></div></div> |
|
</div> |
|
</div> |
|
|
|
<script type="text/javascript"> |
|
|
|
var NameProvider = ["Princeton","Ewing","Hamilton","Hopewell Twp","Lawrence","East Windsor","West Windsor","Trenton"]; |
|
|
|
var matrix = [ |
|
[7235,119,131,128,606,167,497,175], //Princeton |
|
[1045,4029,1021,498,1227,67,691,2578], //Ewing |
|
[1790,3050,12757,589,2846,490,1909,7465], //Hamilton |
|
[1202,675,345,1667,739,41,419,653], //Hopewell Twp |
|
[1432,789,11171,546,4353,214,1061,1657], //Lawrence |
|
[563,213,538,115,487,1907,582,579], //East Windsor |
|
[708,180,418,227,547,349,2681,244], //West Windsor |
|
[1560,2401,3751,68,1660,398,1044,10,975] //Trenton |
|
]; |
|
var colors = ["#C4C4C4","#69B40F","#EC1D25","#C8125C","#008FC8","#10218B","#134B24","#737373"]; |
|
|
|
var chord = d3.layout.chord() |
|
.padding(.04) |
|
.sortSubgroups(d3.descending) //sort the chords inside an arc from high to low |
|
.sortChords(d3.descending) //which chord should be shown on top when chords cross. Now the biggest chord is at the bottom |
|
.matrix(matrix); |
|
|
|
var width = 900, |
|
height = 650, |
|
innerRadius = Math.min(width, height) * .41, |
|
outerRadius = innerRadius * 1.05; |
|
|
|
var fill = d3.scale.ordinal() |
|
.domain(d3.range(NameProvider.length)) |
|
.range(colors); |
|
|
|
var arc = d3.svg.arc() |
|
.innerRadius(innerRadius) |
|
.outerRadius(outerRadius); |
|
|
|
var svg = d3.select("#chart").append("svg:svg") |
|
.attr("width", width) |
|
.attr("height", height+50) |
|
.append("svg:g") |
|
.attr("transform", "translate(" + width / 2 + "," + (height / 2+30) + ")"); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Draw outer Arcs ///////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
var g = svg.selectAll("g.group") |
|
.data(chord.groups) |
|
.enter().append("svg:g") |
|
.attr("class", "group") |
|
.on("mouseover", fade(.02)) |
|
.on("mouseout", fade(.80)); |
|
|
|
g.append("svg:path") |
|
.style("stroke", function(d) { return fill(d.index); }) |
|
.style("fill", function(d) { return fill(d.index); }) |
|
.attr("d", arc); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Append Ticks //////////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
var ticks = svg.append("svg:g").selectAll("g.ticks") |
|
.data(chord.groups) |
|
.enter().append("svg:g").selectAll("g.ticks") |
|
.attr("class", "ticks") |
|
.data(groupTicks) |
|
.enter().append("svg:g") |
|
.attr("transform", function(d) { |
|
return "rotate(" + (d.angle * 180 / Math.PI - 90) + ")" |
|
+ "translate(" + outerRadius+40 + ",0)"; |
|
}); |
|
|
|
ticks.append("svg:line") |
|
.attr("x1", 1) |
|
.attr("y1", 0) |
|
.attr("x2", 5) |
|
.attr("y2", 0) |
|
.style("stroke", "#000"); |
|
|
|
ticks.append("svg:text") |
|
.attr("x", 10) |
|
.attr("dy", ".35em") |
|
.attr("transform", function(d) { return d.angle > Math.PI ? "rotate(180)translate(-16)" : null; }) |
|
.style("text-anchor", function(d) { return d.angle > Math.PI ? "end" : null; }) |
|
.text(function(d) { return d.label; }); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Append Names //////////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
g.append("svg: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(" + (innerRadius + 55) + ")" |
|
+ (d.angle > Math.PI ? "rotate(180)" : ""); |
|
}) |
|
.text(function(d,i) { return NameProvider[i]; }); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// Draw inner chords /////////////////////// |
|
//////////////////////////////////////////////////////////// |
|
|
|
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(innerRadius)); |
|
|
|
//////////////////////////////////////////////////////////// |
|
////////////////// 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("stroke-opacity", opacity) |
|
.style("fill-opacity", opacity); |
|
}; |
|
}//fade |
|
|
|
// Returns an array of tick angles and labels, given a group. |
|
function groupTicks(d) { |
|
var k = (d.endAngle - d.startAngle) / d.value; |
|
return d3.range(0, d.value, 1000).map(function(v, i) { |
|
return { |
|
angle: v * k + d.startAngle, |
|
label: i % 4 ? null : v/1000 + "%" |
|
}; |
|
}); |
|
}//groupTicks |
|
|
|
</script> |
|
</body> |
|
</html> |