-1

I am trying to read data from a csv file, and I want to store the data of each column in an array as in the code below. The problem that I get and I didn't know how to fix is that all the values are defined inside the brackets, but once I try to deal with the arrays else where, the data is undefined. Any ideas about what is going wrong? My version of D3 is v3.

<script>

var computerid = [];
var timestamp = [];
var percentage = [];

d3.csv("cpu-util.csv", function(data) {
    for (var i = 0; i < data.length; i++) {
        timestamp[i] = data[i].timestamp;
        computerid[i] = data[i].Computer_ID; 
        percentage[i] = data[i].Percentage;
        console.log(computerid[i]); //prints value
        console.log(timestamp[i]);
        console.log(percentage[i]);

    }
});

console.log(computerid[1]); //here, it prints undefined although inside the loop it prints values

Part of the csv file:

Computer_ID, timestamp, value, Percentage

1, 01-07-11 0:00, 0.8, 8

  • There is not enough information to provide an answer for this question. Please consider providing more information. – Coola Mar 24 '19 at 18:38
  • I have updated the question after figuring out somethings. The problem is that my values are defined inside the loop, but outside it, the values are not defined. – Maha Alrasheed Mar 24 '19 at 19:00
  • Yes the scope of the variable could be a major issue. In JS, the variable scope would be defined based on where it is declared. – Coola Mar 24 '19 at 19:05
  • It wasn't declared inside any function, all the arrays are global variables. – Maha Alrasheed Mar 24 '19 at 19:09
  • Could you post a part of the csv file as well. To see the data structure. – Coola Mar 24 '19 at 19:10
  • Based on the above code the array `computerid` is scoped within the function and is not a global variable. Hence when you are outside the function it will show as undefined because it was not declared outside the function. – Coola Mar 24 '19 at 19:12
  • Actually I forgot to paste the part where I declared the arrays, I think they are global. – Maha Alrasheed Mar 24 '19 at 19:19
  • Ah I see, so they are globally defined. But now we come to asynchronous code. JS runs in asynchronous manner. Read more about it here: https://www.pluralsight.com/guides/introduction-to-asynchronous-javascript . That is possibly the reason why you are seeing this. – Coola Mar 24 '19 at 19:23
  • Possible duplicate of [How do I return the response from an asynchronous call?](https://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) – altocumulus Mar 24 '19 at 19:25
  • Oh I see now, I didn't know about the asynchronous behavior. Thank you all! – Maha Alrasheed Mar 24 '19 at 19:30
  • There is also additional problems with your code which I will highlight below based on the CSV data you have provided. – Coola Mar 24 '19 at 19:33
  • Hi @MahaAlrasheed I have provided some tips which will help you get started below. Hopefully it helps. Please mark as answer if you feel it provides enough information to get started at least. – Coola Mar 24 '19 at 19:50

1 Answers1

0

Your CSV data needs to be in the correct format. There are a few unnecessary spaces which makes it difficult to parse as it includes the spaces in the header names on the basis of which it keeps the property names in the objects.

cpu-util.csv should be

Computer_ID,timestamp,value,Percentage
1,01-07-11 0:00,0.8,8

In addition d3.js parses the data keeping the header labels. therefore computerid array should be filled using the Computer_ID property of the data. Thus your code should be something like:

<script>
   var timestamp = [],
       computerid = [],
       percentage = [];

 d3.csv("cpu-util.csv", function(data) {
   console.log(data); //see the data structure
    for (var i = 0; i < data.length; i++) {
        timestamp[i] = data[i].timestamp; //use the property names.
        computerid[i] = data[i].Computer_ID; 
        percentage[i] = data[i].Percentage;
        console.log(computerid[i]);
        console.log(timestamp[i]);
        console.log(percentage[i]);
    }
     console.log(computerid[0]); //this will appear as it is within the function and 
                                 //the array is filled by the time this line is run
  });

  console.log(computerid[0]); //this will be undefined due to the asynchronous nature of javascript. 
                              //This line of code runs before the for loop within the function
</script>

If you see the console log, the console.log(computerid[0]) will appear first in the log before the other three in the function, due to the asynchronous nature of javascript. There are ways in which you can chain functions to make them synchronous using either Async/Await or Promises.

Also d3.js parses all the information as strings. So number values such as Percentage would need to be converted to number data types using a function. Just keep this in mind.

Coola
  • 2,934
  • 2
  • 19
  • 43
  • Thank you so much! I didn't know about this asynchronous behavior. Again, thanks! – Maha Alrasheed Mar 26 '19 at 19:20
  • Please mark the question as answered if you are happy with the answer and also up vote it if you like it. https://stackoverflow.com/help/someone-answers – Coola Mar 26 '19 at 19:26