Reputation: 2728
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
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
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