D3:将鼠标滚轮重新映射为平移手势而不是缩放手势
D3: remap mousewheel to be panning gesture instead of zoom gesture
默认情况下,当您在 D3 中创建新的缩放行为时,它会映射鼠标滚轮来控制缩放级别。如果图表大于图表区域,您还可以单击并拖动以平移图表。我想将鼠标滚轮手势重新映射为在垂直轴上平移(鼠标滚轮向上平移,鼠标滚轮向下平移)。有人知道如何完成此操作吗?
好的,我们开始:
基于 Lars' comment, we can specify event handler for mousewheel event. As shown in the answer,我们首先将 wheel.zoom
事件映射到自定义处理程序 pan
selection.call(zoomer)
.on("wheel.zoom",pan) // handler function for mousewheel zoom
其次,我们需要定义平移手势,基本上就是translate
in x and/or y 方向.
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 fiddle and bl.ock also modifying Mike's 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)));
}
您还可以在使用 d3.behavior.zoom()
创建的函数中拦截车轮事件。 "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)
,所有的逻辑都包含在那个函数中。
默认情况下,当您在 D3 中创建新的缩放行为时,它会映射鼠标滚轮来控制缩放级别。如果图表大于图表区域,您还可以单击并拖动以平移图表。我想将鼠标滚轮手势重新映射为在垂直轴上平移(鼠标滚轮向上平移,鼠标滚轮向下平移)。有人知道如何完成此操作吗?
好的,我们开始:
基于 Lars' comment, we can specify event handler for mousewheel event. As shown in the answer,我们首先将 wheel.zoom
事件映射到自定义处理程序 pan
selection.call(zoomer)
.on("wheel.zoom",pan) // handler function for mousewheel zoom
其次,我们需要定义平移手势,基本上就是translate
in x and/or y 方向.
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 fiddle and bl.ock also modifying Mike's 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)));
}
您还可以在使用 d3.behavior.zoom()
创建的函数中拦截车轮事件。 "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)
,所有的逻辑都包含在那个函数中。