var svg = d3.select('svg'), width = +svg.attr('width'), height = +svg.attr('height'), radius = 32 var circles = d3.range(9).map(function () { return { x: Math.round(Math.random() * (width - radius * 2) + radius), y: Math.round(Math.random() * (height - radius * 2) + radius) } }) var color = d3.scaleOrdinal() .range(d3.schemeCategory10) var voronoi = d3.voronoi() .x(function (d) { return d.x; }) .y(function (d) { return d.y; }) .extent([ [-1, -1], [width + 1, height + 1] ]) var circle = svg.selectAll('g') .data(circles) .enter().append('g') .attr('class', function (d, i) { return 'g g-' + i; }) .on('click', function (d) { return console.log(d); }) var cell = circle.append('path') .data(voronoi.polygons(circles)) .attr('d', renderCell) .attr('id', function (d, i) { return 'cell-' + i; }) circle.append('clipPath') .attr('id', function (d, i) { return 'clip-' + i; }) .append('use') .attr('xlink:href', function (d, i) { return '#cell-' + i; }) circle.append('circle') .attr('clip-path', function (d, i) { return 'url(#clip-' + i + ')'; }) .attr('cx', function (d) { return d.x; }) .attr('cy', function (d) { return d.y; }) .attr('r', radius) .style('fill', function (d, i) { return color(i); }) function renderCell(d) { return d == null ? null : 'M' + d.join('L') + 'Z' } function move(sel) { d3.select(sel) .raise() .select('circle') .transition() .ease(d3.easeLinear) .duration(200) .attr('cx', function (d) { return d.x = Math.round(Math.random() * (width - radius * 2) + radius); }) .attr('cy', function (d) { return d.y = Math.round(Math.random() * (height - radius * 2) + radius); }) cell = cell.data(voronoi.polygons(circles)) .attr('d', renderCell) d3.select('span.x-value').text(d3.select(sel).datum().x) d3.select('span.y-value').text(d3.select(sel).datum().y) } d3.interval(function () { return move('.g-3'); }, 1000)