javascript - D3 JSON数据转换

标签 javascript json d3.js

我有这个 JSON 数据结构:

[
    { "dep": "d1", "name": "name1", "size": "size1" },
    { "dep": "d1", "name": "name2", "size": "size2" },
    { "dep": "d2", "name": "name1", "size": "size3" },
    { "dep": "d2", "name": "name1", "size": "size4" }
]

我想将它转换成这样的嵌套结构:

{
    "name": "root",
    "children": [
        { "name": "d1",
            "children": [
                { "dep": "d1", "name": "name1", "size": "size1" },
                { "dep": "d1", "name": "name2", "size": "size2" }
            ]
        },
        { "name": "d2",
            "children": [
                { "dep": "d2", "name": "name1", "size": "size3" },
                { "dep": "d2", "name": "name2", "size": "size4" }
            ]
        }
    ]
}

... 并进一步使用它来制作 Reingold–Tilford Tree .谁能指出我正确的方向,我是 D3 的新手!

最佳答案

该策略是根据您的需要创建一个新的空数据结构,然后通过遍历整个原始数据集来填充它。这是代码:

var data = [
    { "dep": "d1", "name": "name1", "size": "size1" },
    { "dep": "d1", "name": "name2", "size": "size2" },
    { "dep": "d2", "name": "name1", "size": "size3" },
    { "dep": "d2", "name": "name2", "size": "size4" }
]

var newData = {"name": "root", "children": {}}

data.forEach(function (d) {
    if (typeof newData.children[d.dep] !== 'undefined') {
        newData.children[d.dep].children.push(d)
    } else {
        newData.children[d.dep] = {"name": d.dep, "children": [d]}
    }
})
newData.children = Object.keys(newData.children).map(function (key) {
    return newData.children[key];
});

最后的赋值是将对象转化为数组。

这为 newData 提供了所需的结果:

{
    "name": "root",
    "children": [
        { "name": "d1",
            "children": [
                { "dep": "d1", "name": "name1", "size": "size1" },
                { "dep": "d1", "name": "name2", "size": "size2" }
            ]
        },
        { "name": "d2",
            "children": [
                { "dep": "d2", "name": "name1", "size": "size3" },
                { "dep": "d2", "name": "name2", "size": "size4" }
            ]
        }
    ]
}

jsFiddle: http://jsfiddle.net/chrisJamesC/eB4jF/

注意:此方法不适用于嵌套结构。对于嵌套结构执行此操作会更难,但您始终可以使用递归函数。


编辑:正如@imarane 在他的回答中所建议的,您可以使用 d3.nest()这比我手工制作的解决方案要好得多。因此,您可能会接受他的回答。通过使用它,甚至可以很容易地拥有多层嵌套:

var data = [
    { "dep": "d1", "name": "name1", "size": "size1" },
    { "dep": "d1", "name": "name2", "size": "size2" },
    { "dep": "d2", "name": "name1"},
    { "dep": "d2"}
]

var newData = {
    "key":"root", 
    "children": 
        d3.nest()
            .key(function(d){return d.dep})
            .key(function(d){return d.name})
            .key(function(d){return d.size})
            .entries(data)
}     

哪个给:

{"key":"root","children":[
    {"key":"d1","values":[
        {"key":"name2","values":[
            {"dep":"d1","name":"name2","size":"size1"},
            {"dep":"d1","name":"name2","size":"size2"}
        ]}
    ]},
    {"key":"d2","values":[
        {"key":"name1","values":[
            {"dep":"d2","name":"name1"}
        ]},
        {"key":"undefined","values":[
            {"dep":"d2"}
        ]}
    ]}
]}

下面是哪个数据结构(希望能更好的理解整点):

var data = [
    { "dep": "d1", "name": "name2", "size": "size1" },
    { "dep": "d1", "name": "name2", "size": "size2" },
    { "dep": "d2", "name": "name1"},
    { "dep": "d2"}
]

JsFiddle: http://jsfiddle.net/chrisJamesC/eB4jF/2/

有关 Nest 的更多信息: http://bl.ocks.org/phoebebright/raw/3176159/

关于javascript - D3 JSON数据转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15912966/

相关文章:

javascript - D3 中的鼠标位置

javascript - 无法通过javascript为DOM元素设置渐变颜色

javascript - 动态添加方法到对象

css - 显示特定的 Tick 值

php - Stripe - 通过 PHP、iOS 和 Alamofire 进行部分退款

json - 如何修复错误类型 'System.Web.Script.Serialization.JavaScriptSerializer' 未定义

javascript - 在 D3 map 上显示工具提示

javascript - 动态 html 属性的字符串插值

javascript - 具有可变延迟和等待的 Angular 4 setTimeout()

php - 如何正确地遍历一个大的 json 文件