Skip to content

Instantly share code, notes, and snippets.

@GerardoFurtado
Last active December 27, 2015 07:24
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 GerardoFurtado/bdc8c1ef62857314ac03 to your computer and use it in GitHub Desktop.
Save GerardoFurtado/bdc8c1ef62857314ac03 to your computer and use it in GitHub Desktop.
Formula 1: Teammate Battles
[
{
"driver": "Lewis Hamilton",
"battle": [
{"year": 2007, "points": 50.0, "teammate": "Fernando Alonso", "team": "McLaren"},
{"year": 2008, "points": 64.9, "teammate": "Heikki Kovalainen", "team": "McLaren"},
{"year": 2009, "points": 69.0, "teammate": "Heikki Kovalainen", "team": "McLaren"},
{"year": 2010, "points": 52.9, "teammate": "Jenson Button", "team": "McLaren"},
{"year": 2011, "points": 45.7, "teammate": "Jenson Button", "team": "McLaren"},
{"year": 2012, "points": 50.3, "teammate": "Jenson Button", "team": "McLaren"},
{"year": 2013, "points": 52.5, "teammate": "Nico Rosberg", "team": "Mercedes"},
{"year": 2014, "points": 54.8, "teammate": "Nico Rosberg", "team": "Mercedes"},
{"year": 2015, "points": 54.2, "teammate": "Nico Rosberg", "team": "Mercedes"}
]
},
{
"driver": "Nico Rosberg",
"battle": [
{"year": 2006, "points": 36.4, "teammate": "Mark Webber", "team": "Williams"},
{"year": 2007, "points": 53.6, "teammate": "Alexander Wurz", "team": "Williams"},
{"year": 2008, "points": 65.4, "teammate": "Kazuki Nakajima", "team": "Williams"},
{"year": 2009, "points": 100.0, "teammate": "Kazuki Nakajima", "team": "Williams"},
{"year": 2010, "points": 66.4, "teammate": "Michael Schumacher", "team": "Mercedes"},
{"year": 2011, "points": 53.9, "teammate": "Michael Schumacher", "team": "Mercedes"},
{"year": 2012, "points": 65.5, "teammate": "Michael Schumacher", "team": "Mercedes"},
{"year": 2013, "points": 47.5, "teammate": "Lewis Hamilton", "team": "Mercedes"},
{"year": 2014, "points": 45.2, "teammate": "Lewis Hamilton", "team": "Mercedes"},
{"year": 2015, "points": 45.8, "teammate": "Lewis Hamilton", "team": "Mercedes"}
]
},
{
"driver": "Sebastian Vettel",
"battle": [
{"year": 2008, "points": 89.7, "teammate": "Sébastien Bourdais", "team": "Toro Rosso"},
{"year": 2009, "points": 54.7, "teammate": "Mark Webber", "team": "Red Bull"},
{"year": 2011, "points": 51.4, "teammate": "Mark Webber", "team": "Red Bull"},
{"year": 2010, "points": 60.3, "teammate": "Mark Webber", "team": "Red Bull"},
{"year": 2012, "points": 61.1, "teammate": "Mark Webber", "team": "Red Bull"},
{"year": 2013, "points": 66.6, "teammate": "Mark Webber", "team": "Red Bull"},
{"year": 2014, "points": 41.2, "teammate": "Daniel Ricciardo", "team": "Red Bull"},
{"year": 2015, "points": 65.0, "teammate": "Kimi Raikonnen", "team": "Ferrari"}
]
},
{
"driver": "Kimi Raikonnen",
"battle": [
{"year": 2001, "points": 42.9, "teammate": "Nick Heidfeld", "team": "Sauber"},
{"year": 2002, "points": 36.9, "teammate": "David Coulthard", "team": "McLaren"},
{"year": 2003, "points": 64.1, "teammate": "David Coulthard", "team": "McLaren"},
{"year": 2004, "points": 65.2, "teammate": "David Coulthard", "team": "McLaren"},
{"year": 2005, "points": 61.5, "teammate": "various", "team": "McLaren"},
{"year": 2006, "points": 59.1, "teammate": "various", "team": "McLaren"},
{"year": 2007, "points": 53.9, "teammate": "Felipe Massa", "team": "Ferrari"},
{"year": 2008, "points": 43.6, "teammate": "Felipe Massa", "team": "Ferrari"},
{"year": 2009, "points": 68.6, "teammate": "various", "team": "Ferrari"},
{"year": 2012, "points": 67.8, "teammate": "various", "team": "Lotus"},
{"year": 2013, "points": 61.6, "teammate": "Romain Grosjean", "team": "Lotus"},
{"year": 2014, "points": 25.5, "teammate": "Fernando Alonso", "team": "Ferrari"},
{"year": 2015, "points": 35.0, "teammate": "Sébastien Vettel", "team": "Ferrari"}
]
},
{
"driver": "Valtteri Bottas",
"battle": [
{"year": 2013, "points": 80.0, "teammate": "Pastor Maldonado", "team": "Williams"},
{"year": 2014, "points": 58.1, "teammate": "Felipe Massa", "team": "Williams"},
{"year": 2015, "points": 52.9, "teammate": "Felipe Massa", "team": "Williams"}
]
},
{
"driver": "Felipe Massa",
"battle": [
{"year": 2002, "points": 36.4, "teammate": "Nick Heidfeld", "team": "Sauber"},
{"year": 2004, "points": 35.3, "teammate": "Giancarlo Fisichella", "team": "Sauber"},
{"year": 2005, "points": 55.0, "teammate": "Jacques Villeneuve", "team": "Sauber"},
{"year": 2006, "points": 39.8, "teammate": "Michael Schumacher", "team": "Ferrari"},
{"year": 2007, "points": 46.1, "teammate": "Kimi Raikonnen", "team": "Ferrari"},
{"year": 2008, "points": 56.4, "teammate": "Kimi Raikonnen", "team": "Ferrari"},
{"year": 2009, "points": 55.0, "teammate": "Kimi Raikonnen", "team": "Ferrari"},
{"year": 2010, "points": 36.4, "teammate": "Fernando Alonso", "team": "Ferrari"},
{"year": 2011, "points": 31.5, "teammate": "Fernando Alonso", "team": "Ferrari"},
{"year": 2012, "points": 30.5, "teammate": "Fernando Alonso", "team": "Ferrari"},
{"year": 2013, "points": 31.6, "teammate": "Fernando Alonso", "team": "Ferrari"},
{"year": 2014, "points": 41.9, "teammate": "Valtteri Bottas", "team": "Williams"},
{"year": 2015, "points": 47.1, "teammate": "Valtteri Bottas", "team": "Williams"}
]
},
{
"driver": "Daniil Kvyat",
"battle": [
{"year": 2014, "points": 25.8, "teammate": "Jean-Eric Vergne", "team": "Toro Rosso"},
{"year": 2015, "points": 50.8, "teammate": "Daniel Ricciardo", "team": "Red Bull"}
]
},
{
"driver": "Daniel Ricciardo",
"battle": [
{"year": 2011, "points": 50.0, "teammate": "various", "team": "HRT"},
{"year": 2012, "points": 38.5, "teammate": "Jean-Eric Vergne", "team": "Toro Rosso"},
{"year": 2013, "points": 60.6, "teammate": "Jean-Eric Vergne", "team": "Toro Rosso"},
{"year": 2014, "points": 58.8, "teammate": "Sebastian Vettel", "team": "Red Bull"},
{"year": 2015, "points": 49.2, "teammate": "Daniil Kvyat", "team": "Red Bull"}
]
},
{
"driver": "Sergio Pérez",
"battle": [
{"year": 2011, "points": 36.8, "teammate": "Kamui Kobayashi", "team": "Sauber"},
{"year": 2012, "points": 52.4, "teammate": "Kamui Kobayashi", "team": "Sauber"},
{"year": 2013, "points": 39.7, "teammate": "Jenson Button", "team": "McLaren"},
{"year": 2014, "points": 38.1, "teammate": "Nico Hulkenberg", "team": "Force India "},
{"year": 2015, "points": 57.4, "teammate": "Nico Hulkenberg", "team": "Force India "}
]
},
{
"driver": "Nico Hulkenberg",
"battle": [
{"year": 2010, "points": 31.9, "teammate": "Rubens Barrichello", "team": "Williams"},
{"year": 2012, "points": 57.8, "teammate": "Paul di Resta", "team": "Force India"},
{"year": 2013, "points": 89.5, "teammate": "Esteban Gutiérrez", "team": "Sauber"},
{"year": 2014, "points": 61.9, "teammate": "Sergio Pérez", "team": "Force India"},
{"year": 2015, "points": 42.6, "teammate": "Sergio Pérez", "team": "Force India"}
]
},
{
"driver": "Romain Grosjean",
"battle": [
{"year": 2009, "points": 0.0, "teammate": "Fernando Alonso", "team": "Renault"},
{"year": 2012, "points": 33.3, "teammate": "Kimi Raikonnen", "team": "Lotus"},
{"year": 2013, "points": 41.9, "teammate": "various", "team": "Lotus"},
{"year": 2014, "points": 88.9, "teammate": "Pastor Maldonado", "team": "Lotus"},
{"year": 2015, "points": 65.4, "teammate": "Pastor Maldonado", "team": "Lotus"}
]
},
{
"driver": "Max Verstappen",
"battle": [
{"year": 2015, "points": 73.1, "teammate": "Carlos Sainz Jr.", "team": "Toro Rosso"}
]
},
{
"driver": "Felipe Nasr",
"battle": [
{"year": 2015, "points": 75.9, "teammate": "Marcus Ericsson", "team": "Sauber"}
]
},
{
"driver": "Pastor Maldonado",
"battle": [
{"year": 2011, "points": 20.0, "teammate": "Rubens Barrichello", "team": "Williams"},
{"year": 2012, "points": 59.2, "teammate": "Bruno Senna", "team": "Williams"},
{"year": 2013, "points": 20.0, "teammate": "Valtteri Bottas", "team": "Williams"},
{"year": 2014, "points": 11.1, "teammate": "Romain Grosjean", "team": "Lotus"},
{"year": 2015, "points": 34.6, "teammate": "Romain Grosjean", "team": "Lotus"}
]
},
{
"driver": "Carlos Sainz Jr.",
"battle": [
{"year": 2015, "points": 26.9, "teammate": "Max Verstappen", "team": "Toro Rosso"}
]
},
{
"driver": "Jenson Button",
"battle": [
{"year": 2000, "points": 33.3, "teammate": "Ralf Schumacher", "team": "Williams"},
{"year": 2001, "points": 20.0, "teammate": "Giancarlo Fisichella", "team": "Benetton"},
{"year": 2002, "points": 60.9, "teammate": "Jarno Trulli", "team": "Renault"},
{"year": 2003, "points": 66.7, "teammate": "various", "team": "BAR"},
{"year": 2004, "points": 70.9, "teammate": "Takuma Sato", "team": "BAR"},
{"year": 2005, "points": 97.4, "teammate": "various", "team": "BAR"},
{"year": 2006, "points": 65.1, "teammate": "Rubens Barrichello", "team": "Honda"},
{"year": 2007, "points": 100.0, "teammate": "Rubens Barrichello", "team": "Honda"},
{"year": 2008, "points": 21.4, "teammate": "Rubens Barrichello", "team": "Honda"},
{"year": 2009, "points": 55.2, "teammate": "Rubens Barrichello", "team": "Brawn"},
{"year": 2010, "points": 47.1, "teammate": "Lewis Hamilton", "team": "McLaren"},
{"year": 2011, "points": 54.3, "teammate": "Lewis Hamilton", "team": "McLaren"},
{"year": 2012, "points": 49.7, "teammate": "Lewis Hamilton", "team": "McLaren"},
{"year": 2013, "points": 60.3, "teammate": "Sergio Pérez", "team": "McLaren"},
{"year": 2014, "points": 69.6, "teammate": "Kevin Magnussen", "team": "McLaren"},
{"year": 2015, "points": 59.3, "teammate": "Fernando Alonso", "team": "McLaren"}
]
},
{
"driver": "Fernando Alonso",
"battle": [
{"year": 2001, "points": 50.0, "teammate": "various", "team": "Minardi"},
{"year": 2003, "points": 62.5, "teammate": "Jarno Trulli", "team": "Renault"},
{"year": 2004, "points": 56.2, "teammate": "various", "team": "Renault"},
{"year": 2005, "points": 69.6, "teammate": "Giancarlo Fisichella", "team": "Renault"},
{"year": 2006, "points": 65.0, "teammate": "Giancarlo Fisichella", "team": "Renault"},
{"year": 2007, "points": 50.0, "teammate": "Lewis Hamilton", "team": "McLaren"},
{"year": 2008, "points": 76.3, "teammate": "Nelson Piquet Jr.", "team": "Renault"},
{"year": 2009, "points": 100.0, "teammate": "various", "team": "Renault"},
{"year": 2010, "points": 63.6, "teammate": "Felipe Massa", "team": "Ferrari"},
{"year": 2011, "points": 68.5, "teammate": "Felipe Massa", "team": "Ferrari"},
{"year": 2012, "points": 69.5, "teammate": "Felipe Massa", "team": "Ferrari"},
{"year": 2013, "points": 68.4, "teammate": "Felipe Massa", "team": "Ferrari"},
{"year": 2014, "points": 74.5, "teammate": "Kimi Raikonnen", "team": "Ferrari"},
{"year": 2015, "points": 40.7, "teammate": "Jenson Button", "team": "McLaren"}
]
},
{
"driver": "Marcus Ericsson",
"battle": [
{"year": 2014, "points": 50.0, "teammate": "various", "team": "Caterham"},
{"year": 2015, "points": 25.0, "teammate": "Felipe Nasr", "team": "Sauber"}
]
},
{
"driver": "Will Stevens",
"battle": [
{"year": 2015, "points": 50.0, "teammate": "various", "team": "Marussia"}
]
}
]
<!DOCTYPE html>
<html lang="en">
<head>
<link href='https://fonts.googleapis.com/css?family=PT+Serif' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Roboto' rel='stylesheet' type='text/css'>
<meta charset="utf-8">
<title>Teammate Battles</title>
<style type="text/css">
body {
/* padding-left: 100px;*/
background-color: #335C67;
font-family: 'PT Serif', serif;
}
#container {
width: 1100px;
margin-left: auto;
margin-right: auto;
margin-top: 20px;
padding: 1px 10px 10px 10px;
background-color: white;
box-shadow: 1px 1px 1px 1px #fff;
}
h1 {
font-weight: 700;
color: darkslategray;
font-family: 'Roboto', sans-serif;
font-size: 50px;
margin-bottom: 20px;
margin-top: 30px;
padding-left: 60px;
}
p {
font-size: 18px;
width: 1000px;
margin-top: 5px;
padding-left: 60px;
margin-bottom: 5px;
}
a {
color: #335C67;
}
.footer {
font-size: 14px;
margin-top: 0px;
}
select {
font-family: "Roboto";
font-size: 16px;
}
.dropdown {
display: inline;
padding-left: 10px;
}
ol {
padding-left: 100px;
width: 950px;
}
svg {
background-color: white;
padding-left: 60px;
}
.bar.negative:hover {
fill: saddlebrown;
}
.bar.positive:hover {
fill: saddlebrown;
}
.bar.negative {
fill: crimson;
}
.bar.positive {
fill: steelblue;
}
.value {
fill: white;
}
.axis path,
.axis line {
fill: none;
stroke: white;
shape-rendering: crispEdges;
}
.axis text {
font-family: sans-serif;
font-size: 10px;
}
.y.axis text {
font-family: "Roboto";
font-size: 16px;
}
.y.axis path,
.y.axis line {
stroke: #fff;
opacity: 1;
}
div.tooltip {
position: absolute;
text-align: center;
white-space: normal;
padding: 2px;
font-size: 14px;
background: whitesmoke;
border: 1px solid gray;
border-radius: 4px;
pointer-events: none;
cursor: none;
}
</style>
<script type="text/javascript" src="http://d3js.org/d3.v3.js" charset="utf-8"></script>
</head>
<body>
<div id="container">
<h1>Formula 1: Teammate Battles</h1>
<p>In Formula 1, it’s always complicated and to some extent subjective determining if a good (or a bad) performance is due to the talent of the driver or to the quality of the car. That’s why the teammate battle is so important: the teammate is the only other driver on circuit that has the same equipment, and almost all the differences in results are due to differences between the drivers.</p>
<p>This chart shows the careers of the 2015 season drivers, displaying how many percent of his team’s points, in a given year, the driver was able to score. The math is simple: if the driver scored more than 50% of his teams points (a blue bar, going up), he won the teammate battle. If he scored less than 50% (a red bar, going down), he lost it. The y axis shows the percentage (the top of blue bars and the bottom of red bars), the x axis shows the corresponding season. Hover the bars to see more information (as the name of the team and the competing teammate). </p>
<p>Choose the driver: <span id="opt"></span></p>
<br>
<div id="svganchor"></div>
<br>
<p>Some additional explanations:</p>
<ol>
<li>In the dropdown menu, the drivers are shown according to the 2015 final point results.</li>
<li>An exact value of 50% of the points, as the duo Hamilton/Alonso scored in 2007, will not render any visible bar. In those situations, I created a tiny red line (good luck trying to hover on that).</li>
<li>I considered only drivers that have at least one complete season. That’s why Roberto Merhi and Alexander Rossi are not in this chart.</li>
<li>When a driver had more than one teammate in a given season, they are named "various".</li>
<li>Be careful when analysing these data. A big bar can sometimes mean nothing: for instance, imagine a really bad season for a team, in which driver A scored nothing and driver B scored a mere 1 point. In this situation, driver B scored 100% of his team’s points!</li>
</ol>
<p>Source of almost all the data: <a href="www.f1fanatic.co.uk">www.f1fanatic.co.uk</a>.</p>
<p class="footer">Created by Gerardo Furtado.</p>
</div>
<script type="text/javascript">
var w = 1000;
var h = 400;
var padding = [ 30, 40, 0, 0 ]; //Top, right, bottom, left
//Set up scales and axes
var xScale = d3.scale.ordinal()
.domain([ "2000", "2001", "2002", "2003", "2004", "2005", "2006", "2007", "2008", "2009", "2010", "2011", "2012", "2013", "2014", "2015" ])
.rangeRoundBands([ padding[3], w - padding[1] ], .2);
var yScale = d3.scale.linear()
.range([ h - (padding[2] + padding[0]), padding[0] ]);
yScale.domain([0, 100]);
var xAxis = d3.svg.axis()
.scale(xScale)
.orient("bottom")
.ticks(16);
var yAxis = d3.svg.axis()
.scale(yScale)
.tickValues([50])
.tickFormat(function(d){
return d + "%";
})
.orient("right");
//set up svg
var svg = d3.select("#svganchor")
.append("svg")
.attr("width", w)
.attr("height", h);
//this is the tooltip
var tt = d3.select("#svganchor").append("div")
.attr("class", "tooltip")
.style("opacity", 0);
//loads the json
d3.json("driversdata.json", function(data) {
//text with driver's name on the right corner
var drivername = svg.append("text")
.attr("y", 0)
.attr("font-family", "Roboto")
.attr("font-size", 18)
.attr("font-weight", 100)
.attr("x", xScale(2015) + xScale.rangeBand())
.attr("text-anchor", "end")
.attr("alignment-baseline", "hanging")
.text("Driver: " + this.value);
//creating the midline
var mline = svg.append("line")
.attr("y1", yScale(50))
.attr("y2", yScale(50))
.attr("x2", (w - padding[1]))
.attr("x1", (w - padding[1]))
.attr("stroke-width", "1px")
.attr("stroke-dasharray", "1,2")
.attr("stroke", "darkslategray")
.attr("opacity", 1);
//creating the dorpdown menu
var dropdown = d3.select("#opt")
.append("div")
.attr("class","dropdown") //for positioning menu with css
.append("select");
//creating each option element within the dropdown
dropdown.selectAll("option")
.data(data)
.enter()
.append("option")
.attr("value", function(d){ return d.driver })
.text(function(d) {
return d.driver
});
//listening to the dropdown
dropdown.on("change", redraw);
function redraw() {
//reads the data for the specified driver
var tv = this.value;
var result = data.filter(function(d) {
return d.driver == tv;
});
var result = result[0].battle;
//the active years of each driver
var years = d3.extent(result, function(d) { return d.year});
//set up the bars
var bars = svg.selectAll("rect")
.data(result, function(d) { return d.year});
bars.enter()
.append("rect")
.attr("y", yScale(50))
.attr("x", function(d) {
return xScale(d.year)
})
.attr("height", 0)
.attr("width", xScale.rangeBand());
bars.transition().duration(500).attr("x", function(d) {
return xScale(d.year)
})
.attr("width", xScale.rangeBand())
.attr("y", yScale(50))
.attr("height", 0)
.transition()
.duration(500)
.attr("y", function(d) {
if (d.points == 50) {
return yScale(50.1)
} else if (d.points < 50) {
return yScale(50)
} else {
return yScale(+d.points)
}
})
.attr("height", function(d) {
if (d.points == 50) {
return 1
} else if (d.points < 50) {
return (yScale(d.points) - yScale(50))
} else {
return (yScale(50) - yScale(d.points))
}
})
.attr("class", function(d) { return d.points <= 50 ? "bar negative" : "bar positive"; });
bars.exit()
.attr("pointer-events", "none")
.transition()
.duration(1000)
.attr("y", yScale(50))
.attr("height", 0)
.remove();
//change the midline
mline.transition().duration(500).attr("x1", (xScale(years[0]) - 14));
//shows the tooltip
bars.on("mousemove", function(d) {
tt.html("In <strong>" + d.year + "</strong>, " + tv + " scored <strong><br>" + d.points + "%</strong> of " + d.team + "'s points.<br>His teammate was " + d.teammate)
.style('top', d3.event.pageY - 12 + 'px')
.style('left', d3.event.pageX + 25 + 'px')
.style("opacity", 0.9);
});
//removes the tooltip
bars.on("mouseout", function() {
tt.style("opacity", 0)
});
//update the driver name
drivername.text( function() {
if (years[0] == years [1]) {
return "Driver: " + tv + " (" + years[0] + ")"
} else { return "Driver: " + tv + " (from " + years[0] + " to " + years[1] + ")"
}
});
//update the xAxis
xAxis.tickValues(d3.range(years[0], (years[1] + 1)));
d3.transition(svg).select(".x.axis")
.transition()
.duration(500)
.call(xAxis);
}
//the first driver to appear is LH
this.value = "Lewis Hamilton";
redraw();
svg.append("g")
.attr("class", "y axis")
.attr("transform", "translate(" + (w - padding[1]) + "," + 0 + ")")
.call(yAxis);
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (h - (padding[2] + padding[0])) +")")
.call(xAxis);
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment