Skip to content

Instantly share code, notes, and snippets.

@tophtucker
Last active May 12, 2016 02:43
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tophtucker/a18d11836a353730cef46bd005a82851 to your computer and use it in GitHub Desktop.
Save tophtucker/a18d11836a353730cef46bd005a82851 to your computer and use it in GitHub Desktop.
Diagonal IV
height: 600

Someone just wanted to animate boxes in diagonally. The key is mapping ℕ✕ℕ → ℕ by the Cantor pairing function! This version additionally zigzags by using the inverse of the triangular number equation to find the row of the triangle you're on and then invert the order of the arguments to the Cantor pairing function every other row.

This does not depend on data initially being sorted, or in any particular shape or arrangement; it could be square, rectangular, sparse, etc.

See also:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
position: relative;
font-family: sans-serif;
}
div {
background: black;
border: 1px solid white;
position: absolute;
width: 40px;
height: 40px;
color: rgba(255,255,255,.5);
font-size: 16px;
text-align: center;
overflow: hidden;
padding-top: 10px;
}
</style>
<body></body>
<script src="//d3js.org/d3.v4.0.0-alpha.35.min.js" charset="utf-8"></script>
<script>
var dimensions = [960,600];
var gridSize = 40;
var delay = 40;
var duration = 400;
var color = d3.scaleRainbow().domain([0,15]);
d3.select('body')
.selectAll('div')
.data(makeData)
.enter()
.append('div')
.style('left', function(d) { return d.column * gridSize + 'px'; })
.style('top', function(d) { return d.row * gridSize + 'px'; })
.style('opacity', 0)
.text(function(d) { return cantorZigZag(d.column, d.row); })
.sort(comparatorZigZag)
.style('background-color', function(d,i) { return color(i); })
.transition()
.duration(duration)
.delay(function(d,i) { return i * delay; })
.style('opacity', 1);
// https://en.wikipedia.org/wiki/Pairing_function#Cantor_pairing_function
// i.e., from 2D coord to serialized 1D coord
function cantorPairingFunction(x,y) {
return (1/2) * (x + y) * (x + y + 1) + y;
}
function comparatorCantor(a,b) {
return cantorPairingFunction(a.column, a.row) - cantorPairingFunction(b.column, b.row);
}
function cantorZigZag(x,y) {
var triangleRow = Math.floor(getTriangularNumberInverse(cantorPairingFunction(x,y)))
if(triangleRow % 2 == 0) {
return cantorPairingFunction(x,y);
} else {
return cantorPairingFunction(y,x);
}
}
function comparatorZigZag(a,b) {
return cantorZigZag(a.column, a.row) - cantorZigZag(b.column, b.row);
}
// https://en.wikipedia.org/wiki/Triangular_number
function getTriangularNumber(n) {
return n * (n + 1) / 2;
}
function getTriangularNumberInverse(n) {
return (1/2) * (-1 + Math.sqrt(8 * n + 1));
}
function makeData() {
return d3.range((dimensions[0]/gridSize)*(dimensions[1]/gridSize)).map(function(d) {
return {
row: Math.floor(d / (dimensions[0]/gridSize)),
column: d % (dimensions[0]/gridSize)
}
});
}
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment