如何临时禁用d3.js中的缩放 [英] How to temporarily disable the zooming in d3.js

查看:900
本文介绍了如何临时禁用d3.js中的缩放的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在搜索暂时禁用d3库提供的缩放功能的可能性。我尝试在停用缩放时保存当前的缩放/平移值,并在重新启用缩放时设置缩放/平移值。很抱歉,此操作无效。



这是我创建的代码示例:

  var savedTranslation = null; 
var savedScale = null;

var body = d3.select(body);

var svg = body.append(svg);

var svgContainer = svg.append(svg:g);

var circle = svgContainer.append(svg:circle)
.attr('cx',100)
.attr('cy',100)
.attr('r',30)
.attr('fill','red');

circle.on('click',clickFn);

function clickFn(){
if(circle.attr('fill')==='red'){
circle.attr('fill','blue' )
}
else if(circle.attr('fill')==='blue'){
circle.attr('fill','red')
}
};

svg.call(zoom = d3.behavior.zoom()。on('zoom',redrawOnZoom))。on('dblclick.zoom',null);


function redrawOnZoom(){
if(circle.attr('fill')==='red'){
if(savedScale!== null ){
zoom.scale(savedScale)
savedScale = null
}
if(savedTranslation!== null){
zoom.translate(savedTranslation)
savedTranslation = null
}
//实际的缩放
svgContainer.attr('transform','translate('+ d3.event.translate +')'' '+ d3.event.scale +')');
}
else {
//保存当前比例
savedScale = zoom.scale()
savedTranslation = zoom.translate()
}
};

这里是 working jsfiddle example。



编辑:



按照以下步骤操作:


  1. 点击圆圈,颜色变为蓝色,缩放功能无效

  2. 使用鼠标滚轮IN ONE DIRECTION几次,就好像要放大(例如放大)

  3. 再次点击圆圈,将颜色区域变为红色,重新启用缩放

  4. 使用鼠标滚轮,圆形将会很大/微小。


解决方案>

我一直在努力解决同样的问题。而且,我发现了一个解决方案,可以保存缩放和翻译,而不会出现您看到的当前解决方案的跳跃。



主要的更改是执行保存/更新缩放并在点击功能中翻译。因此,对缩放功能的引用可用,必须在缩放行为之后设置点击。解决方案看起来像这样。与您的问题相同的样板:

  var savedTranslation = null; 
var savedScale = null;

var body = d3.select(body);

var svg = body.append(svg);

var svgContainer = svg.append(svg:g);

var circle = svgContainer.append(svg:circle)
.attr('cx',100)
.attr('cy',100)
.attr('r',30)
.attr('fill','red');

然后缩放功能,而不管理保存的比例和翻译:

  svg.call(zoom = d3.behavior.zoom()。on('zoom',redrawOnZoom))。on('dblclick.zoom',null) ; 

function redrawOnZoom(){
if(circle.attr('fill')==='red'){
//实际的缩放
svgContainer.attr('transform','translate('+ zoom.translate()+')'+'scale('+ zoom.scale()+')');
}
};

最后,附上下面的点击行为,保存和设置比例和翻译:

  circle.on('click',clickFn); 

function clickFn(){
if(circle.attr('fill')==='red'){
circle.attr('fill','blue' )
if(savedScale === null){
savedScale = zoom.scale();
}
if(savedTranslation === null){
savedTranslation = zoom.translate();
}
}
else if(circle.attr('fill')==='blue'){
circle.attr('fill','red')
if(savedScale!== null){
zoom.scale(savedScale);
savedScale = null;
}
if(savedTranslation!== null){
zoom.translate(savedTranslation);
savedTranslation = null;
}
}
};

这是一个工作版本: http://jsfiddle.net/cb3Zm/1/



但是,阻力发生,这似乎不理想,但我还没有能够解决它。


I am searching for a possibility to temporarily disable the zooming functionality provided by the d3 library. I tried to save the cave the current scale/translation values when the zooming is deactivated and set the zoom/translate-values when the zooming is active again. Unfortunately this will not work.

Here is a code example I created :

var savedTranslation = null;
var savedScale = null;

var body = d3.select("body");

var svg = body.append("svg");

var svgContainer = svg.append("svg:g");

var circle = svgContainer.append("svg:circle")
    .attr('cx', 100)
    .attr('cy', 100)
    .attr('r',30)
    .attr('fill', 'red');

circle.on('click', clickFn);

function clickFn(){
    if (circle.attr('fill') === 'red'){
        circle.attr('fill','blue')
    }
    else if (circle.attr('fill') === 'blue'){
        circle.attr('fill','red')
    }
}; 

svg.call(zoom = d3.behavior.zoom().on('zoom', redrawOnZoom)).on('dblclick.zoom', null);


 function redrawOnZoom(){
     if (circle.attr('fill') === 'red'){
         if (savedScale !== null){
             zoom.scale(savedScale)
             savedScale = null
         }
         if (savedTranslation !== null){
             zoom.translate(savedTranslation)
             savedTranslation = null
         }
         // the actual "zooming"
         svgContainer.attr('transform', 'translate(' + d3.event.translate + ')' + ' scale(' +         d3.event.scale + ')');
     }
     else {
         // save the current scales
         savedScale = zoom.scale()
         savedTranslation = zoom.translate()
     }
};

Here is a working jsfiddle example.

EDIT:

The false behavior can be reproduced by following steps :

  1. Click on the circle, the color changes to blue,zooming is not working
  2. Use mouse wheel IN ONE DIRECTION several times as if you would be zooming (e.g. zoom in)
  3. Click again on the circle, the color chnages to red, zoom is re-enabled
  4. Use mouse wheel, the circle will be huge/tiny

解决方案

I have been struggling with the same problem. And, I have found a solution that saves zoom and translation without the jumpiness that you see with the current solution.

The main change is to perform the saving/updating of zoom and translate in the "click" function. And so that a reference to the zoom function is available, the click must be set after the zoom behavior. The solution looks like this. The same boilerplate from your problem:

var savedTranslation = null;
var savedScale = null;

var body = d3.select("body");

var svg = body.append("svg");

var svgContainer = svg.append("svg:g");

var circle = svgContainer.append("svg:circle")
    .attr('cx', 100)
    .attr('cy', 100)
    .attr('r',30)
    .attr('fill', 'red');

Then the zoom function, without managing the saved scale and translate:

svg.call(zoom = d3.behavior.zoom().on('zoom', redrawOnZoom)).on('dblclick.zoom', null);

function redrawOnZoom(){
     if (circle.attr('fill') === 'red'){
         // the actual "zooming"
         svgContainer.attr('transform', 'translate(' + zoom.translate() + ')' + ' scale(' + zoom.scale() + ')');
     }
};

Finally, attach the click behavior below, with the saving and setting of scale and translation:

circle.on('click', clickFn);

function clickFn(){
    if (circle.attr('fill') === 'red'){
        circle.attr('fill','blue')
         if (savedScale === null){
             savedScale = zoom.scale();
         }
          if (savedTranslation === null){
             savedTranslation = zoom.translate();
         }      
    }
    else if (circle.attr('fill') === 'blue'){
        circle.attr('fill','red')
        if (savedScale !== null){
             zoom.scale(savedScale);
             savedScale = null;
         }
         if (savedTranslation !== null){
             zoom.translate(savedTranslation);
             savedTranslation = null;
         }
    }
}; 

Here is a working version: http://jsfiddle.net/cb3Zm/1/.

However, the click event still happens when a drag occurs, and that doesn't seem ideal, but I haven't been able to fix it yet.

这篇关于如何临时禁用d3.js中的缩放的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