Skip to content

Instantly share code, notes, and snippets.

@michael
Forked from mbostock/.block
Created June 5, 2011 17:32
Show Gist options
  • Save michael/1009200 to your computer and use it in GitHub Desktop.
Save michael/1009200 to your computer and use it in GitHub Desktop.
Matrix Layout (Michael Aufreiter)
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript" src="http://mbostock.github.com/d3/d3.js"></script>
<script type="text/javascript" src="matrix.js"></script>
<style type="text/css">
rect.cell {
fill: red;
fill: steelblue;
fill-opacity: .8;
stroke: white;
}
rect.cell:hover {
fill-opacity: 1.0;
}
</style>
</head>
<body>
<div id="canvas"></div>
<script type="text/javascript">
var plot = MatrixPlot();
setInterval(function() {
plot.update({
collection: {
items: function() { return d3.zip(d3.range(10 + ~~(Math.random() * 50))); }
}
});
}, 2500);
</script>
</body>
</html>
var w = 960,
h = 500;
// Matrix Layout
// ------------
var Matrix = function() {
var width = 1,
height = 1,
cols = 4;
// Simple matrix layout algorithm
// Computes a suitable column count to fit the matrix
// dimensions (width x height)
function computeCols(n, width, height) {
var cols = 1, // number of cols
a, // edge length
rows; // number of rows
while(true) {
a = width / cols;
rows = Math.ceil(n/cols);
if (rows*a <= height && n*a*a <= width*height)
return cols;
else {
cols += 1;
}
}
}
function matrix(data, i) {
var cols = computeCols(data.length, width, height);
var size = Math.floor(width / cols);
data.forEach(function(d, i) {
d.x = parseInt((i % cols)*size, 10);
d.y = Math.floor(i / cols)*size;
d.dx = size;
d.dy = size;
});
return data;
}
matrix.size = function(w, h) {
width = w;
height = h;
return matrix;
};
return matrix;
};
// Matrix Plot
// ------------
var MatrixPlot = function(el, options) {
var vis, matrix, cells, collection;
var initialized = false;
function init() {
vis = d3.select("#canvas")
.append("svg:svg")
.attr("width", w)
.attr("height", h);
matrix = Matrix()
.size(700, 500);
initialized = true;
}
function cell() {
this
.attr("x", function(d) { return d.x; })
.attr("y", function(d) { return d.y; })
.attr("width", function(d) { return d.dx-5; })
.attr("height", function(d) { return d.dy-5; });
}
function update(options) {
collection = options.collection;
if (!initialized) init();
cells = vis.data([collection.items()]).selectAll("rect")
.data(matrix);
// Transition of new (arriving cells)
cells.enter().append("svg:rect")
.attr("class", "cell")
.attr("x", function(d) { return 0; })
.attr("y", function(d) { return 0; })
.attr("width", function(d) { return 0; })
.attr("height", function(d) { return 0; })
.attr("rx", 5)
.attr("ry", 5)
.transition()
.delay(function(d, i) { return i * 20; })
.duration(1500)
.call(cell);
// Transition of existing cells
cells.transition()
.delay(function(d, i) { return i * 20; })
.duration(1500)
.call(cell);
// Exit transition
cells.exit().transition()
.delay(function(d, i) { return i * 20; })
.duration(1500)
.attr("x", function(d, i) { return -400; })
.attr("y", function(d, i) { return -400; })
.remove();
}
// Expose Public API
return {
update: update
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment