new·The score now tells you which way it movedA brain's exam only ever grows: its own material writes questions, and so does every question a real caller asked and did not get answered. The score is a percentage over that growing set, so a brain that learned more could post a smaller number — and this week three did. One of them answered two MORE questions than the week before and showed eighteen points less. Printed as a single percentage, that reads as decline to a reader and as punishment to anyone who contributes material.all news →
mozg.beta
Sign in

D3 · all subjects

d3-zoom

54 notes, read out of this brain and free to use. Each one was extracted from a source and is re-checked against its exam.

d3.zoom behavior creation and application

d3.zoom() creates a zoom behavior. Calling zoom(selection) applies the zoom behavior to selected elements.

Zoom transform manipulation methods

Zoom objects have transform methods: zoom.transform(selection, transform) changes the transform for selected elements. zoom.translateBy(selection, tx, ty) translates the transform. zoom.translateTo(selection, x, y) translates the transform to absolute coordinates. zoom.scaleBy(selection, k) scales the transform. zoom.scaleTo(selection, k) scales the transform to absolute scale.

Zoom configuration methods: constrain, filter, touchable, wheelDelta, extent, scaleExtent, translateExtent, clickDistance, tapDistance, duration, interpolate, on

Zoom objects have configuration methods: zoom.constrain(function) overrides transform constraint logic. zoom.filter(function) controls which input events initiate zooming. zoom.touchable(function) sets the touch support detector. zoom.wheelDelta(function) overrides scaling for wheel events. zoom.extent(extent) sets the extent of the viewport. zoom.scaleExtent([min, max]) sets the allowed scale range. zoom.translateExtent(extent) sets the extent of the zoomable world. zoom.clickDistance(distance) sets the click distance threshold. zoom.tapDistance(distance) sets the tap distance threshold. zoom.duration(ms) sets the duration of zoom transitions. zoom.interpolate(function) controls interpolation of zoom transitions. zoom.on(typenames, listener) listens for zoom events.

Zoom transform methods: scale, translate, apply, applyX, applyY, invert, invertX, invertY, rescaleX, rescaleY, toString

Transform objects (from d3.zoomTransform) have these methods: transform.scale(k) scales a transform by the specified amount. transform.translate(tx, ty) translates a transform by the specified amount. transform.apply(point) applies transform to given point. transform.applyX(x) applies transform to given x-coordinate. transform.applyY(y) applies transform to given y-coordinate. transform.invert(point) unapplies transform to given point. transform.invertX(x) unapplies transform to given x-coordinate. transform.invertY(y) unapplies transform to given y-coordinate. transform.rescaleX(scale) applies transform to x scale's domain. transform.rescaleY(scale) applies transform to y scale's domain. transform.toString() formats the transform as an SVG transform string.

Zoom transform retrieval and identity

d3.zoomTransform(element) gets the zoom transform for a given element. d3.zoomIdentity is the identity transform.

Unbinding zoom behavior

To unbind the zoom behavior from a selection, use selection.on('.zoom', null). To disable only wheel-driven zooming, use selection.on('wheel.zoom', null).

Pitfall: transform application order matters

When applying zoom transforms, the translate must be applied before the scale. The order of transformations matters.

Example: apply zoom transform to SVG

To apply the zoom transformation to SVG: g.attr('transform', 'translate(' + transform.x + ',' + transform.y + ') scale(' + transform.k + ')'); Or more simply: g.attr('transform', transform);

zoom() constructor

zoom() creates a new zoom behavior. The returned behavior is both an object and a function, typically applied to selected elements via selection.call().

zoom(selection) applies behavior and event listeners

Calling zoom(selection) applies the zoom behavior to the specified selection, binding necessary event listeners for panning and zooming, and initializing the zoom transform on each element to the identity transform if not already defined. The zoom behavior uses selection.on() internally with the name '.zoom' for event listeners.

zoom.transform(selection, transform, point) signature and behavior

Sets the current zoom transform of selected elements to the specified transform. If selection is a selection, changes are instantaneous and emit start, zoom, and end events. If selection is a transition, a zoom tween is defined using interpolateZoom, emitting start, zoom (for each tick), and end events. The transform can be a zoom transform or a function returning one. The point can be a two-element array [x, y] or a function; if not specified, it defaults to the center of the viewport extent. If a function, it is invoked for each element with the current event and datum d, with this context as the DOM element.

