With D3, how can I avoid SVG graph links being ren

2019-08-10 07:32发布

On page load, my D3 graph visualization looks like this, as expected:

node on top of links

However, after clicking the root node to collapse all connections, then clicking it again to expand them, the links to the root appear on top of the root node.

links on top of node

How can I fix this?

This only occurs with the root node.

My code is fairly long, so you can find it here.

2条回答
ら.Afraid
2楼-- · 2019-08-10 08:07

Create two SVG groups (<g>) to act as layers, and keep your nodes and links in different layers.

Here's the gist of it:

var vis = d3.select("body").append("svg"); // Visualisation root

// Append layers in desired draw order; these groups are permanent elements.
var linksLayer = vis.append("g").attr("id", "links-layer");
var nodesLayer = vis.append("g").attr("id", "nodes-layer");

...

// Inside the layer-groups, shuffle nodes around as needed based on data.

var nodes = nodesLayer.selectAll(".node").data(nodeData);
nodes.enter() ...

var links = linksLayer.selectAll(".link").data(linkData);
links.enter() ...

This saves cycles compared to shuffling elements to the back on every new entry, is more robust, and is easier to understand when inspecting the DOM tree.

查看更多
可以哭但决不认输i
3楼-- · 2019-08-10 08:10

When your links are re-inserted, they appear after your root node in the DOM. This affects the visibility and the rendering order. This only happens when all links are removed then inserted. Not sure how to fix it exactly though, but a "hack" is to do it like this:

d3.selection.prototype.moveToBack = function() { 
    return this.each(function() { 
        var firstChild = this.parentNode.firstChild; 
        if (firstChild) { 
            this.parentNode.insertBefore(this, firstChild); 
        } 
    }); 
};

Then, in the updatefunction:

path.moveToBack();
查看更多
登录 后发表回答