|
// url parser http://stackoverflow.com/a/901144/678708 |
|
function getParameterByName(name) { |
|
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]"); |
|
var regexS = "[\\?&]" + name + "=([^&#/]*)"; |
|
var regex = new RegExp(regexS); |
|
var results = regex.exec(parent.window.location.href); |
|
if(results == null) {return "";} else {return decodeURIComponent(results[1].replace(/\+/g, " "));} |
|
} |
|
|
|
function isNumber(n) {return !isNaN(parseFloat(n)) && isFinite(n);} |
|
|
|
function drawBox() { |
|
// defaults |
|
var data = { |
|
count : 31, |
|
total : 1000000 |
|
}; |
|
|
|
var box = { |
|
size : 1 |
|
}; |
|
|
|
var layout = { |
|
output : 200, |
|
padding : 0, |
|
outerPadding : 0, |
|
outline : 1, |
|
pixelperfect : false |
|
}; |
|
|
|
input = { |
|
count : getParameterByName("count"), |
|
total : getParameterByName("total"), |
|
boxsize : getParameterByName("boxsize"), |
|
size : getParameterByName("size"), |
|
pixelperfect : getParameterByName("pixelperfect"), |
|
padding : getParameterByName("padding"), |
|
outerPadding : getParameterByName("outerpadding"), |
|
outline : getParameterByName("outline") |
|
} |
|
|
|
//console.log("inputs:",input); |
|
if (isNumber(input.count)) {data.count = parseFloat(input.count);} |
|
if (isNumber(input.total)) {data.total = parseInt(input.total);} |
|
if (isNumber(input.size)) {layout.output = parseInt(input.size);} |
|
if (isNumber(input.padding)) {layout.padding = parseFloat(input.padding);} |
|
if (isNumber(input.boxsize)) {box.size = parseFloat(input.boxsize);} |
|
if (input.pixelperfect) {layout.pixelperfect = parseInt(input.pixelperfect);} |
|
if (input.outerPadding) {layout.outerPadding = parseInt(input.outerPadding);} |
|
if (input.outline) {layout.outline = parseFloat(input.outline);} |
|
var remainder = data.count % 1; |
|
|
|
layout.dim = Math.ceil(Math.sqrt(data.total)); |
|
layout.dimCount = Math.ceil(Math.sqrt(data.count)); |
|
if (data.total != layout.dim * layout.dim) { |
|
data.total = layout.dim * layout.dim; |
|
console.info("changing count to next squared integer " + data.total); |
|
} |
|
layout.innerWidth = (box.size * layout.dim) + layout.padding * (layout.dim - 1); |
|
if (layout.pixelperfect) { |
|
layout.scale = 1 |
|
} else { |
|
layout.scale = (layout.output - layout.outline * 2) / (layout.innerWidth + layout.outerPadding * 2); |
|
} |
|
layout.outline = layout.outline / layout.scale; |
|
layout.offset = layout.outerPadding + layout.outline; |
|
layout.width = layout.innerWidth + 2 * layout.offset; |
|
if (layout.pixelperfect) {layout.output = layout.width;} |
|
console.log("data:", data, "layout:", layout); |
|
|
|
d3.select("#vis").append("svg") |
|
.attr("viewBox", "0 0 " + layout.width + " " + layout.width) |
|
.attr("width", layout.output) |
|
.attr("height", layout.output); |
|
|
|
d3.select("svg").append("rect") |
|
.attr("x", layout.outline/2) |
|
.attr("y", layout.outline/2) |
|
.attr("width", layout.width - layout.outline) |
|
.attr("height", layout.width - layout.outline) |
|
.attr("stroke", "black") |
|
.attr("stroke-width", layout.outline) |
|
.attr("fill", "none") |
|
.classed("outline", true); |
|
|
|
d3.select("svg") |
|
.append("g") |
|
.classed("boxes", true); |
|
|
|
var x = 0, y = 0, c = 0; |
|
var xP; |
|
var step = box.size + layout.padding; |
|
var y0 = layout.width - layout.offset - box.size; |
|
var yP = y0; |
|
var boxes = d3.selectAll(".boxes"); |
|
var lastFull = data.count - remainder; |
|
|
|
for (y; y < layout.dimCount && y < layout.dim && c < lastFull; y++) { |
|
xP = layout.offset; |
|
for (x = 0; x < layout.dimCount && x < layout.dim && c < lastFull; x++) { |
|
c++; |
|
//console.log(c,xP,yP,y); |
|
boxes.append("rect") |
|
.attr("x", xP) |
|
.attr("y", yP) |
|
.attr("width", box.size) |
|
.attr("height", box.size) |
|
.attr("id", c); |
|
xP += step; |
|
} |
|
yP = yP - step; |
|
} |
|
//console.log(c,xP,yP,x,y,lastFull, remainder, layout.dim); |
|
if (remainder > 0) { |
|
if (x >= layout.dimCount) { |
|
xP = layout.offset; |
|
} else { |
|
yP += step; |
|
} |
|
if (lastFull < 3 && x < layout.dim ) { |
|
yP = y0; |
|
xP = layout.offset + (step * lastFull); |
|
} //no new line |
|
boxes.append("rect") |
|
.attr("x", xP) |
|
.attr("y", yP) |
|
.attr("width", box.size * remainder) |
|
.attr("height", box.size) |
|
.attr("id", data.count); |
|
} |
|
document.getElementById("count").innerHTML = data.count; |
|
if (data.total = 1000000) { |
|
document.getElementById("total").innerHTML = "a million"; |
|
} else { |
|
document.getElementById("total").innerHTML = data.total; |
|
} |
|
document.title = (data.count + " in " + data.total); |
|
} |