Skip to content

Instantly share code, notes, and snippets.

@anaeliaovalle
Last active February 13, 2017 09:26
Show Gist options
  • Save anaeliaovalle/e57763e85def2a95be931c69eff6bfa6 to your computer and use it in GitHub Desktop.
Save anaeliaovalle/e57763e85def2a95be931c69eff6bfa6 to your computer and use it in GitHub Desktop.
D3 Stacked Area Chart Example
license: mit
hour assault burglary larceny_theft missing_person non_criminal other_offenses suspicious_occ vandalism vehicle_related warrants
0 60 15 124 12 45 105 23 25 18 16
1 41 21 75 7 32 50 18 32 10 12
2 55 15 49 1 11 39 16 24 15 10
3 39 17 34 4 21 38 9 21 7 10
4 12 29 27 2 11 17 7 18 6 2
5 16 17 24 4 12 16 4 16 8 4
6 21 14 47 7 35 26 7 16 14 10
7 26 12 46 9 38 42 13 16 21 17
8 37 18 96 15 76 67 16 19 18 15
9 41 23 122 22 68 68 26 18 23 15
10 52 16 152 18 76 77 27 22 27 17
11 47 17 182 20 83 63 35 21 17 15
12 51 23 188 24 115 100 37 41 33 30
13 62 16 205 13 76 83 27 41 20 22
14 51 22 206 19 74 91 23 33 21 24
15 47 32 198 22 76 98 29 37 29 29
16 53 21 231 9 87 117 27 37 40 31
17 57 36 295 17 96 100 28 49 48 30
18 54 31 345 20 71 62 27 70 53 22
19 79 32 357 9 82 94 29 57 34 18
20 62 21 284 13 67 62 25 51 48 21
21 49 26 220 5 51 79 13 50 44 10
22 56 24 157 22 70 82 16 60 49 20
23 61 19 154 12 73 78 24 48 39 22
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font: 10px avenir;
}
.axis path,
.axis line {
fill: none;
stroke: #000;
shape-rendering: crispEdges;
}
.browser text {
text-anchor: end;
}
</style>
<body>
<script src="http://d3js.org/d3.v3.js"></script>
<script>
function get_colors(n) {
var colors = ["#a6cee3","#1f78b4","#b2df8a","#33a02c",
"#fb9a99","#e31a1c","#fdbf6f","#ff7f00","#cab2d6",
"#6a3d9a"];
return colors[ n % colors.length];}
var margin = {top: 61, right: 140, bottom: 101, left: 50},
width = 960 - margin.left - margin.right,
height = 500 - margin.top - margin.bottom;
var times = ["12am","1a", "2a", "3a", "4a", "5a", "6a",
"7a", "8a", "9a", "10a", "11a", "12pm", "1p",
"2p", "3p", "4p", "5p", "6p", "7p", "8p",
"9p", "10p", "11p"];
var x = d3.scale.linear()
.range([0, width]);
var y = d3.scale.linear()
.range([height, 0]);
var color = d3.scale.category10();
var xAxis = d3.svg.axis()
.scale(x)
.orient("bottom")
.ticks(24, "s");
var yAxis = d3.svg.axis()
.scale(y)
.orient("left")
.ticks(5, "s");
var area = d3.svg.area()
.x(function(d) { return x(d.hour); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
var stack = d3.layout.stack()
.values(function(d) { return d.values; });
var svg = d3.select("body").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
svg.append("text")
.attr("x", 0)
.attr("y", -40)
.attr("dy", "0.71em")
.attr("fill", "#000")
.text("SFPD Incidents by Hour in Dec 2016")
.style("font", "23px avenir")
.style("fill", "#000000");
svg.append("text")
.attr("x", 0)
.attr("y", 402)
.attr("dy", "0em")
.style("font", "12px avenir")
.style("fill", "#000000")
.text("This is a plot of the 10 most frequent incidents over a 24-hour period in San Francisco during December 2016. Interestingly enough, most ");
svg.append("text")
.attr("x", 0)
.attr("y", 402)
.attr("dy", "1em")
.style("font", "12px avenir")
.style("fill", "#000000")
.text("categories follow a similar structure: the occurences dip in the early morning and peak during the lunch and early evening hours.");
svg.append("text")
.attr("x", 0)
.attr("y", 402)
.attr("dy", "3em")
.style("font", "12px avenir")
.style("fill", "#000000")
.text("By Anaelia Ovalle")
.style("font-weight", "bold");
d3.csv("data.csv", function(error, data) {
color.domain(d3.keys(data[0]).filter(function(key) {return key !== "hour"; }));
data.forEach(function(d) {
d.hour = +d.hour;
d.burglary = +d.burglary;
d.assault= +d.assault;
d.larceny_theft= +d.larceny_theft;
d.vehicle_related = +d.vehicle_related;
d.missing_person = +d.missing_person;
d.non_criminal = +d.non_criminal;
d.other_offenses = +d.other_offenses;
d.suspicious_occ = +d.suspicious_occ;
d.warrants = +d.warrants;
});
var browsers = stack(color.domain().map(function(name) {
return {
name: name,
values: data.map(function(d) {
return {hour: d.hour, y: d[name] * 1};
})
};
}));
// // Find the value of the hour with highest total value
var maxHourVal = d3.max(data, function(d){
var vals = d3.keys(d).map(
function(key){
return key !== "hour" ? d[key] : 0 });
return d3.sum(vals);
});
// // Set domains for axes
x.domain(d3.extent(data, function(d) { return d.hour; }));
y.domain([0, 800])
var browser = svg.selectAll(".browser")
.data(browsers)
.enter().append("g")
.attr("class", "browser");
browser.append("path")
.attr("class", "area")
.attr("d", function(d) { return area(d.values); })
.style("fill", function(d,i) {
return get_colors(i); });
browser.append("text")
.datum(function(d) { return {name: d.name, value: d.values[d.values.length - 1]}; })
.attr("transform", function(d) { return "translate(" + x(d.value.hour) + "," + y(d.value.y0 + d.value.y / 2) + ")"; })
.attr("x", -6)
.attr("dy", "-0.882em")
.text(function(d) {
if(d.name == "larceny_theft"){
return "larceny/theft";
}
if(d.name == "non_criminal"){
return "non-criminal";
}
if(d.name == "assault"){
return d.name;
}})
.style("font", "15px avenir")
.attr("transform", function(d) { return "translate(500," + y(d.value.y0 + d.value.y / 2) + ")"; })
svg.append("g")
.attr("class", "x axis")
.attr("transform", "translate(0," + height + ")")
.call(xAxis).append("text")
.attr("x", 350)
.attr("y", 36)
.attr("fill", "#000")
.text("Hour of Time")
.style("font-weight", "bold");
svg.append("g")
.attr("class", "y axis")
.call(yAxis)
.append("text")
.attr("transform", "rotate(-90)")
.attr("x", -250)
.attr("y", -40)
.attr("dy", "0.3408em")
.attr("fill", "#000")
.text("Number of Incidents")
.style("font-weight", "bold");
var legend = svg.selectAll(".legend")
.data(color.domain()).enter()
.append("g")
.attr("class","legend")
.attr("transform", "translate(" + (width +20) + "," + 0+ ")");
legend.append("rect")
.attr("x", 0)
.attr("y", function(d, i) { return 20 * i; })
.attr("width", 10)
.attr("height", 10)
.style("fill", function(d, i) {
return get_colors(i);});
legend.append("text")
.attr("x", 20)
.attr("dy", "0.75em")
.attr("y", function(d, i) { return 20 * i; })
.text(function(d) {return d});
legend.append("text")
.attr("x",0)
// .attr("dy", "0.75em")
.attr("y",-10)
.text("Categories");
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment