目录
zoom.transform(selection, transform)
zoom.translateBy(selection,x,y)
zoom.translateTo(selection, x, y)
zoom.translateExtent([extent])
zoom .clickDistance([distance])
zoom.interpolate([interpolate])
zoom.on(typenames [,listener])
D3.js绘图工具系列文章总提纲:【传送门】
修改d3默认事件(进阶):按住轮滑为平移,滚动轮滑为缩放【传送门】
效果图(包含了画布的拖拽与缩放及圆的拖拽,其中圆的拖拽效果可在【传送门】查看):
实现逻辑
1、创建一个SVG容器:
使用d3.js创建一个SVG容器(h5代码中须有相关id标签),用于呈现图表和图形;
let svg = reactive({});
// 生成画布的dom节点id为d3Canvas;须在html代码中添加
svg = d3
.select('#d3Canvas')
.append("svg")
.attr("id", "svg")
.attr("width", 500)
.attr("height", 500)
.attr("viewBox", "0 0 500 500");
2、创建一个主分组:
使用d3.js对所创建的SVG容器,添加一个g标签,用于控制整体缩放;不将事件直接绑定于svg上,是因为会出现bug:画面呈现出一闪一闪的,解决方案是将所有元素使用g标签进行包裹。
let g = reactive({});
g = svg.append("g").attr("id", "svg-grid");
3、添加背景:
用于让拖拽缩放效果更明显;
g.insert("rect", ":first-child")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "url(#grid)");
// 使用网格样式填充 SVG 元素背景
var pattern = svg.insert("defs", ":first-child")
.append("pattern")
.attr("id", "grid")
.attr("width", 20)
.attr("height", 20)
.attr("patternUnits", "userSpaceOnUse");
// 添加网格线
pattern.append("path")
.attr("d", "M 20 0 L 0 0 0 20")
.attr("stroke", "lightgray")
.attr("stroke-width", 0.5)
.attr("fill", "none");
4、定义缩放和平移行为:
使用d3.zoom()函数创建一个缩放和平移行为,可以通过设置缩放比例和平移偏移量来控制缩放和平移的效果;
function zoomed(event, svg) {
// 对g进行偏移赋值
g.attr("transform", event.transform);
}
var zoom = d3
.zoom()
.scaleExtent([0.3, 10])
.on("zoom", (event) => zoomed(event));
5、应用缩放和平移行为:
将缩放和平移行为应用到SVG容器上,使得图表可以响应鼠标事件。
g.call(zoom)
注:若需对画布进行缩放及平移则修改两个参数:
scale:缩放;
translate:平移;
initZoom(svg) {
……
g.call(zoom.transform, d3.zoomIdentity.scale(0.6).translate(0, 150));
}
完整代码
let svg = reactive({});
// 生成画布的dom节点id为d3Canvas;须在html代码中添加
svg = d3
.select('#d3Canvas')
.append("svg")
.attr("id", "svg")
.attr("width", 500)
.attr("height", 500)
.attr("viewBox", "0 0 500 500");
let g = reactive({});
g = svg.append("g").attr("id", "svg-grid");
g.insert("rect", ":first-child")
.attr("width", "100%")
.attr("height", "100%")
.attr("fill", "url(#grid)");
// 使用网格样式填充 SVG 元素背景
var pattern = svg.insert("defs", ":first-child")
.append("pattern")
.attr("id", "grid")
.attr("width", 20)
.attr("height", 20)
.attr("patternUnits", "userSpaceOnUse");
// 添加网格线
pattern.append("path")
.attr("d", "M 20 0 L 0 0 0 20")
.attr("stroke", "lightgray")
.attr("stroke-width", 0.5)
.attr("fill", "none");
function zoomed(event, svg) {
// 对g进行偏移赋值
g.attr("transform", event.transform);
}
var zoom = d3
.zoom()
.scaleExtent([0.3, 10])
.on("zoom", (event) => zoomed(event));
g.call(zoom)
g.append("circle")
.attr("cx", 50)
.attr("cy", 50)
.attr("r", 20)
.style("fill", "blue")
.attr("id", `circle-1`)
缩放API方法
以下是一些最常用的缩放API方法(放于此便于查阅,为引用内容【原文传送门】):
-
d3.zoom()
-
zoom(selection)
-
zoom.transform(selection, transform)
-
zoom.translateBy(selection, x, y)
-
zoom.translateTo(selection, x, y)
-
zoom.scaleTo(selection, k)
-
zoom.scaleBy(selection, k)
-
zoom.filter([filter])
-
zoom.wheelDelta([delta])
-
zoom.extent([extent])
-
zoom.scaleExtent([extent])
-
zoom.translateExtent([extent])
-
zoom.clickDistance([distance])
-
zoom.duration([duration])
-
zoom.interpolate([interpolate])
-
zoom.on(typenames[, listener])
让我们简单介绍一下这些Zooming API方法.
d3.zoom()
它会创建一个新的缩放行为.我们可以使用下面的脚本访问它.
<script>
var zoom = d3.zoom();
</script>
zoom(选择)
它用于对选定元素应用缩放变换.例如,您可以使用以下语法实例化mousedown.zoom行为.
selection.call(d3.zoom().on(" mousedown.zoom",mousedowned));
zoom.transform(selection, transform)
它用于设置所选元素的当前缩放变换到指定的转换.例如,我们可以使用以下语法将缩放变换重置为标识变换.
selection.call(zoom.transform,d3.zoomIdentity );
我们还可以使用以下语法将缩放变换重置为标识变换1000毫秒.
selection.transition().duration(1000).call(zoom.transform,d3.zoomIdentity);
zoom.translateBy(selection,x,y)
通俗点讲对 selection 进行 [x, y] 的偏移,若放于实际应用时,应为两点之间的差值,即:
x = x2 - x1;
y = y2 - y1;
源代码定义如下.
zoom.translateBy = function(selection, x, y, event) {
zoom.transform(selection, function() {
return constrain(this.__zoom.translate(
typeof x === "function" ? x.apply(this, arguments) : x,
typeof y === "function" ? y.apply(this, arguments) : y
), extent.apply(this, arguments), translateExtent);
}, null, event);
};
zoom.translateTo(selection, x, y, p)
用于对 selection 进行 x1,y1 到 p: [x2, y2] 的偏移,其中 [x1, y1] 为起点,[x2, y2] 为终点。
源代码定义如下:
zoom.translateTo = function(selection, x, y, p, event) {
zoom.transform(selection, function() {
var e = extent.apply(this, arguments),
t = this.__zoom,
p0 = p == null ? centroid(e) : typeof p === "function" ? p.apply(this, arguments) : p;
console.log("translateTo", e, t, p0);
return constrain(identity.translate(p0[0], p0[1]).scale(t.k).translate(
typeof x === "function" ? -x.apply(this, arguments) : -x,
typeof y === "function" ? -y.apply(this, arguments) : -y
), e, translateExtent);
}, p, event);
};
zoom.scaleTo(selection, k)
它用于将所选元素的当前缩放变换缩放为 k .这里, k 是一个比例因子,指定为数字或函数.
zoom.scaleTo = function(selection, k) {
zoom.transform(selection, function() {
k = = = "function" ? k.apply(this, arguments) : k;
});
};
zoom.scaleBy(selection,k)
它用于按 k 缩放所选元素的当前zoon变换.这里, k 是一个比例因子,指定为数字或返回数字的函数.
zoom.scaleBy = function(selection, k) {
zoom.scaleTo(selection, function() {
var k0 = this.__zoom.k,
k1 = k = = = "function" ? k.apply(this, arguments) : k;
return k0 * k1;
});
};
zoom.filter([filter])
它用于将过滤器设置为指定的缩放功能行为.如果未指定过滤器,则返回当前过滤器,如下所示.
function filter() {
return !d3.event.button;
}
zoom.wheelDelta(δ)
&Delta的值由轮三角函数返回.如果未指定delta,则返回当前的wheel delta函数.
zoom.extent([extent])
用于设置指定数组点的范围.如果未指定范围,则返回当前范围访问器,默认为[[0,0],[width,height]],其中width是元素的客户端宽度,height是其客户端高度.
zoom.scaleExtent([extent])
用于将比例范围设置为指定的数字数组[k0,k1].这里, k0 是允许的最小比例因子.而 k1 是允许的最大比例因子.如果未指定extent,则返回当前缩放范围,默认为[0,∞].考虑下面定义的示例代码.
selection
.call(zoom)
.on("wheel", function() { d3.event.preventDefault(); });
当已经处于比例范围的相应限制时,用户可以尝试通过转动进行缩放.如果我们想要阻止滚轮输入滚动而不管刻度范围如何,请注册滚轮事件监听器以防止浏览器默认行为.
zoom.translateExtent([extent])
如果指定了范围,则将translate范围设置为指定的点数组.如果未指定范围,则返回当前的翻译范围,默认为[[ - ∞, - ∞],[+∞,+∞]].
zoom .clickDistance([distance])
此方法用于设置可缩放区域在向上和向下之间移动的最大距离,这将触发后续点击事件.
zoom.duration([duration])
此方法用于设置双击时缩放过渡的持续时间,然后双击指定的数量毫秒并返回缩放行为.如果未指定持续时间,则返回当前持续时间,默认为250毫秒,定义如下.
selection
.call(zoom)
.on("dblclick.zoom", null);
zoom.interpolate([interpolate])
此方法用于内插缩放过渡到指定的函数.如果未指定interpolate,则返回当前插值工厂,默认为d3.interpolateZoom.
zoom.on(typenames [,listener])
如果指定了侦听器,它将为指定的类型名设置事件侦听器并返回缩放行为.类型名是一个包含一个或多个由空格分隔的类型名的字符串.每个typename都是一个类型,可选地后跟句点(.)和名称,例如zoom.one和zoom.second.该名称允许为同一类型注册多个侦听器.此类型必须来自以下其中一项;
-
开始 : 缩放开始后(例如在mousedown上).
-
缩放 : 更改缩放变换后(例如在mousemove上).
-
结束 : 缩放结束后(例如在鼠标上).
感谢阅读!在您离开之前,不妨留下您的足迹:
👍 点个赞,让我知道您喜欢这篇文章!
📝 有任何想法、建议或问题?欢迎在下方评论区分享您的想法!
🔁 分享给您的朋友们,让更多人受益!
💌 喜欢我的内容?立即订阅我的博客,获取更多精彩内容!
谢谢您的支持与参与,让我们一起创造更好的内容体验!