|
<!DOCTYPE html> |
|
<meta charset="utf-8"> |
|
<style> |
|
|
|
.hexagon { |
|
fill: none; |
|
stroke: #000; |
|
stroke-width: .5px; |
|
} |
|
|
|
</style> |
|
<body> |
|
<script src="http://d3js.org/d3.v3.min.js"></script> |
|
<script src="http://d3js.org/d3.hexbin.v0.min.js"></script> |
|
<script> |
|
|
|
var width = 960, |
|
height = 500, |
|
i = -1, |
|
θ = 0, |
|
δθ = .03, |
|
n = 2000, |
|
k = 20; // samples to replace per frame |
|
|
|
var randomX = d3.random.normal(width / 2, 80), |
|
randomY = d3.random.normal(height / 2, 80), |
|
points = d3.range(n).map(function() { return [randomY(), randomX()]; }); |
|
|
|
var color = d3.scale.linear() |
|
.domain([0, 20]) |
|
.range(["white", "steelblue"]) |
|
.interpolate(d3.interpolateLab); |
|
|
|
var hexbin = d3.hexbin() |
|
.size([height, width]) |
|
.radius(20); |
|
|
|
var svg = d3.select("body").append("svg") |
|
.attr("width", width) |
|
.attr("height", height); |
|
|
|
var hexagon = svg.append("g") |
|
.attr("class", "hexagons") |
|
.selectAll("path") |
|
.data(hexbin(points)) |
|
.enter().append("path") |
|
.attr("d", hexbin.hexagon(19.5)) |
|
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")rotate(90)"; }) |
|
.style("fill", function(d) { return color(d.length); }); |
|
|
|
d3.timer(function() { |
|
θ += δθ; |
|
randomX = d3.random.normal(width / 2 + 80 * Math.cos(θ), 80), |
|
randomY = d3.random.normal(height / 2 + 80 * Math.sin(θ), 80); |
|
|
|
for (var j = 0; j < k; ++j) { |
|
i = (i + 1) % n; |
|
points[i][0] = randomY(); |
|
points[i][1] = randomX(); |
|
} |
|
|
|
hexagon = hexagon |
|
.data(hexbin(points), function(d) { return d.i + "," + d.j; }); |
|
|
|
hexagon.exit().remove(); |
|
|
|
hexagon.enter().append("path") |
|
.attr("d", hexbin.hexagon(19.5)) |
|
.attr("transform", function(d) { return "translate(" + d.y + "," + d.x + ")rotate(90)"; }); |
|
|
|
hexagon |
|
.style("fill", function(d) { return color(d.length); }); |
|
}); |
|
|
|
</script> |