【问题标题】:D3: remap mousewheel to be panning gesture instead of zoom gestureD3:将鼠标滚轮重新映射为平移手势而不是缩放手势
【发布时间】:2015-02-19 10:19:57
【问题描述】:

默认情况下,当您在 D3 中创建新的缩放行为时,它会映射鼠标滚轮来控制缩放级别。如果图表大于图表区域,您也可以单击并拖动以平移图表。我想重新映射鼠标滚轮手势以代替在垂直轴上平移(鼠标滚轮向上平移,鼠标滚轮向下平移)。任何人都知道如何做到这一点?

【问题讨论】:

  • 您可以禁用/重新映射this question 的答案中概述的事件。
  • 感谢@LarsKotthoff,这是非常有用的信息。我仍然需要有关如何准确编写我自己的处理程序的信息,该处理程序将向北和向南平移,但这是一个很好的起点。

标签: javascript d3.js


【解决方案1】:

好的,我们开始: 基于Lars' comment,我们可以为鼠标滚轮事件指定事件处理程序。如answer 所示,我们首先将wheel.zoom 事件映射到自定义处理程序pan

selection.call(zoomer)
      .on("wheel.zoom",pan) // handler function for mousewheel zoom

其次,我们需要定义平移手势,基本上是在x和/或y方向的translate

function pan() {
  svg.attr("transform", "translate(" + [dx,dy] + ")");
}

我们还需要量化两个方向的移动,并将其与鼠标滚轮移动相关联。通过查看MouseWheel事件的细节,我们发现了两个有用的属性deltaXdeltaY,表示鼠标滚轮在每个方向上移动了多少。

最终的pan函数如下

function pan() {
    current_translate = d3.transform(svg.attr("transform")).translate;
    dx = d3.event.wheelDeltaX + current_translate[0];
    dy = d3.event.wheelDeltaY + current_translate[1];
    
  svg.attr("transform", "translate(" + [dx,dy] + ")");
  d3.event.stopPropagation();
}

这是一个working fiddlebl.ock 也修改了迈克的geometric zoom example

跨浏览器支持:

鼠标滚轮事件似乎在浏览器之间有所不同。对于 Safari 和 Firefox 支持,您需要添加以下内容:

selection.call(zoomer)
  .on("wheel.zoom",pan) 
  .on("mousewheel.zoom", pan)
  .on("DOMMouseScroll.zoom", pan)

另外,wheelDelta 的解释在 Firefox 中是相反的。 wheelDelta可以被this function修复

function crossWheelDelta()
  // cross-browser wheel delta
  var e = window.event || e; // old IE support
  return Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));
}

【讨论】:

  • 我不知道怎么处理 crossWheelDelta() 我应该在哪里使用这个函数?
【解决方案2】:

您还可以在使用d3.behavior.zoom() 创建的函数中拦截车轮事件。默认情况下,滚轮滚动和鼠标拖动都会触发“缩放”事件,因此一种可能的策略是等待缩放事件并在缩放函数中拦截滚轮事件。

例如,下面是一种使用滚轮滚动和鼠标拖动进行 Y 平移的方法:

var panYOnScrollAndDrag = d3.behavior.zoom()
   .scaleExtent([1, 1]) // prevents wheel events (or anything) from changing the scale
   .on("zoom", function() {
      if (d3.event.sourceEvent.type === "wheel") {
         // use the `d3.event.sourceEvent.deltaY` value to translate
         // e.g., yTranslation += yTranslationDelta;
      } else if (d3.event.sourceEvent.type === "mousemove") {
         // use the normal d3.event.translate array to translate
         // e.g., yTranslation = d3.event.translate[1];
      }
      container.attr("transform", "translate(0," + yTranslation + ")");
   });

然后你可以像这样将这个函数扔到相关的 d3 容器中,selection.call(panYOnScrollAndDrag),所有的逻辑都包含在那个函数中。

【讨论】:

    猜你喜欢
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-27
    • 2018-12-02
    • 2011-06-28
    相关资源
    最近更新 更多