2013-05-02 28 views
16

我有數據的外部CSV文件中列像這樣:如何從對象d3.scale.linear使用數組獲得最大值()域()

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

回答

28

你的csv文件中的數據將在你傳遞給csv函數的回調中(在你的情況下是「data」參數)。因此,您可以在csv函數之外定義yScale,但是如果您希望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]); 
    ... 
} 

如果你想找到這兩個最大和那麼我建議使用d3.extent(...),它也應該接受一個存取函數,並且將返回一個長度爲2的數組,其中包含最小值和最大值。

+1

感謝您的幫助。這是我的第一個問題,非常感謝他們的幫助和友好的態度。我接受了Christopher Chiche的回答,因爲它不需要循環就能感受到「更多d3」。我實現了你的第二個解決方案,但不得不做兩個改動才能使它工作,即在d.field_goal_attempts前面使用'+',以便max返回2000而不是600,並將值放在domain()中的方括號中。我是新來的,所以我不想改變你的代碼,以防萬一我錯了,但認爲能很好地告訴你:)。再次感謝! – Emil 2013-05-04 02:05:43

+0

是的,如果值存儲爲字符串,則需要field_goal_attempts前的'+'。而你對域名是一個數組的論點絕對正確!我將進行編輯。很高興我能幫上忙! – Superboggly 2013-05-06 18:04:30

+0

在開始的時候不會添加那個+會給我很多問題,你是一個救星@Superboggly! – 2016-06-03 22:46:55

1

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()會是偉大的,但據我所知它不是。首先計算列表然後計算最大值的優點是,如果要計算最小值,平均值或其他值,則可以減少計算量。

+0

感謝您的幫助。這是我的第一個問題,非常感謝它提供的幫助和友好的態度。我會投你的答案,但我很害羞,因爲這樣做:(我接受了@Superbogly的答案,因爲它'覺得'更'd3'忽略forEach方法的需要 - 聽起來很糟糕,不是嗎?無論如何,Python術語'Pythonic'怪罪於Python人羣 - 我對編碼和StackOverflow都很陌生,所以我只想表達我對你的迴應的讚賞。謝謝:) – Emil 2013-05-04 02:09:55

+0

不客氣。他的回答確實比我的好。我通過閱讀了解了一件新事物。 – 2013-05-04 06:03:54

相關問題