Built with blockbuilder.org
forked from anonymous's block: fresh block
forked from ptvans's block: d3.js nest example
license: mit |
Built with blockbuilder.org
forked from anonymous's block: fresh block
forked from ptvans's block: d3.js nest example
<!DOCTYPE html> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<style> | |
body { margin:20; | |
position:fixed;top:0;right:0;bottom:20;left:0; } | |
</style> | |
</head> | |
<body> | |
<script> | |
var width = 900; | |
var height = 650; | |
var x = d3.scaleBand() | |
.rangeRound([0, width]) | |
.padding(0.1) | |
.align(0.1); | |
var y = d3.scaleLinear() | |
.rangeRound([height, 0]); | |
var z = d3.scaleOrdinal() | |
.range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]); | |
var transactions = [ | |
{amount: 2700.00, vendor: "check", date: "3/01/2016", category: "rent"}, | |
{amount: 48.87, vendor: "oreillys autoparts", date: "3/21/2016", category: "auto parts"}, | |
{amount: 68.43, vendor: "Van Kleef", date: "4/04/2016", category: "bars"}, | |
{amount: 22.13, vendor: "pub", date: "4/04/2016", category: "bars"}, | |
{amount: 18.87, vendor: "oreillys autoparts", date: "5/21/2016", category: "auto parts"}, | |
{amount: 148.51, vendor: "safeway", date: "6/10/2016", category: "grocery"} | |
]; | |
//assign months | |
var parseDate = d3.timeParse("%m/%d/%Y"); | |
var formatMonth = d3.timeFormat("%y-%m"); | |
transactions.forEach(function(d) { | |
d.date = +parseDate(d.date); | |
var month = formatMonth(d.date); | |
d.month = month; | |
}); | |
console.log(transactions); | |
//group by month and then category | |
var byCategory = d3.nest() | |
.key(function(d) { return d.month; }) | |
.key(function(d) { return d.category; }) | |
.rollup(function(leaves) { | |
return d3.sum(leaves, function(d) { return parseFloat(d.amount); }) | |
}) | |
.entries(transactions); | |
console.log("by cat",byCategory); | |
var categoryMap = byCategory.map( function(d){ | |
console.log("d", d); | |
var tempMap = { "month" : d.key } | |
d.values.forEach(function(e){ | |
tempMap[e.key] = e.value; | |
}) | |
return tempMap; | |
}); | |
// now use StackLayout | |
// https://github.com/d3/d3-shape/blob/master/README.md#stack | |
console.log("map",categoryMap); | |
//group by month and then category | |
var byMonth = d3.nest() | |
.key(function(d) { return d.month; }) | |
.rollup(function(leaves) { | |
return d3.sum(leaves, function(d) { return parseFloat(d.amount); }) | |
}) | |
.entries(transactions); | |
console.log("by month", byMonth) | |
//group by month and then category | |
var nestedMonth = d3.nest() | |
.key(function(d) { return d.month; }) | |
.rollup(function(leaves) { return leaves }) | |
.entries(transactions); | |
console.log("nested month", nestedMonth) | |
// DOMAINS | |
//x.domain(d3.extent(transactions, function(d) { return d.month; })); | |
x.domain(d3.set(transactions, function(d){return d.month}).values()); | |
console.log(x.domain()); | |
//x domain map to month | |
y.domain([0, d3.max(byMonth, function(d) { return d.value; })]).nice(); | |
//y domain needs to map to amount by month | |
z.domain(function(d) { return d.category; }); | |
//z domain needs to map to categories | |
var svg = d3.select("body").append("svg") | |
.attr("width", width) | |
.attr("height", height); | |
g = svg.append("g"); | |
g.selectAll(".categories") | |
.data(byCategory) | |
.enter().append("rect") | |
.attr("class", "categories") | |
.attr("fill", function(d) { return z(d.key); }) | |
.attr("x", 6) | |
.attr("y", 20) | |
.attr("height", 20) | |
.attr("width", 40) | |
g.selectAll(".transactions") | |
.data(transactions) | |
.enter().append("rect") | |
.attr("class", "transactions") | |
.attr("fill", function(d) { return z(d.category); }) | |
.attr("x", function(d) { return x(d.month); }) | |
.attr("y", 10) | |
.attr("height", function(d) { return y(d.amount); }) | |
.attr("width", x.bandwidth()) | |
.text(function(d) {return d.category}) | |
g.selectAll(".labels") | |
.data(transactions) | |
.enter().append("text") | |
.attr("class", "labels") | |
.attr("fill", "black") | |
.attr("x", function(d) { return x(d.month); }) | |
.attr("y", 50) | |
.text(function(d) {return d.category}) | |
</script> | |
</body> |
.categories { | |
height: 10px; | |
width: 20px; | |
} |