2012-02-29 3 views
33

Я использую это для разбора CSV-файла и создать массив данных, как указано в d3 документации:CSV в массив в d3.js

d3.csv("afile.csv", function(data) { 
    data.forEach(function(d) { 
    d.date = formatDate.parse(d.date); 
    d.price = +d.price; 
}); 

Однако, если после этого метода я пытаюсь вызвать data[0] это говорит он не определен. Это потому, что data является ссылкой и один раз d3.csv() не входит в сферу действия? Если это так, то как я могу это преодолеть. Мне нужно ссылаться на данные из d3.csv()

ответ

120

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 
} 
+0

есть в любом случае, чтобы читать из MongoDB с помощью d3.js? –

+0

@SGaber Я не думаю, что это хорошая идея передать ваши учетные данные для пользователей. – TranslucentCloud

-2

Вы можете объявить переменную вне функции обратного вызова, а затем присвоить его значения из 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 вне обратного вызова

+0

Но это точно моя проблема. Всякий раз, когда я ссылаюсь на csv_data вне обратного вызова, я получаю undefined. Внутри обратного вызова просто отлично. Вот почему я предположил, что csv_data имеет ссылку на данные, и поэтому, когда функция выходит за рамки, эта ссылка уничтожается. Тем не менее, я решил проблему, следуя совершенно другому подходу. Спасибо за ответ –

+1

Хорошо, извините, что не помогайте в конце, но подумайте о размещении своего решения или изменении подхода, если это полезно для будущей ссылки на других пользователей. – msonsona

+1

Какой был совершенно другой подход? – Donnied

3

Я думаю, ваша проблема заключается во времени, потому что это асинхронная вызов. Итак, загрузите данные, как есть, но вызовите функцию в коде d3 (где у Майка есть doSomethingWithRows()). Не следуйте своему коду d3 с какой-либо дополнительной обработкой (где у Майка есть «second()»), переместите этот код в функцию doSomethingWithRows(). Он будет иметь данные и уйти ...

0

Я думаю, проблема уже решена, но я столкнулся с аналогичной проблемой, и вышеупомянутое обсуждение было не так полезно. Итак, отправляю, как я понял выход из этой проблемы: здесь причина, по которой data[0] не определена, вероятно, связана с тем, что сам браузер не читается браузером. Эта ошибка чтения, вероятно, связана с прямой загрузкой файла данных (csv), то есть с использованием следующей команды d3.csv("myCSVfile.csv",....). Этот подход может не работать, потому что веб-приложениям обычно требуется загрузка файлов с веб-серверов (не знаю, почему это так). Поэтому необходимо создать локальный веб-сервер. Используйте этот форум, чтобы узнать, как: How do I setup a local HTTP server using Python. Обновленный код, если вы используете Python 3 для создания локального веб-сервера, будет: d3.csv("http://localhost:8000/myCSVfile.csv",.....).

Смежные вопросы