Почему эта функция 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, сравнивая результаты.