如何从d3.scale.linear()。domain()中使用的对象数组中获取最大值

时间:2013-05-02 22:22:24

标签: javascript arrays d3.js

我有一个外部csv文件,其数据列如下:

name, field_goal_attempts, field_goal_makes

我正在尝试使用线性刻度,但遇到难以获得我的域的最大值。

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

我很困惑:

1)我是否应该将yScale函数放在

之外或之内
d3.csv("filename.csv", function(data) {

回调函数;和

2)如何获取field_goal_attempts列中项目的最大值,然后输入yScale函数。

这是我目前的代码:

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
        });
});

2 个答案:

答案 0 :(得分:32)

csv文件中的数据将在您传递给csv函数的回调中(在您的情况下是“data”参数)。因此,您可以在csv函数之外定义yScale,但如果您希望max与数据相关,则需要在回调中设置它。

至于查找max,许多在数组上工作的D3函数都会接受可选的访问器函数,以精确地处理您的场景。所以计算我将使用的最大值:

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

所以你可以把两种方式中的一种放在一起:

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]);
    ...
}

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]);
    ...
}

如果你想找到max和min,那么我建议使用d3.extent(...),它也应该接受一个访问器函数,并返回一个长度为2的数组,其中包含最小值和最大值。

答案 1 :(得分:2)

1)只要在计算最大值时更新函数内部的域,yScale就可以保持在d3.csv()函数之外。例如,您可以在d3.csv()内执行以下操作:

yScale.domain([0, my_max])

2)要计算最大值,这里是我通常使用的方法:

//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)

确实将这样的函数传递给d3.max()会很好,但据我所知,事实并非如此。首先计算列表然后计算最大值的优点是,如果要计算最小值,平均值或其他任何值,则计算量较少。