Accepted answer

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 ="body")

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

    // enter 
      // enter + update
        .attr("x", scale)

<script src=""></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

Related Query