Javi
Javi

Reputation: 493

How can I choose an specific SVG in d3 and change its attributes?

I have listed four svgs in the html file. Each one with a different class based on their respective colour. Every SVG contains a rectangle and a circle.

 <body>
    <svg class="green">
      <g class="blue">

        <rect width="500", height= "500", fill="blue"></rect>
        <circle cx="100", cy="100", r ="50"></circle>
      </g>
    </svg>

      <svg class="green">
        <g class="green">
          <rect width="500", height= "500", fill="green"></rect>
          <circle cx="100", cy="100", r ="50"></circle>
        </g>
      </svg>

      <svg class="green">
        <g class="red">
          <rect width="500", height= "500", fill="red"></rect>
          <circle cx="100", cy="100", r ="50"></circle>
        </g>
      </svg>

      <svg class="green">
        <g class="yellow">
          <rect width="500", height= "500", fill="yellow"></rect>
          <circle cx="100", cy="100", r ="50"></circle>
        </g>
      </svg> 
      <script src="app.js"></script>
  </body>
  <script src="app.js"></script>

The app.js file contains a code that, whenever the mouse touches the rectangle, all the SVGs will disappear. As soon as this concludes the rectangles appear again.

//app.js

const svg = d3.selectAll("svg")
const rectangles = d3.selectAll("rect")

rectangles
.on("mouseover", function(){
    svg.attr("opacity", 0)
    svg.select(".green").attr("opacity", 1)
})
.on("mouseout", function(){
    svg.attr("opacity", 1)
})

But what I want to do is that only one rectangle disappear, the rectangle that is touched by the mouse. I was trying with multiple if-statements and switch-cases but is there a better way? Maybe with d3.select but I can't come with something

Upvotes: 0

Views: 49

Answers (1)

1Cr18Ni9
1Cr18Ni9

Reputation: 1867

According to the structure of your HTML, I guess this is what you want to achieve:

const svg = d3.selectAll("svg");
const rectangles = d3.selectAll("rect");

rectangles
.on("mouseover", function(){
    // "this" is the rectangle element
    // "this.parentNode.parentNode" is the svg that holding it.
    let parentSvg = this.parentNode.parentNode;

    svg.attr("opacity", function () {
      return parentSvg ==  this ? 1 : 0;
    });
})
.on("mouseout", function(){
    svg.attr("opacity", 1)
});
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/d3.min.js"></script>
<svg class="green">
      <g class="blue">

        <rect width="500", height= "500", fill="blue"></rect>
        <circle cx="100", cy="100", r ="50"></circle>
      </g>
    </svg>

      <svg class="green">
        <g class="green">
          <rect width="500", height= "500", fill="green"></rect>
          <circle cx="100", cy="100", r ="50"></circle>
        </g>
      </svg>

      <svg class="green">
        <g class="red">
          <rect width="500", height= "500", fill="red"></rect>
          <circle cx="100", cy="100", r ="50"></circle>
        </g>
      </svg>

      <svg class="green">
        <g class="yellow">
          <rect width="500", height= "500", fill="yellow"></rect>
          <circle cx="100", cy="100", r ="50"></circle>
        </g>
      </svg>

Upvotes: 1

Related Questions