Csv для массива в d3.js
Я использую это, чтобы разобрать файл csv и создать данные массива, как указано в d3 docs:
d3.csv("afile.csv", function(data) {
data.forEach(function(d) {
d.date = formatDate.parse(d.date);
d.price = +d.price;
});
Однако, если после этого метода я пытаюсь вызвать data[0]
, он говорит, что это undefined. Это потому, что data
является ссылкой и один раз d3.csv()
выходит за пределы области действия. Если это так, то как я могу это преодолеть. Мне нужно ссылаться на данные из d3.csv()
Ответы
Ответ 1
d3.csv - асинхронный метод. Это означает, что код внутри функции обратного вызова запускается при загрузке данных, но код после и вне функции обратного вызова будет запускаться сразу после запроса, когда данные еще не доступны. Другими словами:
first();
d3.csv("path/to/file.csv", function(rows) {
third();
});
second();
Если вы хотите использовать данные, загруженные d3.csv, вам нужно поместить этот код внутри функции обратного вызова (где third
есть выше):
d3.csv("path/to/file.csv", function(rows) {
doSomethingWithRows(rows);
});
function doSomethingWithRows(rows) {
// do something with rows
}
Или вы можете сохранить его как глобальную переменную в окне, о которой вы можете впоследствии обратиться:
var rows;
d3.csv("path/to/file.csv", function(loadedRows) {
rows = loadedRows;
doSomethingWithRows();
});
function doSomethingWithRows() {
// do something with rows
}
Если вы хотите, вы также можете явно назначить загруженные данные объекту окна, а не объявлять переменную, а затем управлять двумя разными именами:
d3.csv("path/to/file.csv", function(rows) {
window.rows = rows;
doSomethingWithRows();
});
function doSomethingWithRows() {
// do something with rows
}
Ответ 2
Я думаю, что ваша проблема - это время, потому что это асинхронный вызов. Итак, загрузите данные, как есть, но вызовите функцию в коде d3 (где у Майка есть doSomethingWithRows()). Не следуйте своему коду d3 с какой-либо дополнительной обработкой (где у Майка есть "second()" ), переместите этот код в функцию doSomethingWithRows(). Он будет иметь доступные данные и уйти...
Ответ 3
Я думаю, что проблема уже решена, но я столкнулся с аналогичной проблемой, и вышеупомянутое обсуждение было не так полезно. Итак, отправляю, как я понял выход из этой проблемы: вот почему data[0]
есть undefined, вероятно, потому, что сам браузер не читается браузером. Эта ошибка чтения, вероятно, связана с прямой загрузкой файла данных (csv), то есть с использованием следующей команды d3.csv("myCSVfile.csv",....)
. Этот подход может не работать, потому что веб-приложениям обычно требуется загрузка файлов с веб-серверов (не знаю, почему это так). Поэтому необходимо создать локальный веб-сервер. Используйте этот форум, чтобы узнать, как: Как настроить локальный HTTP-сервер с помощью Python. Обновленный код, если вы используете Python 3 для создания локального веб-сервера, будет: d3.csv("http://localhost:8000/myCSVfile.csv",.....)
.
Ответ 4
Вы можете объявить переменную вне функции обратного вызова, а затем присвоить ей значения из csv:
var csv_data;
d3.csv("afile.csv", function(data) {
data.forEach(function(d) {
d.date = formatDate.parse(d.date);
d.price = +d.price;
csv_data = data;
});
а затем используйте csv_data вне обратного вызова