zoom.translateBy(selection, x, y) signature and behavior

Translates the current zoom transform of selected elements by x and y, such that the new tx1 = tx0 + kx and ty1 = ty0 + ky. If selection is a transition, defines a zoom tween. The x and y amounts can be numbers or functions. If functions, they are invoked for each element with datum d and index i, with this context as the DOM element.

zoom.translateTo(selection, x, y, p) signature and behavior

Translates the current zoom transform such that the given position ⟨x,y⟩ appears at given point p. The new tx = px - kx and ty = py - ky. If p is not specified, it defaults to the center of the viewport extent. If selection is a transition, defines a zoom tween. The x and y coordinates can be numbers or functions; the p point can be a two-element array [px, py] or a function. If functions, they are invoked for each element with datum d and index i, with this context as the DOM element.

zoom.scaleTo(selection, k, p) signature and behavior

Scales the current zoom transform of selected elements to k, such that the new k₁ = k. The reference point p does move. If p is not specified, it defaults to the center of the viewport extent. If selection is a transition, defines a zoom tween. The k scale factor can be a number or a function; the p point can be a two-element array [px, py] or a function. If functions, they are invoked for each element with datum d and index i, with this context as the DOM element.

zoom.constrain(constrain) default constraint function

If constrain is specified, sets the transform constraint function and returns the zoom behavior. If not specified, returns the current constraint function. The default constraint function is: function constrain(transform, extent, translateExtent) { var dx0 = transform.invertX(extent[0][0]) - translateExtent[0][0], dx1 = transform.invertX(extent[1][0]) - translateExtent[1][0], dy0 = transform.invertY(extent[0][1]) - translateExtent[0][1], dy1 = transform.invertY(extent[1][1]) - translateExtent[1][1]; return transform.translate(dx1 > dx0 ? (dx0 + dx1) / 2 : Math.min(0, dx0) || Math.max(0, dx1), dy1 > dy0 ? (dy0 + dy1) / 2 : Math.min(0, dy0) || Math.max(0, dy1)); }. The constraint function must return a transform given the current transform, viewport extent, and translate extent. The default implementation attempts to ensure that the viewport extent does not go outside the translate extent.

zoom.filter(filter) default filter function

If filter is specified, sets the filter function and returns the zoom behavior. If not specified, returns the current filter. The default filter is: function filter(event) { return (!event.ctrlKey || event.type === 'wheel') && !event.button; }. The filter is passed the current event and datum d, with this context as the DOM element. If the filter returns falsey, the initiating event is ignored and no zoom gestures start. The default filter ignores mousedown events on secondary buttons.

zoom.touchable(touchable) default touch detector

If touchable is specified, sets the touch support detector and returns the zoom behavior. If not specified, returns the current detector. The default detector is: function touchable() { return navigator.maxTouchPoints || ('ontouchstart' in this); }. Touch event listeners are only registered if the detector returns truthy for the element when the zoom behavior is applied.

zoom.wheelDelta(delta) default wheel delta function

If delta is specified, sets the wheel delta function and returns the zoom behavior. If not specified, returns the current function. The default wheel delta function is: function wheelDelta(event) { return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1); }. The value Δ returned determines the amount of scaling: the scale factor transform.k is multiplied by 2^Δ. For example, Δ of +1 doubles the scale factor, Δ of -1 halves it.

zoom.extent(extent) viewport extent

If extent is specified, sets the viewport extent to an array of points [[x0, y0], [x1, y1]] where [x0, y0] is the top-left corner and [x1, y1] is the bottom-right corner, and returns the zoom behavior. The extent can also be a function returning such an array; if a function, it is invoked for each element with datum d, with this context as the DOM element. If not specified, returns the current extent accessor, which defaults to [[0, 0], [width, height]] where width is the client width and height is the client height of the element; for SVG elements, the nearest ancestor SVG viewBox, width, and height attributes are used. The viewport extent affects the center point used by scaleBy and scaleTo, the path chosen by interpolateZoom, and enforcement of the translate extent.

zoom.scaleExtent(extent) scale factor constraints

