I have register the zoom behavior with element, now I want to toggle between zoom-able and not zoom-able, does anyone know how to unregister the zoom behavior of SVG element ?
var svg = d3.select("#topology-div")
.append("svg")
.attr("class", "topology-map")
.attr("width", data.width)
.attr("height", data.height)
.call(zoom); // <<-- I want unregister zoom later
do you mean like:
svgElement.call(d3.behavior.zoom().on("zoom"); //deactivate zoom behavior
Related
Using the code pattern here, I want to programmatically achieve semantic zooming (in or out). I'm unsure how to get the proper x, y, and scaleExtent terms that are augmented via the zoom:
var svg = d3.select("body").append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom));
See JSfiddle here. The zoomIn and zoomOut functions should simulate the mousewheel events centered in the SVG.
Here's a solution based on the answer below: http://jsbin.com/dociwuvacu/1
I believe I successfully updated your fiddle, but in case not, here is the type of code you would need:
function zoomIn() {
zoomer.scale(zoomer.scale()+.1);
zoomer.event(svg);
}
function zoomOut() {
zoomer.scale(zoomer.scale()-.1);
zoomer.event(svg);
}
I have the following layout:
Gray side: the main container (zoom, pan)
White circles: d3 nodes (mousedown, mouseup, drag)
Red rectangles: rectangles (drag, without container panning)
When dragging the red rectangles, I don't want to drag the main container too.
Also, when zooming, they should'n be affected.
I think that the issue is related to:
// Add rectangle for pan handlers
containerParent.append("rect")
.attr("width", SVGWidth)
.attr("height", SVGHeight)
.style("fill", "none")
.style("pointer-events", "all");
JSFIDDLE
By moving the code snippet from your post before appending g element containing starter elements, the issue is fixed:
...
// Add rectangle for pan handlers
containerParent.append("rect")
.attr("width", SVGWidth)
.attr("height", SVGHeight)
.style("fill", "none")
.style("pointer-events", "all");
// Add starter elements and their container
var starterElmsParent = containerParent.append("g");
...
Fiddle: http://jsfiddle.net/praveenscience/88gL4aks/
I have probably a relativly simple question.
Here is my simple diagram enter link description here
And I would love to implement zooming in and out functionality, using the behaviour descibed here
enter link description here. But I cant make it work, maybe You would spot the problem.
Thanks for Your time.
The whole zooming in functionality seems to be handled with this assignment and function:
svg = d3.select("body").append("svg").attr("width", width).attr("height", height)
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom));
function zoom() {
svg.clearRect(0, 0, width, height);
}
The code you have tried for zooming is used for canvas. You can use transform attribute for zooming in svg.
You can put the whole graph in a (group) element and apply transform attribute to element.
svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.call(d3.behavior.zoom().x(x).y(y).scaleExtent([1, 8]).on("zoom", zoom))
.append("g");
function zoom() {
svg.attr("transform","translate("+ d3.event.translate+") scale("+d3.event.scale+")");
}
Here is the fiddle
I'm trying to implement both dragging and zooming event handlers for a circle item using d3js. I've added behaviors for both events as given below
var circle = svg.append("circle")
.attr("fill", "green")
.attr("opacity", 0.6)
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 13)
.call(d3.behavior.drag().on("drag", drag))
.call(d3.behavior.zoom().on("zoom", zoom));
without zooming the object, dragging works fine. after zooming in/out of the object, dragging does not work, yet all events containing a mousedown is caught as "zoom" event.
For full source please see http://jsfiddle.net/xTaDC/
Seems that i did not understand the "d3.behavior". https://github.com/mbostock/d3/blob/master/examples/mercator/mercator-zoom-constrained.html provides only zoom handler and handles both dragging and zooming.
What am i doing wrong here?
As far as I know, d3's zoom behavior already handles dragging, so the drag thing is redundant. Try making use of the zoom's d3.event.translate (which is a 2 element array, so if you want to get the x value only, you can go d3.event.translate[0]) to replicate the functionality in your Drag into your Zoom.
Additional tip: To make things easier on yourself, make sure that you apply your call(zoom) on the parent of whatever it is that you're trying to drag. This will prevent jittery and shaky behavior.
Source is of course, the d3 wiki.
"This behavior automatically creates event listeners to handle zooming and panning gestures on a container element. Both mouse and touch events are supported."
https://github.com/mbostock/d3/wiki/Zoom-Behavior
I faced similar problem and solved it by overriding other sub events of zoom.
Add below code after zoom and drag event listeners
.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
So the full code will look like
var circle = svg.append("circle")
.attr("fill", "green")
.attr("opacity", 0.6)
.attr("cx", 100)
.attr("cy", 100)
.attr("r", 13)
.call(d3.behavior.drag().on("drag", drag))
.call(d3.behavior.zoom().on("zoom", zoom))
.on("mousedown.zoom", null)
.on("touchstart.zoom", null)
.on("touchmove.zoom", null)
.on("touchend.zoom", null);
Append your graph with sensitive event area (must be the last append) :
var rect = svg.append("svg:rect")
.attr("class", "pane")
.attr("width", w)
.attr("height", h);
AFTER (not include) add event management on this area
rect.call(d3.behavior.zoom().x(x).scaleExtent([0.5, 4]).on("zoom", draw));
and the draw function is
function draw() {
svg.select("g.x.axis").call(xAxis);
svg.select("g.y.axis").call(yAxis);
svg.select("path.area").attr("d", area);
svg.select("path.line").attr("d", line);
}
see this exemple : https://groups.google.com/forum/?fromgroups=#!topic/d3-js/6p7Lbnz-jRQ%5B1-25-false%5D
In 2020, use d3.zoom to enable zooming and panning: https://observablehq.com/#d3/zoom
If you want to enable panning for the background, while allowing to drag the circle, see the official example where d3.drag and d3.zoom are used on different elements: https://observablehq.com/#d3/drag-zoom
When an event is in play, d3.event.x gives the position of the x coordinate of the mouse click, but relative to the entire HTML doc. I tried using jQuery's $('svg').position() to get the actual position of the svg but this return blatantly fallacious values.
Is there some easy way to find the position of an svg relative to the page that I am overlooking? I am using Chrome, by the way, in case the jQuery problem is an obscure browser error.
EDIT: I checked this in firefox and $('svg').position() returns the correct coordinates. ?!?
Instead of using d3.event, which is the browser's native event, use d3.mouse to get the coordinates relative to some container. For example:
var svg = d3.select("body").append("svg")
.attr("width", 960)
.attr("height", 500);
var rect = svg.append("rect")
.attr("width", "100%")
.attr("height", "100%")
.on("mousemove", mousemove);
function mousemove(d, i) {
console.log(d3.mouse(this));
}