web-dev-qa-db-ja.com

オブジェクトの配列から最大値を取得してd3.scale.linear()。domain()で使用する方法

私は次のような列にデータを含む外部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
        });
});
20
Emil

Csvファイルのデータは、csv関数に渡すコールバックにあります(この場合、「data」パラメーター)。したがって、csv関数の外でyScaleを定義できますが、最大値をデータ依存にする場合は、コールバック内で設定する必要があります。

最大値を見つけることに関しては、配列で機能する多くのD3関数は、正確にシナリオに応じてオプションのアクセサー関数を受け入れます。したがって、私が使用する最大値を計算します:

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

したがって、次の2つの方法のいずれかですべてをまとめることができます。

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の両方を検索したい場合は、アクセサ関数も受け入れ、最小値と最大値を含む長さ2の配列を返すd3.extent(...)を使用することをお勧めします。

34
Superboggly

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()に渡すのは素晴らしいことですが、私が知る限りそうではありません。最初にリストを計算し、次に最大値を計算することの利点は、最小値、平均値などを計算する場合、計算量が少なくて済むことです。

2