Skip to content

Instantly share code, notes, and snippets.

@HarryStevens
Last active December 2, 2017 06:16
Show Gist options
  • Save HarryStevens/81e7699d43b2373ba805e23c5eafa21e to your computer and use it in GitHub Desktop.
Save HarryStevens/81e7699d43b2373ba805e23c5eafa21e to your computer and use it in GitHub Desktop.
Grid Generator
license: gpl-3.0
<!DOCTYPE html>
<html>
<head>
<style>
body {
margin: 0 auto;
display: table;
font-family: "Helvetica Neue", sans-serif;
}
button {
margin: auto;
display: table;
margin-bottom: 10px;
}
rect.selected {
stroke: #000;
stroke-width: 2px;
}
.axis .domain {
display: none;
}
.axis .tick text.selected {
font-weight: bold;
font-size: 1.2em;
fill: #47ff63;
}
.axis .tick line.selected {
stroke: #47ff63;
}
.tip {
position: absolute;
font-size: .8em;
text-align: center;
text-shadow: -1px -1px 1px #ffffff, -1px 0px 1px #ffffff, -1px 1px 1px #ffffff, 0px -1px 1px #ffffff, 0px 1px 1px #ffffff, 1px -1px 1px #ffffff, 1px 0px 1px #ffffff, 1px 1px 1px #ffffff;
}
</style>
</head>
<body>
<button id="new">New grid</button>
<div id="grid"></div>
<script src="https://d3js.org/d3.v4.min.js"></script>
<script src="https://unpkg.com/jeezy@1.11.2/lib/jeezy.min.js"></script>
<script src="https://unpkg.com/data2grid@1.0.0/build/data2grid.min.js"></script>
<script>
d3.select("body").append("div").attr("class", "tip").style("display", "none");
var first_time = true;
var margin = {top: 20, bottom: 1, left: 20, right: 1};
var dim = d3.min([window.innerWidth * .9, window.innerHeight * .9]);
var width = dim - margin.left - margin.right, height = dim - margin.top - margin.bottom;
var svg = d3.select("#grid").append("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom)
.append("g")
.attr("transform", "translate(" + margin.left + ", " + margin.top + ")");
var padding = .1;
var x = d3.scaleBand()
.range([0, width])
.paddingInner(padding);
var y = d3.scaleBand()
.range([0, height])
.paddingInner(padding);
var x_axis = d3.axisTop(y);
var y_axis = d3.axisLeft(x);
svg.append("g")
.attr("class", "x axis")
.call(x_axis);
svg.append("g")
.attr("class", "y axis")
.call(y_axis);
function generateData(){
var data = [];
["steelblue", "tomato", "lightgrey"].forEach(function(color){
for (var i = 0; i < (first_time ? 147 : jz.num.randBetween(10, 3000)); i++){
data.push({color: color});
}
});
data.forEach(function(d, i){
d.id = i;
return d;
});
if (first_time) first_time = false;
return data;
}
draw(generateData());
d3.select("button").on("click", function(){
draw(generateData());
});
function draw(data){
var grid = data2grid.grid(data);
var rows = d3.max(grid, function(d){ return d.row; });
x.domain(d3.range(1, rows + 1));
y.domain(d3.range(1, rows + 1));
d3.select(".x.axis").transition().call(x_axis);
d3.select(".y.axis").transition().call(y_axis)
var square = svg.selectAll("rect")
.data(grid, function(d){ return d.id; });
square.exit()
.transition()
.style("opacity", 1e-6)
.remove();
square
.transition()
.attr("x", function(d){ return x(d.column); })
.attr("y", function(d){ return y(d.row); })
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.style("fill", function(d){ return d.color; });
square.enter().append("rect")
.attr("x", function(d){ return x(d.column); })
.attr("y", function(d){ return y(d.row); })
.attr("width", x.bandwidth())
.attr("height", y.bandwidth())
.style("fill", function(d){ return d.color; })
.style("opacity", 1e-6)
.transition()
.style("opacity", 1)
d3.selectAll("rect")
.on("mouseover", function(d){
d3.select(this).classed("selected", true);
d3.select(".tip")
.style("display", "block")
.html("Row: " + d.row + "<br />Column: " + d.column);
var row_pos = y(d.row);
var col_pos = x(d.column);
var tip_pos = d3.select(".tip").node().getBoundingClientRect();
var tip_width = tip_pos.width;
var tip_height = tip_pos.height;
var grid_pos = d3.select("#grid").node().getBoundingClientRect();
var grid_left = grid_pos.left;
var grid_top = grid_pos.top;
var left = grid_left + col_pos + margin.left + (x.bandwidth() / 2) - (tip_width / 2);
var top = grid_top + row_pos + margin.top - tip_height - 5;
d3.select(".tip")
.style("left", left + "px")
.style("top", top + "px");
d3.select(".x.axis .tick:nth-of-type(" + d.column + ") text").classed("selected", true);
d3.select(".y.axis .tick:nth-of-type(" + d.row + ") text").classed("selected", true);
d3.select(".x.axis .tick:nth-of-type(" + d.column + ") line").classed("selected", true);
d3.select(".y.axis .tick:nth-of-type(" + d.row + ") line").classed("selected", true);
})
.on("mouseout", function(){
d3.selectAll("rect").classed("selected", false);
d3.select(".tip").style("display", "none");
d3.selectAll(".axis .tick text").classed("selected", false);
d3.selectAll(".axis .tick line").classed("selected", false);
});
}
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment