Using d3.extent to define a scale domain returns NaN

1,861 views
Skip to first unread message

Matz

unread,
Feb 24, 2013, 5:30:53 PM2/24/13
to d3...@googlegroups.com

Hi all,
I'm new to data visualization and I've been using d3 since a few months. I really start to enjoy using all the possibilities it offers. 

I encountered a problem when defining a scale with the d3.extent method.I have a simple key:value array and i want to define a scale.domain based on the max and min value of this array, so i use d3.extent(d3.values(myarray))
When i use it in the console, all is well and i get my [min,max]
But in the script itself, when i write var myscale=d3.scale.sqrt().domain(d3.extent(d3.values(myarray)))

myscale.domain() returns[NaN,NaN].

Am i doing something wrong ?

Thanks a lot!

Simon Russell

unread,
Feb 24, 2013, 5:37:03 PM2/24/13
to d3...@googlegroups.com
What are the min and max you're getting?


--
You received this message because you are subscribed to the Google Groups "d3-js" group.
To unsubscribe from this group and stop receiving emails from it, send an email to d3-js+un...@googlegroups.com.
For more options, visit https://groups.google.com/groups/opt_out.
 
 

Ian Johnson

unread,
Feb 24, 2013, 5:59:51 PM2/24/13
to d3...@googlegroups.com

Can you post a sample of your data? Is it coming from CSV? Might need to parse out the numbers before calling extent. Also you may need to pass a function to extent to tell it where to find the values.

Matz

unread,
Feb 24, 2013, 8:12:25 PM2/24/13
to d3...@googlegroups.com
Yes it's coming from a CSV file, here's the beginning of the file
"IndicatorName","IndicatorCode","CountryName","countryCode","val"
"Population, total",SP.POP.TOTL,Afghanistan,AFG,34385068
"Population, total",SP.POP.TOTL,Albania,ALB,3204284
"Population, total",SP.POP.TOTL,Algeria,DZA,35468208
"Population, total",SP.POP.TOTL,American Samoa,ASM,68420


// creates an associative array with id:val pairs
var cVal = {};
d3.csv(fileToLoad, function(error,data){
data.forEach(function(d, i){
cVal[d.countryCode] = +d.val;
});
});

var myScale = d3.scale.sqrt()
.domain(d3.extent(d3.values(cVal)))
.range([0,d3.round(svgSize.w*.95)]);

No double quotes in the CSV file and the console command gets the correct values...
Here's what chrome console returns:
myScale.domain()
[NaN, NaN]
d3.extent(d3.values(cVal))
[9827, 1337825000]

Simon Russell

unread,
Feb 24, 2013, 8:21:44 PM2/24/13
to d3...@googlegroups.com
Right. Does the scale actually work as expected? Perhaps domain() (with no args) just isn't working.

(As an aside, you could consider using d3.map (see https://github.com/mbostock/d3/wiki/Arrays#wiki-d3_map) instead of an Object for your country -> population map)


--

Matz

unread,
Feb 24, 2013, 9:28:02 PM2/24/13
to d3...@googlegroups.com
No, the scale doesn't work. The method scale.domain() without args returns the domain values assigned in the first part.
I also tried to use [d3.min(array),d3.max(array)] but had the same result.

I've been thinking about using d3.map, it's probably going to be the next step.

Simon Russell

unread,
Feb 24, 2013, 9:29:26 PM2/24/13
to d3...@googlegroups.com
What if you hard code the domain, instead of calculating it?
Message has been deleted

Matz

unread,
Feb 24, 2013, 10:01:31 PM2/24/13
to d3...@googlegroups.com
It works and that's what i did to move on with the rest of the script, but i need it to be dynamic. 

my cVal is an object, not an array, and i think that's why extent min or max don't work with it.
I'm looking at d3.map an feels it could be the way out.
Once the csv parsed, the data looks like below:

I'm looking for a way to make a simple array with the val. Then the extent function will work better.


Array[212]
  1. [0 … 99]
    1. 0Object
      1. CountryName"Afghanistan"
      2. IndicatorCode"SP.POP.TOTL"
      3. IndicatorName"Population, total"
      4. countryCode"AFG"
      5. val"34385068"
      6. __proto__Object
    2. 1Object
    3. 2Object

Simon Russell

unread,
Feb 24, 2013, 10:18:01 PM2/24/13
to d3...@googlegroups.com
Oh, right, what am I saying.  I just re-examined your code.  It's because the .csv call is asynchronous.  cVal doesn't have any values at the point you're doing the d3.extent.


--

Mathieu Chesnel

unread,
Feb 24, 2013, 10:30:37 PM2/24/13
to d3...@googlegroups.com
That makes sense. I thought because I parsed the csv in an array it would be first stored and then the code would go on. 
I could probably use the queue function to force the full loading of the file before going further, but that will slow down the whole thing...


2013/2/24 Simon Russell <si...@bellyphant.com>

Simon Russell

unread,
Feb 24, 2013, 10:32:51 PM2/24/13
to d3...@googlegroups.com
I have no idea how your code is structured, but you can also just put everything inside the function you pass to 'csv'.

Simon.


Mathieu Chesnel

unread,
Feb 24, 2013, 10:49:51 PM2/24/13
to d3...@googlegroups.com
I have 2 sources files, but if i load one into the other it just might work.
I that case i guess the scale.domain will be empty at first but will update when the right data kick in right ?

I'm going to give it a try. Thanks for the suggestion.


2013/2/24 Simon Russell <si...@bellyphant.com>
You received this message because you are subscribed to a topic in the Google Groups "d3-js" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/d3-js/INRV7dDj7pg/unsubscribe?hl=en.
To unsubscribe from this group and all its topics, send an email to d3-js+un...@googlegroups.com.

Simon Russell

unread,
Feb 24, 2013, 11:06:37 PM2/24/13
to d3...@googlegroups.com
Yeah, that's basically it.  You'll need to redraw whatever graph as well, if you're drawing it outside the csv call.

Mathieu Chesnel

unread,
Feb 25, 2013, 11:37:20 AM2/25/13
to d3...@googlegroups.com
I just made the change and it works perfectly, thanks again!


2013/2/24 Simon Russell <si...@bellyphant.com>
Reply all
Reply to author
Forward
0 new messages