I'm struggling to grasp the concept of updating only those d3
nodes where the data has changed. Despite my efforts, I still can't seem to get it right. In the test example provided below, I am noticing that everything is being updated instead of just the required nodes.
Could it be possible that I am approaching this problem entirely wrong or am I simply making a small mistake?
In this particular example, clicking on a shape toggles its form between a circle and square while also updating a "clickCnt" property associated with it. Subsequently, the data is redrawn. Although the functionality partially works, it appears that everything is getting redrawn. Additionally, there seems to be an issue when clicking on the "red" shape even though the code is identical to that of the other shapes.
var nodeData = [];
nodeData.push({ "type": 'red', "shape": "circle", "clickCount": 0, x: 30, y: 100 });
nodeData.push({ "type": 'orange', "shape": "square", "clickCount": 0, x: 110, y: 100 });
nodeData.push({ "type": 'yellow', "shape": "circle", "clickCount": 0, x: 210, y: 100 });
nodeData.push({ "type": 'green', "shape": "square", "clickCount": 0, x: 310, y: 100 });
// Additional node data entries...
var width = 400;
var height = 400;
d3.select("div#svg-container").select("svg").remove();
var svg = d3.select("#svg-container").append("svg")
.attr("width", width)
.attr("height", height);
var content = svg.append("g")
function render(data) {
var groups = content.selectAll("g")
.data(data, function (d) {
return d;
});
groups.exit().remove();
groups.enter()
.append("g")
.attr('transform', function (d, i) {
return 'translate(' + d.x + ',' + d.y + ')'
})
.each(function (d) {
// Code for appending text, shapes, click handling, etc.
});
}
render(nodeData);
function handleIconClick(evt) {
if (evt.shape == "circle") {
evt.shape = "square"
} else if (evt.shape == "square") {
evt.shape = "circle"
}
evt.clickCount++;
document.getElementById('output').innerHTML = "Item clicked: " + evt.type + " " + evt.clickCount;
render(nodeData);
}
.circle {
stroke: red;
stroke-width: 2px;
}
.square {
stroke: blue;
stroke-width: 2px;
}
#timeline-background {
background: slategray;
}
.label {
fill: blue;
}
.small-text {
font-size: 16px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<body>
<label id="output">out</label>
<div id="timeline-background" style="width: 100%; height: 100%;">
<div id="svg-container"></div>
</div>
</body>