通过D3

时间:2015-07-10 14:20:33

标签: javascript json d3.js

我想使用d3.nest()为JSON创建一个键值对。

原始JSON如下所示:

[
{
    "Country": "Mexico", 
    "Climate": 100,
    "Safety Index": 50,
    "Life Expectancy": 80,
    "Corruption": 30,
    "Per Capita Income": 20
},
{
    "Country": "UK",
    "Climate": 70,
    "Safety Index": 80,
    "Life Expectancy": 70,
    "Corruption": 70,
    "Per Capita Income": 80
},
{
    "Country": "US",
    "Climate": 80,
    "Safety Index": 70,
    "Life Expectancy": 90,
    "Corruption": 70,
    "Per Capita Income": 80
}
]

我想将其转化为:

[
{"key": "Mexico", "value":
    [ 
        { "key": "Climate", "value": 100 },
        { "key": "Safety Index", "value": 50 },
        { "key": "Life Expectancy", "value": 80 },
        { "key": "Corruption", "value": 30 },
        { "key": "Per Capita Income", "value": 20 }
    ]},
{"key": "UK", "value":
    [ 
        { "key": "Climate", "value": 70 },
        { "key": "Safety Index", "value": 80 },
        { "key": "Life Expectancy", "value": 70 },
        { "key": "Corruption", "value": 70 },
        { "key": "Per Capita Income", "value": 80 }
    ]},
{"key": "US", "value":
    [ 
        { "key": "Climate", "value": 80 },
        { "key": "Safety Index", "value": 70 },
        { "key": "Life Expectancy", "value": 90 },
        { "key": "Corruption", "value": 70 },
        { "key": "Per Capita Income", "value": 80 }
    ]}
    ]

我的尝试:

var nest = d3.nest()
             .key(function(d) { return d.Country; })
             .entries(data);

我的问题非常基础,因为我是D3的新手。我该如何改变D3中JSON的结构?

修改

这是根据与此示例类似的不同类别(http://bl.ocks.org/mbostock/5872848)为每个国家/地区创建单独的条形图。如果有更好的方法我应该考虑这个,请告诉我。

3 个答案:

答案 0 :(得分:2)

如果你想要你提供的确切输出,并坚持使用巢,你可以使用:

var nest = d3.nest()
         .key(function(d) { return d.Country; })
         .rollup(function(d) {
              var countryGroupedObject = d[0];
              return d3.nest()
                       .key(function(innerKey) { return innerKey; })
                       .rollup(function(innerKey) { return countryGroupedObject[innerKey]; })
                       .entries(Object.keys(countryGroupedObject));
          })
         .entries(data);

这里的潜在问题是你假设每个国家都是独一无二的(例如,不会有两个“墨西哥”条目)。因此,内部嵌套仅在d[0]上运行(这将是为给定国家列出的第一个项目)。

编辑:实际上,这不是完全您要求的内容,国家/地区密钥:值将存在于内部分组中。如果这是一个问题,可以通过在内部嵌套之前放置以下内容来忽略它: delete countryGroupedObject.Country;

编辑2:以上代码使用嵌套的nest函数,因为问题就是这样。在实际系统中,内部nest对我来说更有意义是纯粹的Javascript,如下所示:

function getGraphParams(countryObj){
    return Object.keys(countryObj)
                   .filter(function(key){ return key !== "Country"; })
                   .map(function(key){ return { key: key, value: countryObj[key] }; })
}

答案 1 :(得分:0)

这是一个没有D3的解决方案:

var a = ...; // Original Array of JSON
var b = [];
a.forEach(function(item) {
    var r = {};
    r.key = item.Country;
    r.value = [];
    for (var i in item) {
        if (i === "Country") { continue; }
        r.value.push({"key": i, "value": item[i]});
    }
    b.push(r);
});

不确定为什么你只使用" key"作为你的关键和"价值"虽然你重视键值,但这似乎与使用JSON中的隐式键和值相反。但我认为你有理由这样做。

答案 2 :(得分:0)

你说:

  

如果有更好的方式我应该考虑这个,请告诉我。

如果您要更改数据结构,为什么不将其更改为此类内容?

[
    ["Mexico", 100, 50, 80, 30, 20],
    ["UK", 70, 80, 70, 70, 80],
    ["US", 80, 70, 90, 70, 80],
]

它更小,不包含任何裁员。

如果您希望您的结构尽可能接近代码示例的数据结构,我仍然建议坚持原始数据结构,因为原始数据结构中的CSV文件被转换为相当的数据结构与原始JSON文件的数据结构非常相似。