3

I draw many circles with some loops via d3.js

var line = d3.svg.line()
var  r = 1


var svg = d3.select("body").append("svg:svg")
    .attr("width", 1000)
    .attr("height",1000)

for ( var x=0; x< 1000 ; x+=3*r)
  {
    for ( var y=0; y< 1000 ; y+=3*r)
    {
      svg.append("circle")
          .attr("cx", x)
          .attr("cy", y)
          .attr("r", r)
    }
  }

fiddle

It seems the browser refreshes the display only after the loops have finished. Then all objects appear at once. How can I force a refresh after every element, so I can watch the progress of the image?

Thanks

1 Answers1

0

I would create the data separately and then use a transition:

var data = [];
for ( var x=0; x< 1000 ; x+=3*r) {
  for ( var y=0; y< 1000 ; y+=3*r) {
    data.push([x, y]);
  }
}

svg.selectAll("circle").data(data).enter()
   .append("circle")
   .attr("cx", function(d) { return d[0]; })
   .attr("cy", function(d) { return d[1]; })
   .attr("r", r)
   .attr("opacity", 0)
   .transition()
   .duration(100)
   .delay(function(d, i) { return i * 100; })
   .attr("opacity", 1);
Lars Kotthoff
  • 107,425
  • 16
  • 204
  • 204
  • Eh, well, `.opacity()` isn't part of D3's API, right? A stumble by the great Lars, you won't see that very often ;-) Anyway, do you have any clue as to why the circles will not be drawn one after the other using the OP's approach? – altocumulus Oct 06 '15 at 20:11
  • Thanks for spotting, fixed that -- I sometimes wish D3 would make these things less verbose to type. I would guess that the browser is optimising updating the display as the circles are added so quickly and doesn't do so for every circle, as you'd barely be able to see it anyway. – Lars Kotthoff Oct 06 '15 at 20:14
  • That works, but the problem is that I have to wait a long time before the browser starts to show anything. [link] (http://jsfiddle.net/pyf3qsfw/). I did not understand the single threaded nature of the browser. So the browser is not able to update the ui while it is busy running the javascript loop. A way around that is to return the control back to the browser link in the question [link](http://stackoverflow.com/questions/5551378/javascript-pausing-execution-of-function-to-wait-for-user-input). – Franz657587 Oct 07 '15 at 07:10
  • Your fiddle works fine for me. Note that this doesn't have anything to do with the browser being single-threaded (it isn't), but the browser optimising how things are drawn by preventing too frequent updates. – Lars Kotthoff Oct 07 '15 at 17:31