var ƒ = d3.f d3.tsv('data.tsv', function(error, data) { d3.selectAll('svg').remove() var c = d3.conventions() c.x.domain(d3.extent(data, ƒ('sepalWidth'))) c.y.domain(d3.extent(data, ƒ('sepalLength'))) c.drawAxis() var s = 4 var collide = d3.forceRectCollide(function(d){ return [ [-d.sepalWidth*s/2, -d.sepalLength*s/2], [ d.sepalWidth*s/2, d.sepalLength*s/2] ]}) var simulation = d3.forceSimulation(data) .force('x', d3.forceX(ƒ('sepalWidth', c.x)).strength(.1)) .force('y', d3.forceY(ƒ('sepalLength', c.y)).strength(.1)) .force('collide', collide) for (var i = 0; i < 400; ++i) simulation.tick() c.svg.appendMany(data, 'rect.dot') .each(function(d){ var w = d.sepalWidth *s var h = d.sepalLength*s d3.select(this) .attr('x', d.x - w/2) .attr('y', d.y - h/2) .attr('width', w) .attr('height', h) }) .style('fill', ƒ('species', d3.scaleOrdinal().range(d3.schemeCategory10))) .call(d3.attachTooltip) })