First of all, it's important to note that the statement below is not entirely accurate. Pressing enter will only provide you with nodes that do not have an existing DOM element. To update nodes that already exist, you would need to use merge (in version 4).
When I need to create new circles and update the dataset for my circles, I follow these steps:
svg.selectAll("circle").data(newDataSet, function(d) { return d; }).enter().append("circle");
Regarding your specific question, the code below will assign a click listener to each circle DOM node.
svg.selectAll("circle").data(dataArray).enter().append("circle").on("click", function(d) {/* perform actions */});
Therefore, newly added nodes will require new event listeners to be assigned.
If you are unsure about data joins, I recommend reading this article. Implementing data joins would resemble something like this:
function createCircles(data) {
var circles = d3.select('svg')
.selectAll('circle')
.data(data, function(d) {
return d;
});
circles.exit().remove();
circles.enter()
.append('circle')
.merge(circles)
.attr('r', function(d) {
return d + 5;
})
.attr('cx', function(d, i) {
return 50 + 50 * i;
})
.attr('cy', function(d, i) {
return 30;
})
.on('click', function() {
// perform actions
});
}
var data = [1, 2, 3];
createCircles(data);
data = [10, 15, 16];
createCircles(data);
If you are worried about assigning multiple event listeners, consider attaching the event listener to the parent element of the circles and allow events to bubble up.