D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
mbostock
Full window
Github gist
Waterfall
A waterfall chart.
<!DOCTYPE html> <meta charset="utf-8"> <style> svg { font: 10px sans-serif; } .axis path, .axis line { fill: none; stroke: #000; shape-rendering: crispEdges; } .rect { fill: #333; } .rect--negative { fill: brown; } .label { fill: white; font-size: 12px; text-anchor: end; } .label-change { font-weight: bold; } .label-value { fill-opacity: 0.8; } .label--negative { text-anchor: start; } </style> <svg width="960" height="500"></svg> <script src="//d3js.org/d3.v4.0.0-alpha.9.min.js"></script> <script> var formatChange = d3.format("+d"), formatValue = d3.format("d"); var svg = d3.select("svg"); var margin = {top: 20, right: 40, bottom: 40, left: 80}, width = +svg.attr("width") - margin.left - margin.right, height = +svg.attr("height") - margin.top - margin.bottom; var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); d3.requestTsv("data.tsv", function(d) { d.value = +d.value; return d; }, function(error, data) { if (error) throw error; // Compute a simple “stack” by iterating over the data. data.reduce(function(v, d) { return d.value1 = (d.value0 = v) + d.value; }, 0); var x = d3.scaleLinear() .domain(d3.extent(data, function(d) { return d.value1; })).nice() .range([0, width]); var y = d3.scaleBand() .domain(data.map(function(d) { return d.region; })) .rangeRound([0, height]) .padding(0.1); g.append("g") .attr("transform", "translate(0," + height + ")") .attr("class", "axis axis--x") .call(d3.axisBottom(x)); g.append("g").selectAll("rect") .data(data) .enter().append("rect") .attr("class", function(d) { return "rect rect--" + (d.value0 < d.value1 ? "positive" : "negative"); }) .attr("y", function(d) { return y(d.region); }) .attr("x", function(d) { return x(d.value0 < d.value1 ? d.value0 : d.value1); }) .attr("width", function(d) { return d.value0 < d.value1 ? x(d.value1) - x(d.value0) : x(d.value0) - x(d.value1); }) .attr("height", y.bandwidth()); var label = g.append("g").selectAll("text") .data(data) .enter().append("text") .attr("class", function(d) { return "label label--" + (d.value0 < d.value1 ? "positive" : "negative"); }) .attr("y", function(d) { return y(d.region) + y.bandwidth() / 2; }); label.append("tspan") .attr("class", "label-change") .attr("dy", "-.2em") .text(function(d) { return formatChange(d.value1 - d.value0); }); label.append("tspan") .attr("class", "label-value") .attr("dy", "1.1em") .text(function(d) { return formatValue(d.value1); }); label.selectAll("tspan") .attr("x", function(d) { return x(d.value1) + (d.value0 < d.value1 ? -6 : 6); }); g.append("g") .attr("class", "axis axis--y") .attr("transform", "translate(" + x(0) + ",0)") .call(d3.axisLeft(y).tickSize(0).tickPadding(x(0) + 6)); }); </script>
https://d3js.org/d3.v4.0.0-alpha.9.min.js