|
<!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> |