Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/404.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript D3JSON数据转换_Javascript_Json_D3.js - Fatal编程技术网

Javascript D3JSON数据转换

Javascript D3JSON数据转换,javascript,json,d3.js,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" } ] 我想把它转换成这样的嵌套

我有这个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" }
            ]
        }
    ]
}

。。。并进一步利用它来制作。谁能给我指一下正确的方向吗,我对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];
});
最后的任务是将对象转换为数组

这将为
新数据
提供所需的结果:

{
    "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:

注意:此方法不适用于嵌套结构。对于嵌套结构来说,这样做要困难得多,但您始终可以使用递归函数


编辑:正如@imarane在他的回答中所建议的,您可以使用比我手工制作的解决方案更好的方法。因此,你可以接受他的回答。通过玩它,甚至可以很容易地拥有多个级别的嵌套:

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"}
        ]}
    ]}
]}
其中包含以下数据结构(我希望更好地理解整个要点):

JsFiddle:


有关嵌套的更多信息:

另一个选项是使用D3中内置的嵌套方法

var nested = d3.nest()
.key(function(d,i){ return d.dep; })
.entries(data);
哪些产出:

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

JsFiddle:

嘿,伙计们,我想我找到了一个相当简单的解决方案。我以一种非常精简的方式完成了一个层次条形图的大型数据集(400000行)的非常好的嵌套。它利用了下划线库和一个附加函数
..nest
。只需下载并包含必要的两个库

src="underscore-min.js"
src="underscore.nest.js"
然后使用
\uuu.nest
函数创建您的结构。这是我的台词:

var newdata = _.nest(data, ["Material", "StudyName"]);
“Material”
“StudyName”
是我要将结构分组到的列


如果您需要完成更多的工作,还可以使用其他选项来使用此功能,但我会将其保留为这样使用此功能。如果需要,您可以在浏览器的控制台中检查输出

function reSortRoot(root, value_key) {
                //console.log("Calling");
                for ( var key in root) {
                    if (key == "key") {
                        root.name = root.key;
                        delete root.key;
                    }
                    if (key == "values") {
                        root.children = [];
                        for (item in root.values) {
                            root.children.push(reSortRoot(root.values[item],
                                    value_key));
                        }
                        delete root.values;
                    }
                    if (key == value_key) {
                        root.value = parseFloat("1");
                        delete root[value_key];
                    }
                }
                return root;
            } 

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

            var testJson = d3.nest()
            .key(function(d)  { return d.dep; })
            .entries(testdata); 
             console.log(testJson);

            var testRoot={};
            testRoot.key = "Information";
            testRoot.values = testJson;
            testRoot = reSortRoot(testRoot, "name");

             console.log(testRoot);
由于已被弃用以支持,我们可以使用来实现与d3.nest一起使用的功能:

var output = {
  "name": "root",
  "children": d3.groups(input, d => d.dep).map(([k, vs]) => ({ "name": k, "children": vs }))
};
例如:

var输入=[
{“dep”:“d1”,“name”:“name1”,“size”:“size1”},
{“dep”:“d1”,“name”:“name2”,“size”:“size2”},
{“dep”:“d2”,“name”:“name1”,“size”:“size3”},
{“dep”:“d2”,“name”:“name1”,“size”:“size4”}
];
变量输出={
“名称”:“根”,
“children”:d3.groups(input,d=>d.dep).map([k,vs])=>({“name”:k,“children”:vs}))
};
控制台日志(输出)

FYI,虽然您可能会以JSON的形式接收数据,但在转换数据时,您正在使用JavaScript对象和数组。此时,问题与JSON无关。这应该可以解决您的问题。您是如何创建初始Json数据结构的?您是否有数据源并添加到数据中?还是硬代码?谢谢,我会给你第一个选择试试。。。我已经使用了.nest(),它用于数据转换。但是“树布局”需要“名称”和“子项”作为默认值,而我无法让“键”和“值”起作用……第一个选项就像一个符咒!d3.nest()部分效率很高,但需要解决“键”和“值”问题。谢谢你有什么建议吗:如何将所有的“键”映射到“名字”和“值”映射到你的第二个孩子。建议?除了递归遍历所有元素并更改名称之外,我看不到任何其他方法,这需要复制和删除每个字段。不过,你可以用它作为灵感。谢谢,我试过这个。但正如我提到的,我无法将“键”和“值”映射到“名称”和“子项”:因为这是树布局所要求的。我肯定你有一些技巧来映射这些?在树示例中,你可以使用d3.layout.tree().children(函数(d){return d.values})将children访问器更改为d.values。有关它们所做的工作,请参见此处。。这里和这里……这些都是旧的,所以我不知道从那以后发生了什么变化。德国劳埃德船级社。
var output = {
  "name": "root",
  "children": d3.groups(input, d => d.dep).map(([k, vs]) => ({ "name": k, "children": vs }))
};