d3-zoom
示例 · 平移和缩放 让用户通过限制视图来专注于感兴趣的区域。它使用直接操作:点击并拖动进行平移(平移),滚动鼠标滚轮进行缩放(缩放),或使用触摸进行捏合。平移和缩放在基于网页的地图中被广泛使用,但也可以用于可视化,如密集的时间序列和散点图。
缩放行为是一种灵活的抽象,能够处理各种输入方式和浏览器特性带来的意外情况。缩放行为与 DOM 无关,因此可以在 HTML、SVG 或 Canvas 中使用。你可以将 d3-zoom 与 d3-scale 和 d3-axis 结合使用来 缩放坐标轴。你可以使用 zoom.scaleExtent 限制缩放,使用 zoom.translateExtent 限制平移。你可以将 d3-zoom 与其他行为结合使用,例如 d3-drag 进行 拖拽,以及 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 应用于所选元素。
缩放(选择)
🌐 zoom(selection)
来源 · 将此缩放行为应用于指定的 选择,绑定必要的事件监听器以允许平移和缩放,并在每个选定的元素上初始化 缩放变换,如果尚未定义,则采用单位变换。
此函数通常不会被直接调用,而是通过 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)
来源 · 如果 selection 是一个选择,则将所选元素的 当前缩放变换 设置为指定的 transform,立即触发开始、缩放和结束 事件。
如果 selection 是一个过渡,使用 interpolateZoom 定义一个到指定 transform 的“缩放”补间,在过渡开始时触发 start 事件,在过渡的每一个时间刻度触发 zoom 事件,然后在过渡结束(或被中断)时触发 end 事件。该过渡将尝试将指定 point 周围的视觉移动最小化;如果未指定 point,则默认为视口 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.
transform 可以指定为 缩放变换 或返回缩放变换的函数;同样,point 可以指定为两元素数组 [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 调用。例如,要立即将缩放变换重置为 identity transform :
🌐 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)
来源 · 如果 selection 是一个选择,则将所选元素的 当前缩放变换 按 x 和 y 平移,使得新的 tx1 = tx0 + kx 且 ty1 = ty0 + ky。如果 selection 是一个过渡,则定义一个“缩放” tween 来平移当前变换。此方法是 zoom.transform 的便捷方法。x 和 y 平移量可以指定为数字或返回数字的函数。如果是函数,则对每个选定的元素调用该函数,并传入当前数据 d 和索引 i,同时 this 上下文作为当前的 DOM 元素。
zoom.translateTo(selection, x, y, p)
来源 · 如果 selection 是一个选择, translates 将所选元素的 当前缩放变换 平移,使给定位置 ⟨x,y⟩ 出现在给定点 p。新的 tx = px - kx,ty = py - ky。如果未指定 p,则默认为视口 范围 的中心。如果 selection 是一个过渡,则定义一个“缩放”缓动,用于平移当前变换。该方法是 zoom.transform 的便捷方法。x 和 y 坐标可以指定为数字,也可以指定为返回数字的函数;同样,p 点可以指定为一个两元素数组 [px,py] 或一个函数。如果是函数,则对每个所选元素调用它,并传入当前数据 d 和索引 i,上下文 this 为当前 DOM 元素。
zoom.scaleBy(selection, k, p)
来源 · 如果 selection 是一个选择,则按 k 缩放所选元素的当前缩放变换,使新的 k₁ = k₀k。参考点 p 会移动。如果未指定 p,则默认为视口范围的中心。如果 selection 是一个过渡,则定义一个“缩放”补间以平移当前变换。此方法是 zoom.transform 的便捷方法。k 缩放因子可以指定为数值或返回数值的函数;类似地,p 点可以指定为一个两元素数组 [px,py] 或一个函数。如果是函数,则会针对每个所选元素调用它,传入当前数据 d 和索引 i,并以当前 DOM 元素作为 this 上下文。
zoom.scaleTo(selection, k, p)
来源 · 如果 selection 是一个选择,按 k 缩放所选元素的 当前缩放变换,使得新的 k₁ = k。参考点 p 会移动。如果未指定 p,则默认为视口 范围 的中心。如果 selection 是一个过渡,则定义一个“缩放”补间以平移当前变换。此方法是 zoom.transform 的便捷方法。k 缩放因子可以指定为数字或返回数字的函数;同样,p 点可以指定为一个两元素数组 [px,py] 或一个函数。如果是函数,则对每个选中的元素调用,并传入当前数据 d 和索引 i,this 上下文为当前 DOM 元素。
zoom.constrain(constrain)
来源 · 如果指定了 constrain,则将变换约束函数设置为指定的函数并返回缩放行为。如果未指定 constrain,则返回当前的约束函数,默认为:
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、视口范围 和 平移范围 的 [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)
来源 · 如果指定了 filter,则将过滤器设置为指定的函数并返回缩放行为。如果未指定 filter,则返回当前过滤器,默认如下:
function filter(event) {
return (!event.ctrlKey || event.type === 'wheel') && !event.button;
}该过滤器接收当前事件(event)和数据项 d,并将 this 上下文作为当前 DOM 元素。如果过滤器返回假值,则将忽略发起事件,并且不会启动任何缩放手势。因此,过滤器决定了哪些输入事件会被忽略。默认过滤器会忽略次要按钮的 mousedown 事件,因为这些按钮通常用于其他目的,例如上下文菜单。
🌐 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)
来源 · 如果指定了 touchable,则将触摸支持检测器设置为指定的函数,并返回缩放行为。如果未指定 touchable,则返回当前的触摸支持检测器,默认值为:
function touchable() {
return navigator.maxTouchPoints || ("ontouchstart" in this);
}只有当检测器在缩放行为应用时对相应元素返回真值时,才会注册触摸事件监听器。默认检测器对于大多数支持触摸输入的浏览器工作良好,但并非全部;例如,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.
缩放.wheelDelta(delta)
🌐 zoom.wheelDelta(delta)
来源 · 如果指定了 delta,则将滚轮增量函数设置为指定的函数,并返回缩放行为。如果未指定 delta,则返回当前的滚轮增量函数,默认值为:
function wheelDelta(event) {
return -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1);
}轮子增量函数返回的值 Δ 决定了响应 WheelEvent 时应用的缩放量。缩放因子 transform.k 会乘以 2Δ;例如,Δ 为 +1 时,缩放因子加倍,Δ 为 -1 时,缩放因子减半。
zoom.extent(extent)
来源 · 如果指定了 extent,则将视口范围设置为指定的点数组 [[x0, y0], [x1, y1]],其中 [x0, y0] 是视口的左上角,[ x1, y1] 是视口的右下角,并返回此缩放行为。extent 也可以指定为返回此类数组的函数;如果是函数,则对每个选定元素调用该函数,并传入当前数据 d,以 this 作为当前 DOM 元素的上下文。
如果未指定 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 选择的路径;并且需要视口范围来执行可选的 translate extent。
🌐 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)
来源 · 如果指定了 extent,则将缩放范围设置为指定的数字数组 [k0, k1],其中 k0 是允许的最小缩放因子,k1 是允许的最大缩放因子,并返回此缩放行为。如果未指定 extent,则返回当前的缩放范围,默认值为 [0, ∞]。缩放范围限制放大和缩小。在交互过程中以及使用 zoom.scaleBy、zoom.scaleTo 和 zoom.translateBy 时会强制执行;然而,在使用 zoom.transform 显式设置变换时则不强制执行。
如果用户尝试在已经达到比例范围相应极限时通过滚轮缩放,滚轮事件将被忽略,不会触发缩放手势。这允许用户在放大后滚动穿过可缩放区域,或在缩小后向上滚动。如果你希望无论比例范围如何都始终阻止滚轮输入的滚动,请注册滚轮事件监听器以阻止浏览器的默认行为:
🌐 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)
来源 · 如果指定了 extent,则将平移范围设置为指定的点数组 [[x0, y0], [x1, y1]],其中 [x0, y0] 是世界的左上角,[ x1, y1] 是世界的右下角,并返回此缩放行为。如果未指定 extent,则返回当前的平移范围,默认值为 [[-∞, -∞], [+∞, +∞]]。平移范围限制平移操作,并可能在缩小缩放时引起平移效应。它在交互操作以及使用 zoom.scaleBy、zoom.scaleTo 和 zoom.translateBy 时被强制执行;然而,当使用 zoom.transform 明确设置变换时,它不会被强制执行。
缩放.点击距离(距离)
🌐 zoom.clickDistance(distance)
来源 · 如果指定了 distance,则设置鼠标在 mousedown 和 mouseup 之间允许移动的最大距离,以触发后续的点击事件。如果在 mousedown 和 mouseup 之间的任何时刻,鼠标与 mousedown 时的位置的距离大于或等于 distance,则 mouseup 后的点击事件将被抑制。如果未指定 distance,则返回当前的距离阈值,默认为零。距离阈值以客户端坐标(event.clientX 和 event.clientY)来衡量。
缩放.点击距离(distance)
🌐 zoom.tapDistance(distance)
来源 · 如果指定了 distance,则设置双击手势在第一次 touchstart 和第二次 touchend 之间可以移动的最大距离,从而触发随后的双击事件。如果未指定 distance,则返回当前的距离阈值,默认值为 10。距离阈值以客户端坐标 (event.clientX 和 event.clientY) 测量。
缩放.持续时间(duration)
🌐 zoom.duration(duration)
来源 · 如果指定了duration,则将双击和双指轻敲的缩放过渡持续时间设置为指定的毫秒数,并返回缩放行为。如果未指定duration,则返回当前持续时间,默认为250毫秒。如果持续时间不大于零,则双击和双指轻敲会立即触发缩放变换,而不会启动平滑过渡。
要禁用双击和双击过渡效果,你可以在将缩放行为应用于选择内容后移除缩放行为的 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)
来源 · 如果指定了 interpolate,则将缩放过渡的插值生成器设置为指定的函数。如果未指定 interpolate,则返回当前的插值生成器,默认使用 interpolateZoom 实现平滑缩放。要在两个视图之间直接应用插值,请改用 interpolate。
zoom.on(typenames, listener)
来源 · 如果指定了 listener,则为指定的 typenames 设置事件 listener 并返回缩放行为。如果已经为同一类型和名称注册了事件监听器,则在添加新监听器之前会移除现有的监听器。如果 listener 为 null,则移除指定 typenames 的当前事件监听器(如果有)。如果未指定 listener,则返回匹配指定 typenames 的第一个当前分配的监听器(如果有)。当分发指定事件时,每个 listener 将以与 selection.on 监听器相同的上下文和参数被调用:当前事件 (event) 和数据 d,其中 this 作为当前 DOM 元素的上下文。
typenames 是一个包含一个或多个 typename 的字符串,它们由空格分隔。每个 typename 是一个 type,可选地后跟一个句点(.)和一个 name,例如 zoom.foo 和 zoom.bar;该名称允许为相同的 type 注册多个监听器。type 必须是以下之一:
🌐 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 时)。zoom- 缩放变换发生变化后(例如 mousemove 时)。end- 缩放结束后(例如 mouseup 时)。
有关更多信息,请参阅 dispatch.on。
🌐 See dispatch.on for more.
缩放事件
🌐 Zoom events
当调用 zoom event listener 时,它会将当前缩放事件作为第一个参数传入。event 对象暴露了几个字段:
🌐 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.type - 字符串 “start”、“zoom” 或 “end”;见 zoom.on。
- event.transform - 当前的 缩放变换。
- event.sourceEvent - 底层输入事件,例如 mousemove 或 touchmove。
缩放行为处理各种交互事件:
🌐 The zoom behavior handles a variety of interaction events:
| 事件 | 监听元素 | Zoom 事件 | 是否阻止默认行为? |
|---|---|---|---|
| mousedown⁵ | 选择 | start | 否¹ |
| mousemove² | 窗口¹ | zoom | 是 |
| mouseup² | 窗口¹ | end | 是 |
| dragstart² | 窗口 | - | 是 |
| selectstart² | 窗口 | - | 是 |
| click³ | 窗口 | - | 是 |
| dblclick | 选择 | 多个⁶ | 是 |
| wheel⁸ | 选择 | zoom⁷ | 是 |
| touchstart | 选择 | 多个⁶ | 否⁴ |
| touchmove | 选择 | zoom | 是 |
| touchend | 选择 | end | 否⁴ |
| touchcancel | 选择 | end | 否⁴ |
所有被消费的事件的传播都会立即停止。
🌐 The propagation of all consumed events is immediately stopped.
¹ 必须捕获 iframe 外的事件;参见 d3-drag#9。
² 仅在活动的基于鼠标的手势期间适用;参见 d3-drag#9。
³ 仅在某些基于鼠标的手势之后立即适用;参见 zoom.clickDistance。
⁴ 必须允许触摸输入的 点击模拟;参见 d3-drag#9。
⁵ 如果在触摸手势结束后 500 毫秒内,则会被忽略;假设 点击模拟。
⁶ 双击和双点按会启动一个发出 start、zoom 和 end 事件的过渡;参见 zoom.tapDistance。
⁷ 第一次滚轮事件发出 start 事件;当 150 毫秒内没有接收到滚轮事件时,会发出 end 事件。
⁸ 如果已经到达 scale extent 的相应限制,则会被忽略。
zoomTransform(节点)
🌐 zoomTransform(node)
Source · 返回指定 node 的当前变换。请注意,node 通常应为 DOM 元素,而不是 selection。(一个 selection 可能包含多个节点,且处于不同状态,而此函数仅返回单个变换。)如果你有一个 selection,请先调用 selection.node:
var transform = d3.zoomTransform(selection.node());在一个 事件监听器 的上下文中,节点 通常是接收输入事件的元素(它应该等于 event.transform),this:
🌐 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;但是,你应该使用此方法而不是直接访问它。如果给定的 node 没有定义的变换,则返回最近祖级的变换,如果不存在祖级,则返回单位变换。返回的变换表示一个二维变换矩阵,形式如下:
🌐 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⟩。变换对象暴露以下属性:
- transform.x - 沿 x 轴的平移量 tx。
- transform.y - 沿 y 轴的平移量 ty。
- transform.k - 缩放因子 k。
这些属性应被视为只读;不要对变换进行修改,而是使用 transform.scale 和 transform.translate 来派生一个新的变换。另请参阅 zoom.scaleBy、zoom.scaleTo 和 zoom.translateBy 以获取缩放行为的方便方法。要创建具有给定 k、tx 和 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。
new d3.ZoomTransform(k, x, y)
来源 · 返回一个具有缩放 k 和平移 (x, y) 的变换。
transform.scale(k)
来源 · 返回一个变换,其缩放 k₁ 等于 k₀k,其中 k₀ 是此变换的缩放。
transform.translate(x, y)
源 · 返回一个变换,其平移 tx1 和 ty1 等于 tx0 + tk x 和 ty0 + tk y,其中 tx0 和 ty0 是此变换的平移,tk 是此变换的缩放。
transform.apply(point)
来源 · 返回指定点的变换,该点是一个包含两个数字元素的数组 [x, y]。返回的点等于 [xk + tx, yk + ty]。
transform.applyX(x)
来源 · 返回指定 x 坐标的变换,xk + tx。
transform.applyY(y)
源 · 返回指定 y 坐标的变换,yk + ty。
transform.invert(point)
来源 · 返回指定 point 的逆变换,该 point 是一个包含两个数字元素 [x, y] 的数组。返回的点等于 [(x - tx) / k, (y - ty) / k]。
transform.invertX(x)
来源 · 返回指定x坐标的逆变换,(x - tx) / k。
transform.invertY(y)
来源 · 返回指定 y 坐标的逆变换,(y - ty) / k。
transform.rescaleX(x)
来源 · 返回一个副本的连续刻度 x,其定义域已被转换。其实现方法是首先对刻度的值域应用逆 x 变换,然后再应用逆刻度以计算对应的定义域:
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)
来源 · 返回一个其定义域已被转换的连续刻度 y 的副本。这是通过首先对刻度的取值范围应用逆 y 变换,然后应用逆刻度计算对应的定义域来实现的:
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()
来源 · 返回表示与此变换对应的 SVG 变换 的字符串。实现如下:
function toString() {
return "translate(" + this.x + "," + this.y + ") scale(" + this.k + ")";
}