Reputation: 817
Here is the structure of my HTML
svg
g id=invisibleG
g
circle
g
circle
g
circle
So I want something like this on hover of any particular circle
svg
g id=invisibleG
g
circle --> radius is increased on hover.....decreased on hoverout
text
g
circle
g
circle
here is the code
.on("mouseover",function(){
var r=d3.select(this).attr("r");
d3.select(this).style('fill','tan')
.style('fill-opacity', '1')
.transition()
.duration(1000)
.attr("r",50);
d3.select(this).attr("stroke","blue")
.attr("stroke-width",4);
})
.on("mouseout",function(){
var r=d3.select(this).attr("prevRadius");
d3.select(this).attr("r",r)
.attr("stroke-width",0)
.style('fill-opacity','0');
});
Now the problem is that when I hover over a circle and immediately hover out of it the transition which is started in mouseover doesn't stop immediately.It completes its transition and the size of radius is increased despite being the fact that mouseout event should be called.And whatever the transition was going should stop. Please let me know the problem and its solution .
Upvotes: 1
Views: 1811
Reputation: 109232
You just need to use transitions in both cases. From the documentation:
If a newer transition runs on a given element, it implicitly cancels any older transitions, including any that were scheduled but not yet run. This allows new transitions, such as those in response to a new user event, to supersede older transitions even if those older transitions are staged or have staggered delays.
So your code would need to be something like this.
.on("mouseover", function() {
this.prevRadius = d3.select(this).attr("r");
d3.select(this)
.style('fill','tan')
.style('fill-opacity', '1')
.transition()
.duration(1000)
.attr("r",50)
d3.select(this)
.attr("stroke","blue")
.attr("stroke-width",4);
}).on("mouseout", function() {
d3.select(this)
.transition()
.attr("r", this.prevRadius)
.attr("stroke-width",0)
.style('fill-opacity','0');
});
Demo here.
Upvotes: 1
Reputation: 2259
If your d3 version is mature enough (3.3+), they seemed to have added selection.interrupt
So you could perhaps try:
.on("mouseout",function(){
d3.select(this).interrupt();
// if interrupt isn't supported in your version use below
//d3.select(this).transition().duration(0);
})
Otherwise, newer transitions on the same selection will cancel the old active transitions. So you could run a new transition on mouseout where you transition to the reset values again. If you want to just freeze the transitions, just run a dummy transition to cancel the old one.
FURTHER INSIGHTS
If your goal is to stop the only transition of the r (radius) dead in its tracks see this fiddle which uses interrupt.
If your goal is to reset the r value or the non-transition changes you've made during the mouseover, see this fiddle
Upvotes: 0