来自 JSON 的 D3 节点和链接,其中包含嵌套的子数组

D3 nodes and links from JSON with nested arrays of children

本文关键字:包含 嵌套 数组 链接 D3 JSON 节点 来自      更新时间:2023-09-26

我有一个看起来像这样的JSON文件:

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

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

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

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

您可能

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

如果您确实想要使用真正的强制导向布局,则必须将数据重写为 D3 期望的nodeslinks格式。无论如何,这是网络图的标准逻辑结构。

我找到了一个包含我需要的代码的示例。此函数平展数据。它在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)

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

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