Skip to content

Instantly share code, notes, and snippets.

@jywsn
Last active August 29, 2015 14:02
Show Gist options
  • Save jywsn/8d06543a5b658192d771 to your computer and use it in GitHub Desktop.
Save jywsn/8d06543a5b658192d771 to your computer and use it in GitHub Desktop.
d3-layout-stack-stream
// Generate data. This 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 x and y values.
var dataset = [];
var n = 5; // number of categories
var m = 100; // number of samples per category
for(var i = 0; i < n; i++) {
var category = [];
for(var x = 0; x < m; x++) {
category.push({x: x, y: 10*Math.random()});
}
dataset.push(category);
}
// 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();
// A streamgraph can be generated using the "wiggle" offset, which attempts to
// minimize change in slope weighted by layer thickness.
var stack = d3.layout.stack().offset("wiggle");
// After 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'
// starts at y0 and the 'top' is at y0 + y
stack(dataset);
// x-domain is the range x-coordinates in the data. Here it will always
// be [0, m-1], but this is how you would calculate it with real data.
var x = d3.scale.linear()
.domain([0, d3.max(dataset, function(category) {
return d3.max(category, function(d) { return d.x; });
})
])
.range([0, w]);
// y-domain is the range of 'top' values (see above)
var y = d3.scale.linear()
.domain([0, d3.max(dataset, function(category) {
return d3.max(category, function(d) { return d.y0 + d.y; });
})
])
.range([h, 0]);
// Construct an area generator that will generate path data for a closed
// piecewise linear curve. The top line is formed using the x- and y1-accessor
// functions. The bottom line is formed using the x- and y0-accessor functions.
// Note that we are incorporating the 'baseline' values in each line.
var area = d3.svg.area()
.x(function(d) { return x(d.x); })
.y0(function(d) { return y(d.y0); })
.y1(function(d) { return y(d.y0 + d.y); });
// Define inner 'g' for actual chart drawing area
var svg = d3.select('#stream').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+')');
// Create a path for each category
svg.selectAll('path')
.data(dataset)
.enter().append('path')
.attr('d', area)
.style('fill', function(d, i) { return color(i); });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment