Home > other >  D3 svg click event and circle click event overlapping
D3 svg click event and circle click event overlapping

Time:12-09

The problem I am trying to solve is the following :

I create lets say an svg of 500x500 pixels. In this svg I append a circle of 50px radius. I add a click event on the circle so that it's color changes to red. I add a click event on the rest of the svg so that the circle's color changes to green.

Is this possible?

I have tryed to place the click event on the svg and it covers the entire 500x500px preventing the click event attached to the circle to work.

I have been hinted to use stopPropagation, but was unsuccessfull using it.

var svg = d3.select("#cv")
  .attr("height", 300)
  .attr("width", 300)
  .style("border", "1px solid red")
  .on("click", function(d) {
    circ.style("fill", "green")
  });

var circ = svg
  .append("circle")
  .attr("r", 100)
  .attr("cx", 100)
  .attr("cy", 100)
  .attr("stroke", "black")
  .style("fill", "grey")
  .on("click", function(d) {
    circ.style("fill", "red")
  });
#cv {
  width: 300px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg id="cv">
<defs>
 <pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="200" width="200">
      <image x="0" y="0" href="https://i.stack.imgur.com/skwGx.jpg" width="200" height="200"></image>
    </pattern>
</defs>
</svg>

CodePudding user response:

You can use a trick for this: append a white rectangle with the same dimensions as the SVG, and add the click listener to it. Make sure you add it first, because SVG has no z-index, but instead works by drawing each item over all previous items. So the first item you define is essentially the background.

var svg = d3.select("#cv")
  .attr("height", 300)
  .attr("width", 300)
  .style("border", "1px solid red");

var bg = svg.append("rect")
  .attr("width", 300)
  .attr("height", 300)
  .attr("fill", "white")
  .on("click", function(d) {
    circ.style("fill", "green")
  });

var circ = svg
  .append("circle")
  .attr("r", 100)
  .attr("cx", 100)
  .attr("cy", 100)
  .attr("stroke", "black")
  .style("fill", "grey")
  .on("click", function(d) {
    circ.style("fill", "red")
  });
#cv {
  width: 300px;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<svg id="cv">
<defs>
 <pattern id="image" x="0" y="0" patternUnits="userSpaceOnUse" height="200" width="200">
      <image x="0" y="0" href="https://i.stack.imgur.com/skwGx.jpg" width="200" height="200"></image>
    </pattern>
</defs>
</svg>

  • Related