12

我正在使用D3js 拖动。单个元素被拖得很好。但我想拖动一组元素。如何完成。这是我的Js Fiddle 链接上的内容:

  function onDragDrop(dragHandler, dropHandler) {
        var drag = d3.behavior.drag();

    drag.on("drag", dragHandler)
    .on("dragend", dropHandler);
    return drag;
    }

    var g = d3.select("body").select("svg").append("g")
    .data([{ x: 50, y: 50 }]);

    g.append("rect")
    .attr("width", 40)
    .attr("height", 40)
    .attr("stroke", "red")
    .attr("fill","transparent")
    .attr("x", function (d) { return d.x; })
    .attr("y", function (d) { return d.y; })
    .call(onDragDrop(dragmove, dropHandler));

    g.append("text")
    .text("Any Text")
    .attr("x", function (d) { return d.x; })
    .attr("y", function (d) { return d.y; })
    .call(onDragDrop(dragmove, dropHandler));

    function dropHandler(d) {
       // alert('dropped');
    }

    function dragmove(d) {
        d3.select(this)
      .attr("x", d.x = d3.event.x)
      .attr("y", d.y = d3.event.y);
    }

我想同时拖动矩形和文本。这是我尝试过的,但没有运气。我认为缺少一些简单的东西。

4

2 回答 2

25

首先, <g> 元素不关心xy属性(如:它们只是被忽略)。你可以transform="translate(x,y)"改用。

其次,您需要检查您在 dragmove 处理程序中获得的元素实际上是 <g> 元素,而不是它的子元素。这是因为 <g> 元素本身没有实际的命中区域。不过,他们的孩子会这样做,鼠标事件首先传递给孩子,然后冒泡传递给父母。您可以检查evt.targetevt.currentTarget看到这一点。target是最初被击中的元素,currentTarget是当前正在处理事件的事件目标(例如,如果事件冒泡,则为 <g> 元素)。

于 2013-04-11T08:24:24.507 回答
4

对于 d3 v4:

var drag_this = d3.drag().subject(this)
    .on('start',function (d) {
        if (d.x1){
            d.x1 =  d3.event.x - d.xt;
            d.y1 =  d3.event.y - d.yt;
        }else{
            d.x1 = d3.event.x;
            d.y1 = d3.event.y;
        }
    })
    .on('drag',function(d){
        d3.select(this)
        .attr("transform", "translate(" + (d3.event.x - d.x1)  + "," + (d3.event.y - d.y1) + ")");

        d.xt = d3.event.x - d.x1;
        d.yt = d3.event.y - d.y1;
    });

my_group.call(drag_this);

这假设您将数据绑定到该组。

于 2016-11-13T23:33:28.570 回答