D3.js - 缩放 API
D3.js - 缩放 API (Zooming API)
Section titled “D3.js - 缩放 API (Zooming API)”缩放 (Zooming) 和平移 (panning) 是探索详细可视化图形的关键交互方式。D3 的 Zoom API (d3-zoom) 提供了一种强大的方法来实现这些行为,通常通过鼠标滚轮、拖动或触摸手势。本章将介绍如何配置和使用 Zooming API。
配置 Zoom API
Section titled “配置 Zoom API”您可以通过包含完整的 D3 库或独立的 d3-zoom 模块来使用 Zoom API。d3-zoom 模块处理复杂的事件管理,以实现平滑的缩放和平移。
<!-- 选项 1: 包含完整的 D3 库 --><script src="https://d3js.org/d3.v7.min.js"></script>
<!-- 选项 2: 包含独立的 d3-zoom 模块 --><!-- 注意: d3-zoom 依赖于 d3-dispatch, d3-drag, d3-interpolate, d3-selection, d3-transition --><!-- 为简单起见,完整的 D3 包通常对初学者更友好。 --><!-- <script src="https://d3js.org/d3-zoom.v2.min.js"></script> -->
<script> // 示例初始化 // const zoom = d3.zoom(); // d3.select("svg").call(zoom);</script>核心缩放概念
Section titled “核心缩放概念”缩放行为通过监听选定的 SVG 元素上的输入事件 (如鼠标滚轮、拖动) 来工作。当这些事件发生时,D3 会计算一个 ‘zoom transform’ (缩放变换)。这个变换 (包括 x, y 坐标平移和 k 缩放因子) 随后应用于您想要缩放/平移的内容。
缩放交互的关键元素:
- 缩放行为 (Zoom Behavior): 使用
d3.zoom()创建。 - 目标元素 (Target Element): 一个 SVG 元素 (通常是
<svg>或<g>元素),它监听缩放手势。您使用selection.call(zoom)将缩放行为应用于此元素。 - 缩放事件 (Zoom Event): 缩放行为会分派
zoom事件。您的监听器 (listener) 函数会接收一个event对象,其中event.transform包含当前的缩放变换 (zoom transform)。 - 应用变换 (Applying the Transform): 在缩放事件监听器内部,您将
event.transform应用于您想要缩放和平移的元素。这通常通过设置包含可视化元素的 SVG 组 (<g>) 元素的transform属性来完成。
Zooming API 方法
Section titled “Zooming API 方法”以下是 D3 Zoom API 中一些最常用的方法:
- d3.zoom() − 创建一个新的缩放行为 (zoom behavior)。
- zoom(selection) − 将缩放行为应用于给定的 selection。这通常通过
selection.call(zoom)完成。 - zoom.transform(selection, transform[, point]) − 以编程方式将选中元素的当前缩放变换 (zoom transform) 设置为指定的
transform。可选的point可以指定缩放原点 (zoom origin)。 - zoom.translateBy(selection, x, y) − 将选中元素的当前缩放变换在屏幕坐标系下平移
x和y。 - zoom.translateTo(selection, x, y[, point]) − 平移选中元素的当前缩放变换,使得给定的
point(数据坐标) 显示在指定的x, y位置 (屏幕坐标)。 - zoom.scaleBy(selection, k[, point]) − 将选中元素的当前缩放变换按
k(乘数) 进行缩放,可选地围绕指定的point(屏幕坐标) 进行。 - zoom.scaleTo(selection, k[, point]) − 将选中元素的当前缩放变换缩放至绝对比例因子 (absolute scale factor)
k,可选地围绕指定的point(屏幕坐标) 进行。 - zoom.filter([filterFunction]) − 设置一个过滤函数 (filter function) 来控制哪些输入事件触发缩放手势。默认过滤器会忽略鼠标右键或按下 Alt 等修饰键时的缩放。
- zoom.wheelDelta([deltaFunction]) − 自定义鼠标滚轮事件如何转换为缩放。默认值是
(event) => -event.deltaY * (event.deltaMode === 1 ? 0.05 : event.deltaMode ? 1 : 0.002) * (event.ctrlKey ? 10 : 1)。 - zoom.extent([[x0, y0], [x1, y1]]) − 设置视口范围 (viewport extent)。默认为所属 SVG 元素的尺寸。
- zoom.scaleExtent([minScale, maxScale]) − 设置允许的最小和最大比例因子 (scale factors) (例如,
[0.5, 8])。 - zoom.translateExtent([[x0, y0], [x1, y1]]) − 设置可平移范围 (pannable extent)。考虑到当前比例,防止平移超出这些边界。
- zoom.clickDistance([distance]) − 设置鼠标在 mousedown 和 mouseup 事件之间移动的最大距离,以便识别为 click 事件。
- zoom.duration([duration]) − 设置双击 (放大) 和编程调用缩放时触发的缩放过渡 (zoom transitions) 的持续时间 (以毫秒为单位)。默认值为 250ms。
- zoom.interpolate([interpolateFactory]) − 为缩放过渡设置插值工厂 (interpolation factory)。默认值为
d3.interpolateZoom。 - zoom.on(typenames[, listener]) − 为缩放事件附加一个事件监听器 (event listener)。常见的 typenames 包括
start(缩放手势开始)、zoom(变换变化) 和end(缩放手势结束)。
示例:在 SVG 元素上进行基本缩放
Section titled “示例:在 SVG 元素上进行基本缩放”让我们创建一个简单的示例,以便我们可以在一组 SVG 圆形上进行缩放和平移。
<!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>D3.js Zoom Example</title> <script src="https://d3js.org/d3.v7.min.js"></script> <style> svg { border: 1px solid #ccc; cursor: grab; } .zoomed-content circle { fill: steelblue; } </style></head><body> <svg width="600" height="400"> <g class="zoomed-content"> <circle cx="100" cy="100" r="40"></circle> <circle cx="250" cy="150" r="30"></circle> <circle cx="400" cy="200" r="50"></circle> </g> </svg>
<script> const svg = d3.select("svg"); const g = svg.select(".zoomed-content");
// 创建缩放行为 const zoom = d3.zoom() .scaleExtent([0.5, 5]) // 最小和最大缩放级别 .on("zoom", (event) => { // event.transform 包含当前变换 (k, x, y) g.attr("transform", event.transform); });
// 将缩放行为应用于 SVG 元素 svg.call(zoom);
// 可选:设置初始变换 // svg.call(zoom.transform, d3.zoomIdentity.translate(50, 50).scale(1.2)); </script></body></html>在此示例中,鼠标拖动将平移圆形,鼠标滚轮将放大或缩小。来自 ‘zoom’ 事件的 event.transform 对象直接应用于包含圆形的 <g> 元素。
重要注意事项
Section titled “重要注意事项”- 事件处理 (Event Handling): 现代 D3 将
event对象作为第一个参数传递给监听器 (listeners)。d3.event已被弃用。通过event.transform访问缩放变换 (zoom transform)。 - 变换应用 (Transform Application): 将缩放变换 (zoom transform) 应用于容器
<g>元素,而不是单独的形状,以获得更好的性能和更易于管理。 - 坐标系统 (Coordinate Systems): 注意区分屏幕坐标 (screen coordinates) 和数据坐标 (data coordinates),尤其是在使用
translateTo或scaleTo等方法并带有point参数时。 - 与坐标轴的交互 (Interaction with Axes): 当缩放带有坐标轴 (axes) 的图表时,您需要在缩放事件处理程序 (zoom event handler) 中更新坐标轴比例尺 (axis scales) 并重新渲染坐标轴。请参阅比例尺 (scales) 上的
rescaleX/rescaleY方法。
对于更高级的缩放场景,例如编程缩放 (programmatic zooming) 或与其他交互的集成,请查阅 d3-zoom 官方文档。