Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get maximum value from an array of objects to use in d3.scale.linear().domain()

Tags:

I have an external csv file with data in columns like so:

name, field_goal_attempts, field_goal_makes

I am trying to use a linear scale but am encountering difficulty getting the maximum value for my domain.

var yScale = d3.scale.linear()
               .domain(0, d3.max(...

I am confused as to:

1) Whether I should put the yScale function outside or inside the

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

callback function; and

2) How to get the maximum value of items in the field_goal_attempts column to then feed into the yScale function.

Here is my code at present:

var yScale = d3.scale.linear()
    .domain([0, 4000]) //d3.max(data, function(d) {return d })])
    .range([0, 500]);

d3.csv("test.csv", function (data) {
    svg.selectAll("rect")
        .data(data)
        .enter()
        .append("rect")
        .attr("fill", "blue")
        .attr("x", magic_number) // I'm not concerned about the magic numbers at this point :)
        .attr("y", 0)
        .attr("width", another_magic_number)
        .attr("height", function (d) {
            return d.field_goal_attempts
        })
        .attr("id", function (d, i) {
            return i
        });
});
like image 930
Emil Avatar asked May 02 '13 22:05

Emil


People also ask

Which function returns an array containing the smallest and largest data points in d3?

min is d3. max, which returns the maximum value.

What is d3 scale linear?

The d3. scaleLinear() method is used to create a visual scale point. This method is used to transform data values into visual variables.

What is d3 scale?

D3 has around 12 different scale types (scaleLinear, scalePow, scaleQuantise, scaleOrdinal etc.) and broadly speaking they can be classified into 3 groups: scales with continuous input and continuous output. scales with continuous input and discrete output. scales with discrete input and discrete output.


2 Answers

The data in your csv file will be in the callback you pass to the csv function (in your case the "data" parameter). So you can define yScale outside of the csv function, but if you want the max to be data dependent you will need to set it inside the callback.

As for finding the max, many D3 functions that work on arrays will accept optional accessor functions for precisely your scenario. So computing the max I would use:

var max = d3.max(data, function(d) { return +d.field_goal_attempts;} );

So you could put it all together one of two ways:

var yScale = d3.scale.linear().domain(0,100);
d3.csv("test.csv", function(data){
    var max = d3.max(data, function(d) { return +d.field_goal_attempts;} );
    yScale.domain([0,max]);
    ...
}

or

d3.csv("test.csv", function(data){
    var max = d3.max(data, function(d) { return +d.field_goal_attempts;} );
    var yScale = d3.scale.linear().domain([0,max]);
    ...
}

If you want to find both max and min then I suggest using d3.extent(...) which should also accept an accessor function and will return an array of length 2 with the min and max values.

like image 104
Superboggly Avatar answered Nov 18 '22 14:11

Superboggly


1) The yScale can stay outside of the d3.csv() function as long as you update the domain inside of the function when having computed the max. For example you could do the following inside of d3.csv():

yScale.domain([0, my_max])

2) To compute the max, here is the method I usually use:

//Create list containing only field_goal_attempts
field_goal_attempts_list = data.forEach(function(d){return d.field_goal_attempts})

//Compute max using d3.max() function
field_goal_attempts_max = d3.max(field_goal_attempts_list)

It is true that passing such function to d3.max() would be great but as far as I know it is not. The advantage of first computing the list and then computing the max is that you do less computation if you want to compute the min, the mean or anything else.

like image 40
Christopher Chiche Avatar answered Nov 18 '22 14:11

Christopher Chiche