我创建了一个简单的脚本来读取JSON文件并将其重组为d3.js接受的状态。
不要过多关注重组,它按预期工作。我唯一的问题是,尽管我将不同的节点对象添加到节点数组,并将不同的链接对象添加到链接数组,但console.logs告诉我两个数组最后都是空的。
function loadJSON(file, callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', file, true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
var nodes = new Array();
var links = new Array();
function load(jsonPath) {
loadJSON(jsonPath, function(response) {
var actual_JSON = JSON.parse(response);
//create array which will hold all the nodes and links
//we create a var for the stringified nodes
var stringifiedJson = JSON.stringify(actual_JSON.nodes);
//we trim the string of the beginning and ending brackets
stringifiedJson = stringifiedJson.substring(2, stringifiedJson.length - 2);
//restructuring nodes
//logic for separating all the nodes
var nodeArray = stringifiedJson.split(",");
for (var i = 0; i < nodeArray.length; i++) {
//for every separated node, now we separate the ID from the IP
var currArr = nodeArray[i].split(":");
//currArr[0] is id, currArr[1] is IP
var node = {
id: currArr[0].substring(1, currArr[0].length - 1),
ip: currArr[1].substring(1, currArr[1].length - 1)
};
//node is added to array of nodes
nodes.push(node);
console.log(node);
}
//restructuring links
//make a variable of the links object
var objectWithLinks = actual_JSON.links[0];
//put all the keys of that objects in an array Keys, to be able to access the values later
var keys = [];
for (var k in objectWithLinks) keys.push(k);
//For each key in the links object, we see how many destinations it has, and we restructure it so a link has one source and one destination
for (var i = 0; i < keys.length; i++) {
//we check how many destinations the link has, and start seperating them
for (var key in objectWithLinks[keys[i]].dst_ips) {
var trimmedKey = key.substring(1, key.length - 1);
var sourceKeyAsNumber = Number(keys[i]);
var destinationKeyAsNumber = Number(key);
var link = {
source: sourceKeyAsNumber,
target: destinationKeyAsNumber
};
//link is added to array of links
links.push(link);
console.log(link);
}
}
});
}
load("gas.json");
console.log("length of links", links.length);
console.log("length of nodes", nodes.length);
答案 0 :(得分:1)
这里的想法是在读取文件时调用回调。
因此你有这样的事情:
//Note that I have just stripped the code to highlight the concept.
//The code will not run as is
//statement 1
loadJSON(path, function(){
//statement 2
nodes.push(node);
});
//statement 3
console.log(nodes.length);
如果您尝试访问回调之外的值,则无法保证语句2 和语句3 的执行顺序。如果语句3 在语句2 之前执行,您将获得一个空数组,这就是本例中发生的情况。
要解决此问题,请访问回调中的值。
//statement 1
loadJSON(path, function(){
//statement 2
nodes.push(node);
//statement 3
console.log(nodes.length);
});
在您提供的代码中,它将如下所示:
function loadJSON(file, callback) {
var xobj = new XMLHttpRequest();
xobj.overrideMimeType("application/json");
xobj.open('GET', file, true); // Replace 'my_data' with the path to your file
xobj.onreadystatechange = function() {
if (xobj.readyState == 4 && xobj.status == "200") {
// Required use of an anonymous callback as .open will NOT return a value but simply returns undefined in asynchronous mode
callback(xobj.responseText);
}
};
xobj.send(null);
}
var nodes = new Array();
var links = new Array();
function load(jsonPath) {
loadJSON(jsonPath, function(response) {
var actual_JSON = JSON.parse(response);
//create array which will hold all the nodes and links
//we create a var for the stringified nodes
var stringifiedJson = JSON.stringify(actual_JSON.nodes);
//we trim the string of the beginning and ending brackets
stringifiedJson = stringifiedJson.substring(2, stringifiedJson.length - 2);
//restructuring nodes
//logic for separating all the nodes
var nodeArray = stringifiedJson.split(",");
for (var i = 0; i < nodeArray.length; i++) {
//for every separated node, now we separate the ID from the IP
var currArr = nodeArray[i].split(":");
//currArr[0] is id, currArr[1] is IP
var node = {
id: currArr[0].substring(1, currArr[0].length - 1),
ip: currArr[1].substring(1, currArr[1].length - 1)
};
//node is added to array of nodes
nodes.push(node);
console.log(node);
}
//restructuring links
//make a variable of the links object
var objectWithLinks = actual_JSON.links[0];
//put all the keys of that objects in an array Keys, to be able to access the values later
var keys = [];
for (var k in objectWithLinks) keys.push(k);
//For each key in the links object, we see how many destinations it has, and we restructure it so a link has one source and one destination
for (var i = 0; i < keys.length; i++) {
//we check how many destinations the link has, and start seperating them
for (var key in objectWithLinks[keys[i]].dst_ips) {
var trimmedKey = key.substring(1, key.length - 1);
var sourceKeyAsNumber = Number(keys[i]);
var destinationKeyAsNumber = Number(key);
var link = {
source: sourceKeyAsNumber,
target: destinationKeyAsNumber
};
//link is added to array of links
links.push(link);
console.log(link);
}
}
console.log("length of links", links.length);
console.log("length of nodes", nodes.length);
});
}
load("gas.json");