Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/user-interface/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将笔刷限制为离散范围_Javascript_User Interface_User Controls_D3.js_Brush - Fatal编程技术网

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");
}