Skip to content

Instantly share code, notes, and snippets.

@captainelaine
Created February 27, 2016 20:06
Show Gist options
  • Save captainelaine/89cbd2aa709e3848d1e4 to your computer and use it in GitHub Desktop.
Save captainelaine/89cbd2aa709e3848d1e4 to your computer and use it in GitHub Desktop.
Transition Plot
team 2009 2010 2011 2012 2013 2014 2015
RedBull 153.5 498 650 460 596 405 187
Ferrari 70 396 375 400 354 216 428
McLaren 71 454 497 378 122 181 27
Williams 34.5 69 5 76 5 320 257
Mercedes 172 214 165 142 360 701 703
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
<link href='https://fonts.googleapis.com/css?family=Ubuntu:300italic,500|Josefin+Sans:400italic' rel='stylesheet' type='text/css'>
<!DOCTYPE html>
<!-- Modification of an example by Scott Murray from Knight D3 course -->
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Line Chart with Multiple Data Sets, Transitions</title>
<!-- this is the cdn link to bootstrap's css -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<style type="text/css">
body {
background-color: white;
font-family: 'Ubuntu', sans-serif;
}
h1 {
font-size: 25px;
margin-top: 60px;
text-align: center;
}
p {
font-size:16px;
font-weight: bold;
line-height: 25px;
font-style: italic;
}
#Ferrari.selected {
background-color: rgb(246,61,50);
opacity: 0.95;
}
#RedBull.selected {
background-color: rgb(164,65,107);
opacity:0.95;
}
#McLaren.selected {
background-color: rgb(163,174,177);
opacity:0.95;
}
#Williams.selected {
background-color: rgb(37,168,225);
opacity:0.95;
}
#Mercedes.selected {
background-color: rgb(196,204,206);
}
svg {
background-color: white;
}
.axis path,
.axis line {
fill: none;
stroke: #ccc;
stroke-width: 1px;
shape-rendering: crispEdges;
}
.line {
fill: none;
stroke-width: 2.5px;
stroke-opacity: 60%;
}
path.line.unfocused{
fill: none;
stroke-opacity: 60%;
}
path.line.focused {
fill: none;
stroke-width: 5px;
stroke-opacity: 100%;
}
.axis text {
font-family: sans-serif;
font-size: 11px;
line-height: 1em;
}
.tooltip {
position: absolute;
z-index: 10;
}
.tooltip p {
background-color: white;
border: none;
padding: 2px;
}
/* this is an adjustment to bootstrap's row for my page */
.row {
padding-top: 50px;
}
/* this is an adjustment to bootstrap for my page */
.btn-group {
padding-top:50px;
margin-left:150px;
padding-left: 80px;
}
.btn btn-default {
padding-left: 30px;
}
#red {
color: red;
font-weight: bolder;
}
.chart {
float:left;
margin-left: 30px;
}
.note {
width: 500px;
float:right;
margin-top:60px;
margin-right: 80px;
}
.source {
text-align: center;
font-style:normal;
margin-top: 20px;
}
.picture {
text-align: center;
margin-top: 15px;
margin-bottom: -20px;
}
.logo {
width:65px;
height:65px;
margin-right: 30px;
}
#mer {
width:100px;
height: 60px;
}
#mc {
width: 80px;
height: 80px;
}
</style>
</head>
<body>
<h1>Five F1 old teams' performances from Season 2009</h1>
<p class="source"><a href="https://en.wikipedia.org/wiki/Formula_One">Source: Wikipedia-Formula One</a></p>
<div class="picture">
<img src="redbull.svg" class="logo" alt="RedBull">
<img src="ferrari.svg" class="logo" alt="Ferrari">
<img src="mclaren.svg" class="logo" id="mc" alt="McLaren">
<img src="williams.svg" class="logo" alt="Williams">
<img src="mercedes.svg" class="logo" id="mer" alt="Mercedes">
</div>
<div class="note">
<p>Although changes of drivers and teams happen frequently in Formula One field.</br>There are five old teams who have stayed in F1 longer than any others. </br> Some of them, like <em id="red">Ferrari</em>, participated in F1 race since the race was created.</p>
<p>Although they were “grand old men” in the F1 paddock, they can not keep being the champion.</p>
<p>The development of F1 technology is changing quickly, especially in the past few years. </br>Moreover, the change of the game rules gave other teams some chances to challenge these boss teams.</p>
<p>Thus from the chart, you can see the floating of these five teams from Season 2009.</br>This can lead you to find out the deep reasons of the changes of performances in this special area.</p>
</div>
<div class="chart">
<div class="btn-group" role="group" aria-label="...">
<button type="button" class="btn btn-default" id="RedBull">RedBull</button>
<button type="button" class="btn btn-default" id="Ferrari">Ferrari</button>
<button type="button" class="btn btn-default" id="McLaren">McLaren</button>
<button type="button" class="btn btn-default" id="Williams">Williams</button>
<button type="button" class="btn btn-default" id="Mercedes">Mercedes</button>
</div>
<div id="svg"></div>
</div>
<!--
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
-->
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script type="text/javascript">
//Dimensions and padding
var fullwidths = 800;
var fullheights = 430;
var margins = {top: 20, right: 50, bottom:70, left: 100};
var widths = fullwidths - margins.left - margins.right;
var heights = fullheights - margins.top - margins.bottom;
//Set up date formatting and years
var dateFormats = d3.time.format("%Y");
// My shortcut for the scale is to list the first and last only - will set the extents.
// Also, I set the earlier year to 1999 to get a little spacing on the X axis.
//Set up scales - I already know the start and end years, not using data for it.
var xScales = d3.time.scale()
.range([ 0, widths]);
// don't know the yScale domain yet. Will set it with the data.
var yScales = d3.scale.linear()
.range([ 0, heights]);
//Configure axis generators
var xAxiss = d3.svg.axis()
.scale(xScales)
.orient("bottom")
.ticks(10)
.tickFormat(function(d) {
return dateFormats(d);
})
.innerTickSize([10])
.outerTickSize([10]);
var yAxiss = d3.svg.axis()
.scale(yScales)
.orient("left")
.innerTickSize([10])
.outerTickSize([10]);
//Configure line generator
// each line dataset must have an x and y for this to work.
var lines = d3.svg.line()
.x(function(d) {
return xScales(dateFormats.parse(d.year));
})
.y(function(d) {
return yScales(+d.points);
});
// add a tooltip to the page - not to the svg itself!
var tooltips = d3.select("body")
.append("div")
.attr("class", "tooltip");
//Create the empty SVG image
var svgs = d3.select("#svg")
.append("svg")
.attr("width", fullwidths)
.attr("height", fullheights)
.append("g")
.attr("transform", "translate(" + margins.left + "," + margins.top + ")");
//Load data
d3.csv("f1teampoint.csv", function(error, data) {
var yearss = ["2009", "2010","2012","2013","2014","2015"];
var datasets=[];
data.forEach(function(d,i){
var teampoints=[];
yearss.forEach(function(y){
if(d[y]) {
teampoints.push ({
year:y,
points: d[y]
});
}
});
datasets.push({
team: d.team,
totalpoint: teampoints
});
});
console.log(datasets);
// Notice what happens if you don't sort by year :)
// doing the max on the unnested data - easier to get the full set of Measles that way!
xScales.domain(
d3.extent(yearss, function(d) {
return dateFormats.parse(d);
}));
yScales.domain([
d3.max(datasets, function(d) {
return d3.max(d.totalpoint,function(d){
return +d.points;
});
}),
0
]);
function filtervalue(team) {
// Helper function to get the values from the data object that has the country key
// special case for id's with too many words in them, sadly:
return datasets.filter(function (d) {
return d.team == team;
})[0].totalpoint;
}
// Default on first load is Congo- using a helper function:
var Ferrari = filtervalue("Ferrari");
svgs.selectAll("path")
.data( [Ferrari] )
.enter()
.append("path")
.attr("class", "line")
.attr("id","Ferrariline")
.attr("d", lines)
.style("stroke","rgb(246,61,50)");
// set the button to show the default country selected:
d3.select("button#Ferrari").classed("selected", true);
//Axes
svgs.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + heights + ")")
.call(xAxiss);
svgs.append("g")
.attr("class", "y axis")
.call(yAxiss);
svgs.append("text")
.attr("class", "xlabel")
.attr("transform", "translate(" + (margins.left + widths / 2) + " ," +
(heights + margins.bottom) + ")")
.style("text-anchor", "middle")
.attr("dy", "-20px")
.attr("dx", "-90px")
.text("Season");
svgs.append("text")
.attr ("class", "ylabel")
.attr("transform", "rotate(-90)")
.attr("y", 0 - margins.left) // you may need to adjust this
.attr("x", 0 - (heights / 2)) // you may need to adjust
.attr("dy", "4em")
.style("text-anchor", "middle")
.text("Total Points");
d3.selectAll("button").on("click", function() {
// Handle the button click to change the data set.
var selectedline = d3.select("path.line");
var thisButton = d3.select(this);
// current attr "id" is returned if you don't set it to anything!
var newdata = filtervalue(thisButton.attr("id")); // the id has to match the country name for this to work.
d3.selectAll("button").classed("selected", false);
thisButton.classed("selected", true);
selectedline
.transition()
.duration(2000)
.attr("d", lines(newdata))
;
d3.selectAll("path.line")
.on("mouseover", mouseoverFunc) // putting these on the g nodes gets us a lot!
.on("mouseout", mouseoutFunc);
if(thisButton.attr("id")=== "Williams") {
selectedline.style("stroke","rgb(37,168,225)");
} else if (thisButton.attr("id")=== "Mercedes") {
selectedline.style("stroke","rgb(196,204,206)");
} else if (thisButton.attr("id")=== "Ferrari") {
selectedline.style("stroke","rgb(246,61,50)");
} else if (thisButton.attr("id")=== "McLaren") {
selectedline.style("stroke","rgb(163,174,177)");
} else {selectedline.style("stroke","rgb(164,65,107)")};
function mouseoverFunc(d) {
d3.selectAll("path.line").classed("focused", true);
// now undo the unfocus on the current line and set to focused.
};
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);
};
});
}); // end of data csv
</script>
</div>
<!-- Latest compiled and minified JavaScript -->
</body>
</html>
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Display the source blob
Display the rendered blob
Raw
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment