2012-02-29 50 views
33

estoy usando esto para analizar un archivo CSV y crear una serie de datos como se especifica en la documentación D3:csv a matriz en d3.js

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

Sin embargo, si después de este método Trato de llamar data[0] que dice no está definido ¿Esto es porque data es una referencia y una vez que d3.csv() está fuera de alcance se destruye? Si este es el caso, ¿cómo puedo superar esto? Necesito hacer referencia a los datos de d3.csv()

Respuesta

120

d3.csv es un método asíncrono. Esto significa que el código dentro de la función de devolución de llamada se ejecuta cuando se cargan los datos, pero el código después y fuera de la función de devolución de llamada se ejecutará inmediatamente después de realizar la solicitud, cuando los datos aún no están disponibles. En otras palabras:

first(); 
d3.csv("path/to/file.csv", function(rows) { 
    third(); 
}); 
second(); 

Si desea utilizar los datos que se carga por d3.csv, que o bien tienen que poner ese código dentro de la función de devolución de llamada (donde third es decir, más arriba):

d3.csv("path/to/file.csv", function(rows) { 
    doSomethingWithRows(rows); 
}); 

function doSomethingWithRows(rows) { 
    // do something with rows 
} 

O bien, puede guardarlo como una variable global en la ventana que se puede hacer referencia a más tarde:

var rows; 

d3.csv("path/to/file.csv", function(loadedRows) { 
    rows = loadedRows; 
    doSomethingWithRows(); 
}); 

function doSomethingWithRows() { 
    // do something with rows 
} 

Si lo desea, también puede asignar los datos cargados de forma explícita al objeto de ventana, en lugar de declarar una variable y luego la gestión de dos nombres diferentes:

d3.csv("path/to/file.csv", function(rows) { 
    window.rows = rows; 
    doSomethingWithRows(); 
}); 

function doSomethingWithRows() { 
    // do something with rows 
} 
+0

¿Hay alguna forma de leer de MongoDB usando d3.js? –

+0

@SGaber No creo que sea una buena idea pasar sus credenciales de base de datos a los usuarios. – TranslucentCloud

-2

Se puede declarar una variable fuera de la función de devolución de llamada y luego asignarlo con los valores de la 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; 
}); 

y luego usar CSV_data fuera de la devolución de llamada

+0

Pero ese es exactamente mi problema. Cada vez que hago referencia a csv_data fuera de la devolución de llamada, todo lo que obtengo no está definido. Dentro de la devolución de llamada está bien. Es por eso que asumí que csv_data tiene una referencia de datos y, por lo tanto, una vez que la función sale del alcance, la referencia se destruye. Sin embargo, he resuelto el problema siguiendo un enfoque completamente diferente. Gracias por la respuesta –

+1

Ok, lo siento, no para ayudar al final, pero considere publicar su solución o cambio de enfoque si es útil para futuras referencias a otros usuarios – msonsona

+1

¿Cuál fue el enfoque completamente diferente? – Donnied

3

Creo que su problema es el tiempo, porque es una llamada asincrónica. Por lo tanto, cargue los datos como lo ha hecho, pero llame a la función dentro del código d3 (donde Mike tiene 'doSomethingWithRows()'). No siga su código d3 con más procesamiento (donde Mike tiene 'segundo()'), mueva ese código a la función 'doSomethingWithRows()'. Tendrá los datos disponibles y listo ...

0

Creo que el problema ya está resuelto, pero me enfrenté a un problema similar y la discusión anterior no fue tan útil. Así que publicando cómo calculé una salida a este problema: aquí, la razón por la cual data[0] no está definido es probablemente porque el navegador no lee los datos en sí. Es probable que esta falla al leer cargue directamente el archivo de datos (csv), es decir, utilizando el siguiente comando d3.csv("myCSVfile.csv",....). Este enfoque puede no funcionar porque las aplicaciones web normalmente requieren cargar archivos de los servidores web (no estoy seguro de por qué este es el caso). Por lo tanto, un servidor web local debe implementarse. Utilice este foro para aprender cómo: How do I setup a local HTTP server using Python. El código actualizado, si usa Python 3 para crear un servidor web local será: d3.csv("http://localhost:8000/myCSVfile.csv",.....).