If extent is specified, sets the scale extent to an array of numbers [k0, k1] where k0 is the minimum allowed scale factor and k1 is the maximum allowed scale factor, and returns the zoom behavior. If not specified, returns the current scale extent, which defaults to [0, ∞]. The scale extent restricts zooming. It is enforced on interaction and when using scaleBy, scaleTo, and translateBy; however, it is not enforced when using transform to set the transform explicitly. If the user tries to zoom by wheeling when already at a scale extent limit, the wheel events are ignored.

zoom.translateExtent(extent) translation bounds

If extent is specified, sets the translate extent to an array of points [[x0, y0], [x1, y1]] where [x0, y0] is the top-left corner of the world and [x1, y1] is the bottom-right corner of the world, and returns the zoom behavior. If not specified, returns the current translate extent, which defaults to [[-∞, -∞], [+∞, +∞]]. The translate extent restricts panning. It is enforced on interaction and when using scaleBy, scaleTo, and translateBy; however, it is not enforced when using transform to set the transform explicitly.

zoom.clickDistance(distance) click suppression threshold

If distance is specified, sets the maximum distance the mouse can move between mousedown and mouseup that will trigger a click event, and returns the zoom behavior. If the mouse moves distance or greater from its mousedown position, the following click event is suppressed. If not specified, returns the current distance threshold, which defaults to zero. The distance is measured in client coordinates (event.clientX and event.clientY).

zoom.tapDistance(distance) double-tap threshold

If distance is specified, sets the maximum distance a double-tap gesture can move between first touchstart and second touchend that will trigger a double-click event, and returns the zoom behavior. If not specified, returns the current distance threshold, which defaults to 10. The distance is measured in client coordinates (event.clientX and event.clientY).

zoom.duration(duration) transition time

If duration is specified, sets the duration for zoom transitions on double-click and double-tap to the specified number of milliseconds, and returns the zoom behavior. If not specified, returns the current duration, which defaults to 250 milliseconds. If the duration is not greater than zero, double-click and double-tap trigger instantaneous changes to the zoom transform rather than smooth transitions.

zoom.interpolate(interpolate) zoom transition interpolation

If interpolate is specified, sets the interpolation factory for zoom transitions and returns the zoom behavior. If not specified, returns the current interpolation factory, which defaults to interpolateZoom to implement smooth zooming. To apply direct interpolation between two views, use interpolate instead.

zoom.on(typenames, listener) event listener registration

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, it is removed before the new one is added. If listener is null, removes listeners for the specified typenames. If listener is not specified, returns the first currently-assigned listener matching the typenames. When an event is dispatched, each listener is invoked with the same context and arguments as selection.on listeners: the current event and datum d, with this context as the 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 type must be one of: 'start' (after zooming begins, such as on mousedown), 'zoom' (after a change to the zoom transform, such as on mousemove), or 'end' (after zooming ends, such as on mouseup).

Zoom event object fields

When a zoom event listener is invoked, it receives a zoom event object with the following fields: event.target (the associated zoom behavior), event.type (the string 'start', 'zoom', or 'end'), event.transform (the current zoom transform), event.sourceEvent (the underlying input event such as mousemove or touchmove).

Zoom event interaction table

The zoom behavior handles these interaction events: mousedown (listening element: selection, zoom event: start, default prevented: 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⁴). Notes: ¹ Necessary to capture events outside an iframe. ² Only applies during active mouse-based gestures. ³ Only applies immediately after some mouse-based gestures. ⁴ Necessary for click emulation on touch input. ⁵ Ignored if within 500ms of a touch gesture ending. ⁶ Double-click and double-tap initiate a transition emitting 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. ⁸ Ignored if already at the corresponding limit of the scale extent. All consumed events have propagation immediately stopped.

zoomTransform(node) retrieve current transform

Returns the current transform for the specified node. The node should be a DOM element, not a selection. If the node has no defined transform, returns the transform of the closest ancestor, or if none exists, the identity transformation. The transform is stored internally as element.__zoom.

ZoomTransform matrix representation

A zoom transform represents a two-dimensional transformation matrix of the form: k 0 tx; 0 k ty; 0 0 1. This matrix is capable of representing only scale and translation. The position ⟨x,y⟩ is transformed to ⟨xk + tx, yk + ty⟩.

ZoomTransform properties

A zoom transform object exposes the following properties: transform.x (the translation amount tx along the x-axis), transform.y (the translation amount ty along the y-axis), transform.k (the scale factor k). These properties should be considered read-only; instead of mutating a transform, use transform.scale() and transform.translate() to derive a new transform.

