使用d3拖动行为的来源为树节点创建“拖动句柄”

时间:2014-07-11 16:08:24

标签: javascript d3.js drag-and-drop drag

我对d3比较陌生,而且我仍然遇到困扰我的事情。

基本上,我有一个可拖动节点的树。我想限制"拖动手柄"节点只有圆圈,而不是圆圈和文字(以及我最后添加的其他内容)。

我知道它与我在拖动行为中正确设置原点有关,但我似乎无法得到它。

我在stackoverflow上找到了一些有用的信息(抱歉,我只能发布两个链接),看着https://groups.google.com/forum/#!topic/d3-js/fjp1mpvVW1M我似乎将拖动行为应用于子元素然后尝试将变换应用到其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");
  })

这可以防止文本成为拖动句柄,但仍允许我在单击文本时执行操作。

1 个答案:

答案 0 :(得分:1)

在CSS中为与节点对应的文本设置以下行:

  pointer-events: none;

(一种方法是将一个名为let的人说“node-label”给所有这些文本,然后,如上所述定义该类'property“pointer-events”< / p>

这样可以通过抓取文字来阻止拖动。

我还会给你两个实例。它们处理的是力布局,而不是像你的情况那样的树,但它没关系,原理是一样的。

example 1 - 通过抓住圆圈和标签来拖动

example 2 - 只抓住圈子拖动

它们之间的区别仅在于:

  pointer-events: none;