Skip to content

Instantly share code, notes, and snippets.

@GerardoFurtado
Created March 18, 2019 08:47
Show Gist options
  • Save GerardoFurtado/02b32d9625f81e8f6f69ae5dac63473e to your computer and use it in GitHub Desktop.
Save GerardoFurtado/02b32d9625f81e8f6f69ae5dac63473e 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 n0 = cell.size();
var cellUpdate = cell.selectAll("rect")
.data(d3.range(n1));
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