D3:重新映射鼠标滚轮而不是缩放手势

时间:2015-02-19 10:19:57

标签: javascript d3.js

默认情况下,在D3中创建新的缩放行为时,它会将鼠标滚轮映射到控制缩放级别。如果图表大于图表区域,也可以单击并拖动以平移图表。我想重新映射鼠标滚轮手势,而不是在垂直轴上平移(鼠标滚轮向上平移,鼠标滚轮向下平移)。任何人都有任何线索如何实现这一目标?

2 个答案:

答案 0 :(得分:6)

好的,我们走了: 基于Lars' comment,我们可以为mousewheel事件指定事件处理程序。如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事件的详细信息,我们找到两个有用的属性 deltaX deltaY ,表示鼠标滚轮在每个方向上的移动量。

最终的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,修改了Mike的geometric zoom example

跨浏览器支持:

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

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

另外,wheelDelta的解释在Firefox中是相反的。 wheelDelta可以修复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))); }

{{1}}

答案 1 :(得分:5)

您还可以使用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),并且所有逻辑都包含在那个函数中。