// 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); }