I've been trying to refactor my code such that instead of removing all the elements and replacing them like I have been doing, I update the container's data and positions. I've used this tutorial to understand how to handle data selections, however I'm still having trouble understanding how to update or exit data selections. I have two main questions about this:
How do I correctly add attributes to where I update the data?
When I update the data, how do I choose to append the data to the rectangles?
All of the following code is within a click function of a different element. Below is where I first create the selection which should run the first time the element is clicked.
var update = function () {
if (firstClick == true) {
firstClick = false;
magBox = svgContainer.selectAll("svg")
.data(containerViewer)
.enter()
.append("rect")
.attr("width", 10)
.attr("height", 10)
.attr("y", -1000)
.attr("width", ((max_x / 3.5) / selectedContainer[1].length))
// sets height of magBox to a percentage of the total waterfall height
.attr("height", ((max_x / 3.5) / 1.7) / arrayMagnified)
// sets the position left from
.attr("x", function () {
lencount++;
if (lencount == parseInt(containerViewer.length / arrayMagnified)) {
console.log(lencount);
lencount = 0;
}
if (d3.event.pageX / max_x - 0.01 >= 0.5) {
return -(rectSize * 2) + (lencount * ((max_x / 3.5) / selectedContainer[1].length));
}
else {
return (rectX - (magFrameWidth * 0.9)) + (lencount * ((max_x / 3.5) / selectedContainer[1].length));
}
})
.attr("y", function (d, i) {
// height of each magBox pixel
var pixelHeight = ((max_x / 3.5) / 1.7) / arrayMagnified;
// uses i to iterate in relation to array length
var iterator = parseInt(i / selectedContainer[1].length);
if (selected > (rawDataStore.length) / 2) {
return (-(rectSize * 2) + pixelHeight * iterator);
}
else {
return ((rectY - magFrameHeight * 0.8) + pixelHeight * iterator);
}
})
.style("fill", function (d) {
negativeColors = -1 * d;
invertedColors = normalize_value(negativeColors, -(rmax), -(rmin), 0, 255);
return "rgb(" + 255 + "," + (parseInt(invertedColors)) + "," + 0 + ")";
});
}
After the first time this runs, it should then go to the following else condition which updates the data every consecutive time this is clicked:
else {
magBox.data(containerViewer);
d3.selectAll(".magContainer").moveToFront();
}
};
update();
Currently, it works the first time but then doesn't update the data or replace the attributes. When I try entering, appending, and adding attributes to the "else" section of the code, it creates a new selection as opposed to updating the first one.
If there's any additional things I'm missing conceptually, I'd be happy to know!