Created
March 15, 2015 19:14
-
-
Save vicapow/a5586b51071a4bff4e65 to your computer and use it in GitHub Desktop.
masonic demo
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Checkout the project page at: https://github.com/shawnbot/masonic | |
(function(exports) { | |
var VERSION = "0.1.0"; | |
d3.masonic = function() { | |
var columnCount = 0, | |
columnWidth = 200, | |
outerWidth = 0, | |
outerHeight = 0, | |
columns = [], | |
bricks = [], | |
getWidth = function() { return this.offsetWidth; }, | |
getHeight = function() { return this.offsetHeight; }, | |
zero = d3.functor(0); | |
function masonic(d, i) { | |
if (columns.length === 0) { | |
columns = d3.range(columnCount).map(zero); | |
} | |
var w = getWidth.apply(this, arguments) || 0, | |
h = getHeight.apply(this, arguments) || 0, | |
span = Math.ceil(w / columnWidth), | |
brick = { | |
width: w, | |
height: h, | |
data: d | |
}; | |
span = brick.span = Math.min(span, columnCount); | |
if (span === 1) { | |
place(brick, columns); | |
} else { | |
var groupCount = columnCount + 1 - span, | |
groupY = [], | |
groupColY; | |
for (var i = 0; i < groupCount; i++) { | |
groupColY = columns.slice(i, i + span); | |
groupY[i] = Math.max.apply(Math, groupColY); | |
} | |
place(brick, groupY); | |
} | |
return brick; | |
} | |
function place(brick, cols) { | |
var minY = Math.min.apply(Math, cols), | |
len = cols.length, | |
shortest = 0; | |
for (var i = 0; i < len; i++) { | |
if (cols[i] === minY) { | |
shortest = i; | |
break; | |
} | |
} | |
brick.column = shortest; | |
brick.x = columnWidth * shortest; | |
brick.y = minY; | |
var setHeight = minY + brick.height, | |
setSpan = columnCount + 1 - len; | |
for (i = 0; i < setSpan; i++) { | |
columns[shortest + i] = setHeight; | |
} | |
outerHeight = Math.max.apply(Math, columns); | |
// XXX set outerWidth? | |
outerWidth = Math.max(outerWidth, brick.x + brick.width); | |
} | |
// get/set the item width value (function) | |
masonic.width = function(_) { | |
if (!arguments.length) return getWidth; | |
getWidth = d3.functor(_); | |
return masonic; | |
}; | |
// get/set the item height value (function) | |
masonic.height = function(_) { | |
if (!arguments.length) return getHeight; | |
getHeight = d3.functor(_); | |
return masonic; | |
}; | |
// get/set column width | |
masonic.columnWidth = function(_) { | |
if (!arguments.length) return columnWidth; | |
columnWidth = _; | |
if (outerWidth === 0) { | |
outerWidth = columnCount * columnWidth; | |
} | |
return masonic; | |
}; | |
// get/set column count | |
masonic.columnCount = function(_) { | |
if (!arguments.length) return columnCount; | |
columnCount = _; | |
return masonic; | |
}; | |
// get/set outer width | |
// Note: the setter also sets columnWidth if columnCount > 0 | |
masonic.outerWidth = function(_) { | |
if (!arguments.length) return outerWidth; | |
outerWidth = _; | |
if (columnWidth > 0) { | |
columnCount = Math.floor(outerWidth / columnWidth); | |
} | |
return masonic; | |
}; | |
// getter only | |
masonic.outerHeight = function() { | |
if (arguments.length) throw "outerHeight() is a getter only"; | |
return outerHeight; | |
}; | |
masonic.reset = function() { | |
bricks = []; | |
columns = []; | |
outerHeight = 0; | |
return masonic; | |
}; | |
return masonic.reset(); | |
}; | |
d3.masonic.version = VERSION; | |
})(this); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<title></title> | |
<style> | |
body { | |
margin: 0; | |
} | |
</style> | |
</head> | |
<body> | |
<script src="http://d3js.org/d3.v3.js" charset="utf-8"></script> | |
<script src="d3-masonic.js" charset="utf-8"></script> | |
<script> | |
'use strict'; | |
var w = window.innerWidth, h = window.innerHeight | |
var s = 1 | |
var duration = 500 | |
var n = 6 | |
var acc = function(d, prop) { return function accessor(d) { return d[prop] } } | |
var body = d3.select('body') | |
var svg = body.append('svg') | |
.attr({width: w, height: h}) | |
.style('background-color', 'black') | |
var color = d3.scale.category20() | |
function randomSize(min, max, step) { | |
return Math.round(min + Math.random() * (max - min)) * step | |
} | |
function genData() { | |
return d3.range(n) | |
.map(function(d, i) { | |
var size = Math.pow(randomSize(2, 15, s), 2) | |
return { | |
width: size, | |
height: size, | |
id: i, | |
masonic: null | |
} | |
}) | |
} | |
var bricks = svg.selectAll('rect') | |
.data(genData, function(d) { return d.id }) | |
.enter() | |
.append('rect') | |
.style('fill', function(d, i) { return color(i) }) | |
var masonic = d3.masonic() | |
.width(function(d) { return d.width }) | |
.height(function(d) { return d.height }) | |
.columnWidth(s) | |
function resize() { | |
var outerWidth = body.property('offsetWidth') | |
masonic.outerWidth(800).reset() | |
bricks | |
// .sort(function(a, b) { return b.width * b.height - a.width * a.height }) | |
.datum(function(d, i) { | |
d.masonic = masonic(d) | |
delete d.masonic.data | |
return d | |
}) | |
.transition() | |
.ease('cubic-out') | |
.duration(duration) | |
.attr({ | |
x: function(d) { return d.masonic.x }, | |
y: function(d) { return 500 - d.masonic.y - d.masonic.height }, | |
width: function(d) { return d.masonic.width }, | |
height: function(d) { return d.masonic.height } | |
}) | |
} | |
resize() | |
setInterval(function() { | |
bricks.data(genData, function(d) { return d.id }) | |
resize() | |
}, duration) | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment