Built with blockbuilder.org
xxxxxxxxxx
<head>
<meta charset="utf-8">
<script src="https://d3js.org/d3.v4.min.js"></script>
<style>
body { margin:0;position:fixed;top:0;right:0;bottom:0;left:0;
}
svg { background: white; }
.poly {opacity:.3;fill:none}
.spread {opacity: .1 }
</style>
</head>
<body>
<script>
(function() {
var options = {
width: 960,
height: 500,
points: 25,
iterations: 50,
colorScale: d3.interpolateRgb('#0d0', '#22f'),
modes: ['spread', 'point'], // Valid: "spread", "line", "point"
pointSize: 3,
filterPolygons: function(step) {
var last = options.iterations - 1;
return step == 0 || step == last;
}
};
var points = [];
var width = options.width, height = options.height;
var count = options.points;
while(count-- > 0) {
points.push([
Math.random() * width,
Math.random() * height
]);
};
var layers = [points];
var voronoi = d3.voronoi().size([width, height]);
var iterations = options.iterations;
while(iterations-- > 0) {
points = voronoi.polygons(points).map(function(poly) {
return d3.polygonCentroid(poly);
});
layers.push(points);
}
var scale = d3.scaleSequential(options.colorScale).domain([0, options.iterations]);
var $svg = d3.select('body').append('svg')
.attr('width', options.width)
.attr('height',options.height);
$svg.selectAll('.layer')
.data(layers)
.enter()
.append('g')
.attr('class', 'layer')
.each(function(layer, step) {
var color = scale(step);
if(options.filterPolygons(step)) {
d3.select(this)
.append('g')
.attr('class', 'polys')
.selectAll('.poly')
.data(function() { return voronoi.polygons(layer);})
.enter()
.append('path')
.attr('class', 'poly')
.attr('stroke', color)
.attr('fill', color)
.attr('d', function(poly) {
return 'M' + poly.map(function(point) {
return point.join(',');
}).join('L') + 'Z';
});
}
var enter = d3.select(this).selectAll()
.data(function(points) {return points;})
.enter();
options.modes.map(function(mode) {
switch(mode) {
case 'spread':
return enter
.append('path')
.attr('class', 'spread')
.attr('d', function(p, i) {
return 'M' + layers[0][i].join(',') + 'L' + p.join(',');
})
.attr('stroke', color);
case 'line':
return enter
.append('path')
.attr('class', 'line')
.attr('d', function(p, i) {
var prev = step ? layers[step - 1][i] : p;
return 'M' + prev.join(',') + 'L' + p.join(',');
})
.attr('stroke', color);
case 'point':
return enter
.append('circle')
.attr('class', 'point')
.attr('r', options.pointSize * .5)
.attr('fill', color)
.attr('cx', function(p) {return p[0]})
.attr('cy', function(p) {return p[1]});
}
});
});
}());
</script>
</body>
https://d3js.org/d3.v4.min.js