在csv中阅读日期解析

时间:2017-03-24 21:28:03

标签: javascript date csv d3.js

很难正确加载我的数据。这是带有第一个内容行的标题行:

BookingID,Type,Status,Unit Booked,Unit Owner,Destination,Booking Date,Checkin,Checkout,Renter - FirstName,Renter - LastName,Renter - EmailAddress,Renter - WorkPhone,Renter - HomePhone,#Adults,#Children,Total Stay,Total Paid,Total Due
15642889,House,Confirmed,GV T3 #2106,,,3/20/2016 7:00:00 PM,3/23/2016 3:00:00 PM,3/28/2016 11:00:00 AM,FirstName,LastName,first&last@gmail.com,+1 (000) 000-0000,+1 (000) 000-0000,2,0,895,895,0

按照我的意愿加载和解析我的csv的相关行:

var parseDate = d3.time.format("%m/%d/%Y %H:%M:%S %p").parse;
var data = d3.csv("Sales Export Friendly 3-19-17.csv", function(data) {
    return {
        unit: data["Unit Booked"],
        date: parseDate(data["Booking Date"]).getMonth() + 1,
        checkin: parseDate(data["Checkin"]).getMonth() + 1,
        LOS: parseDate(data["Checkout"]).valueOf() - parseDate(data["Checkin"]).valueOf()/(24*60*60*1000),
        total: +data["Total Stay"],
        avgNight: (+data["Total Stay"]) / ((new Date(data["Checkout"]).valueOf() - new Date(data["Checkin"]).valueOf())/(24*60*60*1000))
        };
});

我的想法是,我会做这样的事情:

d3.parcoords()("#TopLeft").alpha(0.4)
        .data(data)
        .dimensions(data.columns)

如果我尝试console.log(data.columns);在我的回调函数之后,我得到了未定义。这是console.log(数据);打印,看起来很奇怪:

Object { header: Cn/u.header(), mimeType: Cn/u.mimeType(), responseType: Cn/u.responseType(), response: Cn/u.response(), get: Cn/</u[n](), post: Cn/</u[n](), send: Cn/u.send(), abort: Cn/u.abort(), on: M/<(), row: e/o.row() }

我目前得到的错误代码:

TypeError: data.slice is not a function

在d3.parcoords和

上调用数据(数据)时
TypeError: e is undefined

在这一行:

checkin: parseDate(data["Checkin"]).getMonth() + 1,

我对这里出了什么问题非常困惑。我正在使用d3 v3。

1 个答案:

答案 0 :(得分:0)

编辑:我错了。回调是按行的。但是,数据确实在最新版本的d3中异步加载。我很难找到使用此功能的正确方法,但找到了解决方案。 d3.csv现在返回一个承诺。要使用已解析的数据,请将doSomething传递给promise.then()

针对上下文的原始评论:

  

CSV文件是异步加载的,因此请设置   data = d3.csv(path,callback)毫无意义。当您声明一个   回调,那是必须发生的事情。回调可以参考   全局变量,或仅使用局部变量并将结果传递给   下一阶段。根据您的代码判断,您想输出一个对象   保留存储在其下的过滤/后处理列   各自的键。

     

此外,我怀疑时间解析方法是否可以应用于数组。   为此,您可能必须使用array.map。

     

我会建议类似的东西(未经测试):

var parseDate = d3.time.format("%m/%d/%Y %H:%M:%S %p").parse;
d3.csv("Sales Export Friendly 3-19-17.csv", function(data) {
    //Note that data is a local in this function scope
    let filtered_data = {
        unit: data["Unit Booked"],
        date: data["Booking Date"].map(s=>parseDate().getMonth()+1),
        checkin: data["Checkin"].map(s=>parseDate().getMonth()+1),
        total: data["Total Stay"].map(s=>+s),
    };

    filtered_data.LOS = [];
    filtered_data.avgNight = [];
    let N = data["Checkout"].length;
    for (let i=0; i < N; i++) {
        filtered_data.LOS[i] = parseDate(data["Checkout"][i]).valueOf() -parseDate(data["Checkin"][i]).valueOf()/(24*60*60*1000),
        filtered_data.avgNight[i] = (+data["Total Stay"][i])/filtered_data.LOS[i];
    }
    doSomething(filtered_data);
});