【发布时间】:2014-07-11 16:08:24
【问题描述】:
我对 d3 还比较陌生,但我仍然会遇到一些让我难以理解的事情。
基本上,我有一棵带有可拖动节点的树。我想将节点的“拖动句柄”限制为只有圆圈,而不是圆圈和文本(以及我最终添加的任何其他内容)。
我知道这与在我的拖动行为中正确设置原点有关,但我似乎不太明白。
我在 stackoverflow 上找到了一些有用的信息(抱歉,我只能发布两个链接),查看 https://groups.google.com/forum/#!topic/d3-js/fjp1mpvVW1M 似乎我正在将拖动行为应用于 ag 容器的子元素,然后尝试将转换应用于其 g 容器。
我怎样才能做到这一点?
以下是相关代码:
var dragListener = d3.behavior.drag()
.origin(function () {
var t = d3.select(this);
return {
x: t.attr("x") + d3.transform(t.attr("transform")).translate[0],
y: t.attr("y") + d3.transform(t.attr("transform")).translate[1]
};
})
.on("drag", function (d) {
d.x0 += d3.event.dy;
d.y0 += d3.event.dx;
//var node = d3.select(this); //this works
var node = d3.select(this.parentNode) //this doesn't work
node.attr("transform", "translate(" + d.y0 + "," + d.x0 + ")");
});
var nodeEnter = node.enter().append("g")
//.call(dragListener) // this works
.attr("class", "node")
.attr("transform", function(d) { return "translate(" + source.y0 + "," + source.x0 + ")"; })
.on("click", click);
nodeEnter.append("circle")
.call(dragListener) // this doesn't work
.attr("r", 1e-6)
.style("fill", function(d) { return d._children ? "lightsteelblue" : "#fff"; });
这是一个小提琴: http://jsfiddle.net/tsmith77/4R3Cb/
更新
我无法让子组做我想做的事,但我通过拦截文本上的 mousedown 事件完成了我想做的事:
nodeEnter.append("text")
.on("mousedown", function (d) {
d3.event.stopPropagation();
})
.on("click", function (d) {
alert("text clicked");
})
这可以防止文本成为拖动句柄,但仍然允许我在单击文本时执行操作。
【问题讨论】:
-
您在这里遇到了麻烦,因为您使用了两种不同的方式来设置位置(
transform和设置元素的坐标),并且很容易在此处混淆。您是否正在寻找类似jsfiddle.net/4R3Cb/3 的内容 -
谢谢拉斯。是的,类似的东西。只有在拖动圆圈时,我才会希望整个节点移动。我的 //this 有效代码和 //this doesn't work 代码之间唯一期望的行为差异是圆是我的用户可以“抓取”进行拖动的唯一元素。
-
嗯,在您的示例中看起来已经是这种情况了?至少我不能把里面的文字拖进去。
-
很抱歉未能传达我的愿望。我希望整个节点(文本和圆圈)在拖动时移动,但我希望圆圈是唯一可以用鼠标“抓住”的东西。原因是我有一个附加到文本的点击事件,我不希望用户在他们只想拖动时意外触发。
-
这正是我在你的 jsfiddle 中得到的行为,以 this question 应该有用的一些抖动为模。
标签: javascript d3.js drag-and-drop drag