Updating SVG Element Z-Index With D3 Updating SVG Element Z-Index With D3 javascript javascript

Updating SVG Element Z-Index With D3


As explained in the other answers, SVG does not have a notion of a z-index. Instead, the order of elements in the document determines the order in the drawing.

Apart from reordering the elements manually, there is another way for certain situations:

Working with D3 you often have certain types of elements that should always be drawn on top of other types of elements.

For example, when laying out graphs, links should always be placed below nodes. More generally, some background elements usually need to be placed below everything else, while some highlights and overlays should be placed above.

If you have this kind of situation, I found that creating parent group elements for those groups of elements is the best way to go. In SVG, you can use the g element for that. For example, if you have links that should be always placed below nodes, do the following:

svg.append("g").attr("id", "links")svg.append("g").attr("id", "nodes")

Now, when you paint your links and nodes, select as follows (the selectors starting with # reference the element id):

svg.select("#links").selectAll(".link")// add data, attach elements and so onsvg.select("#nodes").selectAll(".node")// add data, attach elements and so on

Now, all links will always be appended structurally before all node elements. Thus, the SVG will show all links below all nodes, no matter how often and in what order you add or remove elements. Of course, all elements of the same type (i.e. within the same container) will still be subject to the order in which they were added.


One of the solutions presented by the developer is: "use D3's sort operator to reorder the elements." (see https://github.com/mbostock/d3/issues/252)

In this light, one might sort the elements by comparing their data, or positions if they were dataless elements:

.on("mouseover", function(d) {    svg.selectAll("path").sort(function (a, b) { // select the parent and sort the path's      if (a.id != d.id) return -1;               // a is not the hovered element, send "a" to the back      else return 1;                             // a is the hovered element, bring "a" to the front  });})


Since SVG doesn't have Z-index but use the order of the DOM elements, you can bring it to front by:

this.parentNode.appendChild(this);

You can then e.g. make use of insertBefore to put it back on mouseout. This however requires you to be able to target the sibling-node your element should be inserted before.

DEMO: Take a look at this JSFiddle