Newbie
Newbie

Reputation: 2728

Draw multiple circles using d3.js in a 3x3 format

I am trying to draw 9 circles in a 3x3 format using d3.js . Here is my script:-

<script src="//d3js.org/d3.v3.min.js"></script>
<script type="text/javascript" src="//ajax.aspnetcdn.com/ajax/jquery/jquery-1.9.0.min.js"></script>

<div class="barChart"></div>
<div class="circles"></div>
<style>

</style>
<script>

$(document).ready(function () {

        circles();
    $(".circles").show();
    function circles() {
        var svg = d3.select(".circles").append("svg");

        var data = ["Z","Z","Z","Z","Z","Z","Z","Z","Z"];
        var groups = svg.selectAll("g")
            .data(data).attr("width",100).attr("height",100)
            .enter()
            .append("g");

        groups.attr("transform", function(d, i) {
            var x = 100;
            console.log(i);
            var y = 50 * i + 100 ;

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

        var circles = groups.append("circle")
                    .attr({cx: function(d,i){
                              return 0;
                            },
                            cy: function(d,i){
                              return 0;}})

                    .attr("r", "20")
                    .attr("fill", "red")
                    .style("stroke-width","2px");

        var label = groups.append("text")
            .text(function(d){
              return d;
            })
            .style({
              "alignment-baseline": "middle",
              "text-anchor": "middle",
              "font-family":"Arial",
              "font-size":"30",
              "fill":"white"
            });
    }
});

But , I am just getting some half circles.

And also , I tried to have only one value in the data and tried to run the circles() in a loop but I got circles in a straight line with lot of spacing between them

for (var i = 0; i <=8 ;i++){
      circles();
}

And

 var groups = svg.selectAll("g")
            .data("Z").attr("width",100).attr("height",100)
            .enter()
            .append("g");

If I follow the second method, I got circles in a straight line and with lot of spacing. So how to get the circles like in the figure and with less spacing ? Can anyone please help me

Upvotes: 0

Views: 464

Answers (2)

Damien Fayol
Damien Fayol

Reputation: 958

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

Upvotes: 0

chriskelly
chriskelly

Reputation: 7736

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'});

Upvotes: 2

Related Questions