score:2

Accepted answer

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.

score:1

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;
}

score:2

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.


Related Query

More Query from same tag