如何临时禁用d3.js中的缩放 [英] How to temporarily disable the zooming in 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()
}
};
编辑:
按照以下步骤操作:
- 点击圆圈,颜色变为蓝色,缩放功能无效
- 使用鼠标滚轮IN ONE DIRECTION几次,就好像要放大(例如放大)
- 再次点击圆圈,将颜色区域变为红色,重新启用缩放
- 使用鼠标滚轮,圆形将会很大/微小。
我一直在努力解决同样的问题。而且,我发现了一个解决方案,可以保存缩放和翻译,而不会出现您看到的当前解决方案的跳跃。
主要的更改是执行保存/更新缩放并在点击功能中翻译。因此,对缩放功能的引用可用,必须在缩放行为之后设置点击。解决方案看起来像这样。与您的问题相同的样板:
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 :
- Click on the circle, the color changes to blue,zooming is not working
- Use mouse wheel IN ONE DIRECTION several times as if you would be zooming (e.g. zoom in)
- Click again on the circle, the color chnages to red, zoom is re-enabled
- 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屋!