Почему эта функция vanilla js возвращает разные результаты в d3v3 и d3v4

Это MWE, основанный на некоторых шаблонах от v3 до v4 изумительного d3.js.

Данные находятся в 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, я не понимаю, почему эта ванильная функция JS возвращает разные результаты, и что с этим делать? Любая помощь будет принята с благодарностью.

1 ответ

Решение

Причина этого различия заключается в том, что D3 v4.x создает дополнительное свойство с именем columns к data массив, когда он анализирует CSV (см. документацию).

Так, например, учитывая ваши данные:

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

D3 создает после "обычных" объектов этот дополнительный объект (технически говоря, дополнительное свойство для массива):

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

Который вы можете позвонить, используя data.columns,

Проблема, с которой вы сталкиваетесь сейчас, заключается в том, что когда вы используете for...in Цикл, в конечном итоге вы итерируете это свойство, получая много NaN.

Решение: вы можете просто избежать перебора columns или, если вам это не нужно, вы можете удалить его из своих данных. Существует несколько способов удаления свойства из массива в JavaScript, более простой способ заключается в следующем:

delete incData.columns;

Чтобы проверить это columns собственность, просто console.log(data) используя D3 v3 и v4, сравнивая результаты.

Другие вопросы по тегам