javascript - 将画笔限制在离散范围内

标签 javascript user-interface user-controls d3.js 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))
}

但是,这感觉有点笨重,并且会导致不良行为,即当用户拖动画笔时,光标可以悬停在画笔边缘,将光标符号从“拖动”手变成“调整大小“-箭头。

有没有一种更优雅、更强大的方式来获取只允许选择离散范围的画笔?

最佳答案

这可能对 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/

相关文章:

javascript - 使用 JavaScript 解码 url 编码的 windows-1251 (cp1251) 字符串

javascript - 如何在 CodeceptJS 中尝试捕捉

android - 在 android studio 中创建自定义小部件?

ios - 在 Swift 中运行 API 查询时如何显示加载屏幕?

ASP.net 自定义 GridView 控件

c# - MultiBinding 和 IMultiValueConverter Convert() 只调用一次

javascript - 为什么我在测试中得到 "Ajax authorization fails"

德尔福Win32 : Speed up dynamically created controls (Parent property)

wpf - 标记 "xxx"在 XML 命名空间“yyy”中不存在/找不到引用

javascript - 单击单选按钮取消选中并选中我的新单选按钮