How to assign click event to every svg element in d3js
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!
vjdhama
I am a product engineer working at GOJEK. Check out my blog : https://medium.com/@vjdhama
Updated on July 25, 2022Comments
-
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 over 9 yearsi tried using
.click
but i doesn't seem to work. Can you post working jsfiddle link. -
vjdhama over 9 yearsI tried changing attributes of
<rect>
inside anonymous function asthis.attr("width", 100)
. It didn't work. -
Vinh Tran over 9 yearsyou might wanna use
d3.select(this).attr("width", 100)
instead ofthis.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 over 9 yearsGreat @VinhTran that works!! And surely i'll use enter-update-exit pattern from now on.
-
Dan Eastwell about 7 yearsThanks @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. :)