2012-11-27 30 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