我有a small JavaScript graphing/histogramming library允许在创建绘图时声明的X或Y方向或两者的缩放/平移。一个简化的例子是this jsfiddle。
我想要做的是允许在例如按下shift键时改变缩放行为。
我示例中缩放逻辑的核心目前如下所示:
function draw() {
// handle rendering of plot
}
// zoom behavior:
var zoom = d3.behavior.zoom();
zoom.x(xscale);
//zoom.y(yscale); <-- add this in if y-scrolling is to be allowed
zoom.on("zoom", draw);
// Restrict zoom action to display box (non-axis part) only:
svg.append("svg:rect")
.attr("class", "pane")
.attr("width", w - (padding_left + padding_right))
.attr("height", h - (padding_top + padding_bottom))
.attr("cursor", "move")
.attr("fill", "none")
.attr("pointer-events", "all")
.attr("x", padding_left)
.attr("y", padding_top)
.call(zoom);
function keydown() {
if(d3.event.shiftKey) {
// turn on y-zoom behavior, turn off x...
}
}
function keyup() {
// revert to old behavior
}
d3.select("body").on("keydown", keydown);
d3.select("body").on("keyup", keyup);
设置绘图时,我可以选择性地打开X或Y缩放;但是我想在按下shift键时间歇地这样做,即在keydown
和keyup
。由于缩放行为已连接到我的“pane”div一次,因此我不清楚如何使其动态化。
谢谢!
答案 0 :(得分:2)
最简单的方法是在zoom
函数中处理此问题。也就是说,您只需修改处理它们的方式,而不是修改生成的事件。因此,如果启用了x缩放,则只指定x比例。代码看起来像这样。
var zoom = d3.behaviour.zoom().on("zoom", onZoom);
var svg = d3.select("body").append("svg").call(zoom);
function onZoom() {
if(x_zoom) {
svg.attr("transform", "scale(" + d3.event.scale + ", 1)");
}
else if(y_zoom) {
svg.attr("transform", "scale(1, " + d3.event.scale + ")");
}
}
答案 1 :(得分:2)
答案 2 :(得分:1)
事实证明,如果您使用新的zoom.x
参数再次调用.y
或d3.scale.linear()
,它将禁用该轴的平移/缩放行为,如果您再次使用原始xscale
或yscale
,它会重新启用它。
但是,我遇到的一个问题是,与mouseover
事件不同,我无法将keydown
和keyup
个事件与个人div
或{{1}绑定};他们被整个页面解雇(见this related question)。这意味着,为了支持i3d3中的多个图表,我必须为每个图表保存单独的svg
和zoom
行为;否则,只有页面上的最后一个图表具有正确的行为。
我会暂时不回答这个问题,看看其他人是否有其他建议。
答案 3 :(得分:1)
我将在Lars Kotthoff回答中添加一些内容。
如果我们添加翻译也会好得多 即
//For X-Zoom
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + " ,1)");
//For Y-Zoom
svg.attr("transform", "translate(" + d3.event.translate + ")scale(1, " + d3.event.scale + ")");
即使您的绘图svg位于不同的容器中,此解决方案仍然有效,并且svg位于不同的容器中。