Prevent mouseout action after click on an element with D3.js

Gio*_*act 5 javascript svg onclick mouseout d3.js

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);
}
Run Code Online (Sandbox Code Playgroud)

Joh*_*ith 4

如果您计划只有一个元素来控制圆圈,请使用“标志”。搞乱有条件地注册/取消注册事件并不是一个好主意。

检查你的小提琴的更新版本:

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);
}
Run Code Online (Sandbox Code Playgroud)

编辑评论

如果您需要“记住”每个元素的状态,而不是使用全局,您应该在这些元素上使用数据绑定:

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);
}
Run Code Online (Sandbox Code Playgroud)

在这里更新了小提琴。