2012-11-27 35 views
3

我對d3相當陌生,但已經能夠使用大量的例子創建一個SVG散點圖,我添加了一個畫筆以允許用戶對這些數據的一個子集進行關注。如何識別包含在D3畫筆中的散點圖數據點?

var svg = d3.select("body").append("svg") 
.attr("width", width + margin.right + margin.left) 
.attr("height", height + margin.top + margin.bottom) 
.append("g") 
.attr("transform", "translate(" + margin.left + "," + margin.top + ")"); 
svg.append("g") 
.attr("class", "x axis") 
.attr("transform", "translate(0," + height + ")") 
.call(d3.svg.axis().scale(x).orient("bottom")); 

svg.append("g") 
.attr("class", "brush") 
.call(d3.svg.brush().x(x).y(y) 
.on("brushstart", brushstart) 
.on("brush", brushmove) 
.on("brushend", brushend)); 


function brushstart() { 
svg.classed("selecting", true); 
} 

function brushmove() { 
var e = d3.event.target.extent(); 
circle.classed("selected", function(d) { 
return e[0][0] <= d[0] && d[0] <= e[1][0] 
    && e[0][1] <= d[1] && d[1] <= e[1][1]; 
}); 
} 

function brushend() { 
    svg.classed("selecting", !d3.event.target.empty()); 
} 

最後,我想要做的是採取的高​​亮區域和它(變焦)爆炸成屏幕上的另一SVG,讓用戶更多的細節鑽英寸所以我想要做的是找出最好的方法來確定應該顯示在其他圖表中的brush.extent內存在的那些數據。

我想過試圖循環遍歷每個數據點,將它的座標與範圍的邊界進行比較,但是如果我開始處理大的散點圖,似乎會很慢。有更好的方法可以更有效地獲取數據子集嗎?

感謝

回答

1

我會用Crossfilter library處理過濾我在這裏。他們已經做了很多努力來確保事情的有效性,而且API非常簡單。

我已經建立了​​的基礎知識,但基本上相當於這些代碼:

var xf = crossfilter(data); 
var xDim = xf.dimension(function(d) { return d[0]; }); 
var yDim = xf.dimension(function(d) { return d[1]; }); 

brush.on('brush', function() { 
    var extent = brush.extent(); 
    xDim.filterRange([extent[0][0], extent[1][0]]); 
    yDim.filterRange([extent[0][1], extent[1][1]]); 
    update(); 
}); 
+0

使用您的撥弄我無法弄清楚如何使用「畫筆」。我想我可以通過Command +單擊圖形上的Mac(Mac)來創建「畫筆」,然後拖動圖形。這會創建一個包含「畫筆」並顯示包含的圓圈的窗口。儘管如此,我也期待得到一個「結果」,而且沒有。那是因爲代碼沒有擴展到在「筆刷」中對圓圈做些什麼,或者我錯過了一些鼠標或擊鍵功能?例如,我期望「刷子」可以像繪圖應用程序的橡皮擦/筆刷那樣累積**。我錯過了什麼?謝謝。 – zerowords

+0

我不確定你的意思是*累計*在這裏。 D3的畫筆不像繪畫應用程序的畫筆:您不是添加到屏幕上而是選擇。給出的例子解決了OP基於'brush.extent'過濾數據的目標,但它沒有做任何有意義的事情(除了顯示和隱藏相應的點)。 – couchand