我正在将我的应用程序从d3 v5升级到v6,并且在迁移d3鼠标功能时遇到了问题。在我的应用程序中,我将转换到顶级svg组,并使用缩放功能来缩放和平移(缩放和翻译)。当我双击屏幕,我采取鼠标的位置,并画一个正方形。
现在,我要用d3指针替换d3鼠标函数。在双击事件中,我通过调用d3.pointer(event)获得鼠标位置。但是,这个函数不会产生一个相对于我的顶级svg组定位和缩放的位置。当我从顶级组中移除翻译和缩放时,职位匹配。
在较早版本的d3中,我可以调用d3.mouse(this.state.svg.node()),它会产生我单击的正确位置,修正为pan和scale。这在第6版中有吗?如果没有,是否有一个干净的方法,我可以调整这一点?新的事件对象具有许多不同的位置属性: pagex、offsetx、screenx、x,这些都不会产生我单击的位置。有干净的方法来解决这个问题吗?
发布于 2020-10-05 03:50:14
您可以指定一个容器元素,该元素将在v5和更早版本中进行缩放转换:
D3.鼠标(容器) 返回当前事件相对于指定容器的x和y坐标。容器可以是HTML或SVG容器元素,例如G元素或SVG元素。坐标作为数字x,y的二元数组返回。(来源)
在d3v6中,可以通过使用d3指针的第二个参数来指定这一点:
D3指针(事件、目标) 返回数字x的两个元素数组,y表示指定事件相对于指定目标的坐标。事件可以是MouseEvent、PointerEvent、Touch或包含UIEvent作为event.sourceEvent的自定义事件。..。如果目标是SVG元素,则使用屏幕坐标转换矩阵的逆变换来转换事件的坐标。如果目标是HTML元素,则事件的坐标相对于目标边界客户端矩形的左上角被转换。(来源)
据我所知,你应该使用:
d3.pointer(event,this.state.svg.node());而不是
d3.mouse(this.state.svg.node());下面是一个d3v6示例:
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 200);
var rect = svg.append("rect")
.attr("width",500)
.attr("height",200)
.attr("fill", "#eee")
var g = svg.append("g");
var zoomed = function(event) {
g.attr("transform", event.transform);
}
rect.call(d3.zoom().on("zoom",zoomed))
.on("click", function(event) {
var xy = d3.pointer(event,g.node());
g.append("circle")
.attr("r", 5)
.attr("cx", xy[0])
.attr("cy", xy[1])
.attr("fill","crimson");
})<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/6.0.0/d3.min.js"></script>
修改这个v5示例:
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 200);
var rect = svg.append("rect")
.attr("width",500)
.attr("height",200)
.attr("fill", "#eee")
var g = svg.append("g");
var zoomed = function() {
g.attr("transform", d3.event.transform);
}
rect.call(d3.zoom().on("zoom",zoomed))
.on("click", function() {
var xy = d3.mouse(g.node());
g.append("circle")
.attr("r", 5)
.attr("cx", xy[0])
.attr("cy", xy[1])
.attr("fill","crimson");
})<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
https://stackoverflow.com/questions/64189608
复制相似问题