4

I know this question has been asked before but their solutions dont see to work for me for some reason.

I am trying to populate two arrays with data from a CSV file where:

name,value
alpha,34
beta,12
delta,49
gamma,89

What I am trying now is

var field1=[];
var field2=[];

d3.csv("data.csv",function(csv){
            csv.map(function(d){
                field1.push(d.name);
                field2.push(+d.value);
            })
        });

console.log("field1",field1);
console.log("field2",field2);

When I view console on my browser I see:

field1 Array [ ] field2 Array [ ]

where:

field1:
Array[0]
  0:"alpha"
  1:"beta"
  2:"delta"
  3:"gamma"

field2:
Array[0]
  0:34
  1:12
  2:49
  3:89

However when I try to access field1[0], I get the value as undefined

field1 undefined

What I guess is happening is field1 array has an array of arrays of "name" column, but I'm not able to access the first element though field[0][0] either. What I get is:

TypeError: field1[0] is undefined 

I'm very new to JavaScript and I don't seem to understand why the array is not populated correctly as a 1 dimensional array or if I'm doing something wrong. I am aware that I can iterate through each row while accessing csv per row but I want to store the csv values in array to be used globally in the script.

Links I have gone through are:

But I seem to be missing or overlooking something.. Please help!

Community
  • 1
  • 1
j_0101
  • 157
  • 4
  • 14

1 Answers1

3

The reason is that

d3.csv("data.csv",function(csv){

is an ajax call so you cannot write something like below (your console log is called before the ajax is completed so you get unexpected results):

var field1=[];
var field2=[];

d3.csv("data.csv",function(csv){
            //executed after successful loading of data
            csv.map(function(d){

                field1.push(d.name);
                field2.push(+d.value);
            })
        });
//called before the loading of AJAX call got completed
console.log("field1",field1);
console.log("field2",field2);

The correct way is:

var field1=[];
var field2=[];

d3.csv("data.csv",function(csv){
            csv.map(function(d){
                field1.push(d.name);
                field2.push(+d.value);
            })
            //called after the AJAX is success
            console.log("field1",field1);
            console.log("field2",field2);
            console.log("field1",field1[0]);
        });

working code here

Hope this helps!

rafforaffo
  • 511
  • 2
  • 7
  • 21
Cyril Cherian
  • 32,177
  • 7
  • 46
  • 55
  • This works! However, is it not possible to somehow store this data outside the csv read in order to do something like concatenate data from multiple csv files and process it for visualization? – j_0101 Jan 30 '16 at 15:58
  • without nesting that is – j_0101 Jan 30 '16 at 16:04
  • yeah you can check this answer http://stackoverflow.com/questions/21842384/importing-data-from-multiple-csv-files-in-d3 or use d3-queue to load several csv https://github.com/d3/d3-queue – Cyril Cherian Jan 31 '16 at 12:55
  • Yes, this solution is correct but painfully un-scalable and results in unreadable code if you've got 20 or 30 operations on that CSV data you need to do. Stupid asynchronous methods! There has to be a better way... – Hack-R Apr 06 '17 at 18:27