score:0

Accepted answer

The simplest way to fix your code is to modify the groups transform

groups.attr("transform", function(d, i) {
    var x = (i % 3) * 100 + 200; // x varies between 200 and 500
    var y = 50 * Math.floor(i / 3) + 100 ; // y varies between 100 and 250

    return "translate(" + [x,y] + ")";
});

Here, i will loop between 0 and 8 because you have 8 elements in your data variable, in the x assigment, i%3 is worth 0,1,2,0,1,2,0,1,2, and in the y assignement, Math.floor(i / 3) is worth 0,0,0,1,1,1,2,2,2 so you basically get a 2D grid :

0,0 1,0 2,0
1,0 1,1 2,1
2,0 2,1 2,2

score:2

Your transform function is positioning your elements in a line instead of a grid. If you log out what you are translating you will see whats happening. i.e.

console.log("translate(" + [x,y] + "");
/* OUTPUTS
translate(100,100)
translate(100,150)
translate(100,200)
translate(100,250)
translate(100,300)
translate(100,350)
translate(100,400)
translate(100,450)   
translate(100,500)
translate(100,100)
*/

They are being stacked one on top of the other vertically.

You can modify the transform function by changing the following lines:

var x = 100 + (50* Math.floor(i/3));           
var y = 50 * (i%3) + 20 ;

Finally, the SVG container is clipping your drawing so you are seeing only half of anything below 150px.

You can modify the width as follows:

var svg = d3.select(".circles")
            .append("svg")
            .attr({"height": '300px'});

Related Query

More Query from same tag