Accepted answer

Firstly, below is not entirely correct. enter will just give you nodes for which there is no existing DOM element. You would use merge (in v4) to update the already existing nodes.

When I want to create new circles and therefore update the data set of my circles I do this:

svg.selectAll("circle").data(newDataSet,function(d){return d;}).enter().append("circle")

Coming to your actual question, below would assign click listener for each of the circle dom node.

svg.selectAll("circle").data(dataArray).enter().append("circle").on("click"),function(d){// do stuff});

So, new nodes added would have to assigned new event listeners.

I think you might be missing understanding of data joins, this is an excellent read. Using data joins would look something like this:

function makeCircles(data) {
        var circles ='svg')
                .data(data, function(d) {
                    return d;


                .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() {

    var data = [1, 2, 3];
    data = [10, 15, 16];

If your concern is about assigning multiple event listeners, why not assign event listener to parent element of circles and let the events bubble?

Related Query

More Query from same tag