我想让用户使用画笔
选择一系列值。但是,只有离散值在我的应用程序中才有意义,因此我想将画笔限制为这些离散值(例如整数)。
实现此目的的一种方法是使用 Ordinal Brushing 中描述的方法。 。在该示例中,画笔本身可以采用连续值,然后将其映射到序数比例的离散值。
我想要一个在用户刷或拖动画笔时捕捉到离散值的画笔。我想出了一些基本上有效的方法:对 target.extent
进行舍入,然后重新选择舍入范围 ( Fiddle ):
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))
}
但是,这感觉有点笨重,并且会导致不良行为,即当用户拖动画笔时,光标可以悬停在画笔边缘,将光标符号从“拖动”手变成“调整大小“-箭头。
有没有一种更优雅、更强大的方式来获取只允许选择离散范围的画笔?
最佳答案
这可能对 D3 用于渲染画笔的 svg 节点的内部进行了过多的挖掘,但一种解决方案是选择这些节点并更改其光标样式。在您的示例中,为画笔生成的节点如下所示(我 trim 了一些属性):
<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");
}
正如我所说,这会让您面临 D3 在未来版本中更改画笔的 svg 节点结构的危险,但它在概念和计算上都相当简单。 this
里面的画笔事件代表外面的<g>
画笔本身的节点,因此我们只需在该级别下应用选择器即可找到调整大小节点。
更进一步,您可以在 brush
中添加额外的逻辑。函数本身可以更改光标,但这是在鼠标移动时进行评估的,因此成本会高得多。
关于javascript - 将画笔限制在离散范围内,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18065504/