How to assign click event to every svg element in d3js

11,772

Solution 1

for (var index in nodeValues) {
    var rect = svg.append("rect")
        .attr(elementAttr(index))
        .style("fill", "red" )
        .on('click', function(d,i) {
            // handle events here
            // d - datum
            // i - identifier or index
            // this - the `<rect>` that was clicked
        });
}

Solution 2

I've refactored your code to be more D3-like -- in particular, you don't need a loop if you use D3's selections and data matching. The code then looks like this:

svg.selectAll("rect")
    .data(nodeValues).enter().append("rect")
    .each(function(d) {
        var attrs = elementAttr(d);
        d3.select(this).attr(attrs);
    })
    .style("fill", rectColor);

Adding the click handler is just an additional statement at the end of this:

    .on("click", function() {
        d3.select(this).attr("width", 120);
    });

Complete demo here.

Solution 3

I gave a vote to Stephen's answer but it's actually just missing one part - instead of .click, it's

.on("click", function(d){...

Here's some documentation. Also, I've jacked Mike's example of zooming with circles in order to implement the binder listener. Here's a fiddle that shows it.

Hope that helps!

Share:
11,772
vjdhama
Author by

vjdhama

I am a product engineer working at GOJEK. Check out my blog : https://medium.com/@vjdhama

Updated on July 25, 2022

Comments

  • vjdhama
    vjdhama almost 2 years

    I have added nine rectangles in a svg element. How do i add click event to each one?

    var nodeValues = [0, 1, 2, 3, 4, 5, 6, 7, 8];
    
    var colors = ["aqua", "darkblue", "black", "red", "green", "gray", "navy", "orange", "teal"];
    
    var main = d3.select("#main");
    
    var svg = main.append("svg")
        .data(nodeValues)
        .attr("width", 300)
        .attr("height", 300);
    
    var elementAttr = function (index) {
        return {
            x: (index % 3) * 100,
            y: Math.floor((index / 3)) * 100,
            width: 95,
            height: 95
        }
    }
    
    for (var index in nodeValues) {
        var rect = svg.append("rect")
            .attr(elementAttr(index))
            .style("fill", "red" );
    }
    

    Here is the Jsfiddle.

    UPDATE : I wish to change attributes like width of rectangle on a click event.

  • vjdhama
    vjdhama over 9 years
    i tried using .click but i doesn't seem to work. Can you post working jsfiddle link.
  • vjdhama
    vjdhama over 9 years
    I tried changing attributes of <rect> inside anonymous function as this.attr("width", 100). It didn't work.
  • Vinh Tran
    Vinh Tran over 9 years
    you might wanna use d3.select(this).attr("width", 100) instead of this.attr("width", 100) Also, if you want to improve your code a little bit, you should use the enter-update-exit pattern, check out jsfiddle.net/z7Y9X/11
  • vjdhama
    vjdhama over 9 years
    Great @VinhTran that works!! And surely i'll use enter-update-exit pattern from now on.
  • Dan Eastwell
    Dan Eastwell about 7 years
    Thanks @stephen-thomas for documenting the callback - commenting 'this - the <rect> that was clicked' is so much easier to understand than 'The specified listener is invoked with the context and arguments determined by the caller' from the documentation. :)