D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
taigereye
Full window
Github gist
Date vs. Category bar 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; } svg { width: 100%; height: 100%; } </style> </head> <body> <svg></svg> <script> // options var margin = {"top": 20, "right": 10, "bottom": 40, "left": 40 } var width = 500; var height = 500; var rectWidth = 60; var topPadding = 1.05; // data var data = [[25, 50, 100, 25], [50, 25, 50, 50], [25, 100, 25, 25], [10, 50, 25, 100] ]; // colors var colors = ["white", "red", "orange", "yellow"]; // ticks var x_ticks = ["April 2017", "May 2017", "June 2017", "July 2017"]; // calculate column totals let colTotals = function(data) { var cols = []; for (var i = 0; i < data.length; i++){ var col = data[i].reduce(function(sum, value){ return (sum + value)}, 0); cols.push(col); } return cols; } // calculate yMax let yDataMax = function(data) { var colHeights = colTotals(data); return d3.max(colHeights) * topPadding; } // scales var xAxisScale = d3.scaleBand() .domain(x_ticks) .range([margin.left, width - margin.right]); var xDataScale = d3.scaleBand() .domain([0, 1, 2, 3]) .range([margin.left, width - margin.right]) .paddingInner(0.2) .paddingOuter(0.2) var yMax = yDataMax(data); var yAxisScale = d3.scaleLinear() .domain([0, yMax]) .range([height - margin.bottom, margin.top]); // svg element var svg = d3.select('svg'); // create bars array let flatten = function(data, colors) { var bars = []; var barTotals = colTotals(data); for (var i = 0; i < data.length; i++) { var yStart = 0; for (var j = 0; j < data[i].length; j++) { if (j != 0) { yStart += data[i][j-1]; } var bar = { "x" : i, "y" : yStart+data[i][j], "yStart": yStart, "height" : data[i][j], "color" : colors[j], "empty" : false }; bars.push(bar); } } return {"bars": bars, "barTotals": barTotals}; } // draw bars var rectData = flatten(data, colors); var bars = rectData.bars; var barTotals = rectData.barTotals; svg.selectAll('rect') .data(bars) .enter().append('rect') .attr('x', function(d, i){ return xDataScale(bars[i].x)}) .attr('y', function(d, i){ return yAxisScale(bars[i].y)}) .attr('width', xDataScale.bandwidth) .attr('height', function(d, i){ return yAxisScale(bars[i].yStart) - yAxisScale(bars[i].y)}) .attr('fill',function (d, i){ if (bars[i].empty){ return "white"; }else{ return bars[i].color; }}) .attr('stroke', 'white') // axes var xAxis = d3.axisBottom() .scale(xAxisScale) var yAxis = d3.axisLeft() .scale(yAxisScale) .ticks(10) // draw axes svg.append('g') .attr('transform', 'translate(' + [0, height - margin.bottom] + ')') .call(xAxis); svg.append('g') .attr('transform', 'translate(' + [margin.left, 0] + ')') .call(yAxis); </script> </body>
https://d3js.org/d3.v4.min.js