D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
rangitatanz
Full window
Github gist
Usage Chart
Built with
blockbuilder.org
<!DOCTYPE html> <head> <meta charset="utf-8"> <script src="https://d3js.org/d3.v4.min.js"></script> <style> body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } </style> </head> <body> <svg width="960" height="500"></svg> <script> var numberSeries = 2, // The number of series. numberValues = 31; // The number of values per series. var dateStart = new Date(2018, 1, 1); var data = []; // The xz array has m elements, representing the x-values shared by all series. // The yz array has n elements, representing the y-values of each of the n series. // Each yz[i] is an array of m non-negative numbers representing a y-value for xz[i]. // The y01z array has the same structure as yz, but with stacked [y₀, y₁] instead of y. var xz = d3.range(numberValues), yz = d3.range(numberSeries).map(function () { return bumps(numberValues); }), y01z = d3.stack().keys(d3.range(numberSeries))(d3.transpose(yz)), yMax = d3.max(yz, function (y) { return d3.max(y); }), y1Max = d3.max(y01z, function (y) { return d3.max(y, function (d) { return d[1]; }); }); var svg = d3.select("svg"), margin = { top: 40, right: 10, bottom: 20, left: 10 }, width = +svg.attr("width") - margin.left - margin.right, height = +svg.attr("height") - margin.top - margin.bottom, g = svg.append("g").attr("transform", "translate(" + margin.left + "," + margin.top + ")"); var x = d3.scaleBand() .domain(xz) .rangeRound([0, width]) .padding(0.08); var y = d3.scaleLinear() .domain([0, y1Max]) .range([height, 0]); var color = d3.scaleOrdinal() .domain(d3.range(numberSeries)) .range(d3.schemeCategory20c); var series = g.selectAll(".series") .data(y01z) .enter().append("g") .attr("fill", function (d, i) { return color(i); }); var rect = series.selectAll("rect") .data(function (d) { return d; }) .enter().append("rect") .attr("x", function (d, i) { return x(i); }) .attr("y", height) .attr("width", x.bandwidth()) .attr("height", 0); rect.transition() .delay(function (d, i) { return i * 10; }) .attr("y", function (d) { return y(d[1]); }) .attr("height", function (d) { return y(d[0]) - y(d[1]); }); g.append("g") .attr("class", "axis axis--x") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x) .tickSize(0) .tickPadding(6)); d3.selectAll("input") .on("change", changed); d3.select("input[value=\"stacked\"]") .property("checked", true); function transitionStacked() { y.domain([0, y1Max]); rect.transition() .duration(500) .delay(function (d, i) { return i * 10; }) .attr("y", function (d) { return y(d[1]); }) .attr("height", function (d) { return y(d[0]) - y(d[1]); }) .transition() .attr("x", function (d, i) { return x(i); }) .attr("width", x.bandwidth()); } // Returns an array of m psuedorandom, smoothly-varying non-negative numbers. // Inspired by Lee Byron’s test data generator. // https://leebyron.com/streamgraph/ function bumps(m) { var values = [], i, j, w, x, y, z; // Initialize with uniform random values in [0.1, 0.2). for (i = 0; i < m; ++i) { values[i] = 0.1 + 0.1 * Math.random(); } // Add five random bumps. for (j = 0; j < 5; ++j) { x = 1 / (0.1 + Math.random()); y = 2 * Math.random() - 0.5; z = 10 / (0.1 + Math.random()); for (i = 0; i < m; i++) { w = (i / m - y) * z; values[i] += x * Math.exp(-w * w); } } // Ensure all values are positive. for (i = 0; i < m; ++i) { values[i] = Math.max(0, values[i]); } return values; } </script> </body>
https://d3js.org/d3.v4.min.js