Подтвердить что ты не робот

Как перетащить группу svg с помощью поведения d3.js drag?

Я использую D3js drag. Единственный элемент - это перетащить отлично. но я хочу перетащить группу элементов. Как это можно сделать. Вот что находится на моей ссылка 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);
    }

Я хочу перетащить одновременно прямоугольник и текст. Вот что я пытался, но не повезло. Я думаю, что я пропустил что-то простое.

4b9b3361

Ответ 1

Во-первых, элемент <g> не нуждается в атрибутах x и y (как в: они просто игнорируются). Вместо этого вы можете использовать transform="translate(x,y)".

Во-вторых, вам нужно будет проверить, что элемент, который вы получаете в обработчике dragmove, фактически является элементом <g> , а не дочерним элементом. Это связано с тем, что элементы <g> не имеют фактической области попадания. Их дети, хотя, и события мыши сначала идут к детям, а затем приходят к родителям. Вы можете проверить evt.target и evt.currentTarget, чтобы увидеть это в действии. target - это элемент, который был первоначально избит, currentTarget - это цель события, которая в данный момент обрабатывает событие (например, элемент <g> , если событие разбухает).

Ответ 2

Для 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);

Это предполагает, что у вас есть данные, привязанные к группе.