Skip to content

Instantly share code, notes, and snippets.

@jrzief
Last active September 6, 2019 16:54
Show Gist options
  • Save jrzief/ff31e41670c174767a57395804dfd00c to your computer and use it in GitHub Desktop.
Save jrzief/ff31e41670c174767a57395804dfd00c to your computer and use it in GitHub Desktop.
Chord diagram 2014 - Commuter data
license: mit
<!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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment