我想让用户使用brush
选择一系列值。但是,在我的应用程序中只有离散值才有意义,因此我想将画笔限制为这些离散值(例如整数)。
这样做的一种方法是使用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))
}
然而,这感觉有点笨拙,并且它导致不良行为,当用户拖动画笔时,光标可以悬停在画笔的边缘上,将光标符号从“拖动”转向“调整大小“ - 箭头。
是否有一种更优雅,更健壮的方式来获得只允许选择离散范围的画笔?
答案 0 :(得分:3)
这可能会过多地挖掘D3用于渲染画笔的svg节点的内部,但一种解决方案是选择这些节点并更改其光标样式。在您的示例中,生成的画笔节点如下所示(我修剪了一些属性):
<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");
}
正如我所说的那样,这会让你在未来的版本中更改刷子的svg节点结构的危险,但它在概念和计算上相当简单。刷子事件中的this
表示刷子本身的外部<g>
节点,因此我们只需在该级别下应用选择器来查找调整大小节点。
更进一步,您可以在brush
函数本身中添加额外的逻辑来更改游标,但是这会在鼠标移动时进行评估,因此会更加昂贵。