8

I have a markup that looks like this which is created using d3.

<g transform="translate(441,114)">
    <rect x="50" y="-30" width="50" height="60" id="yesDecision" class="hoverNodeundefined" style="fill: rgb(51, 110, 123);"></rect>
    <text x="80" y="0" class="id ">Yes</text>
    <circle class="node fixed" r="58" style="fill: rgb(30, 139, 195); stroke: rgb(21, 97, 136);" transform="scale(1.0)"></circle>
    <text x="0" y="20" class="id">Segment</text>
    <rect class="edit-event node-hover-button" x="-20" y="-70" height="29" width="29" rx="15" ry="15"></rect>
    <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="icon-segment.svg" width="30" height="30" x="-15" y="-30" class="id"></image>
    <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="edit-automation.svg" width="16" height="16" x="-14" y="-65" class="edit-event-image node-hover-button"></image>
    <rect class="delete-event node-hover-button" x="-54" y="-54" height="29" width="29" rx="15" ry="15"></rect>
    <image xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="trash-automation.svg" width="20" height="20" x="-50" y="-50" class="delete-event-image node-hover-button"></image>
</g>

I have a mouseover event on the circle element with class node. I'm trying to hide and show the sibling elements of the circle with class node-hover-elements on hover of the circle. Is there a function in d3 similar to that of siblings() in jquery?

Also there will be multiple such g elements. I only want siblings of this element to be shown on hover.

GantTheWanderer
  • 1,255
  • 1
  • 11
  • 19
Sooraj
  • 9,717
  • 9
  • 64
  • 99

2 Answers2

11

For a D3 answer: you can select the parent node...

d3.select(this.parentNode)

... and then selecting everything inside it with that given class:

d3.select(this.parentNode).selectAll(".node-hover-button")

After that, you can do whatever you want with that selection. For instance, changing the opacity of the siblings:

d3.selectAll(".node-hover-button").attr("opacity", 0).attr("pointer-events", "none");
d3.select("circle").on("mouseover", function() {
    d3.select(this.parentNode).selectAll(".node-hover-button").attr("opacity", 1);
}).on("mouseout", function() {
    d3.select(this.parentNode).selectAll(".node-hover-button").attr("opacity", 0);
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<svg>
  <g transform="translate(100,50)">
    <rect x="50" y="-30" width="50" height="60" id="yesDecision" class="hoverNodeundefined" style="fill: rgb(51, 110, 123);"></rect>
    <text x="80" y="0" class="id ">Yes</text>
    <circle class="node fixed" r="58" style="fill: rgb(30, 139, 195); stroke: rgb(21, 97, 136);" transform="scale(1.0)"></circle>
    <text x="0" y="20" class="id">Segment</text>
    <rect class="edit-event node-hover-button" x="-20" y="-70" height="29" width="29" rx="15" ry="15"></rect>
    <rect class="delete-event node-hover-button" x="-54" y="-54" height="29" width="29" rx="15" ry="15"></rect>
  </g>
</svg>
Gerardo Furtado
  • 100,839
  • 9
  • 121
  • 171
  • I appreciate the answer. But in my case when it's the reverse , that is show on mouseover and hide on mouseout - when i move mouse on to the buttons it will be hidden. That is the issue I'm facing. Any work around for this ? ( in above fiddle when i move mouse on the black button the opacity goes back to 1 ) – Sooraj Jan 18 '17 at 06:58
  • @SoorajChandran I just showed you how to create a *selection*. You can use it to make any change you want! Anyway, check my edited snippet. – Gerardo Furtado Jan 18 '17 at 07:11
  • I think you didn't get my point. The small issue in the above snippet is - I hover on blue circle and the black circle appears, and when i move the mouse to black circle it disappears. Is there a way to stop this is what I meant? I hope I conveyed my point. – Sooraj Jan 18 '17 at 07:47
  • 1
    Set their `ponter-events` to `none`. Check my (once again) edited snippet. But have in mind that I already answered your question: how to select the siblings. The problem you're asking here is a *different* problem. – Gerardo Furtado Jan 18 '17 at 08:00
  • Thanks for the answer. But the problem is that I have a click event associated to that shape. – Sooraj Jan 18 '17 at 08:22
  • Thus, you have another issue, never mentioned in the question itself. In that case, I suggest you post another question. – Gerardo Furtado Jan 18 '17 at 08:34
  • I have added a new question here - http://stackoverflow.com/questions/41719273/issue-with-mouse-over-and-mouse-out-d3-js – Sooraj Jan 18 '17 at 12:21
  • What if I'm running this code in a Typescript envyronment where `this` is related to the class itself? – ErickXavier Apr 07 '20 at 19:29
  • @ErickXavier Here: https://stackoverflow.com/a/43552367/5768908 – Gerardo Furtado Apr 08 '20 at 00:39
1

While d3 does not have a built in method like jQuery's siblings, it's easy with just a little javascript.

var children = node.parentNode.childNodes[]  # Gets all child nodes

# Now iterate over all of these nodes
for (var i = 0; i < children.length; i++) {
    if (children[i].getAttribute("id") != "id_im_looking_for" {
        d3.select("parent > *:eq(" + i + ")");             # Use d3 select
    }
}

Of course you would tailor this algorithm to your code.

Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87