1

我一直在尝试将这样的 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()

D3 JSON数据转换

有没有人知道如何在不使用上述方法的情况下将这个 JSON 转换为与 d3 一起工作?

提前致谢 :)

4

2 回答 2

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
    }
]

因此,如果将原始数据分配给名为 var 的 var work,那么这就是您将其转换为数组的方式:

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)
}

这种方法也可以应用于包含这个“工作”数组的外层数据,然后上面的代码片段将嵌套在一个外循环中。

希望这可以帮助....

附言

在这种情况下,d3.nest 不会为您提供帮助,因为它的作用与您的要求相反。它有助于将数据数组转换为哈希。

于 2013-07-29T19:28:57.577 回答
0

这是一个小型转换器,我将它更改为 d3 格式的任何 JSON:

<!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>
于 2020-09-28T01:51:34.260 回答