d3.jseachselectall

How to use .each in d3?


Could you explain to me why the first script does not work? Firebug says "d is undefined". Val is a two-dimensional array after selectall.

<script type="text/javascript">
        setInterval(function() {
            d3.json("./cgi-bin/script1.sh?shmid=" + node.value, function(error, txt){
                if (error) return console.warn(error);

                table = d3.select("#shmid" + node.value);
                val = table.selectAll(".val")

                val.each(function(d,i){
                    console.debug(d,i)
                    d.text(txt.bd[i].val);
                });

                node = node.next;
            })
        }, 500);

    </script>

Working variant:

<script type="text/javascript">
        setInterval(function() {
            d3.json("./cgi-bin/script1.sh?shmid=" + node.value, function(error, txt){
                if (error) return console.warn(error);

                table = d3.select("#shmid" + node.value);
                val = table.selectAll(".val")

                val.each(function(d,i){
                    console.debug(d,i)
                    d3.select(this).text(txt.bd[i].val);
                });

                node = node.next;
            })
        }, 500);

    </script>

Solution

  • From the documentation:

    Invokes the specified function for each element in the current selection, passing in the current datum d and index i, with the this context of the current DOM element.

    In the first case you're using d incorrectly -- it refers to the data bound to the element, not the element itself. In your case, you haven't bound any data to it, so there's nothing to reference.

    It looks like you're trying to do the following:

    table = d3.select("#shmid" + node.value);
    table.selectAll(".val").data(txt.bd)
         .text(function(d) { return d.val; });
    

    This will first bind the data to the elements you're working with and then use the bound data to set the text.