…
If you use NPM, npm install d3-zoom
. Otherwise, download the latest release. You can also load directly from d3js.org, either as a standalone library or as part of D3 4.0. AMD, CommonJS, and vanilla environments are supported. In vanilla, a d3_zoom
global is exported:
<script src="https://d3js.org/d3-color.v0.4.min.js"></script>
<script src="https://d3js.org/d3-dispatch.v0.4.min.js"></script>
<script src="https://d3js.org/d3-ease.v0.7.min.js"></script>
<script src="https://d3js.org/d3-interpolate.v0.8.min.js"></script>
<script src="https://d3js.org/d3-selection.v0.7.min.js"></script>
<script src="https://d3js.org/d3-timer.v0.4.min.js"></script>
<script src="https://d3js.org/d3-transition.v0.2.min.js"></script>
<script src="https://d3js.org/d3-drag.v0.1.min.js"></script>
<script src="https://d3js.org/d3-zoom.v0.0.min.js"></script>
<script>
var zoom = d3_zoom.zoom();
</script>
This table describes how the zoom behavior interprets native events:
Event | Listening Element | Zoom Event | Default Prevented? |
---|---|---|---|
mousedown⁵ | selection | start | no¹ |
mousemove² | window¹ | zoom | yes |
mouseup² | window¹ | end | yes |
dragstart² | window | - | yes |
selectstart² | window | - | yes |
click³ | window | - | yes |
dblclick | selection | multiple⁶ | yes |
wheel | selection | zoom⁷ | yes |
touchstart | selection | multiple⁶ | no⁴ |
touchmove | selection | zoom | yes |
touchend | selection | end | no⁴ |
touchcancel | selection | end | no⁴ |
The propagation of all consumed events is immediately stopped.
¹ Necessary to capture events outside an iframe; see d3-drag#9.
² Only applies during an active, mouse-based gesture; see d3-drag#9.
³ Only applies immediately after a non-empty, mouse-based gesture.
⁴ Necessary to allow click emulation on touch input; see d3-drag#9.
⁵ Ignored if within 500ms of a touch gesture ending; assumes click emulation.
⁶ Double-click and double-tap initiate a transition that emits start, zoom and end events.
⁷ The first wheel event emits a start event; an end event is emitted when no wheel events are received for 150ms.
# d3.zoom()
Creates a new zoom behavior. The returned behavior, zoom, is both an object and a function, and is typically applied to selected elements via selection.call.
# zoom(selection)
Applies this zoom behavior to the specified selection. This function is typically not invoked directly, and is instead invoked via selection.call. For example, to instantiate a zoom behavior and apply it to a selection:
d3.selectAll(".node").call(d3.zoom().on("zoom", zoomed));
Internally, the zoom behavior uses selection.on to bind the necessary event listeners for zooming. The listeners use the name .zoom
, so you can subsequently unbind the zoom behavior as follows:
selection.on(".zoom", null);
Applying the zoom behavior also sets the -webkit-tap-highlight-color style to transparent, disabling the tap highlight on iOS. If you want a different tap highlight color, remove or re-apply this style after applying the drag behavior.
# zoom.transform(selection, transform)
…
# zoom.translateBy(selection, x, y)
… A convenience alias for zoom.transform.
# zoom.scaleBy(selection, k)
… A convenience alias for zoom.transform.
# zoom.scaleTo(selection, k)
… A convenience alias for zoom.transform.
# zoom.filter([filter])
If filter is specified, sets the filter to the specified function and returns the zoom behavior. If filter is not specified, returns the current filter, which defaults to:
function filter() {
return event.type === "wheel" ? event.deltaY : !event.button;
}
If the filter returns falsey, the initiating event is ignored and no zoom gestures are started. Thus, the filter determines which input events are ignored. The default filter ignores mousedown events on secondary buttons, since those buttons are typically intended for other purposes, such as the context menu. The default filter also ignores horizontal wheeling, since only vertical wheeling triggers a zoom.
# zoom.size([size])
…
function size() {
var node = this.ownerSVGElement || this;
return [node.clientWidth, node.clientHeight];
}
# zoom.scaleExtent([scaleExtent])
… Defaults to [0, ∞].
# zoom.center([center])
… Defaults to null.
# zoom.duration([duration])
… Defaults to 250 milliseconds.
# zoom.on(typenames[, listener])
If listener is specified, sets the event listener for the specified typenames and returns the zoom behavior. If an event listener was already registered for the same type and name, the existing listener is removed before the new listener is added. If listener is null, removes the current event listeners for the specified typenames, if any. If listener is not specified, returns the first currently-assigned listener matching the specified typenames, if any. When a specified event is dispatched, each listener will be invoked with the same context and arguments as selection.on listeners: the current datum d
and index i
, with the this
context as the current DOM element.
The typenames is a string containing one or more typename separated by whitespace. Each typename is a type, optionally followed by a period (.
) and a name, such as zoom.foo
and zoom.bar
; the name allows multiple listeners to be registered for the same type. The type must be one of the following:
start
- after zooming begins (such as on mousedown).zoom
- after a change to the zoom transform (such as on mousemove).end
- after zooming ends (such as on mouseup ).
See dispatch.on for more.
When a zoom event listener is invoked, d3.event is set to the current zoom event. The event object exposes several fields:
type
- the string “start”, “zoom” or “end”; see zoom.on.transform
- the current zoom transform.sourceEvent
- the underlying input event, such as mousemove or touchmove.
# d3.zoomTransform([node])
Returns the current transform for the specified node. If a node is not specified, or the given node has no defined transform, returns the identity transformation where k = 1, tx = ty = 0. The returned transform represents a two-dimensional transformation matrix of the form:
k 0 tx
0 k ty
0 0 1
The position ⟨x,y⟩ is transformed to ⟨x × k + tx,y × k + ty⟩. The transform object exposes the following properties:
x
- the translation amount tx along the x-axis.y
- the translation amount ty along the y-axis.k
- the scale factor.
For example, to apply the equivalent transformation to a Canvas 2D context:
context.translate(transform.x, transform.y);
context.scale(transform.k, transform.k);
Similarly, to apply the transformation to HTML elements via CSS:
div.style("transform", "translate(" + transform.x + "px," + transform.y + "px) scale(" + transform.k + ")");
To apply the transformation to SVG:
g.attr("transform", "translate(" + transform.x + "," + transform.y + ") scale(" + transform.k + ")");
Or more simply, taking advantage of transform.toString:
g.attr("transform", transform);
Note that the order of transformations matters! The translate must be applied before the scale.
# transform.scale(k)
…
# transform.translate(x, y)
…
# transform.apply(point)
…
# transform.applyX(x)
…
# transform.applyY(y)
…
# transform.invert(point)
…
# transform.invertX(x)
…
# transform.invertY(y)
…
# transform.rescaleX(x)
…
# transform.rescaleY(y)
…
# transform.toString()
Returns a string representing the SVG transform corresponding to this transform. Implemented as:
function toString() {
return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
}