D3.js merge() - in depth
When starting out, the enter(), update(), exit() is one of the most difficult concepts to grasp in d3.
BUT don't be scared. It's easy once you've got your head round it.
All you need is this snippet of code:
//step 1 - JOIN (with or without a key)
var my_group = svg.selectAll('.**chart_group**')
.data(data, function(d) {return d.id; });
//step 2 - EXIT and REMOVE
my_group.exit().remove();
//step 3 - ENTER
var enter = my_group.enter().append("g").attr("class","**chart_group**");
//step 4 - APPEND
enter.append("rect").attr("class","group_rect");
enter.append("text").attr("class","group_text");
enter.append("image").attr("class","group_image");
//step 5 - MERGE
my_group = my_group.merge(enter);
- join - choose a group name (in this case chart_group) and select it
- key - if you are changing the sort order of the data you will need to use a key function.
- exit, remove this clears out any old DOM elements
- enter - this adds any new DOM elements
append - append your data dependent elements - here each row in the data has a rectangle, text and image appended
merge - merges old and new DOM elements
NB: If you are using a key, Make sure it's unique - id's are generally best.
Now you've appended the data you need to select your elements and add your properties. For example:
** my_group.select(".group_rect")**
.attr("x", d => x_scale(d.id))
.attr("y", d => (height/1.5) - y_scale(d.value))
.attr("fill",d => color_key[d.id])
.attr("width",x_scale.bandwidth()-10)
.attr("height",d => y_scale(d.value));
NB: note that you are NOT using selectAll but select. If you wanted to select all the "group_rect" at a later point you could use:
svg.selectAll(".group_rect")
This all may seem a bit overwhelming but the above is the basic principle and you can use it again and again on your choice of d3's wonderful range of charts.
Here is a bar chart demo to get you started.
P.S Make sure you check out this article updating to d3.js version 5's .join() method.