我想使用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)为每个国家/地区创建单独的条形图。如果有更好的方法我应该考虑这个,请告诉我。
答案 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文件的数据结构非常相似。