2012-03-13 35 views
6

我是D3新手,玩弄散點圖。我無法讓d3.max(數據)在設置域時正常工作!爲什麼域名在D3中不使用d3.max(data)?

,我有以下設置一個隨機的數據集:

var data = []; 
     for (i=0; i < 40; i++){ 
      data.push({"x": i/40, "y": i/8, "a": Math.floor(Math.random() * 3), "x2": Math.random()}); 
     } 

然後將下面的設置我的座標:

var x = d3.scale.linear().domain([0, 1]).range([0 + margin, w-margin]), 
      y = d3.scale.linear().domain([0, d3.max(data)]).range([0 + margin, h-margin]), 
      c = d3.scale.linear().domain([0, 3]).range(["hsl(100,50%,50%)", "rgb(350, 50%, 50%)"]).interpolate(d3.interpolateHsl); 

這使得所有40個點在一個單一的,水平線。如果我用'5'代替d3.max(data),那麼它是一個對角線(儘管從左上角到右下角,我仍然在努力翻轉y座標)。爲什麼不是d3.max(數據)按預期工作?

回答

9

d3.max()需要一組數字,而不是對象。 data的元素具有內部鍵值結構,因此d3.max()無法知道要採取的最大措施。您可以使用類似jQuery's $.map的東西來獲取所需對象的元素,然後獲取最大值,例如

var maxy = d3.max($.map(data, function(d) { return d.y; })); 

編輯:

如在下面的評論中指出,你甚至不需要JQuery的這一點,因爲.map()是土生土長的陣列方法。然後,該代碼變得簡單

var maxy = d3.max(data.map(function(d) { return d.y; })); 

或者更簡單(和未實現Array.map()這些瀏覽器),使用的d3.max,告訴它如何在陣列

var maxy = d3.max(data, function(d) { return d.y; }); 
中訪問值可選的第二個參數
+27

你不需要jQuery的地圖;它是一個本地數組方法:'d3.max(data.map(function(d){return d.y;}))'。 'd3.max()'接受一個可選的訪問器作爲它的第二個參數,所以你也可以使用'd3.max(data,function(d){return d.y;}) – 2012-03-13 20:06:07

3

d3.max API文檔可以找到here

#d3。 最大陣列 [,存取])

返回使用自然順序給定的陣列中的最大值。如果 數組爲空,則返回undefined。可以指定一個可選的訪問函數 ,這與在計算最大值之前調用array.map(訪問器) 等效。與內建的Math.max不同,這個 方法會忽略未定義的值;這對於計算標尺的域而言是有用的,同時僅考慮數據的定義區域。另外,使用自然順序比較元素,而不是數字順序比較 。例如,最大[ 「20」, 「3」]的是 「3」, 而最大的[20,3]是20

將這一信息最初的問題,我們得到:

function accessor(o){ 
    return o.y; 
} 
var y = d3.scale.linear() 
     .domain([0, d3.max(data, accessor)]) 
     .range([0 + margin, h-margin]); 

如果您最終使用了許多存取器函數,那麼您可以創建一個工廠。

function accessor(key) { 
    return function (o) { 
     return o[key]; 
    }; 
} 
var x = d3.scale.linear() 
     .domain([0, d3.max(data, accessor('x'))]) 
     .range([...]), 
    y = d3.scale.linear() 
     .domain([0, d3.max(data, accessor('y'))]) 
     .range([...]); 
0

我有一個類似的問題處理關聯數組。我的數據如下所示:[{「year_decided」:1982,「total」:0},{「year_decided」:「1983」,「Total」:「847」},...}]

Simply在返回值之前傳遞parseInt。

var yScale = d3.scale.linear() 
    .domain([0, d3.max(query,function(d){ return parseInt(d["Total"]); }) ]) 
    .range([0,h]);