D3 nodes and links from JSON with nested arrays of children

≯℡__Kan透↙ 提交于 2019-12-10 23:58:18

问题


I've got a JSON file that looks like this:

{
    Object: {
        children: Array[4]
        ...
    Object: {
        children: Array[1]
            Object: {
                 children: Array[3]
                 ...
            },
            Object: {
                 children: Array[1]
                 ...
            },
        ...
    }
    ...
}

The array is a bunch of objects that have arrays of children that contain arrays of children going a few levels deep.

My problem is when I try to turn this into a set of nodes and links for use in a d3 force layout, I can't get it to display properly. I've tried using array.map or forEach to recursively go through all the objects and create the links myself, but this seems overly tedious.

Is there a simpler way to get this data prepared to be displayed in a force layout? What am I missing?


回答1:


You might want to use a Reingold-Tilford tree in D3.js, rather than a force-directed layout. That way your data is already in the right format, and the layout may work better too.

If you do want to use a true force-directed layout, then you are going to have to rewrite the data into the nodes and links format that D3 expects. This is the standard logical structure for a network graph, in any case.




回答2:


I found an example that had the code I needed. This function flattens the data. It's in Coffeescript because that's what I use.

flatten: (root) =>
    nodes = []
    i = 0
    recurse = (node) =>
        if node.children
            node.size = node.children.reduce(
                (p, v) -> p + recurse(v)
            , 0)
        if !node.id
            node.id = ++i
        nodes.push(node)
        node.size
    root.size = recurse(root)
    nodes

After I did that, I could just run tree.layout().links() to generate the links without having to do it manually.

@nodes = @flatten(@root)
@links = d3.layout.tree().links(@nodes)

Hope that helps someone as this isn't documented in the docs or wiki.




回答3:


The javascript function would be:

function flatten(root) {    
var nodes = [], i = 0;

function recurse(node) {
    if (node.children) 
        node.size = node.children.reduce(function(p, v) { return p + recurse(v); }, 0);
    if (!node.id) 
        node.id = ++i;
    nodes.push(node);
    return node.size;
}

root.size = recurse(root);
return nodes;
}


来源:https://stackoverflow.com/questions/14512523/d3-nodes-and-links-from-json-with-nested-arrays-of-children

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!