Created
February 27, 2016 20:07
-
-
Save captainelaine/a2afb7a3964e7640e7bc to your computer and use it in GitHub Desktop.
Dots on Lines
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Driver | 2007 | 2008 | 2009 | 2010 | 2011 | 2012 | 2013 | 2014 | 2015 | |
---|---|---|---|---|---|---|---|---|---|---|
Lewis Hamilton | 109 | 98 | 49 | 240 | 227 | 190 | 189 | 384 | 381 | |
Nico Rosberg | 20 | 17 | 34.5 | 142 | 89 | 93 | 171 | 317 | 322 | |
Sebastian Vettel | 6 | 35 | 84 | 256 | 392 | 281 | 397 | 167 | 278 | |
Kimi Raikkonen | 110 | 75 | 48 | 207 | 183 | 55 | 150 | |||
Felipe Massa | 94 | 97 | 22 | 144 | 118 | 122 | 112 | 134 | 121 | |
Nico Hulkenberg | 22 | 63 | 51 | 96 | 58 | |||||
Romain Grosjean | 0 | 96 | 132 | 8 | 51 | |||||
Jenson Button | 6 | 3 | 95 | 214 | 270 | 188 | 73 | 126 | 16 | |
Fernando Alonso | 109 | 61 | 26 | 252 | 257 | 278 | 242 | 161 | 11 | |
Mark Webber | 10 | 21 | 69.5 | 242 | 258 | 179 | 199 | |||
Adrian Sutil | 1 | 0 | 5 | 47 | 42 | 29 | ||||
Heikki Kovalainen | 30 | 53 | 22 | 0 | 0 | 0 | 0 | |||
Robert Kubica | 39 | 75 | 17 | 136 | ||||||
Rubens Barrichello | 0 | 11 | 77 | 47 | 4 | |||||
Jarno Trulli | 8 | 31 | 32.5 | 0 | 0 | |||||
Nick Heidfeld | 61 | 60 | 19 | 6 | 34 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href='https://fonts.googleapis.com/css?family=Ubuntu:300italic,500|Josefin+Sans:400italic' rel='stylesheet' type='text/css'> | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>F1 drivers' performances from 2007-2015</title> | |
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script> | |
<style type="text/css"> | |
body { | |
background-color: white; | |
font-family: 'Ubuntu', sans-serif; | |
text-align: center; | |
line-height: 20px; | |
} | |
h1 { | |
font-size: 24px; | |
margin: 0; | |
} | |
p { | |
font-size: 14px; | |
margin: 10px 0 0 0; | |
} | |
svg { | |
background-color: white; | |
opacity: 0.9; | |
} | |
.axis path, | |
.axis line { | |
fill: none; | |
stroke: white; | |
shape-rendering: crispEdges; | |
stroke-width: 0px; | |
} | |
.line.unfocused{ | |
stroke-opacity: 40%; | |
} | |
.line.focused { | |
stroke-width: 3px; | |
stroke-opacity: 100%; | |
} | |
.line { | |
stroke: grey; | |
fill: none; | |
stroke-opacity: 50%; | |
stroke-width: 2px; | |
} | |
#focused { | |
stroke-width: 2px; | |
stroke-opacity: 100px; | |
opacity: 1; | |
} | |
.axis text { | |
font-family: sans-serif; | |
font-size: 11px; | |
} | |
.tooltip { | |
position: absolute; | |
z-index: 10; | |
} | |
.tooltip p { | |
background-color:white; | |
border: none; | |
padding: 2px; | |
font-style: italic; | |
} | |
.name-label { | |
font-size: 15px; | |
font-style: italic; | |
font-family: 'Josefin Sans', sans-serif; | |
opacity: 0.5; | |
} | |
.name-label.focused { | |
opacity: 1; | |
width: 3px; | |
} | |
#high { | |
color: rgb(154,31,36); | |
} | |
a:hover{ | |
color: red; | |
} | |
text.hidden { | |
display: none; | |
} | |
text.bolder { | |
font-weight: bolder; | |
} | |
</style> | |
</head> | |
<body> | |
<h1>F1 drivers' performances from Season 2007 - Season 2015</h1> | |
<p>In the field of Formula One, it is very normal that some drivers will quit the championship due to bad performance or other reasons.</br>It is also pretty natual that drivers will change their teams every season.</p> | |
<p id = "high">However,as the performances of drivers in the race depends a lot on the competitiveness of their race cars. </br>Although a driver's car skill is good enough, there is still little chance that he can win a race with a slow car.</p> | |
<p>Thus in this chart, you may see some drivers always remain their points achieved during the season in a high level. </br>Otherwise, some drivers, for example, Fernando Alonso, whose performance floated a lot during the last couple years due to his transfer to other car teams.</p> | |
<p id="sources"><em><a href= "https://en.wikipedia.org/wiki/Formula_One">Source</a></em></p> | |
<script type="text/javascript"> | |
var fullwidth = 1130; | |
var fullheight = 530; | |
var margin = {top:50, right: 150, bottom: 50, left:100}; | |
var width = fullwidth - margin.left - margin.right; | |
var height = fullheight - margin.top - margin.bottom; | |
var dateFormat = d3.time.format("%Y"); | |
var xScale = d3.time.scale() | |
.range([0,width]); | |
var yScale = d3.scale.linear() | |
.range([0, height]); | |
var color = d3.scale.category10(); | |
var xAxis = d3.svg.axis() | |
.scale(xScale) | |
.orient("bottom") | |
.ticks(10) | |
.tickFormat(function(d){ | |
return dateFormat(d); | |
}) | |
.innerTickSize([10]) | |
.outerTickSize([10]); | |
var yAxis = d3.svg.axis() | |
.scale(yScale) | |
.orient("left") | |
.outerTickSize([10]) | |
; | |
var line = d3.svg.line() | |
.x(function(d) { | |
return xScale(dateFormat.parse(d.year)); | |
}) | |
.y(function(d) { | |
return yScale(+d.amount); | |
}); | |
var tooltip = d3.select("body") | |
.append("div") | |
.attr("class", "tooltip"); | |
var svg = d3.select("body") | |
.append("svg") | |
.attr("width",fullwidth) | |
.attr("height", fullheight) | |
.append("g") | |
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); | |
d3.csv("f1driverpoint_timeline.csv",function(data){ | |
var years = ["2007","2008","2009","2010","2011","2012","2013","2014","2015"]; | |
var dataset= []; | |
data.forEach(function(d,i){ | |
var points = []; | |
years.forEach(function (y){ | |
if (d[y]) { | |
points.push({ | |
year: y, | |
amount: d[y] | |
}); | |
} | |
}); | |
dataset.push({ | |
driver: d.Driver, | |
point: points | |
}); | |
}); | |
console.log(dataset); | |
xScale.domain( | |
d3.extent(years, function(d){ | |
return dateFormat.parse(d); | |
}) | |
); | |
yScale.domain([ | |
d3.max(dataset, function(d){ | |
return d3.max(d.point, function(d) { | |
return +d.amount; | |
}); | |
}), | |
0 | |
]); | |
var groups = svg.selectAll("g.lines") | |
.data(dataset) | |
.enter() | |
.append("g") | |
.attr("class", "lines") | |
.on("mouseover", mouseoverFunc) // putting these on the g nodes gets us a lot! | |
.on("mouseout", mouseoutFunc); | |
groups.append("title") | |
.text(function(d){ | |
return d.driver; | |
}); | |
groups.selectAll("path") | |
.data(function(d){ | |
return [d.point]; | |
}) | |
.enter() | |
.append("path") | |
.attr("class","line") | |
.attr("d", line) | |
.style("stroke", function(d){ | |
return color(d); | |
}); | |
groups.sort(function(a,b){ | |
return d3.ascending(+a.Driver,+b.Driver); | |
}) | |
.transition() | |
.delay(function(d,i){ | |
return i*10; | |
}) | |
.duration(1000) | |
.attr("d",line); | |
var circles = groups.selectAll("circle") | |
.data(function(d){ | |
return d.point; | |
}) | |
.enter() | |
.append("circle"); | |
circles.attr("cx",function(d){ | |
return xScale(dateFormat.parse(d.year)); | |
}) | |
.attr("cy",function(d){ | |
return yScale(+d.amount); | |
}) | |
.attr("r",3) | |
.style("opacity",0); | |
circles | |
.on("mouseover", mouseoverCircle) | |
.on("mousemove",mousemoveCircle) | |
.on("mouseout", mouseoutCircle); | |
groups.append("text") | |
.datum(function(d){ | |
return{ | |
name: d.driver, | |
value: d.point[d.point.length - 1] | |
}; | |
}) | |
.attr("transform", function(d){ | |
return "translate("+ (width + 3) + "," + yScale(+d.value.amount) +")"; | |
}) | |
.attr("x",3) | |
.attr("dy", "1px") | |
.text(function(d){ | |
return d.name; | |
}) | |
.classed("name-label",true); | |
d3.selectAll(".name-label") | |
.classed("hidden",function(d,i){ | |
if(i<=4|| i===9 ||i===8 ||i ===5) { | |
return false; | |
} else { | |
return true; | |
} | |
}); | |
svg.append("g") | |
.attr("class", "x axis") | |
.attr("transform", "translate(0," + height + ")") | |
.call(xAxis); | |
svg.append("g") | |
.attr("class", "y axis") | |
.call(yAxis); | |
d3.selectAll("g.lines") | |
.on("mouseover", mouseoverFunc) | |
.on("mouseout", mouseoutFunc); | |
// this version calls a named function. | |
svg.append("text") | |
.attr("class", "xlabel") | |
.attr("transform", "translate(" + (margin.left + width / 2) + " ," + | |
(height + margin.bottom) + ")") | |
.style("text-anchor", "middle") | |
.attr("dy", "-1px") | |
.attr("dx", "-70px") | |
.text("Season"); | |
svg.append("text") | |
.attr ("class", "ylabel") | |
.attr("transform", "rotate(-90)") | |
.attr("y", 0 - margin.left) // you may need to adjust this | |
.attr("x", 0 - (height / 2)) // you may need to adjust | |
.attr("dy", "3em") | |
.style("text-anchor", "middle") | |
.text("Total Points"); | |
function mouseoverFunc(d) { | |
// line styling: | |
// this is the g element. select it, then the line inside it! | |
//console.log(d, this); | |
d3.selectAll("path.line").classed("unfocused", true); | |
// now undo the unfocus on the current line and set to focused. | |
d3.select(this).select("path.line").classed("unfocused", false).classed("focused", true); | |
d3.selectAll(".name-label").classed("unfocused", true); | |
// now undo the unfocus on the current line and set to focused. | |
d3.select(this).select(".name-label").classed("hidden", false).classed("focused", true); | |
} | |
function mouseoutFunc(d) { | |
// this removes special classes for focusing from all lines. Back to default. | |
d3.selectAll("path.line").classed("unfocused", false).classed("focused", false); | |
tooltip.style("display", "none"); | |
d3.selectAll(".name-label").classed("focused",false).classed("hidden", true).classed ("hidden", function(d,i){ | |
if (i<=4|| i===9 ||i===8 ||i ===5) { | |
return false; | |
}else { | |
return true; | |
} | |
}) | |
// now undo the unfocus on the current line and set to focu // this sets it to invisible! | |
} | |
function mouseoverCircle(d) { | |
d3.select(this) | |
.transition() | |
.style("opacity",1) | |
.style("fill", "grey") | |
.attr("r", 6); | |
tooltip | |
.style("display", null) | |
.html("<p>Season:" +d.year + | |
"<br>Points:" +d.amount + "</p>"); | |
} | |
function mousemoveCircle(d) { | |
//console.log("events", window.event, d3.event); | |
tooltip | |
.style("top", (d3.event.pageY - 10) + "px" ) | |
.style("left", (d3.event.pageX + 10) + "px"); | |
} | |
function mouseoutCircle(d) { | |
d3.select(this) | |
.transition() | |
.style("opacity", 0) | |
.attr("r",3); | |
tooltip | |
.style("display","none"); | |
} | |
}); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment