为什么这个vanilla js函数在d3v3和d3v4中返回不同的结果

时间:2016-09-03 12:21:29

标签: javascript d3.js d3v4

这是一个MWE,基于从惊人的d3.js的v3到v4的一些模板。

数据在csv文件中,两个示例都加载相同的文件(干净):

day,movie1,movie2,movie3,movie4,movie5,movie6
1,20,8,3,0,0,0
2,18,5,1,13,0,0
3,14,3,1,10,0,0
4,7,3,0,5,27,15
5,4,3,0,2,20,14
6,3,1,0,0,10,13
7,2,0,0,0,8,12
8,0,0,0,0,6,11
9,0,0,0,0,3,9
10,0,0,0,0,1,8

这是有问题的MWE:

d3.csv("../data/source/movies.csv", function (error, data) {
dataViz(data)});

function dataViz(incData) {
expData = incData;
stackData =[];    

for (x in incData[0]) {
    if (x != "day") {
        var newMovieObject = {
            name: x, values:[]
        };             
        for (y in incData) {
            newMovieObject
            .values
             .push({
                x: parseInt(incData[y][ "day"]), 
                y: parseInt(incData[y][x])
            })
        }
        stackData
        .push(newMovieObject);
    }}}

现在在v3中,stackData数组有6个对象,每个对象具有 10 值,例如:

{name: "movie1" values:[
  {x: 1, y:20} //0
  ... 
  {x:10, y:0} //9
]
…

}

在v4中,我得到一个包含6个对象的数组,每个对象的 11 值,最后一个令人讨厌的是:

{name: "movie1" values:[
  {x: 1, y:20} //0
  ... 
  {x:10, y:0} //9
  {x: NaN, y: NaN} //10 *ouch*
]
…

}      

作为一个js noob,我不明白为什么这个vanilla JS函数返回不同的结果,该怎么办呢?任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:1)

造成这种差异的原因是D3 v4.x在解析CSV时会向columns数组创建一个名为data的附加属性(查看the documentation)。

所以,例如,给出你的数据:

day,movie1,movie2,movie3,movie4,movie5,movie6
1,20,8,3,0,0,0
2,18,5,1,13,0,0
...

D3在" normal"之后创建对象,这个附加对象(从技术上讲,对数组来说是一个额外的属性):

columns: ["day", "movie", "movie2", "movie3", "movie4", "movie5", "movie6"]

您可以使用data.columns拨打电话。

您现在遇到的问题是,当您使用for...in循环时,您最终也会迭代此属性,从而获得大量NaN。

解决方案:您可以简单地避免迭代columns,或者如果您不需要,可以将其从数据中删除。在JavaScript中有几种从数组中删除属性的方法,更简单的方法是:

delete incData.columns;

要检查此columns属性,只需使用D3 v3和v4 console.log(data),比较结果。