score:1

Accepted answer

there are different ways to achieve this. since the first d in ddd (also known as d3) means data, the approach i like most is binding a datum to the clicked element, indicating that it was clicked:

d.clicked = true;

or, if you want to reverse the boolean after a second click:

d.clicked = !d.clicked;

then, in the mouseover, just check that datum:

if (d.clicked) return;

here is a demo using green circles: if you mouse over them, they turn red. if you click them, they turn blue, and never turn red (or green) again.

var svg = d3.select("svg");
var circles = svg.selectall(null)
  .data(d3.range(5).map(function(d) {
    return {
      x: d
    }
  }))
  .enter()
  .append("circle")
  .attr("cursor", "pointer")
  .attr("cy", 75)
  .attr("cx", d => 30 + 50 * d.x)
  .attr("r", 20)
  .style("fill", "lime");

circles.on("mouseover", function(d) {
  if (d.clicked) return;
  d3.select(this).style("fill", "firebrick")
}).on("mouseout", function(d) {
  if (d.clicked) return;
  d3.select(this).style("fill", "lime")
}).on("click", function(d) {
  d.clicked = !d.clicked;
  d3.select(this).style("fill", "blue")
})
<script src="https://d3js.org/d3.v4.min.js"></script>
<svg></svg>

score:0

probably a few tactics, either

set path.style("pointer-events", "none") for clicked paths, which will stop all future clicks/mouseover events.

or if that is too drastic, add a class to clicked paths path.classed("clicked", true), which you could use in a test during your mouseover event before applying any styling changes


Related Query