console.clear() var ƒ = d3.f var width = 600, height = 600 var color = d3.scaleLinear() .domain([0, 100]) .range(['purple', 'orange']) d3.select('#graph').html('') d3.loadData('britain-points.csv', 'constituencies.json', function(err, res) { if (true || !data){ data = res[1].map(d => d.geo.properties.geoCentroid.map(d => d * 0.5)) data.forEach(p => { p.closest = _.sortBy(data, q => dist(p, q)).slice(0, 100) p.closest = data.filter(q => dist(p, q) < 100) }) } data = _.sortBy(data, p => dist(p, [280, 400])) data.forEach(d => { d.offset = [0, 0] }) steps = 0 if (window.sInterval) sInterval.stop() sInterval = d3.interval(drawStep, 100) drawStep() function drawStep(){ hexs = hexbin().size([width, height]).radius(7).centers() data.forEach(p => { p.offsetX = d3.mean(p.closest, d => d.offset[0]) p.offsetY = d3.mean(p.closest, d => d.offset[1]) p.offsetPos = add(p, [p.offsetX*-.8, p.offsetY*-.8]) }) var tempData = steps % 2 ? _.sortBy(data, p => dist(p, [280, 400])) : d3.shuffle(data) var randomCord = [width*Math.random(), height*Math.random()] tempData = _.sortBy(data, p => dist(p, randomCord)) tempData .forEach((p, i) => { var minDist = 1e16 var minH = null // console.log(p, [offsetX, offsetY], pos) hexs.forEach(h => { if (h.p) return var curDist = dist(h, p.offsetPos) if (curDist < minDist) { minDist = curDist minH = h } }) minH.p = p p.i = i p.dist = minDist p.offset = subtract(p, minH) }) d3.select('#graph').append('svg').at({ width, height }) .appendMany(hexs.filter(d => d.p), 'circle') .translate(ƒ()) .at({ r: h => 6, fill: h => color(h.p.dist) }) // if (steps++ > 18) sInterval.stop() } }) function dist([x0, y0], [x1, y1]) { var xDif = x0 - x1 var yDif = y0 - y1 return Math.sqrt(xDif * xDif + yDif * yDif) } function subtract([x0, y0], [x1, y1]){ return [x0 - x1, y0 - y1] } function add([x0, y0], [x1, y1]){ return [x0 + x1, y0 + y1] }