Skip to content

Instantly share code, notes, and snippets.

@taigereye
Last active August 4, 2017 23:55
Show Gist options
  • Save taigereye/658f6d1280f41e03e63d0b9b790f637e to your computer and use it in GitHub Desktop.
Save taigereye/658f6d1280f41e03e63d0b9b790f637e to your computer and use it in GitHub Desktop.
Category vs. Default bar chart
license: mit
<!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, 100],
[0, 150],
[0, 50]
];
var colors = ["white", "teal"]
// ticks
var x_ticks = ["Bachelor's", "Master's", "PhD"];
// 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])
.range([margin.left, width - margin.right])
.paddingInner(0.2)
.paddingOuter(0.2)
var yMax = dataMax(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(5)
// 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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment