Javascript 将笔刷限制为离散范围
我想让用户使用Javascript 将笔刷限制为离散范围,javascript,user-interface,user-controls,d3.js,brush,Javascript,User Interface,User Controls,D3.js,Brush,我想让用户使用笔刷选择一系列值。然而,在我的应用程序中只有离散值才有意义,所以我想将画笔限制为这些离散值(比如整数) 一种方法是使用中描述的方法。在该示例中,笔刷本身可以采用连续值,然后将连续值映射到顺序比例的离散值 我想得到一个笔刷,它在用户刷牙或拖动笔刷时捕捉离散值。我想出了一些基本上有效的方法:将target.extent四舍五入,然后重新选择四舍五入的范围(): 但是,这感觉有点笨重,这导致了一种不良行为,即当用户拖动画笔时,光标可以悬停在画笔的边缘上,将光标符号从“拖动”手转到“调整
笔刷选择一系列值。然而,在我的应用程序中只有离散值才有意义,所以我想将画笔限制为这些离散值(比如整数)
一种方法是使用中描述的方法。在该示例中,笔刷本身可以采用连续值,然后将连续值映射到顺序比例的离散值
我想得到一个笔刷,它在用户刷牙或拖动笔刷时捕捉离散值。我想出了一些基本上有效的方法:将target.extent
四舍五入,然后重新选择四舍五入的范围():
但是,这感觉有点笨重,这导致了一种不良行为,即当用户拖动画笔时,光标可以悬停在画笔的边缘上,将光标符号从“拖动”手转到“调整大小”箭头
有没有一种更优雅、更健壮的方法来获得只允许选择离散范围的画笔?这可能是对D3用于渲染画笔的svg节点的内部进行了过多挖掘,但一种解决方案是选择这些节点并更改其光标样式。在您的示例中,为笔刷生成的节点如下所示(我删除了一些属性):
正如我所说的,D3在将来的版本中更改了brush的svg节点结构,这会给您带来危险,但在概念上和计算上都相当简单。这个内部笔刷事件表示笔刷本身的外部
节点,因此我们只需在该级别下应用选择器来查找调整大小的节点
更进一步,您可以在画笔
函数本身中添加额外的逻辑来更改光标,但这是在鼠标移动时进行评估的,因此成本要高得多。我认为您的做法是正确的。我试着用同样的监听器实现将你的小提琴改为使用“brushend”事件,而不是“brush”,我认为它感觉有点不那么笨重(平滑滑动,带有快速释放),但这是有争议的。
function brush() {
var s = d3.event.target.extent();
if (d3.event.mode === "move") {
var extentlength = Math.round(s[1] - s[0])
d3.event.target.extent([Math.round(s[0] + 0.5) - 0.5,
Math.round(s[0] + 0.5) - 0.5 + extentlength])
} else {
d3.event.target.extent([Math.round(s[0] + 0.5) - 0.5,
Math.round(s[1] + 0.5) - 0.5])
}
d3.event.target(d3.select(this))
}
<g style="pointer-events: all;">
<rect class="background" style="visibility: hidden; cursor: crosshair;"></rect>
<rect class="extent" style="cursor: move;"></rect>
<g class="resize e" style="cursor: ew-resize;">
<rect style="visibility: hidden;"></rect>
</g>
<g class="resize w" style="cursor: ew-resize;">
<rect style="visibility: hidden;"></rect>
</g>
</g>
var brush = d3.svg.brush().x(x).extent([0.5, 1.5])
.on("brushstart", brushstart)
.on("brush", brush)
.on("brushend", brushend);
function brushstart() {
// disable the resizing cursor
var resizers = d3.select(this).selectAll('g.resize')
.style("cursor", "auto");
}
function brushend() {
// re-enable the resizing cursor
var resizers = d3.select(this).selectAll('g.resize')
.style("cursor", "ew-resize");
}