new d3.ZoomTransform(k, x, y) constructor

Returns a transform with scale k and translation (x, y).

transform.scale(k) multiply scale factor

Returns a transform whose scale k₁ is equal to k₀k, where k₀ is this transform's scale.

transform.translate(x, y) add translation

Returns a transform whose translation tx1 and ty1 is equal to tx0 + tk x and ty0 + tk y, where tx0 and ty0 is this transform's translation and tk is this transform's scale.

transform.apply(point) forward transformation

Returns the transformation of the specified point, which is a two-element array of numbers [x, y]. The returned point is equal to [xk + tx, yk + ty].

transform.applyX(x) forward x transformation

Returns the transformation of the specified x-coordinate: xk + tx.

transform.applyY(y) forward y transformation

Returns the transformation of the specified y-coordinate: yk + ty.

transform.invert(point) inverse transformation

Returns the inverse transformation of the specified point, which is a two-element array of numbers [x, y]. The returned point is equal to [(x - tx) / k, (y - ty) / k].

transform.invertX(x) inverse x transformation

Returns the inverse transformation of the specified x-coordinate: (x - tx) / k.

transform.invertY(y) inverse y transformation

Returns the inverse transformation of the specified y-coordinate: (y - ty) / k.

transform.rescaleX(x) rescale x scale domain

Returns a copy of the continuous scale x whose domain is transformed. This is implemented by first applying the inverse x-transform on the scale's range, and then applying the inverse scale to compute the corresponding domain. The scale x must use interpolateNumber; do not use continuous.rangeRound as this reduces accuracy. This method does not modify the input scale x; x represents the untransformed scale, while the returned scale represents its transformed view.

transform.rescaleY(y) rescale y scale domain

Returns a copy of the continuous scale y whose domain is transformed. This is implemented by first applying the inverse y-transform on the scale's range, and then applying the inverse scale to compute the corresponding domain. The scale y must use interpolateNumber; do not use continuous.rangeRound as this reduces accuracy. This method does not modify the input scale y; y represents the untransformed scale, while the returned scale represents its transformed view.

transform.toString() SVG transform string

Returns a string representing the SVG transform corresponding to this transform. Implemented as: function toString() { return 'translate(' + this.x + ',' + this.y + ') scale(' + this.k + ')'; }.

zoomIdentity identity transform constant

The identity transform where k = 1, tx = ty = 0.

Example: basic zoom behavior application

To instantiate a zoom behavior and apply it to a selection: selection.call(d3.zoom().on('zoom', zoomed));

Example: reset zoom to identity transform instantaneously

To reset the zoom transform to the identity transform instantaneously: selection.call(zoom.transform, d3.zoomIdentity);

Example: reset zoom to identity with transition

To smoothly reset the zoom transform to the identity transform over 750 milliseconds: selection.transition().duration(750).call(zoom.transform, d3.zoomIdentity);

Example: retrieve current zoom transform from selection node

To retrieve the zoom state from a selection: var transform = d3.zoomTransform(selection.node());

Example: retrieve zoom transform in event listener

In the context of an event listener, to retrieve the zoom transform: var transform = d3.zoomTransform(this);

Example: create transform with scale and translation

To create a transform with a given k, tx, and ty: var t = d3.zoomIdentity.translate(x, y).scale(k);

Example: apply zoom transform to Canvas 2D context

To apply the zoom transformation to a Canvas 2D context: context.translate(transform.x, transform.y); context.scale(transform.k, transform.k);

Example: apply zoom transform to HTML elements via CSS

To apply the zoom transformation to HTML elements via CSS: div.style('transform', 'translate(' + transform.x + 'px,' + transform.y + 'px) scale(' + transform.k + ')'); div.style('transform-origin', '0 0');

Pitfall: zoom.transform does not enforce extents

The zoom.transform() method requires that you specify the new zoom transform completely and does not enforce the defined scale extent and translate extent. To derive a new transform from the existing transform and enforce extents, use the convenience methods zoom.translateBy(), zoom.scaleBy(), and zoom.scaleTo().

Pitfall: rescaleX and rescaleY require interpolateNumber

The transform.rescaleX() and transform.rescaleY() methods require that the scale use interpolateNumber. Do not use continuous.rangeRound() as this reduces the accuracy of continuous.invert() and can lead to an inaccurate rescaled domain.

Give your agent this brain