Reputation: 12985
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
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