Skip to content

Instantly share code, notes, and snippets.

@mph006
Created July 31, 2015 01:28
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 mph006/f2dab97977e00e6755dd to your computer and use it in GitHub Desktop.
Save mph006/f2dab97977e00e6755dd to your computer and use it in GitHub Desktop.
Olympic 100M Dash Medals - Chart Resizing, Event Listeners, Voronoi Overlay
<!DOCTYPE html>
<meta charset="utf-8">
<title>Olympics 100 Meter Dash</title>
<style type="text/css">
body {
font-family: arial, sans;
font-size: 13px;
margin: 10px auto;
max-width:900px;
}
.g-graphic-container{
position: relative;
max-width: 900px;
}
svg{
max-width: 900px;
/* border: thin solid #f0f;*/
}
.line {
fill:none;
}
.axis text {
font-size: 12px;
fill: #777;
}
.axis path {
display: none;
}
.axis line {
stroke-width:.3px;
stroke: #dedede;
/*stroke-dasharray: 2px 2px;*/
}
.country-container {
display: inline-block;
margin-right:10px;
}
.info{
position: absolute;
top: 10px;
left: 250px;
}
.country-label{
position: absolute;
top:15px;
left:150px;
}
#countrySelect{
position: absolute;
top: 30px;
left:500px;
}
#decileSelect{
position: absolute;
top: 30px;
left:650px;
}
table {
width: 120px;
margin: 10px 10px;
border-collapse: collapse;
position: absolute;
}
.g-num {
text-align: left;
}
td {
padding: 3px 0;
border-bottom: 1px solid #dedede;
}
.medal-table{
position: absolute;
top: 100px;
left: 120px;
background-color: white;
}
.tooltip{
border: thin solid #dedede;
visibility: hidden;
display: inline-block;
position: absolute;
left:275px;
top:20px;
background-color: white;
padding: 10px;
}
.g-row{
cursor: pointer;
}
h1{
position: relative;
font-size: 25px;
top:10px;
left: 200px;
color:#606060;
}
path{
fill:white;
fill-opacity: 0.1;
stroke: #f0f;
}
path:hover{
fill:orange;
}
</style>
<body>
<div class="g-graphic-container">
<h1>Olympic 100 Meter Dash Records</h1>
<div class="info"></div>
<div class="tooltip">
<div class="athlete-name"></div>
<div class="origin-country"></div>
<div class="win-year"></div>
<div class="medal-status"></div>
<div class="meters-back"></div>
<div class="seconds-back"></div>
</div>
</div>
</body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js" charset="utf-8"></script>
<script type="text/javascript">
var countryMap = {
"USA": "United States",
"GBR": "Great Britain",
"JAM": "Jamaica",
"CAN": "Canada",
"TRI": "Trinidad and Tobago",
"AUS": "Australia",
"GER": "Germany",
"NAM": "Namibia",
"CUB": "Cuba",
"URS": "Soviet Union",
"BAR": "Barbados",
"EUA": "United Team of Germany",
"HUN": "Hungary",
"PAN": "Panama",
"NED": "Netherlands",
"POR": "Portugal",
"NZL": "New Zealand",
"RSA": "South Africa",
"BUL": "Bulgaria"
};
var colors = {
"GOLD": "#efcf6d",
"SILVER": "#b0b0b1",
"BRONZE": "#c59e8a"
}
var margin = {top: 20, right: 50, bottom: 20, left: 80};
var reSpace = new RegExp(" ", 'g');
var graphic = d3.select(".g-graphic-container");
var width = graphic.node().clientWidth - margin.left - margin.right,
height = 600 - margin.top - margin.bottom;
var xScale = d3.scale.linear()
.range([width,0]);
var yScale = d3.scale.ordinal()
// .range([height, 0]);
.rangeRoundPoints([0, height]);
var xAxis = d3.svg.axis()
.scale(xScale)
.tickSize(-height)
.tickPadding(8)
.tickFormat(d3.round)
.orient("bottom");
var yAxis = d3.svg.axis()
.scale(yScale)
.tickSize(-width)
.tickPadding(8)
.orient("right");
var globalData;
//http://stackoverflow.com/questions/14167863/how-can-i-bring-a-circle-to-the-front-with-d3
d3.selection.prototype.moveToFront = function() {
return this.each(function(){
this.parentNode.appendChild(this);
});
};
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
var countryNest;
d3.tsv("medalists.tsv", ready);
function mouseoverMedal(d){
var sel = d3.select(this);
sel.moveToFront();
sel.style("stroke","black").style("stroke-width","2px");
d3.select(".tooltip")
.style("visibility","visible")
.style("transform","translate("+(d3.mouse(this)[0]-366)+"px,"+(d3.mouse(this)[1]-10)+"px)");
d3.select(".athlete-name").text(d.name);
d3.select(".win-year").text(d.year);
d3.select(".medal-status").text(d.medal);
d3.select(".meters-back").text("Meters Back: "+Number((d.metersBack).toFixed(4)));
d3.select(".seconds-back").text("Seconds Behind: "+Number((d.secondsBehind).toFixed(4)));
d3.select(".origin-country").text(d.country);
}
function mouseoverTable(d){
d3.select(this).style("background-color","#fdfd96");
d3.selectAll("#"+d.key.replace(reSpace,"-"))
.style("stroke","black")
.style("stroke-width","2px");
}
function mouseleaveMedal(){
d3.select(".tooltip").style("visibility","hidden");
d3.select(this).style("stroke","none");
}
function mouseleaveTable(d){
d3.select(this).style("background-color","white");
d3.selectAll("#"+d.key.replace(reSpace,"-"))
.style("stroke","none");
}
function createTable(countryNest){
var table = d3.select("body")
.append("table")
.attr("class","medal-table");
var row = table.selectAll(".g-row")
.data(countryNest)
.enter().append("tr")
.attr("class", "g-row")
.on("mouseover",mouseoverTable)
.on("mouseleave",mouseleaveTable);
row.append("td")
.attr("class", "g-x g-num")
.text(function(d) { return d.key;});
row.append("td")
.attr("class", "g-y g-num")
.text(function(d){ return d.values;});
}
function polygon(d) {
return "M" + d.join("L") + "Z";
}
//http://bl.ocks.org/mbostock/8033015
function addVoronoi(){
var voronoi = d3.geom.voronoi()
.clipExtent([[-margin.left, -margin.top], [width + margin.right, height + margin.bottom]]);
verticies = globalData.map(function(d){
//needs a random for some reason...
return [xScale(d.metersBack)+Math.random(),yScale(d.year)+Math.random()]
});
svg.append("g").selectAll("path")
.data(voronoi(verticies), polygon)
.enter().append("path")
.attr("d", polygon)
//bind the mouseover data to the global data datum by index, not the polygon itself
.datum(function(d,i){return globalData[i]})
.on("mouseover",function(d){
console.log(d);
});
}
function ready(error, data) {
if (error) return console.warn(error);
var winnerTime = parseFloat(data[0].time);
data.forEach(function(d){
d.time = parseFloat(d.time);
d.countryCode = d.countryCode.trim();
d.country = countryMap[d.countryCode];
d.medal =d.medal.trim();
//100M Dash
d.secondsBehind = d.time - winnerTime;
var metersPerSecond = 100/d.time;
d.metersBack = d.secondsBehind * metersPerSecond;
});
globalData = data;
var countryNest = d3.nest()
.key(function(d){return d.country;})
.rollup(function(leaves) { return leaves.length; })
.entries(data);
countryNest.sort(function(a,b){return b.values - a.values; });
var years = data.map(function(d){return d.year;})
yearArray = d3.set(years).values();
xScale.domain(d3.extent(data,function(d){return d.metersBack;}));
yScale.domain(yearArray.reverse());
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (height) + ")")
.call(xAxis)
.selectAll("g");
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" +width+ ",0)")
.call(yAxis);
addVoronoi();
svg.selectAll("circle")
.data(data)
.enter()
.append("circle")
.attr("r",5)
.attr("class","medal")
.attr("id",function(d){return d.country.replace(reSpace,"-");})
.attr("cx",function(d){return xScale(d.metersBack);})
.attr("cy",function(d){return yScale(d.year)})
.style("fill",function(d){return colors[d.medal];})
.on("mouseover",mouseoverMedal)
.on("mouseleave", mouseleaveMedal);
createTable(countryNest);
}
function updateWindow(){
width = graphic.node().clientWidth - margin.left - margin.right;
if(width<=460){
d3.select(".medal-table").style("visibility","hidden").style("left","50px");
d3.select("h1").style("font-size","11px");
}
else{
d3.select("h1").style("font-size","25px");
d3.select(".medal-table").style("visibility","visible");
}
xScale.range([width,0]);
d3.select("svg").attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
svg.selectAll("circle")
.attr("cx",function(d){return xScale(d.metersBack);});
svg.select(".y")
.attr("transform", "translate(" +width+ ",0)");
svg.select(".x")
.attr("transform", "translate(0," + (height) + ")")
.call(xAxis);
}
window.onresize = updateWindow;
</script>
name medal time countryCode idx year
Usain Bolt GOLD 9.63 JAM 1 2012
Yohan Blake SILVER 9.75 JAM 2 2012
Justin Gatlin BRONZE 9.79 USA 3 2012
Usain Bolt GOLD 9.69 JAM 4 2008
Richard Thompson SILVER 9.89 TRI 5 2008
Walter Dix BRONZE 9.91 USA 6 2008
Justin Gatlin GOLD 9.85 USA 7 2004
Francis Obikwelu SILVER 9.86 POR 8 2004
Maurice Greene BRONZE 9.87 USA 9 2004
Maurice Greene GOLD 9.87 USA 10 2000
Ato Boldon SILVER 9.99 TRI 11 2000
Obadele Thompson BRONZE 10.04 BAR 12 2000
Donovan Bailey GOLD 9.84 CAN 13 1996
Frankie Fredericks SILVER 9.89 NAM 14 1996
Ato Boldon BRONZE 9.9 TRI 15 1996
Linford Christie GOLD 9.96 GBR 16 1992
Frankie Fredericks SILVER 10.02 NAM 17 1992
Dennis Mitchell BRONZE 10.04 USA 18 1992
Carl Lewis GOLD 9.92 USA 19 1988
Linford Christie SILVER 9.97 GBR 20 1988
Calvin Smith BRONZE 9.99 USA 21 1988
Carl Lewis GOLD 9.99 USA 22 1984
Sam Graddy SILVER 10.19 USA 23 1984
Ben Johnson BRONZE 10.22 CAN 24 1984
Allan Wells GOLD 10.25 GBR 25 1980
Silvio Leonard Tartabull SILVER 10.25 CUB 26 1980
Petar Petrov BRONZE 10.39 BUL 27 1980
Hasely Crawford GOLD 10.06 TRI 28 1976
Donald Quarrie SILVER 10.08 JAM 29 1976
Valery Borzov BRONZE 10.14 URS 30 1976
Valery Borzov GOLD 10.14 URS 31 1972
Robert Taylor SILVER 10.24 USA 32 1972
Lennox Miller BRONZE 10.33 JAM 33 1972
Jim Hines GOLD 9.95 USA 34 1968
Lennox Miller SILVER 10.04 JAM 35 1968
Charles Greene BRONZE 10.07 USA 36 1968
Bob Hayes GOLD 10 USA 37 1964
Enrique Figuerola Camue SILVER 10.2 CUB 38 1964
Harry Jerome BRONZE 10.2 CAN 39 1964
Armin Hary GOLD 10.2 EUA 40 1960
David Sime SILVER 10.2 USA 41 1960
Peter Radford BRONZE 10.3 GBR 42 1960
Bobby Joe Morrow GOLD 10.5 USA 43 1956
W. Thane Baker SILVER 10.5 USA 44 1956
Hector Hogan BRONZE 10.6 AUS 45 1956
Lindy Remigino GOLD 10.4 USA 46 1952
Herbert McKenley SILVER 10.4 JAM 47 1952
E. McDonald Bailey BRONZE 10.4 GBR 48 1952
W. Harrison Dillard GOLD 10.3 USA 49 1948
H. Norwood \Barney\ Ewell SILVER 10.4 USA 50 1948
Lloyd LaBeach BRONZE 10.4 PAN 51 1948
Jesse Owens GOLD 10.3 USA 52 1936
Ralph Metcalfe SILVER 10.4 USA 53 1936
Martinus Osendarp BRONZE 10.5 NED 54 1936
T. \Eddie\ Tolan GOLD 10.3 USA 55 1932
Ralph Metcalfe SILVER 10.3 USA 56 1932
Arthur Jonath BRONZE 10.4 GER 57 1932
Percy Williams GOLD 10.8 CAN 58 1928
John \Jack\ London SILVER 10.9 GBR 59 1928
Georg Lammers BRONZE 10.9 GER 60 1928
Harold Abrahams GOLD 10.6 GBR 61 1924
Jackson Scholz SILVER 10.8 USA 62 1924
Arthur Porritt BRONZE 10.9 NZL 63 1924
Charles Paddock GOLD 10.8 USA 64 1920
Morris Kirksey SILVER 10.9 USA 65 1920
Harry Edward BRONZE 10.9 GBR 66 1920
Ralph Craig GOLD 10.8 USA 67 1912
Alvah Meyer SILVER 10.9 USA 68 1912
Donald Lippincott BRONZE 10.9 USA 69 1912
Reginald Walker GOLD 10.8 RSA 70 1908
James Rector SILVER 11 USA 71 1908
Robert Kerr BRONZE 11 CAN 72 1908
Charles Archie Hahn GOLD 11.2 USA 73 1906
Fay Moulton SILVER 11.3 USA 74 1906
Nigel Barker BRONZE 11.3 AUS 75 1906
Charles Archie Hahn GOLD 11 USA 76 1904
Nathaniel Cartmell SILVER 11.2 USA 77 1904
Bill Hogenson BRONZE 11.2 USA 78 1904
Frank Jarvis GOLD 11 USA 79 1900
J. Walter Tewksbury SILVER 11.1 USA 80 1900
Stanley Rowley BRONZE 11.2 AUS 81 1900
Thomas Burke GOLD 12 USA 82 1896
Fritz Hofmann SILVER 12.2 GER 83 1896
Alojz Sokol BRONZE 12.6 HUN 84 1896
Francis Lane BRONZE 12.6 USA 85 1896
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment