Skip to content

Instantly share code, notes, and snippets.

@suneric1
Last active March 29, 2016 04:49
Show Gist options
  • Select an option

  • Save suneric1/c5432c5ecd181dc8b4fe to your computer and use it in GitHub Desktop.

Select an option

Save suneric1/c5432c5ecd181dc8b4fe to your computer and use it in GitHub Desktop.
Week 10, Small Multiples.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
<link href='https://fonts.googleapis.com/css?family=Open+Sans' rel='stylesheet' type='text/css'>
<link href='https://fonts.googleapis.com/css?family=Roboto:900' rel='stylesheet' type='text/css'>
<title>Sales of Audi & BMW in the U.S.</title>
<style>
body{
font-family: 'Open Sans', sans-serif;
}
h2{
font-family: 'Roboto', sans-serif;
text-align: center;
margin: 60px;
}
.main{
margin: auto;
}
.para{
text-align: justify;
}
.source{
font-size: 14px;
margin-top: 80px;
}
a:link, a:visited{
text-decoration: none;
color: #418FC6;
}
.model{
font-family: 'Roboto', sans-serif;
color: #444;
}
.title{
font-family: 'Roboto', sans-serif;
margin-bottom: 20px;
margin-top: 30px;
}
svg text{
fill: #444;
font-size: 11px;
}
.y.axis path{
fill: none;
stroke: none;
shape-rendering: crispEdges;
}
.axis line {
fill: none;
stroke: #999;
shape-rendering: crispEdges;
}
line{
fill: none;
stroke-width: 3px;
}
path.line{
fill: none;
stroke-width: 1.5px;
transition: 0.1s;
}
.bmw path.line, .bmw line{
stroke: #418FC6;
}
.audi path.line, .audi line{
stroke: #E3314C;
}
g.bmw circle{
fill: #418FC6;
transition: 0.1s;
}
g.audi circle{
fill: #E3314C;
transition: 0.1s;
}
.bmw .area, .bmw rect{
fill: #418FC6;
opacity: 0.2;
}
.audi .area, .audi rect{
fill: #E3314C;
opacity: 0.2;
}
rect.bg{
fill: #fff;
}
.bmw .label{
fill: #418FC6;
}
.audi .label{
fill: #E3314C;
}
.label{
font-family: 'Roboto', sans-serif;
font-size: 11px;
}
.bmw text.caption{
fill: #418FC6;
font-size: 10px;
}
.audi text.caption{
fill: #E3314C;
font-size: 10px;
}
.tick text{
text-anchor: end;
}
button{
background: #fff;
color: #E3314C;
border: 1px solid #E3314C;
padding: 7px;
padding-top: 5px;
padding-bottom: 5px;
border-radius: 4px;
outline: none;
margin-right: 10px;
font-size: 12px;
}
button:hover{
background: #ffcccc;
cursor: pointer;
}
button.selected{
background: #E3314C;
color: #fff;
}
</style>
</head>
<body>
<h2>Sales of Audi & BMW in the U.S.</h2>
<div class="main">
<div class="row col-sm-10 col-sm-offset-2" id="legend"></div>
<div class="row col-sm-10 col-sm-offset-2" id="lineChart"></div>
<div class="row col-sm-10 col-sm-offset-2">
<p class="source"><span style="font-family: 'Roboto', sans-serif; font-size:16px;">Source</span></br><a href="https://www.audiusa.com/newsroom/news">Audi U.S. Press Release 2015</a></br><a href="https://www.press.bmwgroup.com">BMW Group U.S. Reports 2015</a>
</p>
</div>
</div>
</body>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/stupidtable/0.0.1/stupidtable.min.js"></script>
<!-- load the function file you need before you call it... -->
<!-- script type="text/javascript" src="js/tabulate.js"></script -->
<script type="text/javascript">
var fullHeight = 140;
var fullWidth = 300;
var margin = {top:30, bottom:30, left:30, right:30};
var height = fullHeight - margin.top - margin.bottom;
var width = fullWidth - margin.left - margin.right;
xScale = d3.time.scale().range([0,width]);
yScale = d3.scale.linear().range([height,0]);
var parseDate = d3.time.format("%Y").parse;
var outputDate = d3.time.format("%Y");
var bisect = d3.bisector(function(d) {
return parseDate(d.year);
}).left;
var yAxis = d3.svg.axis()
.scale(yScale)
.orient("left")
.tickFormat(d3.format("s"))
.ticks(3)
.tickPadding([3])
.tickSize([0]);
var area = d3.svg.area()
.x(function(d){
return xScale(parseDate(d.year));
})
.y0(height)
.y1(function(d){
return yScale(+d.amount);
});
var line = d3.svg.line()
.x(function(d){
return xScale(parseDate(d.year));
})
.y(function(d){
return yScale(+d.amount);
});
drawlegend();
d3.csv("salesInYears.csv", function(error, data) {
if (error) {
console.log("Had an error loading file.");
}
var years = d3.keys(data[0]).slice(0,5);
var dataset = [];
data.forEach(function(d,i){
var vehicleSales = [];
years.forEach(function(y){
if(d[y]){
vehicleSales.push({
model: d.model,
year: y,
amount: +d[y]
});
}
else{
vehicleSales.push({
model: d.model,
year: y,
amount: 0
});
}
});
dataset.push({
model: d.model,
sales: vehicleSales
});
});
xScale.domain(d3.extent(years, function(d){
return parseDate(d);
}));
yScale.domain([0, d3.max(dataset, function(d){
return d3.max(d.sales, function(d){
return +d.amount;
});
})*1.1]);
var svg = d3.select("#lineChart").selectAll("svg")
.data(dataset)
.enter()
.append("svg")
.attr("class","lineChart")
.attr("width",fullWidth)
.attr("height",fullHeight)
.append("g")
.attr("transform","translate(" + margin.left + "," + margin.top + ")")
.each(multiple);
function multiple(model){
d3.select(this.parentNode)
.attr("class",function(d){
if(d.model.startsWith("A") || d.model.startsWith("Q"))
return "audi";
else
return "bmw";
});
var svg = d3.select(this)
.append("g")
.attr("class",function(d){
if(d.model.startsWith("A") || d.model.startsWith("Q"))
return "audi line";
else
return "bmw line";
});
svg.append("text")
.attr("class", "label")
.attr("x", width/2)
.attr("y", -10)
.style("text-anchor", "middle")
.text(function(d) { return d.model; });
svg.datum(function(d){return d.sales;})
.append("path")
.attr("class","area")
.attr("d",area);
svg
.append("path")
.attr("class","line")
.attr("d",line);
d3.select(this).append("g")
.call(yAxis)
.attr("class","y axis lineChart")
.selectAll("text")
.style("text-anchor","end");
svg.append("text")
.attr("x", width/2)
.attr("y", function(d){
return yScale(+d[d.length - 1].amount);
})
.attr("class", "label")
.style("text-anchor","start")
.attr("dx",8)
.attr("dy",4);
svg.append("text")
.attr("x", 0)
.attr("y", height + margin.bottom/2)
.attr("class", "static_year")
.style("text-anchor", "start")
.text(function(d) { return outputDate(parseDate(d[0].year)); });
svg.append("text")
.attr("x", width)
.attr("y", height + margin.bottom/2)
.attr("class", "static_year")
.style("text-anchor", "end")
.text(function(d) { return outputDate(parseDate(d[d.length - 1].year));});
circle = svg.append("circle")
.attr("r", 2.2)
.attr("opacity", 0)
.style("pointer-events", "none");
caption = svg.append("text")
.attr("class", "caption")
.attr("text-anchor", "middle")
.style("pointer-events", "none")
.attr("dy", -6);
curYear = svg.append("text")
.attr("class", "year")
.attr("text-anchor", "middle")
.style("pointer-events", "none")
.attr("dy", margin.bottom/2)
.attr("y", height);
svg.append("rect")
.attr("class", "bg")
.attr("width",width)
.attr("height",height)
.on("mouseover",mouseOverFunc)
.on("mousemove",mouseMoveFunc)
.on("mouseout",mouseOutFunc);
}
});
function mouseOverFunc(d){
d3.selectAll("circle").attr("opacity", 1.0);
d3.selectAll(".static_year").classed("hidden", true);
return mouseMoveFunc.call(this);
}
function mouseMoveFunc() {
var date, index, year;
year = xScale.invert(d3.mouse(this)[0] + 30).getFullYear();
date = parseDate('' + year);
index = 0;
d3.selectAll("circle")
.attr("cx", xScale(date))
.attr("cy", function(c) {
index = bisect(c, date, 0, c.length - 1);
return yScale(c[index].amount);
});
d3.selectAll("text.caption")
.attr("x", xScale(date))
.attr("y", function(c) {
return yScale(c[index].amount);
})
.text(function(c) {
return c[index].amount;
});
d3.selectAll("text.year")
.attr("x", xScale(date))
.text(year);
};
function mouseOutFunc(d){
d3.selectAll(".static_year").classed("hidden", false);
d3.selectAll("circle").attr("opacity", 0);
d3.selectAll("text.caption").text("");
d3.selectAll("text.year").text("");
}
function drawlegend(){
var legend = d3.select("#legend")
.append("svg")
.attr("width", 180)
.attr("height", 50)
.append("g")
.attr("class", "bmw")
.attr("transform","translate(30,0)");
legend.append("rect")
.attr("width", 30)
.attr("height", 20);
legend.append("line")
.attr("x2", 30);
legend.append("text")
.text("BMW")
.attr("x",35)
.attr("y",13);
var legend = d3.select("#legend svg")
.append("g")
.attr("class", "audi")
.attr("transform","translate(110,0)");
legend.append("rect")
.attr("width", 30)
.attr("height", 20);
legend.append("line")
.attr("x2", 30);
legend.append("text")
.text("Audi")
.attr("x",35)
.attr("y",13);
}
</script>
</html>
model 2011 2012 2013 2014 2015 startingPrice
1/2 Series 7915 6932 6181 6621 10877 32850
3 Series 85882 88857 102784 87451 89265 33150
4 Series 35583 40481 41650
5 Series 46604 48413 48761 47187 41177 50200
6 Series 3180 7171 8684 7757 6685 77300
7 Series 10080 9676 9813 8648 8026 81300
X1 6141 23771 20217 12651 34800
X3 24261 30011 26916 31029 28798 38950
X5 34540 38723 37865 40933 48747 53900
A3 5926 6808 857 19560 32732 30900
A4 31512 34724 33201 30796 25841 35900
A5 14112 15568 17280 15328 11934 40500
A6 9269 17123 19742 20996 20394 46200
A7 5383 7672 7539 7609 6880 68300
A8 5022 5102 5582 5172 4566 81500
Q3 2753 11728 33700
Q5 22571 25045 35561 37869 45949 40900
Q7 8079 9515 13699 16589 17806 54800
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment