Sumeet Kumar Yadav
Sumeet Kumar Yadav

Reputation: 12985

d3.js v5 enter update not inserting rectangle div

I am using d3.js v5 version and trying to understand enter, update. I have two data set [1,2,3.5] and other [1,2,3,4,5] . Firstly I am calling first data which renders [1,2,3.5 ] in red color and then second data is called with blue color[1,2,3,4,5] .

On update why 3 is not getting inserted in blue?

              var scale = d3.scaleLinear().domain([1,5]).range([0,200]);
            
            
              var svg = d3.select("body")
                          .append("svg")
                          .attr("width",250)
                          .attr("height",250);
            
            function render(data,color){
                 // Bind data
                 var rects = svg.selectAll("rect").data(data);
                 
                 //Enter 
                 
                rects =  rects.enter().append("rect");
                
                //update
                rects.attr("x", scale)
                .attr("y",50)
                .attr("width",20)
                .attr("height",20)
                .attr("fill",color);
            };
             
            render([1,2,3.5],"red");
            render([1,2,3,4,5],"blue");
<script src="https://d3js.org/d3.v5.min.js"></script>

Upvotes: 3

Views: 1232

Answers (1)

Yaroslav Sergienko
Yaroslav Sergienko

Reputation: 720

This is because you are re-assigning rects to rects.enter(). Initially rects contains "updated" rectangles. What you want is to get both "enter" and "update", which can be done with merge.

var scale = d3.scaleLinear().domain([1,5]).range([0,200]);
            
var svg = d3.select("body")
            .append("svg")
            .attr("width",250)
            .attr("height",250);

function render(data,color){
    // update
    var rects = svg.selectAll("rect").data(data, d => d);

    // enter 
    rects
      .enter().append("rect")
      // enter + update
      .merge(rects)
        .attr("x", scale)
        .attr("y",50)
        .attr("width",20)
        .attr("height",20)
        .attr("fill",color);
};

render([1,2,3.5],"red");
render([1,2,3,4,5],"blue");
<script src="https://d3js.org/d3.v5.min.js"></script>

Edit: By default, when you call .data(...) d3 joins by index, so 3.5 becomes 3. If you want to join by numerical value , so that 3, 4 and 5 get inserted, you can pass second parameter to .data (read more
https://github.com/d3/d3-selection#selection_data)

Upvotes: 2

Related Questions