d3-zoom
示例 · 平移和缩放 通过限制视图让用户专注于感兴趣的区域。它使用直接操作:点击并拖动可平移(平移),旋转滚轮可缩放(缩放),或触摸捏合。平移和缩放广泛用于基于 Web 的地图绘制,但也可用于可视化,例如密集时间序列和散点图。
¥Examples · Panning and zooming let the user focus on a region of interest by restricting the view. It uses direct manipulation: click-and-drag to pan (translate), spin the wheel to zoom (scale), or pinch with touch. Panning and zooming are widely used in web-based mapping, but can also be used in visualization such as dense time series and scatterplots.
缩放行为是一种灵活的抽象,可以处理各种各样的输入方式和浏览器怪癖。缩放行为与 DOM 无关,因此你可以将其与 HTML、SVG 或 Canvas 一起使用。你可以将 d3-zoom 与 d3-scale 和 d3-axis 到 缩放轴 一起使用。你可以使用 zoom.scaleExtent 限制缩放,使用 zoom.translateExtent 限制平移。你可以将 d3-zoom 与其他行为结合使用,例如将 d3-drag 用于 dragging,将 d3-brush 用于 焦点 + 上下文。
¥The zoom behavior is a flexible abstraction, handling a surprising variety of input modalities and browser quirks. The zoom behavior is agnostic about the DOM, so you can use it with HTML, SVG, or Canvas. You can use d3-zoom with d3-scale and d3-axis to zoom axes. You can restrict zooming using zoom.scaleExtent and panning using zoom.translateExtent. You can combine d3-zoom with other behaviors such as d3-drag for dragging and d3-brush for focus + context.
缩放行为可以通过 zoom.transform 以编程方式控制,允许你实现用户界面控件来驱动显示或通过数据暂存 动画游览。平滑缩放过渡 基于 Jarke J. 的 “平滑高效的缩放和平移”。van Wijk 和 Wim A.A.Nuij。
¥The zoom behavior can be controlled programmatically using zoom.transform, allowing you to implement user interface controls which drive the display or to stage animated tours through your data. Smooth zoom transitions are based on “Smooth and efficient zooming and panning” by Jarke J. van Wijk and Wim A.A. Nuij.
有关平移和缩放地图的示例,另请参阅 d3-tile。
¥See also d3-tile for examples panning and zooming maps.
zoom()
源代码 · 创建一个新的缩放行为。返回的行为 zoom 既是对象又是函数,通常通过 selection.call 应用于选定元素。
¥Source · 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) {#_zoom}
源代码 · 将此缩放行为应用于指定的 selection,绑定必要的事件监听器以允许平移和缩放,并将每个选定元素上的 缩放变换 初始化为恒等变换(如果尚未定义)。
¥Source · Applies this zoom behavior to the specified selection, binding the necessary event listeners to allow panning and zooming, and initializing the zoom transform on each selected element to the identity transform if not already defined.
此函数通常不直接调用,而是通过 selection.call 调用。例如,实例化缩放行为并将其应用于选择对象:
¥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:
selection.call(d3.zoom().on("zoom", zoomed));
在内部,缩放行为使用 selection.on 绑定缩放所需的事件监听器。监听器使用名称 .zoom
,因此你可以按如下方式解除绑定缩放行为:
¥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);
要禁用滚轮驱动的缩放(例如不干扰原生滚动),你可以在将缩放行为应用于选定对象后移除缩放行为的滚轮事件监听器:
¥To disable just wheel-driven zooming (say to not interfere with native scrolling), you can remove the zoom behavior’s wheel event listener after applying the zoom behavior to the selection:
selection
.call(zoom)
.on("wheel.zoom", null);
或者,使用 zoom.filter 可以更好地控制哪些事件可以触发缩放手势。
¥Alternatively, use zoom.filter for greater control over which events can initiate zoom gestures.
应用缩放行为也会将 -webkit-tap-highlight-color 样式设置为透明,从而禁用 iOS 上的点击高亮。如果你想要不同的点击高亮颜色,请在应用拖动行为后移除或重新应用此样式。
¥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 以编程方式更改。
¥The zoom behavior stores the zoom state on the element to which the zoom behavior was applied, not on the zoom behavior itself. This allows the zoom behavior to be applied to many elements simultaneously with independent zooming. The zoom state can change either on user interaction or programmatically via zoom.transform.
要检索缩放状态,请在缩放事件监听器中对当前 缩放事件 使用 event.transform(参见 zoom.on),或对给定节点使用 zoomTransform。后一种行为对于以编程方式修改缩放状态很有用,例如实现放大和缩小按钮。
¥To retrieve the zoom state, use event.transform on the current zoom event within a zoom event listener (see zoom.on), or use zoomTransform for a given node. The latter is useful for modifying the zoom state programmatically, say to implement buttons for zooming in and out.
zoom.transform(selection, transform, point) {#zoom_transform}
源代码 · 如果指定了 separation,则将 separation 访问器设置为指定的函数并返回此簇布局。
¥Source · If selection is a selection, sets the current zoom transform of the selected elements to the specified transform, instantaneously emitting start, zoom and end events.
如果 selection 是一个过渡,则使用 interpolateZoom 为指定的变换定义一个“缩放”补间,在过渡开始时发出 start 事件,在过渡的每个 tick 发出 zoom 事件,并在过渡结束(或中断)时发出 end 事件。过渡将尝试最小化围绕指定点的视觉移动;如果未指定点,则默认为视口 extent 的中心。
¥If selection is a transition, defines a “zoom” tween to the specified transform using interpolateZoom, emitting a start event when the transition starts, zoom events for each tick of the transition, and then an end event when the transition ends (or is interrupted). The transition will attempt to minimize the visual movement around the specified point; if the point is not specified, it defaults to the center of the viewport extent.
变换可以指定为 缩放变换 或返回缩放变换的函数;类似地,该点可以指定为一个二元素数组 [x, y] 或一个返回此类数组的函数。如果是函数,则会为每个选定元素调用该函数,传递当前事件 (event
) 和数据 d
,并将 this
上下文作为当前 DOM 元素。
¥The transform may be specified either as a zoom transform or as a function that returns a zoom transform; similarly, the point may be specified either as a two-element array [x, y] or a function that returns such an array. If a function, it is invoked for each selected element, being passed the current event (event
) and datum d
, with the this
context as the current DOM element.
此函数通常不直接调用,而是通过 selection.call 或 transition.call 调用。例如,立即将缩放变换重置为 身份变换:
¥This function is typically not invoked directly, and is instead invoked via selection.call or transition.call. For example, to reset the zoom transform to the identity transform instantaneously:
selection.call(zoom.transform, d3.zoomIdentity);
要在 750 毫秒内平滑地将缩放变换重置为恒等变换:
¥To smoothly reset the zoom transform to the identity transform over 750 milliseconds:
selection.transition().duration(750).call(zoom.transform, d3.zoomIdentity);
此方法要求你完整指定新的缩放变换,并且不强制执行已定义的 缩放范围 和 平移范围(如果有)。要从现有变换派生新的变换,并强制缩放和平移范围,请参阅便捷方法 zoom.translateBy、zoom.scaleBy 和 zoom.scaleTo。
¥This method requires that you specify the new zoom transform completely, and does not enforce the defined scale extent and translate extent, if any. To derive a new transform from the existing transform, and to enforce the scale and translate extents, see the convenience methods zoom.translateBy, zoom.scaleBy and zoom.scaleTo.
zoom.translateBy(selection, x, y) {#zoom_translateBy}
源代码 · 如果选择是一个选择,translates 将所选元素的 当前缩放变换 乘以 XX,使得给定位置 ⟨x,y⟩ 出现在给定点 p。如果选择为过渡,则定义一个“缩放”补间来平移当前变换。此方法是 zoom.transform 的一个便捷方法。x 和 y 平移量可以指定为数字,也可以指定为返回数字的函数。如果是函数,则会为每个选定元素调用该函数,传递当前数据 d
和索引 i
,并将 this
上下文作为当前 DOM 元素。
¥Source · If selection is a selection, translates the current zoom transform of the 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 translating the current transform. This method is a convenience method for zoom.transform. The x and y translation amounts may be specified either as numbers or as functions that return numbers. If a function, it is invoked for each selected element, being passed the current datum d
and index i
, with the this
context as the current DOM element.
zoom.translateTo(selection, x, y, p) {#zoom_translateTo}
源代码 · 如果选择是一个选择,translates 将所选元素的 当前缩放变换 乘以 k,使得新的 k₁ = k。新的 tx = px - kx 和 ty = py - ky。如果 p 未指定,则默认为视口 extent 的中心。如果选择为过渡,则定义一个“缩放”补间来平移当前变换。此方法是 zoom.transform 的一个便捷方法。x 和 y 坐标可以指定为数字,也可以指定为返回数字的函数;类似地,p 点可以指定为一个二元素数组 [px,py] 或一个函数。如果是函数,则会为每个选定元素调用该函数,传递当前数据 d
和索引 i
,并将 this
上下文作为当前 DOM 元素。
¥Source · If selection is a selection, translates the current zoom transform of the selected elements 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 translating the current transform. This method is a convenience method for zoom.transform. The x and y coordinates may be specified either as numbers or as functions that returns numbers; similarly the p point may be specified either as a two-element array [px,py] or a function. If a function, it is invoked for each selected element, being passed the current datum d
and index i
, with the this
context as the current DOM element.
zoom.scaleBy(selection, k, p) {#zoom_scaleBy}
源代码 · 如果选择是一个选择,scales 将所选元素的 当前缩放变换 乘以 x 和 y,使得新的 tx1 = tx0 + kx 和 ty1 = ty0 + ky。参考点 p 确实会移动。如果 p 未指定,则默认为视口 extent 的中心。如果选择为过渡,则定义一个“缩放”补间来平移当前变换。此方法是 zoom.transform 的一个便捷方法。比例因子 k 可以指定为数字或返回数字的函数;类似地,p 点可以指定为一个二元素数组 [px,py] 或一个函数。如果是函数,则会为每个选定元素调用该函数,传递当前数据 d
和索引 i
,并将 this
上下文作为当前 DOM 元素。
¥Source · If selection is a selection, scales the current zoom transform of the selected elements by k, such that the new k₁ = 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 translating the current transform. This method is a convenience method for zoom.transform. The k scale factor may be specified either as a number or a function that returns a number; similarly the p point may be specified either as a two-element array [px,py] or a function. If a function, it is invoked for each selected element, being passed the current datum d
and index i
, with the this
context as the current DOM element.
zoom.scaleTo(selection, k, p) {#zoom_scaleTo}
源代码 · 如果 selection 为选择集,则将所选元素的 scales 设置为指定的变换,并立即发出 start、zoom 和 end 当前缩放变换。参考点 p 确实会移动。如果 p 未指定,则默认为视口 extent 的中心。如果选择为过渡,则定义一个“缩放”补间来平移当前变换。此方法是 zoom.transform 的一个便捷方法。比例因子 k 可以指定为数字或返回数字的函数;类似地,p 点可以指定为一个二元素数组 [px,py] 或一个函数。如果是函数,则会为每个选定元素调用该函数,传递当前数据 d
和索引 i
,并将 this
上下文作为当前 DOM 元素。
¥Source · If selection is a selection, scales the current zoom transform of the 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 translating the current transform. This method is a convenience method for zoom.transform. The k scale factor may be specified either as a number or a function that returns a number; similarly the p point may be specified either as a two-element array [px,py] or a function. If a function, it is invoked for each selected element, being passed the current datum d
and index i
, with the this
context as the current DOM element.
zoom.constrain(constrain) {#zoom_constrain}
源代码 · 如果指定了 constrain,则将变换约束函数设置为指定的函数并返回缩放行为。如果未指定 constrain,则返回当前约束函数,默认为:
¥Source · If constrain is specified, sets the transform constraint function to the specified function and returns the zoom behavior. If constrain is not specified, returns the current constraint function, which defaults to:
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)
);
}
约束函数必须根据当前变换 视口范围 和 平移范围 返回一个 [transform]#zoomTransform)。默认实现会尝试确保视口范围不超过平移范围。
¥The constraint function must return a [transform]#zoomTransform) 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) {#zoom_filter}
源代码 · 如果指定了 filter,则将过滤器设置为指定的函数并返回缩放行为。如果未指定 filter,则返回当前滤镜,默认为:
¥Source · 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(event) {
return (!event.ctrlKey || event.type === 'wheel') && !event.button;
}
过滤器会传递当前事件 (event
) 和数据 d
,并以 this
上下文作为当前 DOM 元素。如果过滤器返回 false,则忽略启动事件,并且不会启动任何缩放手势。因此,过滤器决定忽略哪些输入事件。默认过滤器会忽略辅助按钮上的鼠标按下事件,因为这些按钮通常用于其他目的,例如上下文菜单。
¥The filter is passed the current event (event
) and datum d
, with the this
context as the current DOM element. 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.
zoom.touchable(touchable) {#zoom_touchable}
源代码 · 如果指定了 touchable,则将触摸支持检测器设置为指定的函数并返回缩放行为。如果未指定 touchable,则返回当前的触摸支持检测器,默认为:
¥Source · If touchable is specified, sets the touch support detector to the specified function and returns the zoom behavior. If touchable is not specified, returns the current touch support detector, which defaults to:
function touchable() {
return navigator.maxTouchPoints || ("ontouchstart" in this);
}
仅当缩放行为为 applied 时,检测器返回相应元素的真值时,才会注册触摸事件监听器。默认检测器适用于大多数支持触摸输入的浏览器,但并非所有浏览器都适用;例如,Chrome 的移动设备模拟器检测失败。
¥Touch event listeners are only registered if the detector returns truthy for the corresponding element when the zoom behavior is applied. The default detector works well for most browsers that are capable of touch input, but not all; Chrome’s mobile device emulator, for example, fails detection.
zoom.wheelDelta(delta) {#zoom_wheelDelta}
源代码 · 如果指定了 delta,则将滚轮增量函数设置为指定函数并返回缩放行为。如果未指定 delta,则返回当前的 Wheel delta 函数,默认为:
¥Source · If delta is specified, sets the wheel delta function to the specified function and returns the zoom behavior. If delta is not specified, returns the current wheel delta function, which defaults to:
function wheelDelta(event) {
return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1);
}
wheel delta 函数返回的值 Δ 决定了响应 WheelEvent 时应用的缩放量。比例因子 transform.k 乘以 2Δ;例如,Δ +1 使比例因子加倍,Δ -1 使比例因子减半。
¥The value Δ returned by the wheel delta function determines the amount of scaling applied in response to a WheelEvent. The scale factor transform.k is multiplied by 2Δ; for example, a Δ of +1 doubles the scale factor, Δ of -1 halves the scale factor.
zoom.extent(extent) {#zoom_extent}
源代码 · 如果指定了范围 (extent),则将视口范围设置为指定的点数组 [[x0, y0], [x1, y1]],其中 [x0, y0] 是视口的左上角,[x1, y1] 是视口的右下角,并返回此缩放行为。范围也可以指定为返回此类数组的函数;如果是函数,则为每个选定元素调用该函数,并传递当前数据 d
,以 this
上下文作为当前 DOM 元素。
¥Source · If extent is specified, sets the viewport extent to the specified array of points [[x0, y0], [x1, y1]], where [x0, y0] is the top-left corner of the viewport and [x1, y1] is the bottom-right corner of the viewport, and returns this zoom behavior. The extent may also be specified as a function which returns such an array; if a function, it is invoked for each selected element, being passed the current datum d
, with the this
context as the current DOM element.
如果未指定 extent,则返回当前 extent 访问器,默认为 [[0, 0], [width, height]],其中 width 是元素的 客户端宽度,height 是其 客户端高度;对于 SVG 元素,使用最近祖级 SVG 元素的 viewBox 属性,或 width 和 height 属性。或者,考虑使用 element.getBoundingClientRect。
¥If extent is not specified, returns the current extent accessor, which defaults to [[0, 0], [width, height]] where width is the client width of the element and height is its client height; for SVG elements, the nearest ancestor SVG element’s viewBox, or width and height attributes, are used. Alternatively, consider using element.getBoundingClientRect.
视口范围影响多个函数:视口中心在 zoom.scaleBy 和 zoom.scaleTo 更改期间保持不变;视口中心和尺寸影响 interpolateZoom 选择的路径;并且需要视口范围来强制执行可选的 平移范围。
¥The viewport extent affects several functions: the center of the viewport remains fixed during changes by zoom.scaleBy and zoom.scaleTo; the viewport center and dimensions affect the path chosen by interpolateZoom; and the viewport extent is needed to enforce the optional translate extent.
zoom.scaleExtent(extent) {#zoom_scaleExtent}
源代码 · 如果指定了范围,则将缩放范围设置为指定的数字数组 [k0, k1],其中 k0 是允许的最小缩放因子,k1 是允许的最大缩放因子,并返回此缩放行为。如果未指定范围,则返回当前比例范围,默认为 [0, ∞]。比例范围限制了缩放。它在交互时以及使用 zoom.scaleBy、zoom.scaleTo 和 zoom.translateBy 时强制执行;但是,使用 zoom.transform 显式设置变换时,此操作并非强制执行。
¥Source · If extent is specified, sets the scale extent to the specified array of numbers [k0, k1] where k0 is the minimum allowed scale factor and k1 is the maximum allowed scale factor, and returns this zoom behavior. If extent is not specified, returns the current scale extent, which defaults to [0, ∞]. The scale extent restricts zooming in and out. It is enforced on interaction and when using zoom.scaleBy, zoom.scaleTo and zoom.translateBy; however, it is not enforced when using zoom.transform to set the transform explicitly.
如果用户在已达到相应缩放范围限制的情况下尝试通过旋转进行缩放,则旋转事件将被忽略,并且不会触发缩放手势。这允许用户在放大后向下滚动经过可缩放区域,或在缩小后向上滚动。如果你希望无论缩放程度如何都始终阻止滚轮输入滚动,请注册滚轮事件监听器以防止浏览器的默认行为:
¥If the user tries to zoom by wheeling when already at the corresponding limit of the scale extent, the wheel events will be ignored and not initiate a zoom gesture. This allows the user to scroll down past a zoomable area after zooming in, or to scroll up after zooming out. If you would prefer to always prevent scrolling on wheel input regardless of the scale extent, register a wheel event listener to prevent the browser default behavior:
selection
.call(zoom)
.on("wheel", event => event.preventDefault());
zoom.translateExtent(extent) {#zoom_translateExtent}
源代码 · 如果指定了范围 (extent),则将平移范围设置为指定的点数组 [[x0, y0], [x1, y1]],其中 [x0, y0] 是世界的左上角,[x1, y1] 是世界的右下角,并返回此缩放行为。如果未指定范围,则返回当前平移范围,默认为 [[-∞, -∞], [+∞, +∞]]。平移范围会限制平移,缩小时可能会导致平移。它在交互时以及使用 zoom.scaleBy、zoom.scaleTo 和 zoom.translateBy 时强制执行;但是,使用 zoom.transform 显式设置变换时,此操作并非强制执行。
¥Source · If extent is specified, sets the translate extent to the specified 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 this zoom behavior. If extent is not specified, returns the current translate extent, which defaults to [[-∞, -∞], [+∞, +∞]]. The translate extent restricts panning, and may cause translation on zoom out. It is enforced on interaction and when using zoom.scaleBy, zoom.scaleTo and zoom.translateBy; however, it is not enforced when using zoom.transform to set the transform explicitly.
zoom.clickDistance(distance) {#zoom_clickDistance}
源代码 · 如果指定了 distance,则设置鼠标在 mousedown 和 mouseup 之间可以移动的最大距离,此距离会触发后续的点击事件。如果在 mousedown 和 mouseup 之间的任何时间点,鼠标距离 mousedown 位置的距离大于或等于 distance ,则 mouseup 之后的点击事件将被抑制。如果未指定距离,则返回当前距离阈值,默认为零。距离阈值以客户端坐标(event.clientX 和 event.clientY)为单位进行测量。
¥Source · If distance is specified, sets the maximum distance that the mouse can move between mousedown and mouseup that will trigger a subsequent click event. If at any point between mousedown and mouseup the mouse is greater than or equal to distance from its position on mousedown, the click event following mouseup will be suppressed. If distance is not specified, returns the current distance threshold, which defaults to zero. The distance threshold is measured in client coordinates (event.clientX and event.clientY).
zoom.tapDistance(distance) {#zoom_tapDistance}
源代码 · 如果指定了 distance,则设置双击手势在第一次 touchstart 和第二次 touchend 之间可以移动的最大距离,此距离会触发后续的双击事件。如果未指定距离,则返回当前距离阈值,默认为 10。距离阈值以客户端坐标(event.clientX 和 event.clientY)为单位进行测量。
¥Source · If distance is specified, sets the maximum distance that a double-tap gesture can move between first touchstart and second touchend that will trigger a subsequent double-click event. If distance is not specified, returns the current distance threshold, which defaults to 10. The distance threshold is measured in client coordinates (event.clientX and event.clientY).
zoom.duration(duration) {#zoom_duration}
源代码 · 如果指定了 dubbo,则设置双击和双击时缩放过渡的持续时间为指定的毫秒数,并返回缩放行为。如果未指定持续时间,则返回当前持续时间,默认为 250 毫秒。如果持续时间不大于零,双击并轻触将触发缩放变换的瞬时变化,而不是启动平滑过渡。
¥Source · 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 duration is not specified, returns the current duration, which defaults to 250 milliseconds. If the duration is not greater than zero, double-click and -tap trigger instantaneous changes to the zoom transform rather than initiating smooth transitions.
要禁用双击和双击过渡效果,你可以在将缩放行为应用于选择内容后移除缩放行为的 dblclick 事件监听器:
¥To disable double-click and double-tap transitions, you can remove the zoom behavior’s dblclick event listener after applying the zoom behavior to the selection:
selection
.call(zoom)
.on("dblclick.zoom", null);
zoom.interpolate(interpolate) {#zoom_interpolate}
源代码 · 如果指定了 interpolate,则将缩放过渡的插值工厂设置为指定的函数。如果未指定 interpolate,则返回当前插值工厂,默认为 interpolateZoom 以实现平滑缩放。要在两个视图之间应用直接插值,请尝试使用 interpolate。
¥Source · If interpolate is specified, sets the interpolation factory for zoom transitions to the specified function. If interpolate is not specified, returns the current interpolation factory, which defaults to interpolateZoom to implement smooth zooming. To apply direct interpolation between two views, try interpolate instead.
zoom.on(typenames, listener) {#zoom_on}
源代码 · 如果指定了 listener,则为指定的 typenames 设置事件监听器并返回缩放行为。如果已为相同类型和名称注册了事件监听器,则在添加新监听器之前,会先移除现有监听器。如果 listener 为 null,则移除指定 typenames 的当前事件监听器(如果有)。如果未指定 listener,则返回第一个当前已分配的、与指定 typenames 匹配的监听器(如果有)。当指定事件被调度时,每个监听器都将使用与 selection.on 监听器相同的上下文和参数进行调用:当前事件 (event
) 和数据 d
,以 this
上下文作为当前 DOM 元素。
¥Source · 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 event (event
) and datum d
, with the this
context as the current DOM element.
typenames 是一个字符串,包含一个或多个用空格分隔的 typename。每个类型名称都是一种类型,后面可以跟一个句点 (.
) 和一个名称,例如 zoom.foo
和 zoom.bar
;该名称允许为同一类型注册多个监听器。类型必须是以下之一:
¥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
- 缩放开始后(例如 mousedown 时)。¥
start
- after zooming begins (such as on mousedown).zoom
- 缩放变换发生变化后(例如 mousemove 时)。¥
zoom
- after a change to the zoom transform (such as on mousemove).end
- 缩放结束后(例如 mouseup 时)。¥
end
- after zooming ends (such as on mouseup ).
更多信息请参阅 dispatch.on。
¥See dispatch.on for more.
缩放事件
¥Zoom events
调用 缩放事件监听器 时,它会接收当前的缩放事件作为第一个参数。事件对象暴露了几个字段:
¥When a zoom event listener is invoked, it receives the current zoom event as a first argument. The event object exposes several fields:
event.target - 相关的 缩放行为。
¥event.target - the associated zoom behavior.
event.type - 字符串“start”、“zoom”或“end”;参见 zoom.on。
¥event.type - the string “start”, “zoom” or “end”; see zoom.on.
event.transform - 当前 缩放变换。
¥event.transform - the current zoom transform.
event.sourceEvent - 底层输入事件,例如 mousemove 或 touchmove。
¥event.sourceEvent - the underlying input event, such as mousemove or touchmove.
缩放行为处理各种交互事件:
¥The zoom behavior handles a variety of interaction events:
事件 | 监听元素 | 缩放事件 | 是否阻止默认设置? |
---|---|---|---|
鼠标按下⁵ | selection | start | 否¹ |
鼠标移动² | window¹ | zoom | yes |
鼠标弹起² | window¹ | end | yes |
dragstart² | window | * | yes |
selectstart² | window | * | yes |
点击³ | window | * | yes |
dblclick | selection | 多个⁶ | yes |
wheel⁸ | selection | zoom⁷ | yes |
touchstart | selection | 多个⁶ | 否⁴ |
touchmove | selection | zoom | yes |
touchend | selection | end | 否⁴ |
touchcancel | selection | end | 否⁴ |
所有消费事件的传播都是 立即停止。
¥The propagation of all consumed events is immediately stopped.
¹ 捕获 iframe 外部事件所必需的;参见 d3-drag#9。
² 仅在鼠标手势活动期间生效;参见 d3-drag#9。
³ 仅在某些鼠标手势之后立即生效;参见 zoom.clickDistance。
⁴ 触摸输入时允许 点击模拟 的必要条件;参见 d3-drag#9。
⁵ 如果在触摸手势结束后 500 毫秒内,则忽略;假设 点击模拟。
⁶ 双击和双击会启动一个触发开始、缩放和结束事件的过渡;参见 zoom.tapDistance。
⁷ 第一个滚轮事件会触发开始事件;当 150 毫秒内未收到任何滚轮事件时,将发出结束事件。
⁸ 如果已经达到 缩放范围 的相应极限,则忽略。
¥¹ 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 some mouse-based gestures; see zoom.clickDistance.
⁴ 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; see zoom.tapDistance.
⁷ 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.
zoomTransform(node)
源代码 · 返回指定节点的当前变换。请注意,节点通常应该是 DOM 元素,而不是选择。(一个选择集可能包含多个处于不同状态的节点,此函数仅返回一个变换。)如果你有选择,请先调用 selection.node:
¥Source · Returns the current transform for the specified node. Note that node should typically be a DOM element, not a selection. (A selection may consist of multiple nodes, in different states, and this function only returns a single transform.) If you have a selection, call selection.node first:
var transform = d3.zoomTransform(selection.node());
在 事件监听器 的上下文中,节点通常是接收输入事件(应该等于 event.transform)的元素,如下所示:
¥In the context of an event listener, the node is typically the element that received the input event (which should be equal to event.transform), this:
var transform = d3.zoomTransform(this);
在内部,元素的变换存储为 element.__zoom;但是,你应该使用此方法而不是直接访问它。如果给定节点没有定义的变换,则返回其最近祖级的变换;如果不存在,则返回 身份变换。返回的变换表示一个二维的 变换矩阵 类型,其形式如下:
¥Internally, an element’s transform is stored as element.__zoom; however, you should use this method rather than accessing it directly. If the given node has no defined transform, returns the transform of the closest ancestor, or if none exists, the identity transformation. The returned transform represents a two-dimensional transformation matrix of the form:
k 0 tx
0 k ty
0 0 1
(此矩阵只能表示缩放和平移;未来版本可能还会允许旋转,但这可能不属于向后兼容的变更。)位置 ⟨x,y⟩ 转换为 ⟨xk + tx,yk + ty⟩。变换对象公开以下属性:
¥(This matrix is capable of representing only scale and translation; a future release may also allow rotation, though this would probably not be a backwards-compatible change.) The position ⟨x,y⟩ is transformed to ⟨xk + tx,yk + ty⟩. The transform object exposes the following properties:
transform.x - 沿 x 轴的平移量 tx。
¥transform.x - the translation amount tx along the x-axis.
transform.y - 沿 y 轴的平移量 ty。
¥transform.y - the translation amount ty along the y-axis.
transform.k - 比例因子 k。
¥transform.k - the scale factor k.
这些属性应视为只读;使用 transform.scale 和 transform.translate 派生新的变换,而不是改变变换。另请参阅 zoom.scaleBy、zoom.scaleTo 和 zoom.translateBy,了解缩放行为的便捷方法。使用给定的 k、tx 和 ty 创建变换:
¥These properties should be considered read-only; instead of mutating a transform, use transform.scale and transform.translate to derive a new transform. Also see zoom.scaleBy, zoom.scaleTo and zoom.translateBy for convenience methods on the zoom behavior. To create a transform with a given k, tx, and ty:
var t = d3.zoomIdentity.translate(x, y).scale(k);
要将变换应用于 Canvas 2D 上下文,请使用 context.translate,然后使用 context.scale:
¥To apply the transformation to a Canvas 2D context, use context.translate followed by context.scale:
context.translate(transform.x, transform.y);
context.scale(transform.k, transform.k);
同样,要通过 CSS 将转换应用于 HTML 元素:
¥Similarly, to apply the 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");
要将变换应用于 SVG:
¥To apply the transformation to SVG:
g.attr("transform", "translate(" + transform.x + "," + transform.y + ") scale(" + transform.k + ")");
或者更简单地利用 transform.toString:
¥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.
zoomIdentity
源代码 · 恒等变换,其中 k = 1,tx = ty = 0。
¥Source · The identity transform, where k = 1, tx = ty = 0.
new d3.ZoomTransform(k, x, y)
源代码 · 返回一个比例为 k 且平移为 (x, y) 的变换。
¥Source · Returns a transform with scale k and translation (x, y).
transform.scale(k) {#transform_scale}
源代码 · 返回一个变换,其比例 k₁ 等于 k₀k,其中 k₀ 是此变换的比例。
¥Source · Returns a transform whose scale k₁ is equal to k₀k, where k₀ is this transform’s scale.
transform.translate(x, y) {#transform_translate}
源代码 · 返回一个变换,其平移 tx1 和 ty1 等于 tx0 + tk x 和 ty0 + tk y,其中 tx0 和 ty0 是此变换的平移,tk 是此变换的比例。
¥Source · 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) {#transform_apply}
源代码 · 返回指定点的变换,它是一个包含两个元素的数字数组 [x, y]。返回的点等于 [xk + tx, yk + ty]。
¥Source · 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) {#transform_applyX}
源代码 · 返回指定 x 坐标的变换,xk + tx。
¥Source · Returns the transformation of the specified x-coordinate, xk + tx.
transform.applyY(y) {#transform_applyY}
源代码 · 返回指定 y 坐标的变换,yk + ty。
¥Source · Returns the transformation of the specified y coordinate, yk + ty.
transform.invert(point) {#transform_invert}
源代码 · 返回指定点的逆变换,该点是一个由两个元素组成的数组 [x, y]。返回的点等于 [(x - tx) / k, (y - (ty) / k)。
¥Source · 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) {#transform_invertX}
源代码 · 返回指定 x 坐标的逆变换,(x - tx) / k。
¥Source · Returns the inverse transformation of the specified x-coordinate, (x - tx) / k.
transform.invertY(y) {#transform_invertY}
源代码 · 返回指定 y 坐标的逆变换,(y - ty) / k。
¥Source · Returns the inverse transformation of the specified y coordinate, (y - ty) / k.
transform.rescaleX(x) {#transform_rescaleX}
源代码 · 返回 连续缩放 x 的 copy,其 domain 已变换。此方法的实现方式是,首先将 逆 x 变换 应用于比例尺的 range,然后应用 逆比例 计算相应的域:
¥Source · 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:
function rescaleX(x) {
var range = x.range().map(transform.invertX, transform),
domain = range.map(x.invert, x);
return x.copy().domain(domain);
}
比例 x 必须使用 interpolateNumber;不要使用 continuous.rangeRound,因为这会降低 continuous.invert 的精度,并可能导致重新缩放后的域不准确。此方法不会修改输入比例 x;因此,x 表示未转换的比例,而返回的比例表示其转换后的视图。
¥The scale x must use interpolateNumber; do not use continuous.rangeRound as this reduces the accuracy of continuous.invert and can lead to an inaccurate rescaled domain. This method does not modify the input scale x; x thus represents the untransformed scale, while the returned scale represents its transformed view.
transform.rescaleY(y) {#transform_rescaleY}
源代码 · 返回 连续缩放 y 的 copy,其 domain 已变换。此方法的实现方式是,首先将 逆 y 变换 应用于比例尺的 range,然后应用 逆比例 计算相应的域:
¥Source · 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:
function rescaleY(y) {
var range = y.range().map(transform.invertY, transform),
domain = range.map(y.invert, y);
return y.copy().domain(domain);
}
比例 y 必须使用 interpolateNumber;不要使用 continuous.rangeRound,因为这会降低 continuous.invert 的精度,并可能导致重新缩放后的域不准确。此方法不会修改输入比例 y;因此,y 表示未转换的比例尺,而返回的比例尺表示其转换后的视图。
¥The scale y must use interpolateNumber; do not use continuous.rangeRound as this reduces the accuracy of continuous.invert and can lead to an inaccurate rescaled domain. This method does not modify the input scale y; y thus represents the untransformed scale, while the returned scale represents its transformed view.
transform.toString() {#transform_toString}
源代码 · 返回一个表示与此变换对应的 SVG 变换 的字符串。实现如下:
¥Source · Returns a string representing the SVG transform corresponding to this transform. Implemented as:
function toString() {
return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
}