2013-04-11 4 views
11

Używam D3js drag. pojedynczy element jest przeciągany perfekcyjnie. ale chcę przeciągnąć grupę elementów. Jak to zrobić. Oto co jest na moim Js Fiddle link:Jak przeciągnąć grupę svg za pomocą drag d3.js?

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); 
    } 

chcę przeciągać zarówno rect i tekstu jednocześnie. Oto, co mam tried, ale bez powodzenia. Chyba brakuje mi czegoś prostego.

+1

Należy dodać swój kod tutaj, a nie tylko odwołuje się do jsfiddle. –

Odpowiedz

22

Po pierwsze, element < g> nie dba o atrybuty x i y (jak w: są po prostu ignorowane). Zamiast tego możesz użyć transform="translate(x,y)".

Po drugie, musisz sprawdzić, czy element, który dostajesz w module obsługi przeciągania, faktycznie jest elementem>>, a nie elementem podrzędnym. Jest tak dlatego, że same elementy nie mają rzeczywistego obszaru działania. Ich dzieci robią jednak wszystko, a zdarzenia myszy najpierw trafiają do dzieci, a następnie pojawiają się w rodzicach. Możesz sprawdzić evt.target i evt.currentTarget, aby zobaczyć to w akcji. target jest element, który został uderzony pierwotnie currentTarget jest celem zdarzenie aktualnie obsługi zdarzenia (na przykład z < g> elementu, jeśli zdarzenie przepuszcza się w górę).

+3

Próbowałem Twojego podejścia. ale elementy migają podczas przeciągania. spójrz tutaj. http://jsfiddle.net/xnjGD/3/ – Sudarshan

+2

To dlatego, że nie dzwonisz przeciągnij z elementu . Oto prosta poprawka: http://jsfiddle.net/xnjGD/4/. Zobacz także http://stackoverflow.com/questions/13078535/stuttering-drag-when-using-d3-behavior-drag-and-transform. –

+8

dzięki Erik. uratowałeś mnie po raz drugi. Dziękuję. i tu jest ostateczne rozwiązanie mojego problemu. http://jsfiddle.net/xnjGD/6/ – Sudarshan

2

Dla 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); 

ta zakłada, że ​​masz dane związane z grupą.