【问题标题】:Fetching and processing data with semicolon delimiters and no headers使用分号分隔符和无标题获取和处理数据
【发布时间】:2018-07-10 21:19:17
【问题描述】:

我在理解 D3.JS 获取文档时遇到了一些麻烦:

我的数据源是:

20180601 000000;1.168200;1.168240;1.168140;1.168230;0;
20180601 000100;1.168220;1.168230;1.168190;1.168190;0;
20180601 000200;1.168180;1.168180;1.168080;1.168120;0;
20180601 000300;1.168130;1.168160;1.168130;1.168140;0;

格式在哪里:

%Y%m%d %H%M%S;number1;number2;number3;number4;number5;

我的困难是:

  1. 向数据添加标头
  2. 使用分号而不是逗号作为分隔符

1) 据我所知,我需要在不解析的情况下读取文件,然后将文本字符串连接到文件的开头,然后最后解析数据。

d3.text(data.csv, function(error, textString){});

var headers = ["date","time","data1","data2"].join("\t");

d3.csv.parse(headers + textString);

2) 我可以使用 dsv 格式并将分隔符设置为分号吗?

d3.dsv(";", "text/plain")

我最终得到的粗略代码是:

var time_parse = d3.timeParse( '%Y%m%d %H%M%S');
var time_format = d3.timeFormat('%H%M');

d3.text(data.csv, function(error, textString){

var headers = ["time;number1;number2;number3;number4;number5;"].join("\t")

d3.csv.parse(headers + textString)

d3.dsv(";", "text/plain")

data.forEach(function(e,i){
    data[i].time = time_parse(e.date);
})

})

理想情况下,我希望数据在记录时看起来像这样:

Time, Number1, Number2, Number3, Number4, Number5
00:00, 1.168200, 1.168240, 1.168140, 1.168230, 0
etc

我的想法有什么缺陷,有人可以就如何解决我的问题和将来的类似问题提供建议吗?

注意:我是 Javascript 和 d3 的新手,虽然我已经能够毫无问题地完成大部分涉及绘制 svg、创建轴和比例、过渡等的文档,但我很难真正理解来自真实来源(例如互联网)的数据并将它们处理成可行的东西。请严厉批评我所说的任何内容并提供建议,我想学习。

【问题讨论】:

    标签: javascript d3.js fetch-api import-from-csv


    【解决方案1】:

    不清楚您使用的是哪个版本的 d3,您引用了 fetch API,但您拥有的一些代码在问题代码中看起来像 d3v3 和 v4(这可能是问题),它们不使用 fetch API。无论如何,我将通过 v5,以及第 4 和第 3 版。

    在所有这些中,根据您拥有的代码块,您的想法看起来非常接近。我们需要:

    • 我们在 dsv 中读取为文本,
    • 添加标题(行尾\n),
    • 并通过 dsv 格式函数运行所有内容,该函数将使用 ; 作为分隔符。

    不需要d3.csv.parse,尽管在你的问题代码块中

    在下面的所有内容中,为了简单起见,我删除了日期格式(哎呀,将它留在 v5 演示中)

    由于在 d3v5 中使用了 d3-fetch 模块,这种方法与更密切相关的 d3v3/v4 有点不同(密切相关在于它们都使用 d3-request 模块,否则会有相当大的差异)。

    d3-fetch: d3v5

    使用 d3v5,使用 d3-fetch 模块的过程可能如下所示:

    var dsv = d3.dsvFormat(";");
    var headers = ["time;number1;number2;number3;number4;number5;\n"]
    
    d3.text("dsv.dsv").then(function(text) {
        var data = dsv.parse(headers+text);
    
        console.log(data);  
        console.log(data.columns);
    
    })
    

    Example

    d3 请求:d3v4

    d3v4 在这方面有更多的灵活性。

    如果我们查看 API 文档,我们会发现 d3.csv 相当于:

    d3.request(url)
        .mimeType("text/csv")
        .response(function(xhr) { return d3.csvParse(xhr.responseText, row); });
    

    (docs)

    因此,如果我们使用 d3.dsvFormat 创建一个新格式,我们可以通过该格式运行内容并获取我们的数据,我们还可以在这个过程中添加标题,一步完成:

    var dsv = d3.dsvFormat(";");
    var headers = ["time;number1;number2;number3;number4;number5;\n"]
    
    d3.request("dsv.dsv")
      .mimeType("text/plain")
      .response(function(data) { return dsv.parse(headers + data.response) })
      .get(function(data) {
        // use data here:   
        console.log(data);  
        console.log(data.columns);
      }); 
    

    Example

    这可能是更不典型的方法,所以我们可以模仿我在上面的 v5 中做的方式:

    var psv = d3.dsvFormat(";");
    var headers = ["time;number1;number2;number3;number4;number5;\n"]
    
    d3.text("dsv.dsv", function(error,data) {
        var data = psv.parse(headers + data.reponse)
    
        console.log(data);  
        console.log(data.columns);
    
    })
    

    Example

    d3 请求:d3v3

    与上面d3v4和d3v5中的第二个选项一样,我们可以解析文本,然后通过dsv格式函数运行它(这里我们只需要考虑d3命名空间在v3/v4之间的变化):

    var dsv = d3.dsv(";","text/plain");
    var headers = ["time;number1;number2;number3;number4;number5;\n"]
    
    d3.text("dsv.dsv", function(error,text) {
        var data = dsv.parse(headers+text);
        console.log(data);  
        // console.log(data.columns) // -> no columns property in v3
    })
    

    Example

    注意

    每行末尾的; 将创建一个空列,因为在它之后的下一行之前应该有一个值。

    【讨论】:

    • 非常感谢您的详细回复 - 这对解决我的问题和提高我的理解很有帮助
    猜你喜欢
    • 1970-01-01
    • 2021-12-11
    • 2015-06-05
    • 1970-01-01
    • 1970-01-01
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多