|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<svg width="960" height="500"></svg> |
|
<script src="//d3js.org/d3.v4.min.js"></script> |
|
<script> |
|
|
|
var svg = d3.select("svg"), |
|
margin = {top: 20, right: 20, bottom: 30, left: 50}, |
|
width = svg.attr("width") - margin.left - margin.right, |
|
height = svg.attr("height") - margin.top - margin.bottom; |
|
|
|
var parseDate = d3.timeParse("%Y %b %d"); |
|
|
|
var x = d3.scaleTime().range([0, width]), |
|
y = d3.scaleLinear().range([height, 0]), |
|
z = d3.scaleOrdinal(d3.schemeCategory10); |
|
|
|
var stack = d3.stack(); |
|
|
|
var area = d3.area() |
|
.x(function(d, i) { return x(d.data.date); }) |
|
.y0(function(d) { return y(d[0]); }) |
|
.y1(function(d) { return y(d[1]); }); |
|
|
|
var g = svg.append("g") |
|
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
|
|
|
d3.tsv("data.tsv", type, function(error, data) { |
|
if (error) throw error; |
|
|
|
var keys = data.columns.slice(1); |
|
|
|
x.domain(d3.extent(data, function(d) { return d.date; })); |
|
z.domain(keys); |
|
stack.keys(keys); |
|
|
|
var layer = g.selectAll(".layer") |
|
.data(stack(data)) |
|
.enter().append("g") |
|
.attr("class", "layer"); |
|
|
|
layer.append("path") |
|
.attr("class", "area") |
|
.style("fill", function(d) { return z(d.key); }) |
|
.attr("d", area); |
|
|
|
layer.filter(function(d) { return d[d.length - 1][1] - d[d.length - 1][0] > 0.01; }) |
|
.append("text") |
|
.attr("x", width - 6) |
|
.attr("y", function(d) { return y((d[d.length - 1][0] + d[d.length - 1][1]) / 2); }) |
|
.attr("dy", ".35em") |
|
.style("font", "10px sans-serif") |
|
.style("text-anchor", "end") |
|
.text(function(d) { return d.key; }); |
|
|
|
g.append("g") |
|
.attr("class", "axis axis--x") |
|
.attr("transform", "translate(0," + height + ")") |
|
.call(d3.axisBottom(x)); |
|
|
|
g.append("g") |
|
.attr("class", "axis axis--y") |
|
.call(d3.axisLeft(y).ticks(10, "%")); |
|
}); |
|
|
|
function type(d, i, columns) { |
|
d.date = parseDate(d.date); |
|
for (var i = 1, n = columns.length; i < n; ++i) d[columns[i]] = d[columns[i]] / 100; |
|
return d; |
|
} |
|
|
|
</script> |
@tschieggem I'm pretty sure that's inaccurate. It's not mentioned explicitly in the docs but the examples there use node-style callbacks as well. Also this example works on the blocks site. And most importantly, the code disagrees.
So I'm assuming you're putting forth an opinion on what the callback signature should be. This probably isn't the place to make a proposal like that (maybe you're looking for the issues?). Moreover, the API has standardized on the widely used node-style callbacks, so it's unlikely to change.