2

我有一个如下所示的 JSON 文件:

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

该数组是一组具有子数组的对象,这些子数组包含深入几级的子数组。

我的问题是,当我尝试将其转换为一组用于 d3 强制布局的节点和链接时,我无法正确显示它。我尝试使用 array.map 或 forEach 递归地遍历所有对象并自己创建链接,但这似乎过于乏味。

有没有更简单的方法可以让这些数据准备好以强制布局显示?我错过了什么?

4

3 回答 3

2

您可能希望在 D3.js 中使用 Reingold-Tilford 树,而不是强制导向布局。这样你的数据已经是正确的格式,布局也可能会更好。

如果您确实想使用真正的力导向布局,那么您将不得不将数据重写为D3 期望的格式nodeslinks无论如何,这是网络图的标准逻辑结构。

于 2013-01-25T12:09:17.140 回答
2

我找到了一个包含我需要的代码的示例。此函数将数据展平。它在 Coffeescript 中,因为这就是我使用的。

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

在我这样做之后,我可以运行 tree.layout().links() 来生成链接,而无需手动执行。

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

希望对某人有所帮助,因为文档或维基中没有记录。

于 2013-01-25T20:55:26.090 回答
1

javascript函数将是:

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;
}
于 2013-09-25T05:13:39.297 回答