more d3.csv questions

1,053 views
Skip to first unread message

Rick Otten

unread,
May 18, 2011, 11:43:28 AM5/18/11
to d3...@googlegroups.com
I'm still experimenting with d3.csv, and perhaps my javascript
inexperience is once again tripping me up here.

When I read in a csv and do stuff with the data I use something like:

d3.csv("my.csv", function(csv) { --stuff-- });

This is working pretty well for me. It is a handy feature, thanks!


What I'd like to do now is that I'd like to read in two csv's and mingle
their data in my charts.

1) It isn't obvious to me out to get the data out of the d3.csv() call to
the more global javascript function that I'm calling it from so I can pick
and choose data from different csv's. (ie, "de-localize it?" or return
it)

2) what is the variable "csv" that I'm passing to the function()? Is that
like the 'd' and 'i' that I use in other D3 calls over the data?

I can easily write a script to merge the two CSV files, but I'd rather
leave them as-is and solve the problem of merging some of the columns in
javascript if I can.


--
Rick Otten
rot...@windfish.net
O=='=+


Justin Palmer

unread,
May 18, 2011, 1:46:00 PM5/18/11
to d3...@googlegroups.com, rot...@windfish.net
The variable "csv" in your function is the array of csv data you just loaded.  Basically it's saying: "Hey, after you load this csv file, name the resulting array from it 'csv' and use it in this function".

Below is an example where one dataset needs to interact with data from a second dataset.  You likely need to nest your callbacks because csv loading is asynchronous.

d3.csv('foo.csv', function(array_of_csv_data) {
  d3.csv('bar.csv', function(second_array_of_csv_data) {
    // Both CSV files are fully loaded here
    data1 = array_of_csv_data[0]
    data2 = second_array_of_csv_data[data1.some_var]
    call_some_global_function(data2)
  })
})

 -Justin

Mike Bostock

unread,
May 18, 2011, 1:57:22 PM5/18/11
to d3...@googlegroups.com
Yep, there are a few ways that you can handle multiple asynchronous loads.

1. Load them serially.

This is the slowest way of doing it, but it's also the simplest to
implement. Justin illustrated this example.

2a. Load them in parallel, checking each source explicitly.

In this case, you typically have two global variables (though you can
use closures to avoid globals), and you assign the value of each
global in the appropriate callback. So, if we wanted to load `foo` and
`bar` in respective CSV files, we would say:

var foo, bar;

d3.csv("foo.csv", function(csv) {
foo = csv;
if (bar) visualize();
});

d3.csv("bar.csv", function(csv) {
bar = csv;
if (foo) visualize();
});

Then you'd put your visualization code in a function called
`visualize`, which will only be called once both foo and bar are
loaded.

2b. Load them in parallel, counting outstanding requests.

This method is a bit simpler when you have a lot of things to load in
parallel. Rather than foo checking bar, and bar checking foo, you just
count your outstanding requests and visualize when they've all
completed.

var remaining = 2, foo, bar;

d3.csv("foo.csv", function(csv) {
foo = csv;
if (!--remaining) visualize();
});

d3.csv("bar.csv", function(csv) {
bar = csv;
if (!--remaining) visualize();
});

Don't forget to update the value of `remaining` if you add or remove requests!

Mike

Reply all
Reply to author
Forward
0 new messages