xxxxxxxxxx
<html lang="en">
<head>
<meta charset="utf-8">
<title>Moto GP</title>
<script type="text/javascript" src="https://d3js.org/d3.v3.min.js"></script>
<style type="text/css" >
body {
margin: 0;
background-color: DarkGray;
font-family: "nyt-cheltenham",georgia,Lucida sans,
"times new roman",times,serif;
}
#container {
width: 900px;
margin-left: auto;
margin-right: auto;
margin-top: 50px;
padding: 50px;
background-color: white;
box-shadow: 3px 3px 5px 6px #ccc;
}
h1 {
font-size: 28px;
border-top: solid 8px #807166;
border-bottom: solid 8px #807166;
}
p {
font-size: 14px;
line-height: 18px;
padding: 30px;
border-bottom: solid 2px #222222;
}
svg {
background-color: white;
}
g rect {
border-radius: 8px;
opacity: 0.6;
}
g.leg text {
font-style: italic;
}
.axis path,
.axis line {
fill: none;
stroke: none;
shape-rendering: crispEdges;
}
.axis text {
font-family: georgia,Lucida sans,
"times new roman",times,serif;
font-size: 14px;
}
</style>
</head>
<body>
<div id="container">
<h1> MotoGP 2001-2015 : Not much room for other. </h1>
<p> The graphs below show the share of wins (top) and podiums finishes (bottom)
taken by 5 riders over the last 16 seasons -since Valentino Rossi joined the GP class.
While Rossi alone dominated the championships over the years 2001-2005,
the successive arrivals of Pedrosa and Stoner (in 2006), Lorenzo (2008) and Marquez (2013),
left the rest of the line-up less and less chances to earnt their place
in the spotlight! </p>
</div>
<script type="text/javascript">
// graphic parameters
var wid = 900, hei = 250;
var hleg = 80 ; // legend above the graph
var margin = {top:20, right:20, bottom:40, left:20};
var pad = 20, inter = 40;
var widbar = 23;
// scales
var xscale = d3.time.scale()
.range([ margin.left, wid - margin.left - margin.right ]),
yscale = d3.scale.linear()
.range([ 0, hei ]),
yscale2 = d3.scale.linear()
.range([ 0, hei ]),
legscale = d3.scale.ordinal()
.rangeRoundBands([ margin.left, wid - margin.left - margin.right ],0.05),
cscale = d3.scale.ordinal()
.range(["#FFFF00","#111111","#0000FF","#FF2222","#FF8C00","#A9A9A9"]);
var dateFormat = d3.time.format("%Y");
// axes
var xaxis = d3.svg.axis()
.scale(xscale)
.orient("bottom")
.ticks(16)
.tickFormat(function(d) {
return dateFormat(d);
});
// graphic elements
// svg in container
var svg = d3.select("#container")
.append("svg")
.attr("width", wid)
.attr("height", hleg+2*hei+margin.bottom);
var datawin = [], datapod = [], names = [];
var riders = ["Rossi","Pedrosa","Lorenzo","Stoner","Marquez","Others" ];
legscale.domain(riders);
// stack layout ...
var stackwins = d3.layout.stack() ;
var stackpods = d3.layout.stack();
// main script
d3.csv("motogp.csv",function(dataraw) {
// reformat data
var ind = -1;
var last = "" ;
var tmp=[];
for (var ii=0; ii<dataraw.length; ii++) {
if (dataraw[ii].rider != last) {
names.push(dataraw[ii].rider );
ind = ind+1;
datawin[ind]=[];
datapod[ind]=[];
}
tmp={
x: dataraw[ii].year,
y: +dataraw[ii].wins,
name: dataraw[ii].rider
};
datawin[ind].push(tmp);
tmp={
x: dataraw[ii].year,
y: +dataraw[ii].podiums,
name: dataraw[ii].rider
};
datapod[ind].push(tmp);
last = dataraw[ii].rider ;
}
// ... applied to data
stackwins(datawin);
stackwins(datapod);
// setting scales limit
xscale.domain([
d3.min(dataraw, function(d) {
return dateFormat.parse(d.year);
}),
d3.max(dataraw, function(d) {
return dateFormat.parse(d.year);
})
]);
yscale.domain([0,
d3.max(datawin , function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
]);
yscale2.domain([0,
d3.max(datapod , function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})
]);
cscale.domain(names);
// add a group for each row of data
var groups = svg.selectAll("g")
.data(datawin)
.enter()
.append("g");
// add a rect for each data value
var rects = groups.selectAll(".bar")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("class", "bar")
.attr("rx",2).attr("ry",2)
.attr("x", function(d, i) {
return xscale(dateFormat.parse(d.x))-widbar/2;
})
.attr("width", widbar)
.attr("y", 0)
.attr("height", 0)
.attr("fill",function(d){
return cscale(d.name)
});
rects.transition()
.duration(1000)
.delay(function(d){
return (d.x-1999) * 250;})
.attr("y", function(d) {
return hei - yscale(d.y0) - yscale(d.y);
})
.attr("height", function(d,i) {
return yscale(d.y);
});
// same set of groups and rects for podiums
var groups2 = svg.selectAll("g.pods")
.data(datapod)
.enter()
.append("g")
.attr("class","pods") ;
// add a rect for each data value
var rects2 = groups2.selectAll(".bar")
.data(function(d) { return d; })
.enter()
.append("rect")
.attr("class", "bar")
.attr("rx",2).attr("ry",2)
.attr("x", function(d, i) {
return xscale(dateFormat.parse(d.x))-widbar/2;
})
.attr("width", widbar)
.attr("y", hei+hleg)
.attr("height", 0)
.attr("fill",function(d){
return cscale(d.name)
});
rects2.transition()
.duration(1000)
.delay(function(d){
return (d.x-1999) * 250;})
.attr("y", function(d) {
return 2*hei +hleg - yscale2(d.y0) - yscale2(d.y);
})
.attr("height", function(d,i) {
return yscale2(d.y);
});
// groups for legend
var gleg = svg.selectAll("g.leg")
.data(riders)
.enter()
.append("g")
.attr("class","leg");
// adding rects and text to legend
var legd = gleg.append("rect")
.attr("class", "leg")
.attr("rx",2).attr("ry",2)
.attr("x", function(d) {
return legscale(d);
})
.attr("width", widbar)
.attr("y", hei+hleg/2)
.attr("height", widbar)
.attr("fill",function(d,i){
return cscale(d)
});
gleg.append("text")
.attr("x", function(d) {
return legscale(d) + widbar+5;
})
.attr("y", hei +hleg/2 + widbar-5)
.text(function(d) {
return d;} )
//Create axes
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + (hei + 5 ) + ")")
.call(xaxis);
});
</script>
</body>
</html>
Modified http://d3js.org/d3.v3.min.js to a secure url
https://d3js.org/d3.v3.min.js