Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reorder elements of SVG ( z-index ) in D3.js

I realise this question has been asked before but I can't get to the bottom of it.

Here is my chart... http://www.gogeye.com/financialnews/piechart/index3.html

All I want to do is have the coin render behind the graph. I know D3 renders in order they are appended.

I have tried to re-append the coin but can't seem to get it working.

I've tried reordering when things are appended in the DOM but keep getting errors probably because variables are getting called before being defined etc.

Can someone give me an example of how to fix this with my code? I don't want you to do the work for me but I've been pulling my hair out for so long, I can't seem to apply other peoples examples to mine.

thanks

like image 884
bboybeatle Avatar asked Jun 04 '14 19:06

bboybeatle


Video Answer


2 Answers

I would recommend creating some "layers" using svg g elements which stands for "group".

When you render your chart, you can first define your layers:

var layer1 = svg.append('g');
var layer2 = svg.append('g');
var layer3 = svg.append('g');
// etc... for however many layers you need

Then when you append new elements, you can decide which layer you want them to be on, and it won't matter what order you assign them in, because the group elements have already been added to the DOM, and are ordered. For example:

var layer1 = svg.append('g');
var layer2 = svg.append('g');

var redCircle = layer2.append('circle')
    .attr('cx', 50)
    .attr('cy', 50)
    .attr('r', 16)
    .attr('fill', 'red')

var blueSquare = layer1.append('rect')
    .attr('x', 25)
    .attr('y', 25)
    .attr('width', 50)
    .attr('height', 50)
    .attr('fill', 'blue');

In this case the red circle will be visible above the blue square even though the blue square was created last. This is because the circle and the square are children of different group elements, which are in a pre-defined order.

Here's a FIDDLE of the above example so you can see it in action.

Doing this should take a lot of the guesswork out of when to add certain elements to your chart, and it also helps to organize your elements into a more logical arrangement. Hope that helps, and good luck.

like image 165
jshanley Avatar answered Sep 29 '22 12:09

jshanley


I am using the D3.js, and found that it has a built-in function for changing the z-order of SVG elements programmatically after the original drawing.

RipTutorial: svg--the-drawing-order covers the d3 builtin function

Quotes from this link:

selection.raise(): Re-inserts each selected element, in order, as the last child of its parent. selection.lower(): Re-inserts each selected element, in order, as the first child of its parent.

d3.selectAll("circle").on("mouseenter", function(){
    d3.select(this).raise(); 
});

d3.selectAll("circle").on("mouseleave", function(){
    d3.select(this).lower(); 
});

see live example their jsFiddle

like image 32
NicoWheat Avatar answered Sep 29 '22 14:09

NicoWheat