I struggled with the same problem. And I found a solution that saves scalability and translation without the enhancement that you see with the current solution.
The main change is to save / update the scaling and transfer to the "click" function. And for access to the zoom function to be available, the click must be set after zooming. The solution looks like this. The same pattern 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 translation:
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 saving and adjusting the 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 the working version: http://jsfiddle.net/cb3Zm/1/ .
However, the click event still occurs when the drag and drop occurs, and this does not seem ideal, but I have not yet been able to fix it.
Zak king
source share