I'm working on a proof of concept that depicts some circles inside an svg element that move and change colour when i click on the svg element. That all works fine. I also wanted to add a mouseover event which changed the colour of the circle to red for example. That worked too.
However, when i updated the position/colour of the circles (those were random-generated values) the mouseover event had disappeared. I figured it was because d3 replaced the old circles with new ones and i didn't define my mouseover eventlistener in the update function, so i just copied it from the 'initialize' code. But then something weird happened. I got an 'Uncaught TypeError: undefined is not a function' in the console, and the eventlistener didn't work. This is the code:
svg2.on("click", function(){
svg2["color"] = d3.rgb(Math.random()*256,Math.random()*256,Math.random()*256);
var circles = svg2.selectAll("circle");
console.log(circles);
circles.transition()
.duration(500)
.ease("circle")
.style("fill",svg2["color"])
.attr("cx",function(d,i){
var val = (Math.random()<0.5)?-Math.random()*50:Math.random()*50;
if(val+d[0]-d[2] >w2 || val+d[0]-d[2]<0) return d[0];
else return d[0]+val;
})
.attr("cy",function(d,i){
var val = (Math.random()<0.5)?-Math.random()*50:Math.random()*50;
if(val+d[1]+d[2] > h2 || val+d[1]-d[2]< 0) return d[1];
else return d[1]+val;
})
.attr("r",function(d){
return d[2];
})
///////// ERROR CAUSED BELOW //////////////
.on("mouseover",function(){
d3.select(this).style("fill",svg2.color);
});
});
I did nothing wrong i thought, because i did exactly as i did before: i selected all my circles, set their attributes and defined an eventlistener with .on(), but it didn't work.
I was able to solve this by defining a function that does exactly as above and call it at the end of my 'update' code. This is the function:
function updateListeners(circles){
circles.on("mouseover",function(){
d3.select(this).style("fill","red");
})
.on("mouseout",function(){
d3.select(this).style("fill",svg2.color);
})
}
So it seems i can update eventlisteners of an object in a called function, but not in the callback function provided with the 'click' event?
Question: Why is that exactly? It's the exact same selection, but why does the 'hard' way work, and the 'easy' way doesn't?