d3.js Update data binding

There are things I don't clearly understand about data binding in d3.js.

I have set up a simple example (that can be found here) where 4 numbers are displayed:

var data0 = [1, 2, 3, 4];
var data1 = [5, 6, 7,8];
var data2 = [10, 11,12];

var lgth = 100;
var wdth = 50;
var position = [[0,0],[0,wdth], [lgth,0],[lgth,wdth]];

var svg = d3.select("#test").append("svg")
            .attr("width", wdth+100)
            .attr("height", lgth+100);

svg.selectAll("text").data(data0)
      .enter().append("text")
      .text(function(d){return d;})
      .attr("x",function(d,i){return position[i][0]+30;})
      .attr("y",function(d,i){return position[i][1]+30;});

However when I try to update these 4 numbers using that function:

function draw1(){
svg.selectAll("text").data(data1)
      //.enter().append("text") /* if not commented does nothing*/
      .text(function(d){return d;})
      .attr("x",function(d,i){return position[i][0]+30;})
      .attr("y",function(d,i){return position[i][1]+30;});
}

it works only if .enter().append("text") is commented. Why ? What if there are less data in the new binding than in the previous one ?

Thanks a lot in advance for the explanation !

1 answer

  • answered 2017-01-11 14:23 Mohammed Imran

      svg.selectAll("text").data(data0)
      .enter().append("text")
      .text(function(d){return d;})
      .attr("x",function(d,i){return position[i][0]+30;})
      .attr("y",function(d,i){return position[i][1]+30;});
    

    .enter().append("text") will create new elements as needed. Here in this case both arrays data0 and data1 have same number of elements so there is no need of new text elements d3 will just update the values. Hence no need of .enter().append("text")

      svg.selectAll("text").data(data1)
      .text(function(d){return d;})
      .attr("x",function(d,i){return position[i][0]+30;})
      .attr("y",function(d,i){return position[i][1]+30;});
    

    You should add the following line in draw1() for exit which will remove old elements(if there is less data in new binding)

    svg.selectAll("text").exit().remove()
    

    I recommend you to refer the following example for understanding the process more clearly: https://bl.ocks.org/mbostock/3808218