Example of stacked area charts --based off of this gist -- addressing this SO question.
forked from mdml's block: D3 Stacked Area Chart Example
license: mit |
Example of stacked area charts --based off of this gist -- addressing this SO question.
forked from mdml's block: D3 Stacked Area Chart Example
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> |