0

I am using d3.js to make data visualization but I am not a JavaScript programmer so I wrote something like the following

        for(var i =0;i<6;i++){
          setTimeout(function(){
            var in = data[0][i];
            slate(" + margin.left + "," + margin.top + ")");
            var svg = d3.select("#clustering").append("svg")
                    .attr("width", width + margin.left + margin.right)
                    .attr("height", height + margin.top + margin.bottom)
                    .append("g")
                    .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
            svg.append("rect")
                    .attr("width", width)
                    .attr("height", height);

            svg.append("g")
                    .attr("class", "x axis")
                    .attr("transform", "translate(0," + height + ")")
                    .call(xAxis);

            svg.append("g")
                    .attr("class", "y axis")
                    .call(yAxis);

            var color = d3.scale.category10();
            refreshGraph();
                },1000);
            }
        /*
        * function displaying data on svg
        * called every time data change
        */
        var refreshGraph = function(){

            // removing all previously drawn dots
            svg.selectAll(".dot")
            .data(instruments)
            .exit()
            .remove();
          }

But I got this error Uncaught Reference Error: svg is not defined I know the function refreshGraph can not see the var svg, but I don't know how to fix this. Thank you for your help.

divo
  • 97
  • 1
  • 7
  • When you use setTimeout in a loop I believe you need to make it into anonymous function using variable. I had similar issue but not with d3 – Riddell Jul 26 '16 at 09:01
  • 2
    "I know the function refreshGraph can not see the var svg" — Nor can anything else. It doesn't appear anywhere in the code you shared. – Quentin Jul 26 '16 at 09:01
  • Well, in this piece of code, I don't see svg defined anywhere... – beerwin Jul 26 '16 at 09:01
  • 1
    @Riddell: That's not the problem the OP is asking about. But it *is* the *next* problem they'd have. Omar: For more on that, see: http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example – T.J. Crowder Jul 26 '16 at 09:01
  • @Riddell as I said I am not a JavaScript programmer can you please explain in code. thank you – divo Jul 26 '16 at 09:02
  • @Quentin I edited the code snippet – divo Jul 26 '16 at 09:05
  • try Console.Log(svg) and see if it's defined on each loop cycle. Use Chrome Devtools and set up some breakpoints – Riddell Jul 26 '16 at 09:06
  • @beerwin I edited the code snippet – divo Jul 26 '16 at 09:06
  • @Riddell it's defined inside the loop but it's not inside the function refreshGraph() – divo Jul 26 '16 at 09:07
  • [var svg] define the svg variable above your loop. then in your loop change it to svg = d3.select("#clustering").append("svg") – Riddell Jul 26 '16 at 09:08

1 Answers1

3

Either:

  • Define the function you assign to refreshGraph inside the function you pass to setTimeout so that svg is still in scope or
  • Declare svg outside the loop entirely so it remains in scope or
  • Pass svg to that function as an argument when you call it
Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335