I would like to prevent the mouseout action of an element when the user click on this element. For an example see this JSFiddle (the circle disappear even if I click on the label).
Is there an easy way to achieve my objective with d3.js? Thank you!
The JSFiddle example code:
var svg = d3.select("#content")
.append("svg")
.attr("width", 600)
.attr("height", 400);
var g = svg.append("g");
var text = g.append("text")
.text("Click me")
.style("fill", "Blue")
.attr("x", 50)
.attr("y", 50)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", click);
var circle = g.append("circle")
.style("fill", "Orange")
.attr("cx", 150)
.attr("cy", 90)
.attr("r", 15)
.classed("hide", true)
.classed("someClass", true);
function mouseover(p){
d3.selectAll("circle.someClass").classed("hide", false);
}
function mouseout(p){
d3.selectAll("circle.someClass").classed("hide", true);
}
function click(p){
d3.selectAll("circle.someClass").classed("hide", false);
}
If you plan to only have one element that controls the circle, use a "flag". Messing with conditionally registering/unregistering events is not a good idea.
Check this updated version of your fiddle:
https://jsfiddle.net/cze9rqf7/
var svg = d3.select("#content")
.append("svg")
.attr("width", 600)
.attr("height", 400);
var g = svg.append("g");
var text = g.append("text")
.text("Click me")
.style("fill", "Blue")
.attr("x", 50)
.attr("y", 50)
.on("mouseover", mouseover)
.on("mouseout", mouseout)
.on("click", click);
var circle = g.append("circle")
.style("fill", "Orange")
.attr("cx", 150)
.attr("cy", 90)
.attr("r", 15)
.classed("hide", true)
.classed("someClass", true);
var isClicked = false;
function mouseover(p){
d3.selectAll("circle.someClass").classed("hide", false);
}
function mouseout(p){
if(!isClicked) {
d3.selectAll("circle.someClass").classed("hide", true);
}
}
function click(p){
isClicked = !isClicked;
d3.selectAll("circle.someClass").classed("hide", false);
}
EDITS For Comments
If you need to "remember" state per element, instead of using a global, you should be using data-binding on those elements:
var text = g.append("text")
.datum({isClicked: false})
.text("Click me")
...
function mouseout(p){
// p is the data-bound object
if(!p.isClicked) {
var className = d3.select(this).attr("class");
d3.selectAll("circle."+className).classed("hide", true);
}
}
function click(p){
// on click edit the data-bound object
p.isClicked = !p.isClicked;
var className = d3.select(this).attr("class");
d3.selectAll("circle."+className).classed("hide", false);
}
Updated fiddle here.