Skip to content

Instantly share code, notes, and snippets.

@jywsn
Last active August 29, 2015 14:02
Show Gist options
  • Save jywsn/ab427884759736346797 to your computer and use it in GitHub Desktop.
Save jywsn/ab427884759736346797 to your computer and use it in GitHub Desktop.
d3-layout-stack
// Data needs to be an aray of arrays, where each array represents the data for one category.
// Within each category array, you need an object for each data value, which must contain an x and a y value.
var dataset = [
[ // category 1
{ x: 0, y: 5 },
{ x: 1, y: 4 },
{ x: 2, y: 2 },
{ x: 3, y: 7 },
{ x: 4, y: 23 }
],
[ // category 2
{ x: 0, y: 10 },
{ x: 1, y: 12 },
{ x: 2, y: 19 },
{ x: 3, y: 23 },
{ x: 4, y: 17 }
],
[ // category 3
{ x: 0, y: 22 },
{ x: 1, y: 28 },
{ x: 2, y: 32 },
{ x: 3, y: 35 },
{ x: 4, y: 43 }
]
];
// Margins
var margin = {top: 20, right: 20, bottom: 20, left: 20};
// Drawing area = svg dimensions - margins
var w = 600 - margin.left - margin.right;
var h = 400 - margin.top - margin.bottom;
// Color, https://github.com/mbostock/d3/wiki/Ordinal-Scales
var color = d3.scale.category10();
// When you stack, each object will be given a y0 value, where y0 = the 'baseline value',
// which is equal to the sum of all the y values in the preceding categories at the same position.
// The 'bottom' of each block starts at y0, the the 'top' of each block is at y0 + y
var stack = d3.layout.stack();
stack(dataset);
var xScale = d3.scale.ordinal()
.domain(d3.range(dataset[0].length))
.rangeRoundBands([0, w], 0.05);
var yScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})])
.range([h, 0]);
var hScale = d3.scale.linear()
.domain([0, d3.max(dataset, function(d) {
return d3.max(d, function(d) {
return d.y0 + d.y;
});
})])
.range([0, h]);
var svg = d3.select('#stack').append('svg')
.attr('width', w + margin.left + margin.right)
.attr('height', h + margin.top + margin.bottom)
.append('g')
.attr('transform', 'translate('+margin.left+','+margin.top+')');
// Add group for each row of data
// 1 row = 1 category, so 'd' is an array
var groups = svg.selectAll('g')
.data(dataset)
.enter()
.append('g')
.style('fill', function(d, i) {
return color(i);
});
// Add a rect for each data value
var rects = groups.selectAll('rect')
// iterate over bound data above
.data(function(d) { return d; })
.enter()
.append('rect')
.attr('x', function(d, i) {
// i = 1 - 5, position along x-axis
return xScale(i);
})
.attr('y', function(d) {
return yScale(d.y + d.y0);
})
.attr('width', xScale.rangeBand())
.attr('height', function(d) {
return hScale(d.y);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment