Built with blockbuilder.org
Last active
October 23, 2015 20:45
-
-
Save enjalot/05ba4a7927618925ccf4 to your computer and use it in GitHub Desktop.
simple grid layout
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> | |
<head> | |
<meta charset="utf-8"> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js"></script> | |
<style> | |
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0; } | |
#display { | |
} | |
#controls { | |
float:left; | |
padding-left: 15px; | |
margin-top: 30px; | |
width: 220px; | |
height: 100%; | |
} | |
svg { | |
position:absolute; | |
left: 220px; | |
width: calc(100% - 235px); | |
height: 100%; | |
} | |
</style> | |
</head> | |
<body> | |
<div id="display"> | |
<div id="controls"> | |
cell width<br><input id="cellWidth" type="range" min="1" max="20" value="15"> | |
<br> | |
cell height<br><input id="cellHeight" type="range" min="1" max="12" value="7"> | |
<br> | |
x margin<br><input id="xmargin" type="range" min="0" max="10" value="3.4"> | |
<br> | |
y margin<br> | |
<input id="ymargin" type="range" min="0" max="10" value="4.24"> | |
<br> | |
<button id="brick">brick</button> | |
</div> | |
<svg></svg> | |
</div> | |
<script> | |
var exampleData = d3.range(1000).map(function(d) { return Math.random() }); | |
var brickSetting = true; | |
//setup the parameters for the layout. all are optional | |
var layout = new grid() | |
.cellWidth(15) | |
.cellHeight(8) | |
.width(500) | |
.margin([3.4, 4.24]) | |
.offset([0, 28]) | |
.brick(brickSetting) | |
var color = d3.scale.linear() | |
.domain([0, 1000]) | |
.range(["#a8ff60", "#0600cc"]) | |
.interpolate(d3.interpolateHcl) | |
//console.log("layout", layout.nodes()); | |
var svg = d3.select("svg") | |
function drawCells() { | |
var cells = svg.selectAll("rect") | |
.data(layout.nodes(exampleData)) // everything is recalculated when nodes is called | |
cells.enter().append("rect") | |
cells.exit().remove() | |
cells | |
.attr({ | |
x: function(d) { return d.x }, | |
y: function(d) { return d.y }, | |
width: layout.cellWidth(), | |
height: layout.cellHeight(), | |
fill: function(d,i) { return color(d.index) } | |
}) | |
} | |
drawCells(); | |
// hook up the sliders | |
d3.select("#cellWidth").on("input", function() { | |
layout.cellWidth(+this.value) | |
drawCells(); | |
}) | |
d3.select("#cellHeight").on("input", function() { | |
layout.cellHeight(+this.value); | |
drawCells(); | |
}) | |
d3.select("#xmargin").on("input", function() { | |
var margin = layout.margin(); | |
margin[0] = +this.value; | |
layout.margin(margin); | |
drawCells(); | |
}) | |
d3.select("#ymargin").on("input", function() { | |
var margin = layout.margin(); | |
margin[1] = +this.value; | |
layout.margin(margin); | |
drawCells(); | |
}) | |
d3.select("#brick").on("click", function() { | |
brickSetting = !brickSetting; | |
layout.brick(brickSetting) | |
drawCells(); | |
if(brick) return d3.select("#brick").text("brick") | |
d3.select("#brick").text("regular") | |
}) | |
// the grid layout itself | |
function grid() { | |
var data = []; | |
var nodes; | |
var width = 100; | |
var cellWidth = 10; | |
var cellHeight = 10; | |
var nColumns = 10; | |
var offset = [0,0]; | |
var margin = [1,1]; | |
var brick = false; | |
function getX(d,i) { | |
return offset[0] + (i % nColumns) * (cellWidth + margin[0]) | |
} | |
function getY(d,i) { | |
return offset[1] + Math.floor(i/nColumns) * (cellHeight + margin[1]) | |
} | |
function newNodes() { | |
nodes = []; | |
data.forEach(function(d,i) { | |
var node = { | |
x: getX(d,i), | |
y: getY(d,i), | |
data: d, | |
index: i | |
} | |
nodes.push(node); | |
}) | |
} | |
newNodes(); | |
function calculate() { | |
nodes.forEach(function(node, i) { | |
node.x = getX(node, node.index); | |
node.y = getY(node, node.index); | |
// calculate the center for convenience | |
node.cx = node.x + cellWidth/2; | |
node.cy = node.x + cellHeight/2; | |
}) | |
} | |
this.nodes = function(val) { | |
if(val) { | |
data = val; | |
newNodes(); | |
} | |
calculate(); | |
return nodes; | |
} | |
this.columns = function(val) { | |
} | |
this.cellWidth = function(val) { | |
if(val) { | |
cellWidth = val; | |
this.width(width); | |
return this; | |
} | |
return cellWidth; | |
} | |
this.cellHeight = function(val) { | |
if(val) { | |
cellHeight = val; | |
return this; | |
} | |
return cellHeight; | |
} | |
this.width = function(val) { | |
if(val) { | |
width = val; | |
nColumns = Math.floor((width) / (cellWidth + margin[0])) + (brick ? 0.5 : 0); | |
//cellWidth = val / nColumns; | |
return this; | |
} | |
return width; | |
} | |
this.margin = function(val) { | |
if(val) { | |
margin = val; | |
this.width(width); | |
return this; | |
} | |
return margin; | |
} | |
this.offset = function(val) { | |
if(val) { | |
offset = val; | |
return this; | |
} | |
return offset; | |
} | |
this.brick = function(val) { | |
if(val === null || val === undefined) return brick; | |
if(val !== null) { | |
brick = val; | |
this.width(width); | |
return this; | |
} | |
return brick; | |
} | |
return this; | |
} | |
</script> | |
</body> | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment