Skip to content

Instantly share code, notes, and snippets.

@GerardoFurtado
Created March 18, 2019 09:29
Show Gist options
  • Save GerardoFurtado/b0d66087d9888a2cac3a42b114e5e8c4 to your computer and use it in GitHub Desktop.
Save GerardoFurtado/b0d66087d9888a2cac3a42b114e5e8c4 to your computer and use it in GitHub Desktop.
Square Grid
license: gpl-3.0

A simple and effective form for visualizing magnitude is this gridded layout of colored squares. Each individual square represents one unit; each small row represents ten units; the small rows are grouped into ten, representing one hundred; lastly, ten groups per large row represents one thousand. This arrangement affords quick and natural reading of exact counts by powers of ten.

For an example of this technique in practice, see Randall Munroe’s Radiation Dose Chart.

forked from mbostock's block: Square Grid

<!DOCTYPE html>
<meta charset="utf-8">
<style>
.cells {
fill: #aaa;
}
.label {
text-anchor: start;
font: 24px sans-serif;
}
</style>
<svg width="960" height="990"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script>
var formatNumber = d3.format(",d");
var svg = d3.select("svg");
var width = +svg.attr("width"),
height = +svg.attr("height");
var groupSpacing = 3,
cellSpacing = 1,
cellSize = Math.floor((width - 11 * groupSpacing) / 100) - cellSpacing,
offset = Math.floor((width - 100 * cellSize - 90 * cellSpacing - 11 * groupSpacing) / 2);
var updateDuration = 125,
updateDelay = updateDuration / 500;
var cell = svg.append("g")
.attr("class", "cells")
.attr("transform", "translate(" + offset + "," + (offset + 30) + ")");
var label = svg.append("text")
.attr("class", "label");
function update(n1) {
var cellUpdate = cell.selectAll("rect")
.data(d3.range(n1));
var n0 = cell.selectAll("rect").size();
var cellExit = cellUpdate.exit().transition()
.delay(function(d, i) { return (n0 - i) * updateDelay; })
.duration(updateDuration)
.attr("width", 0)
.remove();
var cellEnter = cellUpdate.enter().append("rect")
.attr("width", 0)
.attr("height", cellSize)
.attr("x", function(i) {
var x0 = Math.floor(i / 100) % 10, x1 = Math.floor(i % 10);
return groupSpacing * x0 + (cellSpacing + cellSize) * (x1 + x0 * 10);
})
.attr("y", function(i) {
var y0 = Math.floor(i / 1000), y1 = Math.floor(i % 100 / 10);
return groupSpacing * y0 + (cellSpacing + cellSize) * (y1 + y0 * 10);
})
.transition()
.delay(function(d, i) { return (i - n0) * updateDelay; })
.duration(updateDuration)
.attr("width", cellSize);
label
.attr("x", offset + groupSpacing)
.attr("y", offset + groupSpacing)
.attr("dy", ".71em")
.transition()
.duration(Math.abs(n1 - n0) * updateDelay + updateDuration / 2)
.ease(d3.easeLinear)
.tween("text", function() {
var self = this;
var i = d3.interpolateNumber(n0, n1);
return function(t) {
self.textContent = formatNumber(Math.round(i(t)));
};
});
}
(function interval() {
update(Math.floor(Math.random() * 100 * 100));
setTimeout(interval, updateDelay * 100 * 100 + updateDuration + 1000);
})();
d3.select(self.frameElement).style("height", height + "px");
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment