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 :
The d3.zoom () Function in D3.js is used to create a new zoom behaviour. It is used to apply the zoom transformation on a selected element. Parameters: This function does not accept any parameter. Return Value: This function returns the zoom behaviour. Below programs illustrate the d3.zoom () function in D3.js
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 The easiest way I've found is to simply disable all the .zoom events on the selection.
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.
Select a zone to zoom on it (X axis only). Double click to unzoom. A clipPath is used to avoid displaying the circle outside the chart area. all (brush.move, null) is used to dismiss the grey brushing area once the selection has been done.
The easiest way I've found is to simply disable all the .zoom
events on the selection. You'll have to re-call zoom
to enable the behavior again.
if (zoomEnabled) {
svg.call(zoom);
} else {
svg.on('.zoom', null);
}
jsfiddle
See the updated fiddle: http://jsfiddle.net/prayerslayer/La8PR/1/
There I reassign an empty zoom behavior in the click handler.
function clickFn(){
if (circle.attr('fill') === 'red'){
circle.attr('fill','blue');
svg.call( fake );
}
else if (circle.attr('fill') === 'blue'){
circle.attr('fill','red');
svg.call( zoom );
}
};
I suppose there is a better solution as mine probably introduces memory leaks.
The advantage over a global doZoom
flag is that you don't have to save and check scale and translation values because the zoom behavior continues to work (e.g. setting d3.event.scale
) even though you're not altering the view.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With