71

I want to access the parent element of current element

Here is the structure of HTML

svg
   g id=invisibleG
     g
       circle
     g
       circle
     g
       circle

Basically I want to add text inside the circles when I hover over them.

So I want something like this on hover of any particular circle

svg
       g id=invisibleG
         g
           circle --> radius is increased and text presented inside that
           text
         g
           circle
         g
           circle

On hover I can select current element through d3.select(this),How can I get root element(g in my case)?

user3074097
  • 807
  • 1
  • 8
  • 13

2 Answers2

122

You can use d3.select(this.parentNode) to select parent element of current element. And for selecting root element you can use d3.select("#invisibleG").

cuckovic
  • 2,162
  • 2
  • 21
  • 18
  • 2
    Hey how did you come to know about this .I am new to d3.js .Any good book or tutorials might help me,Please suggest. – user3074097 Dec 17 '13 at 19:27
  • 1
    You can learn a lot from this video tutorials, they are great for beginners - http://www.youtube.com/user/d3Vienno/videos?flow=list&sort=da&view=0 – cuckovic Dec 17 '13 at 20:42
  • 2
    Thank you so much. I was looking everywhere for this. And it works perfectly! Is it possible to replace "this" with an element? For example: `temp = d3.select("svg"); d3.select(temp.parentNode) ` gives me errors. – Dao Lam Jul 15 '14 at 22:14
  • 6
    You can do something like this: It does not actually replace "this" but works as intended. `temp = d3.select("svg"); temp.select(function() { return this.parentNode; })` – cuckovic Jul 18 '14 at 10:05
  • 11
    you can also do `temp.node().parentNode` – Ben Southgate Mar 04 '15 at 20:05
  • In case it's not working, there are times you may need to select this[0].parentNode or this[0][0].parentNode. The console will help you sort that if you log an instance of the object – MaxRocket May 15 '15 at 19:09
28

To get the root element g (as cuckovic points out) can be got using:

circle = d3.select("#circle_id"); 
g = circle.select(function() { return this.parentNode; })

This will return a d3 object on which you can call functions like:

transform = g.attr("transform");

Using

d3.select(this.parentNode)

will just return the SVG element. Below I have tested the different variants.

// Variant 1
circle = d3.select("#c1");
g = d3.select(circle.parentNode);
d3.select("#t1").text("Variant 1: " + g);
// This fails:
//transform = d3.transform(g.attr("transform"));

// Variant 2
circle = d3.select("#c1");
g = circle.node().parentNode;
d3.select("#t2").text("Variant 2: " + g);
// This fails:
//transform = d3.transform(g.attr("transform"));


// Variant 3
circle = d3.select("#c1");
g = circle.select(function() {
  return this.parentNode;
});
transform = d3.transform(g.attr("transform"));
d3.select("#t3").text("Variant 3: " + transform);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<html>

<body>
  <svg height="200" width="300">
 <g>
  <circle id="c1" cx="50" cy="50" r="40" fill="green" />
 </g>
<text id="t1" x="0" y="120"></text>
<text id="t2" x="0" y="140"></text>
<text id="t3" x="0" y="160"></text>
</svg>
</body>

</html>
Molossus
  • 459
  • 5
  • 4
  • Thank you. This should be marked as the correct answer; the answer @cuckovic provided works only in limited circumstances. – Markus May 17 '18 at 01:10