Skip to content

Instantly share code, notes, and snippets.

@alexmacy
Last active December 1, 2016 17:31
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alexmacy/05bce18b77003ce39217a7ba33b52ac8 to your computer and use it in GitHub Desktop.
Save alexmacy/05bce18b77003ce39217a7ba33b52ac8 to your computer and use it in GitHub Desktop.
Voronoi Sorting v2 update for d3.unconf badge
license: gpl-3.0
<!DOCTYPE html>
<meta charset="utf-8">
<head>
<style>
body {
background-color: black;
margin: 0;
}
path {
fill-opacity: .75;
stroke: white;
}
</style>
<script src="//d3js.org/d3.v4.min.js"></script>
<script src="//d3js.org/d3-scale-chromatic.v1.min.js"></script>
</head>
<body></body>
<script>
var width = window.innerWidth,
height = window.innerHeight,
samples = [],
minMax;
var voronoi = d3.voronoi()
.size([width, height])
var schemes = ["interpolateBlues", "interpolateGreens", "interpolateGreys",
"interpolateOranges", "interpolatePurples", "interpolateReds",
"interpolateBuGn", "interpolateBuPu", "interpolateGnBu",
"interpolateOrRd", "interpolatePuBuGn","interpolatePuBu",
"interpolatePuRd", "interpolateRdPu", "interpolateYlGnBu",
"interpolateYlGn", "interpolateYlOrBr", "interpolateYlOrRd"]
//the size of the polygon will determine it's fill color - and later, it's placement along the x axis
var logForColor = d3.scaleLog().range([1,0]),
color = d3[schemes[Math.floor(d3.randomUniform(0,schemes.length)())]],
y = d3.scaleLog().range([height,0]);
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
getData();
var paths = svg.selectAll("path")
.data(samples)
.enter().append("path")
paths.attr("transform", "translate(0,0)")
.attr("d", function(d, i) {return getPath(samples[i].sample); })
.style("fill", function(d, i) {return color(logForColor(samples[i].area));})
function getData() {
//if loading data for the first time, generate an array of random coordinates
if (!samples.length) {
for (i=0; i<500; i++) {samples[i] = [Math.random() * width, Math.random() * height];}
//otherwise, update the x coordinate based on the polygon's size
} else {
for (i in samples) {samples[i] = [samples[i].point[0], y(samples[i].area)];}
}
//create new polygons and bind them and their calculated area to the main data array
var voronoiData = voronoi(samples).polygons();
for (i in voronoiData) {
samples[i] = {
point: samples[i],
sample: voronoiData[i],
area: d3.polygonArea(voronoiData[i]),
}
}
//set the domain of the scales by finding the min and max area values
minMax = d3.extent(samples, function(d) {return d.area;});
logForColor.domain([minMax[1],minMax[0]])
y.domain(minMax);
}
//create the paths for the polygons
function getPath(points) {
//redrawing the polygons was causing some unwanted effects when transitioning a polygon to a new shape that has more sides. this was because the new points would be drawn off screen before transitioning into place.
//my solution was to default each polygon to having more points than (hopefully) necessary, with the extra points placed on top of each other. this is potentially not performant as it creates multiple points in the same location.
var thisPath = "M" + points[0];
for (n=1; n<15; n++) {
thisPath += "L" + (n < points.length ? points[n] : points[0])
}
return thisPath;
}
var sortShapes = function() {
color = d3[schemes[Math.floor(d3.randomUniform(0,schemes.length)())]]
//slide the polygons into order of size along the x-axis according to the log scale
paths.transition().duration(2000)
.attr("transform", function(d, i) { return "translate(0," + (-samples[i].point[1] + y(samples[i].area)) + ")"})
//re-calculate the voronoi polygons and their sizes based on the new positions
getData();
//transition to the new sizes and shapes
paths.transition().delay(2000).duration(2000)
.attr("transform", "translate(0,0)")
.attr("d", function(d, i) {return getPath(samples[i].sample);})
.style("fill", function(d, i) {return color(logForColor(samples[i].area));})
//loop the sorting process
d3.timeout(sortShapes, 6000);
}
d3.timeout(sortShapes, 2000);
</script>
@alexmacy
Copy link
Author

alexmacy commented Dec 1, 2016

test comment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment