Skip to content

Instantly share code, notes, and snippets.

@catherinekerr
Last active May 18, 2016 14:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save catherinekerr/573fd81b4d5a0b34f5347a260b3ebbb5 to your computer and use it in GitHub Desktop.
Save catherinekerr/573fd81b4d5a0b34f5347a260b3ebbb5 to your computer and use it in GitHub Desktop.
Top 10 ATP players' results in 2015

Top 10 ATP players' results in 2015

The chart indicates the results of the top 10 ATP players against each other during 2015, using a D3 Chord Diagram. Hover over the circle rim to see number of matches for that player. Hover over an arc to see the results between two players. The thickness of links between players encodes the relative frequency of matches between the players: thicker links represent more matches. Links are directed: for example, Djokovic beat Murray 6 times, but Murray only beat Djokovic once. Links are given the colour of the player who wins most often. Thanks to Mike Bostock for sample code. Data sourced from tennis-data.co.uk.

[[0,6,5,3,4,4,3,2,2,1],
[1,0,0,0,1,3,3,2,2,1],
[3,2,0,3,1,3,0,1,2,0],
[1,1,1,0,2,1,1,1,0,1],
[0,1,0,2,0,1,2,0,1,0],
[0,0,0,0,1,0,0,0,2,2],
[0,0,0,0,0,1,0,1,1,0],
[0,0,0,0,1,1,2,0,0,0],
[0,0,0,1,0,1,0,1,0,0],
[0,0,0,0,1,1,0,1,0,0]]
<!DOCTYPE html>
<html>
<meta charset="utf-8">
<title>Top 10 ATP players results in 2015</title>
<style>
body {
margin: auto;
}
#circle circle {
fill: none;
pointer-events: all;
}
.group path {
fill-opacity: .9;
}
path.chord {
stroke: #000;
stroke-width: .25px;
}
#circle:hover path.fade {
display: none;
}
svg {
font: 12px sans-serif;
margin: 1em;
}
</style>
<header>
</header>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script>
<body>
<!-- Table to hold the chord and text -->
<table border="0" cellpadding="10" style="overflow-y: scroll;">
<tr>
<td><div id="chord_container"></div></td>
<td><div id="text_container">
<h1 style="text-align: center">Top 10 ATP players' results in 2015</h1>
<span style="min-width: 300px; float: right; margin: 1em; font-family: 'PT Sans',sans-serif">
<p>The chart indicates the results of the top 10 ATP players against each other during 2015.
<p>Hover over the circle rim to see number of matches for that player. Hover over an arc to see the results between two players.
<p>The thickness of links between players encodes the relative frequency of matches between the players: thicker links represent more matches.
<p>Links are directed: for example, Djokovic beat Murray 6 times, but Murray only beat Djokovic once. Links are given the colour of the player who wins most often.
<p>Built with <a href="http://d3js.org/">d3.js</a>. Thanks to <a href="http://bost.ocks.org/mike/">Mike Bostock</a> for sample code.</span>
<p>Data sourced from <a href="http://www.tennis-data.co.uk/">tennis-data.co.uk</a>.</span>
</div></td>
</tr>
</table>
<script>
var width = (window.innerWidth < 480 ? window.innerWidth : 480),
height = width,
outerRadius = Math.min(width, height) / 2 - 10,
innerRadius = outerRadius - 24;
var formatPercent = d3.format(".1%");
//var fill = d3.scale.category10();
function fill(n) {
var colors = ['#8dd3c7',
'#ffffb3',
'#bebada',
'#fb8072',
'#80b1d3',
'#fdb462',
'#b3de69',
'#fccde5',
'#d9d9d9',
'#bc80bd']
return colors[n % colors.length];
}
var arc = d3.svg.arc()
.innerRadius(innerRadius)
.outerRadius(outerRadius);
var layout = d3.layout.chord()
.padding(.04)
.sortSubgroups(d3.descending)
.sortChords(d3.ascending);
var path = d3.svg.chord()
.radius(innerRadius);
var svg = d3.select("#chord_container").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("id", "circle")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
svg.append("circle")
.attr("r", outerRadius);
d3.csv("players.csv", function(players) {
d3.json("atpresults.json", function(matrix) {
// Compute the chord layout.
layout.matrix(matrix);
// Add a group per player.
var group = svg.selectAll(".group")
.data(layout.groups)
.enter().append("g")
.attr("class", "group")
.on("mouseover", mouseover);
// Add a mouseover title.
group.append("title").text(function(d, i) {
return players[i].name + ": " + parseInt(d.value+0.5) + " Top 10 wins";
});
// Add the group arc.
var groupPath = group.append("path")
.attr("id", function(d, i) { return "group" + i; })
.attr("d", arc)
.style("fill", function(d, i) { return fill(d.index); });
// Add a text label.
var groupText = group.append("text")
.attr("x", 6)
.attr("dy", 15);
groupText.append("textPath")
.attr("xlink:href", function(d, i) { return "#group" + i; })
.text(function(d, i) { console.log(d); return players[i].name; });
// Remove the labels that don't fit. :(
groupText.filter(function(d, i) { return groupPath[0][i].getTotalLength() / 2 - 6 < this.getComputedTextLength(); })
.remove();
// Add the chords.
var chord = svg.selectAll(".chord")
.data(layout.chords)
.enter().append("path")
.attr("class", "chord")
.style("fill", function(d) { return fill(d.source.index); })
.attr("d", path);
// Add an elaborate mouseover title for each chord.
chord.append("title").text(function(d) {
return players[d.source.index].name
+ " beat " + players[d.target.index].name
+ " " + d.source.value
+ " time(s)"
+ "\n" + players[d.target.index].name
+ " beat " + players[d.source.index].name
+ " " + d.target.value
+ " time(s)";
});
function mouseover(d, i) {
chord.classed("fade", function(p) {
return p.source.index != i
&& p.target.index != i;
});
}
});
});
d3.select(self.frameElement).style("height", "600px");
</script>
We can make this file beautiful and searchable if this error is corrected: No commas found in this CSV file in line 0.
name
Djokovic N.
Murray A.
Federer R.
Wawrinka S.
Nadal R.
Berdych T.
Ferrer D.
Nishikori
Gasq.
Tsonga
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment