我一直在尝试将这样的JSON转换为d3可以使用的东西,但我遇到了一些麻烦。这是JSON的例子
[{
"name" : "MATH210",
"work" : {
"assessment1" : {
"mark" : 65,
"weight" : 40
},
"assessment2" : {
"mark" : 65,
"weight" : 60
}
},
"overallMark" : 95
},
{
"name" : "MATH215",
"work" : {
"assessment1" : {
"mark" : 67,
"weight" : 30
},
"assessment2" : {
"mark" : 65,
"weight" : 45
},
"exam" : {
"mark" : 72,
"weight" : 25
}
},
"overallMark" : 85
},
{
"name" : "MATH220",
"work" : {
"assessment1" : {
"mark" : 65,
"weight" : 50
},
"assessment2" : {
"mark" : 65,
"weight" : 50
}
},
"overallMark" : 75
}]
我对d3很陌生,但我阅读和完成的所有示例都有数组形式的数据,这就是我的第一个方法所关注的。
我会发布一些代码,以便您更好地了解我所做的事情。所以我首先使用像这样的代码
创建一个包含JSON模块对象的数组var count = 0;
// loop through json and instantiate each
// module and store in the modules array
$.each(json, function(i, item) {
progress.modules[count] = new Module( i , item );
count++;
});
然后我使用大量的嵌套for / in循环来提取我想要的数据并将它们存储在每个模块的大量数组中,每个模块有3个不同的数组。
// Arrays that will hold all the broken down data
this.workNames = [], this.marks = [], this.weights = [];
这种方法有效但不适合大量数据。
我想要做的就是根据整体标记及其权重和散点图绘制一些饼图。从我在堆栈溢出和网络上的其他地方读到的,我感觉有一种更优雅的方式来获取这些数据并将其转换为d3可以使用的东西。
也许通过像这样使用d3.nest()
有没有人有任何想法如何在不使用上述方法的情况下将此JSON转换为与d3配合使用?
提前致谢:)
答案 0 :(得分:3)
让我们看一下整体转换的子任务。考虑一下你拥有的这些数据,它是对象的对象(也就是哈希)的形式:
{
"assessment1" : {
"mark" : 67,
"weight" : 30
},
"assessment2" : {
"mark" : 65,
"weight" : 45
},
"exam" : {
"mark" : 72,
"weight" : 25
}
}
最有可能的是,您要将其转换为对象数组:
[
{
"id": "assessment1"
"mark" : 67,
"weight" : 30
},
{
"id": "assessment2"
"mark" : 65,
"weight" : 45
},
{
"id" : "exam"
"mark" : 72,
"weight" : 25
}
]
因此,如果将原始数据分配给名为work
的var,那么这就是您将其转换为数组的方式:
var workAsArray = []; // This will be the resulting array
for(var key in work) {
var entry = work[key]; // This will be each of the three graded things
entry.id = key; // e.g. "id": "assessment1"
workAsArray.push(entry)
}
这种方法也可以应用于包含这个“work”数组的外层数据,然后上面的代码片段将嵌套在外部循环中。
希望这会有所帮助......
P.S。
在这种情况下,d3.nest不会帮助你,因为它与你所要求的相反。它有助于将数据数组转换为哈希值。答案 1 :(得分:0)
这是一个小型转换器,我使它可以将任何JSON更改为d3格式:
<!DOCTYPE html>
<html>
<body>
<p id="demo"></p>
<script>
//Eample JSON
var complexJson = {
"problems": [{
"Diabetes":[{
"medications":[{
"medicationsClasses":[{
"className":[{
"associatedDrug":[{
"name":"asprin",
"dose":"",
"strength":"500 mg"
}],
"associatedDrug#2":[{
"name":"somethingElse",
"dose":69,
"strength":"500 mg"
}]
}],
"className2":[{
"associatedDrug":[{
"name":"asprin",
"dose":"",
"strength":"500 mg"
}],
"associatedDrug#2":[{
"name":"somethingElse",
"dose":"",
"strength":"500 mg"
}]
}]
}]
}],
"labs":[{
"missing_field": "missing_value",
"boolean_field": true
}]
}],
"Asthma":[{}]
}]};
//Test if we should dig deeper
function hasJsonStructure(str) {
if (typeof str === 'string') return false;
try {
return Object.prototype.toString.call(str) === '[object Object]' || Array.isArray(str);
} catch (err) {
return false;
}
};
//Parse and convert object recursive
function walk2(obj2,level) {
var mytempCH = [];
var outer = [];
for (var key in obj2){
var value = obj2[key];
if(hasJsonStructure(value)){
//has children
var mytempCH2 = new Object();
mytempCH2.name = key;
mytempCH2.children = walk2(value,level+1);
outer.push(mytempCH2);
}else{
outer.push({"name": key + ": " + value, "value": level})
}
}
return outer
}
//Preapare Object Root
var myNewObj = new Object();
myNewObj.name = "ConvertedObj";
myNewObj.children = [];
var level = 1;
//Start work
myNewObj.children = walk2(complexJson,1);
//Output text to html
document.getElementById("demo").innerHTML = JSON.stringify(myNewObj); + "<br>";;
</script>
</body>
</html>