truoger
truoger

Reputation: 95

Loop through array to append circles using d3

I have an array consisting of multiple pairs of lat/lon coordinates that I would like to loop through, using d3 to append circle to the map for each coordinate pair in the array.

Here is what I have so far:

var aa = [[-122.490402, 37.786453],[-149.882154, 61.138793]];
console.log(aa[0]);
console.log(aa[1]);

var breweryCircles = [];
for (i=0;i<=aa.length;i++) {
    breweryCircles.push(aa[i]);


    g.selectAll("circle")
        .data(breweryCircles)
        .enter()
        .append('circle')
        .attr("cx", function (d) { return projection(breweryCircles)[0]; })
        .attr("cy", function (d) { return projection(breweryCircles)[1]; })
        .attr("r", "2px")
        .attr("fill", "red")            
};

One circle will draw, but I get an error message in the console for the second circle

Upvotes: 3

Views: 3222

Answers (1)

Gerardo Furtado
Gerardo Furtado

Reputation: 102194

As a general rule, when you write a D3 code, you normally don't need any kind of loop. Of course, we use loops sometimes, but in very specific situations and to solve very specific problems.

That being said, simply bind the data to create your circles in the enter selection. This is the "D3 way", which will append as many circles as the length of your data array:

var circles = svg.selectAll(null)
    .data(aa)
    .enter()
    .append("circle")

And that's all you need. Drop that for loop, which is not only unnecessary but also will hinder your D3 learning process.

Here is a demo (the data array has no geographic coordinates, just the SVG coordinates, but the principle is the same):

var aa = [[20, 37],[40, 61],[203, 77], [143, 107]];

var svg = d3.select("svg");

var circles = svg.selectAll(null)
    .data(aa)
    .enter()
    .append("circle")
    
circles.attr("cx", d=>d[0])
    .attr("cy", d=>d[1])
    .attr("r", 5)
    .attr("fill", "teal")
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

PS: Your code, although not the best D3 practice, is working. The error you're getting is simply due to the fact that you're using <= in the for loop, when you should use just <. Have a look at your code with that change:

var aa = [[20, 37],[40, 61],[203, 77], [143, 107]];

var svg = d3.select("svg");

var breweryCircles = [];
for (i = 0; i < aa.length; i++) {
//use < here--^
    breweryCircles.push(aa[i]);

    svg.selectAll("circle")
        .data(breweryCircles)
        .enter()
        .append('circle')
        .attr("cx", function(d) {
            return d[0];
        })
        .attr("cy", function(d) {
            return d[1];
        })
        .attr("r", 5)
        .attr("fill", "red")
};
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

Upvotes: 6

Related Questions