Skip to content

Instantly share code, notes, and snippets.

@captainelaine
Created March 28, 2016 16:33
Show Gist options
  • Save captainelaine/a9dafcc81ee3dcdb2416 to your computer and use it in GitHub Desktop.
Save captainelaine/a9dafcc81ee3dcdb2416 to your computer and use it in GitHub Desktop.
Week 10, Small Multiples.
Year Driver Australian Malaysia Chinese Spanish Monaco Canadian British Hungaroring Belgian Italian Singapore Japanese Brazil Abu Dhabi
2015 Lewis Hamilton 25 18 25 18 15 25 25 8 25 25 0 25 18 18
2014 Lewis Hamilton 0 25 25 25 18 0 25 15 0 25 25 25 18 25
2013 Lewis Hamilton 10 15 15 0 12 15 12 25 15 2 10 0 2 6
2012 Lewis Hamilton 15 15 15 4 10 25 4 25 0 25 0 10 0 0
2011 Lewis Hamilton 18 4 25 18 8 0 12 12 0 12 10 10 0 25
2015 Nico Rosberg 18 15 18 25 25 18 18 4 18 0 12 18 25 25
2014 Nico Rosberg 25 18 18 18 25 18 0 12 18 18 0 18 25 0
2013 Nico Rosberg 0 12 0 8 25 10 25 0 12 8 12 4 10 15
2012 Nico Rosberg 0 0 25 6 18 8 0 1 0 6 10 0 0 0
2011 Nico Rosberg 0 0 10 6 0 0 8 2 8 0 6 1 6 8
2015 Sebastian Vettel 15 25 15 15 18 10 15 25 0 18 25 15 15 12
2014 Sebastian Vettel 0 15 10 12 0 15 10 6 10 8 18 15 10 8
2013 Sebastian Vettel 15 25 12 12 18 25 0 15 25 25 25 25 25 25
2012 Sebastian Vettel 18 0 10 8 12 12 15 12 18 0 25 25 8 15
2011 Sebastian Vettel 25 25 18 25 25 18 18 18 25 25 25 15 18 0
2015 Kimi Raikkonen 0 12 12 10 8 12 4 0 6 10 15 12 12 15
2014 Kimi Raikkonen 6 0 4 6 0 1 0 8 12 2 4 0 6 2
2013 Kimi Raikkonen 25 6 18 18 1 2 10 18 0 0 15 10 0 0
2012 Kimi Raikkonen 6 10 0 15 2 4 10 18 15 10 8 8 1 25
2015 Valtteri Bottas 0 10 8 12 0 15 10 0 2 12 10 10 10 0
2014 Valtteri Bottas 10 4 6 10 0 6 18 4 15 12 0 8 1 30
2015 Felipe Massa 12 8 10 8 0 8 12 0 8 15 0 0 0 4
2014 Felipe Massa 0 6 0 0 6 0 0 10 0 15 10 6 15 36
2013 Felipe Massa 12 10 8 15 0 4 8 4 6 12 8 1 6 4
2012 Felipe Massa 0 0 0 0 8 1 12 2 10 12 4 18 15 6
2011 Felipe Massa 6 10 8 0 0 8 10 8 4 8 2 6 10 10
2015 Daniil Kvyat 0 2 0 1 12 2 8 18 12 1 8 0 6 1
2014 Daniil Kvyat 2 1 1 0 0 0 2 0 2 0 0 0 0 0
2015 Daniel Ricciardo 8 1 2 6 10 0 0 15 0 4 18 0 0 8
2014 Daniel Ricciardo 0 0 12 15 15 25 15 25 25 10 15 12 0 24
2013 Daniel Ricciardo 0 0 6 1 0 0 4 0 1 6 0 0 1 0
2012 Daniel Ricciardo 2 0 0 0 0 0 0 0 2 0 2 1 0 1
2012 Daniel Ricciardo 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2015 Sergio Perez 1 0 0 0 6 0 2 0 10 8 6 0 0 10
2014 Sergio Perez 1 0 2 2 0 0 0 0 4 6 6 1 0 12
2013 Sergio Perez 0 2 0 2 0 0 0 2 0 0 4 0 8 2
2012 Sergio Perez 4 18 0 0 0 15 0 0 0 18 1 0 0 0
2011 Sergio Perez 0 0 0 2 0 0 6 0 0 0 1 4 0 0
2015 Nico Hulkenberg 6 0 0 0 0 4 6 0 0 6 0 8 8 6
2014 Nico Hulkenberg 8 10 8 1 10 10 4 0 1 0 2 4 4 16
2013 Nico Hulkenberg 0 4 1 0 0 0 1 0 0 10 2 8 4 0
2012 Nico Hulkenberg 0 2 0 1 4 0 0 0 12 0 0 6 10 0
2015 Romain Grosjean 0 0 6 4 0 1 0 6 15 0 0 6 4 2
2014 Romain Grosjean 0 0 0 4 4 0 0 0 0 0 0 0 0 0
2013 Romain Grosjean 1 8 2 0 0 0 0 8 4 4 0 15 0 12
2012 Romain Grosjean 0 0 8 12 0 18 8 15 0 6 0 0 0
2015 Jenson Button 0 0 0 0 4 0 0 2 0 0 0 0 0 0
2014 Jenson Button 15 8 0 0 8 12 12 1 8 4 0 10 12 20
2013 Jenson Button 2 0 10 4 8 0 0 6 8 1 6 2 12 0
2012 Jenson Button 25 0 18 2 0 0 1 8 25 0 18 12 25 12
2011 Jenson Button 8 18 12 15 15 25 0 25 15 18 18 25 15 15
2015 Fernando Alonso 0 0 0 0 0 0 1 10 0 0 0 0 0 0
2014 Fernando Alonso 12 12 15 8 12 8 8 18 6 0 12 0 8 4
2013 Fernando Alonso 18 0 25 25 6 18 15 10 18 18 18 12 15 10
2012 Fernando Alonso 10 25 2 18 15 10 18 10 0 15 15 0 18 18
2011 Fernando Alonso 12 8 6 10 18 0 25 15 12 15 12 18 12 18
2013 Mark Webber 8 18 0 10 15 12 18 12 10 15 0 18 18 18
2012 Mark Webber 12 12 12 0 25 6 25 4 8 0 0 2 12 0
2011 Mark Webber 10 12 15 12 12 15 15 10 18 0 15 12 25 12
2014 Pastor Maldonado 0 0 0 0 0 0 0 0 0 0 0 0 0 0
2013 Pastor Maldonado 0 0 0 0 0 0 0 1 0 0 0 0 0 0
2012 Pastor Maldonado 0 0 4 25 0 0 0 0 0 0 0 4 0 10
2011 Pastor Maldonado 0 0 0 0 0 0 0 0 1 0 0 0 0 0
2012 Kamui Kobayashi 8 0 1 10 0 2 0 0 0 2 0 15 2 8
2011 Kamui Kobayashi 0 6 1 1 10 6 0 0 0 0 0 0 2 1
2013 Paul di Resta 4 0 4 6 2 6 2 0 0 0 0 0 0 8
2012 Paul di Resta 1 6 0 0 6 0 0 0 1 4 12 0 0 2
2011 Paul di Resta 1 1 0 0 0 0 0 6 0 4 8 0 4 2
<link href='https://fonts.googleapis.com/css?family=Ubuntu:300italic,500|Josefin+Sans:400italic' rel='stylesheet' type='text/css'>
<!DOCTYPE html>
<meta charset="utf-8">
<!-- CSS style for table filters based on Nathan Yau's in his tutorial for How American's Spend Their Days -->
<style>
body{
font-size:16px;
font-family: 'Ubuntu',sans-serif;
width: 1000px;
margin-left: 200px;
}
a{
color:#821122;
}
#header{
border-bottom:1px solid #ccc;
margin:20px 26px 20px 20px;
text-align:center;
}
#header h1{
font-size:20px;
font-family: 'Ubuntu',sans-serif;
font-weight:normal;
}
#header p{
font-family: 'Ubuntu',sans-serif;
font-size:14px;
line-height:1.4em;
}
#explain {
margin: 0 0 0 20px;
}
#explain h3{
font-size:17px;
margin:0 0 0.5em 0;
padding:0;
}
#explain p{
width: 700px;
font-size:14px;
line-height:1.4em;
color:#717171;
margin-top:0;
text-align: left;
}
#filters{
margin:0 24px 10px 16px;
float:right;
}
.area{
fill:#e2e2e2;
stroke: #888;
stroke-width: 0.5px;
}
.line {
fill:none;
stroke:steelblue;
stroke-width:1.5px;
}
.endpoint {
fill: steelblue;
font-size: 10px;
}
#filters table{
border-collapse:collapse;
border-top:1px solid #ccc;
}
#filters table td{
padding:0;margin:0;
}
#filters a{
display:block;
align-items: baseline;
padding:2px 4px;
font-size:14px;
color:#919292;
background:#F0F4F5;
cursor:pointer;
border-left:1px solid #CCCCCC;
border-bottom:1px solid #CCCCCC;
border-right:1px solid #CCCCCC;
overflow:hidden;
}
#filters a:hover{
text-decoration:underline;
}
#filters a.current{
background:#fff;color:#000;
font-weight:bold;
}
#filters a.current:hover{
text-decoration:none;
}
.left{
display:inline-block;
}
.clr{
clear:both;
}
.label {
fill: black;
font-size: 12px;
}
.y.axis text, .axislabel {
font-size: 10px;
fill: #888;
}
</style>
<body>
<div id="header">
<h2>F1 drivers' performances in every grand prixes during 2011 - 2015 seasons </h2>
<p><a href = "http://www.f1fanatic.co.uk/">Source: F1Fanatic (The Inoepenoent F1 Blog)</a></p>
</div>
<div id="explain" class="left">
<h3>Australian</h3>
<p>The Australian Grand Prix Corporation coined the phrase 'a great place for the race' and Melbourne is just that. Australia's second largest city is one of the most vibrant and cosmopolitan on earth, with plenty to do both day and night. The climate in late summer is perfect, the people are friendly and, to top it all, the Grand Prix is one of the most well organised of the year.</p>
</div>
<div id="filters">
<table class="left">
<tr>
<td><a id="Australian" class="current">Australian</a></td>
</tr>
<tr>
<td><a id="Malaysia">Malaysia</a></td>
</tr>
<tr>
<td><a id="Chinese">Chinese</a></td>
</tr>
<tr>
<td><a id="Spanish">Spanish</a></td>
</tr>
<tr>
<td><a id="Monaco">Monaco</a></td>
</tr>
<tr>
<td><a id="Canadian">Canadian</a></td>
</tr>
<tr>
<td><a id="British">British</a></td>
</tr>
</table>
<table class="left">
<tr>
<td><a id="Hungaroring">Hungaroring</a></td>
</tr>
<tr>
<td><a id="Belgian">Belgian</a></td>
</tr>
<tr>
<td><a id="Italian">Italian</a></td>
</tr>
<tr>
<td><a id="Singapore">Singapore</a></td>
</tr>
<tr>
<td><a id="Japanese">Japanese</a></td>
</tr>
<tr>
<td><a id="Brazil">Brazil</a></td>
</tr>
<tr>
<td><a id="Abu Dhabi">Abu Dhabi</a></td>
</tr>
</table>
</div>
<div class="clr"></div>
<div id="vis"></div>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script>
var explain = {
"Australian": "The Australian Grand Prix Corporation coined the phrase 'a great place for the race' and Melbourne is just that. </br> Australia's second largest city is one of the most vibrant and cosmopolitan on earth, with plenty to do both day and night. </br>The climate in late summer is perfect, the people are friendly and, to top it all, the Grand Prix is one of the most well organised of the year.",
"Malaysia":"Designed by Hermann Tilke, Sepang is one of the most technical circuits in Formula One. </br>The combination of long high-speed straights, and tight twisting complexes make the track very complicated, but also perfect for overtaking as the track itself is very wide. </br>The drivers love it and, along with Malaysia's distinct atmosphere, it makes for an experience unique in Formula One.",
"Chinese" : "The Shanghai International Circuit was designed as the race circuit for the new millennium. </br>And the modern track, with its stunning architecture, has achieved its goal of becoming China's gateway to the world of Formula One racing since it debuted on the calendar in 2004.",
"Spanish": "The Formula One teams are no strangers to the Circuit de Barcelona-Catalunya (formerly known as the Circuit de Catalunya); not only have they raced there every year since 1991, they also conduct extensive testing at the venue. </br>Barcelona's mix of high- and low-speed corners, plus its abrasive and rather bumpy track surface, makes for a physically and mechanically taxing race.",
"Monaco": "The Monaco Grand Prix is the one race of the year that every driver dreams of winning. Like the Indy 500 or Le Mans, it stands alone, almost distinct from the sport from which it was born. </br>A combination of precision driving, technical excellence and sheer bravery is required to win in Monte Carlo, facets which highlight the differences between the great and the good in Formula One.",
"Canadian": "In the 1960s the rivalry between French and English speaking Canada meant that the country's Grand Prix had two homes: Mosport Park one year and Mont-Tremblant the next. </br>By 1970, however, Mont-Tremblant was deemed too dangerous and the race moved full time to Mosport Park.",
"British": "Like so many of England's racing circuits, Silverstone started life as an aerodrome. </br>When the Second World War ended in 1945, England's other two circuits, Donington Park and the legendary Brooklands, had fallen into disrepair. And so it was that the outer taxiways and interconnecting runways of Silverstone became adopted by the Royal Automobile Club as the home for the British Grand Prix in 1948. </br>The circuit was fast and challenging and in 1949 the shape was formed that remains the basis of the track to this day.",
"Hungaroring": "Hungary first hosted a Grand Prix in the 1930s, but following the Second World War and the building of the Iron Curtain it was not until the 1960s that motorsport began to find a place in the country.",
"Belgian": "Belgium's Spa-Francorchamps circuit is among the most historic on the Formula One calendar, having hosted a (non-championship) Grand Prix as long ago as 1924, and remains one of the most popular venues with drivers and fans alike.",
"Italian": "Monza is regarded by many as the embodiment of Formula One racing.</br>Not only is it a fantastic example of a track that combines speed with skill, it also has a heart and soul all of its own. </br>It has seen some of the finest races of all time, but also some of the sport's worst accidents. The names of great drivers and the sounds of engines from years gone by linger in the grand old trees surrounding the track in the royal park.",
"Singapore": "In 2008 Singapore had the honour of hosting the first night-time event in Formula One history. </br>The inaugural Singapore Grand Prix proved a huge hit, staged on a new street circuit, with the city's famous skyline providing a truly spectacular backdrop.",
"Japanese": "One of the greatest tracks used in Formula One racing today, Japan's Suzuka circuit is a massive test of car and driver ability.</br>Built by Honda as a test facility in 1962, the track was designed by Dutchman John Hugenholz, the Hermann Tilke of his day. </br>A huge theme park was also constructed at the track, including the famous big wheel which dominates the Suzuka skyline.",
"Brazil": "In 1938 a huge plot of land was bought in Sao Paulo by two local property developers who intended to build a large housing development.</br> It soon became clear, however, that one part of the land was not suitable for housing and so they decided to build a racing circuit instead. </br>Sao Paulo grew at an incredible speed though and soon the circuit was surrounded by houses.",
"Abu Dhabi": "Abu Dhabi is a city on the move. Not content with enjoying one of the world's richest oil reserves, the region has recently thrown itself into a massive programme of development. And one of the jewels in Abu Dhabi's crown is the new 5.55-kilometre Yas Marina Circuit, which on November 1, 2009, hosted the country's inaugural Grand Prix. It was also the first F1 twighlight race, with powerful lighting ensuring a seamless transition from day to night."
};
var drivers = [];
var fullwidth = 250,
fullheight = 130;
var margin = {top: 50, right: 15, bottom: 20, left: 25},
width = fullwidth - margin.left - margin.right,
height = fullheight - margin.top - margin.bottom;
var x = d3.time.scale()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var yAxis = d3.svg.axis()
.orient("left")
.ticks(2)
.outerTickSize(0)
.innerTickSize(0)
//.tickFormat(d3.format("s")); // thousands
var current = "Australian"; //the first one shown is Australian Grand Prix
var area = d3.svg.area()
.x(function(d) { return x(d.Year); })
.y0(height)
.y1(function(d) { return y(d[current]); });
var line = d3.svg.line()
.x(function(d) { return x(d.Year); })
.y(function(d) { return y(d[current]); });
d3.select("#explain h3").text(current);
d3.select("#explain p").html(explain[current]);
d3.csv("2011-2015fullseason.csv", typeFix, function(error, data) {
//typeFix is a function that parses the dates and sets the strings to numeric. See below!
console.log("data after load", data);
// Nest data by symbol.
drivers = d3.nest()
.key(function(d) { return d.Driver; })
.sortValues(function(a,b) {
return a.Year - b.Year;
}) // date is already parsed years
.entries(data);
console.log(drivers);
// Compute the minimum and maximum date across symbols.
// We assume values are sorted by date.
x.domain([
d3.min(drivers, function(s) { return s.values[0].Year; }),
d3.max(drivers, function(s) { return s.values[s.values.length - 1].Year; })
]);
y.domain([0, d3.max(drivers, function(c) {
return d3.max(c.values, function(v) { return +v[current];}); // current illness
})
]);
yAxis.scale(y);
// Add an SVG element for each country, with the desired dimensions and margin.
var svg = d3.select("#vis").selectAll("svg")
.data(drivers)
.enter().append("svg")
.attr("width", fullwidth)
.attr("height", fullheight)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")")
.each(multiple); // uses each to call the multiple code for each country
function multiple(drivers) {
// set up each individual chart, with country as data
var localsvg = d3.select(this); //svg is a single chart, with country data.
// Add the area path elements. Note: the y-domain is set per element.
localsvg.append("path")
.attr("class", "area")
.attr("d", function(d) { return area(d.values); });
// Add the line path elements. Note: the y-domain is set per element.
localsvg.append("path")
.attr("class", "line")
.attr("d", function(d) { return line(d.values); });
localsvg.append("text")
.attr("class", "axislabel")
.attr("x", 0)
.attr("y", height + margin.bottom/2)
.style("text-anchor", "start")
.text(function(d) { return d.values[0].Year; });
// Add a small label for the symbol name.
localsvg.append("text")
.attr("class", "label")
.attr("x", width/2)
.attr("y", -8)
.style("text-anchor", "middle")
.text(function(d) { return d.key; });
localsvg.append("text")
.attr("class", "axislabel")
.attr("x", width)
.attr("y", height + margin.bottom/2)
.style("text-anchor", "end")
.text(function(d) {
return d.values[d.values.length - 1].Year;
});
// put a dot on last point
localsvg.append("circle")
.attr("class", "endpoint")
.attr("cx", function(d) {return x(d.values[d.values.length - 1].Year);})
.attr("cy", function(d) { return y(d.values[d.values.length - 1][current]);})
.attr("r", 2);
// label the value on the last point
localsvg.append("text")
.attr("class", "endpoint")
.attr("x", width)
.attr("y", function(d) {return y(d.values[d.values.length - 1][current]);})
.attr("dy", -8)
.style("text-anchor", "end")
.text(function(d) { return d.values[d.values.length - 1][current]; });
localsvg.append("g").attr("class", "y axis").call(yAxis);
} // end multiple
d3.selectAll("#filters a").on("click", function() {
d3.selectAll("#filters a").classed("current", false);
d3.select(this).classed("current", true);
var label = d3.select(this).attr("text");
var selection = d3.select(this).attr("id");
current = selection;
d3.select("#explain h3").text(current);
d3.select("#explain p").html(explain[current]);
transition(current);
});
function transition(current) {
y.domain([0, d3.max(drivers, function(c) {
return d3.max(c.values, function(v) { return +v[current];});
})
]);
yAxis.scale(y);
console.log("in trans", y.domain());
// existing svg that created each chart - now we transition each one
svg.each(function(driver) {
var chartTrans = d3.select(this).transition();
chartTrans.select(".y.axis").call(yAxis);
chartTrans.select("path.area")
.attr("d", function(d) { return area(d.values); });
chartTrans.select("path.line")
.attr("d", function(d) { return line(d.values); });
chartTrans.select("circle.endpoint")
.attr("cy", function(d) {return y(d.values[d.values.length - 1][current]);});
// label the value on the last point
chartTrans.select("text.endpoint")
.attr("y", function(d) {return y(d.values[d.values.length - 1][current]);})
.text(function(d) { return d.values[d.values.length - 1][current]; });
}); // end each
}
});
// this function is applied to all the data values on load!
function typeFix(d) {
d.Australian = +d.Australian;
d.Malaysia = +d.Malaysia;
d.Chinese = +d.Chinese;
d.Spanish = +d.Spanish;
d.Monaco = +d.Monaco;
d.Canadian= +d.Canadian;
d.British = +d.British;
d.Hungaroring = +d.Hungaroring;
d.Belgian = +d.Belgian;
d.Italian= +d.Italian;
d.Singapore = +d.Singapore;
d.Japanese = +d.Japanese;
d.Brazil = +d.Brazil;
d.Abu_Dhabi = +d.Abu_Dhabi;
return d;
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment