繁体   English   中英

如何使用d3.json,d3.csv和d3.zip加载CSV和JSON文件并将两个数据集组合到一个数据集

[英]How to load a CSV and a JSON file and combine both datsets to one dataset using d3.json, d3.csv and d3.zip

这是这里问题的后续问题。

我想使用d3.csvd3.json加载多个数据集,然后使用d3.zip合并这些数据集。 在下面的示例中,我仅使用两个。 该第一数据集将被存储在xyData ,第二个在colData 我的目标是打电话给类似

var combinedData = d3.zip(colData, xyData);

但是,由于这些数据集只能分别在d3.csvd3.json范围内访问,因此不起作用。 有什么解决方法吗? 如果要加载更多的数据集,该如何处理?

第一个数据集如下所示:

//xyData.csv
x,y
0,0.00e+000
0.6981317,6.43e-001
1.3962634,9.85e-001

我的JSON数据集如下所示:

//colData.json
{
    "el1": [
        {"color": "green"},
        {"color": "purple"},
        {"color": "brown"}
    ],

    "el2": [
        {"color": "black"},
        {"color": "red"},
        {"color": "yellow"}
    ],

    "el3":[
        {"color": "brown"},
        {"color": "yellow"},
        {"color": "blue"}
    ]
}

我按以下方式阅读这些数据集:

    //using foreach 
    var xyData = [];    
    d3.csv("xyData.csv", function(myData) {
        myData.forEach(function(d) {
            d.x = +d.x; //convert data to numbers
            d.y = +d.y;
          });
          console.log(myData[1]);
          xyData = myData;
          console.log(xyData[1])
    });
    console.log(xyData) //this will be an empty array

    //loading the json data
    var colData = [];        
    d3.json("colData.json", function(error, jsonData) {
      if (error) return console.warn(error);
      colData = jsonData;
      console.log(colData)
      console.log(colData.el1[0])
    });
    console.log(colData) //this will be an empty array

    //my goal would be:
    //var combinedData = d3.zip(colData, xyData);

我的console.log看起来像这样:

Array [  ]
Array [  ]
Object { x: 0.6981317, y: 0.643 }
Object { x: 0.6981317, y: 0.643 }
Object { el1: Array[3], el2: Array[3], el3: Array[3] }
Object { color: "green" }

这表明加载数据按预期进行。 但是由于这些数据加载器的异步特性,将它们存储为全局变量是行不通的(因此,两个数组仍然为空)。

我的问题是:将两个数据集合并为一个数据集的最佳方法是什么?

既然您说您有可用的jQuery( * ),我们就可以使用它的Deferred功能来管理您正在查看的两个异步操作。

为此,我们将D3的基于回调的方法转换为基于承诺的方法。

为此,我们设置了两个包装D3的.csv.json帮助器并返回jQuery promise的帮助器函数:

d3.csvAsync = function (url, accessor) {
    var result = $.Deferred();

    this.csv(url, accessor, function (data) {
        if (data) {
            result.resolve(data);
        } else {
            result.reject("failed to load " + url);
        }
    });
    return result.promise();
};

d3.jsonAsync = function (url) {
    var result = $.Deferred();

    this.json(url, function (error, data) {
        if (error) {
            result.reject("failed to load " + url + ", " + error);
        } else {
            result.resolve(data);
        }
    });
    return result.promise();
};

现在,我们可以并行调用请求并将它们存储在变量中。 我们还可以使用.then()快速转换结果:

var colDataReq = d3.jsonAsync("colData.json");
var xyDataReq = d3.csvAsync("xyData.csv").then(function (data) {
    data.forEach(function (d) {
        d.x = +d.x;
        d.y = +d.y;
    });
    return data;
});

最后,我们使用$.when()实用程序函数等待两个资源,并通过单个回调对其进行处理。

$.when(xyDataReq, colDataReq).done(function (xyData, colData) {
    var combinedData = d3.zip(colData, xyData);

    // now do something with combinedData
}).fail(function (error) {
    console.warn(error);
});

这样,我们可以避免嵌套(并因此不必要地序列化)两个请求。

同样,由于请求存储在变量中,因此我们可以简单地重用它们而不必更改我们现有的功能。 例如,如果您想记录其中一个请求的内容,则可以在代码中的任何位置执行此操作:

xyDataReq.done(function (data) {
    console.log(data);
});

并且它将在xyDataReq返回后立即运行。

这种方法的另一个结果是-由于我们已经将加载资源与使用资源分离开 -我们可以很早地执行加载,甚至在呈现页面的其余部分之前也可以执行加载。 这样可以节省更多时间。

D3.js实际上可以处理JavaScript对象而不是文件。 如果将文件名替换为使用D3.json(myData){...}存储的对象的变量名(例如,数据的JSON数组),它将有权访问该数据。

假设我们使用的是jQuery,并且还包含一个名为Papa Parse的帮助程序库(它使工作更轻松)。

步骤1.将CSV数据转换为JSON数据并将其存储在变量A中:

var A = Papa.parse(yourCSV);

步骤2.读取JSON数据并将其存储在名为B的变量中

var B;
$(document).ready(function() {
$.getJSON('yourJSON.json', function(json){
    B = json;
});

});

步骤3.将数据集A和B合并为变量C重要信息:在稍后将其提供给D3之前,您可能需要格式化存储在A中的CSV json以查看其预期外观。

var C={};
$.extend(C, A, B);

步骤4. C给D3

d3.json(C, function(error, jsonData) {
  // Use data here to do stuff
});

在我自己的项目中,我已经将以上内容用作解决方法。

您也许可以尝试 D3.csv中调用D3.json,但我之前从未尝试过:

d3.csv("A.csv", function(errorA, dataA) {
  d3.json("B.json", function(errorB, dataB) {
    // Use data to do stuff
  });
});

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM