D3
OG
Old school D3 from simpler times
All examples
By author
By category
About
taigereye
Full window
Github gist
Numeric 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 = [[0, 20, 40, 35, 60, 10], [0, 50, 25, 30, 10, 20], [0, 10, 20, 40, 10, 20], [0, 35, 45, 10, 15, 25], [0, 55, 30, 20, 15, 40] ]; // colors var colors = ["black", "green", "blue", "teal", "purple", "navy"]; // ticks var x_ticks = ["0 - 4", "4 - 8", "8 - 12", "12 - 16", "16 - 20"]; // 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 dataMax = 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, 4]) .range([margin.left, width - margin.right]) .paddingInner(0.2) .paddingOuter(0.2) var yMax = 1; 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]) / barTotals[i]), "yStart": (yStart / barTotals[i]), "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(5) .tickFormat(function(d){ return (d * 100) + '%'}) 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