D3.js: Drag and drop everything in the group ('g') of the element contained in the group using origin () function

I'm not sure what is going on, but I have 2 very simple examples that show what I am asking.

Both examples have "g" which contains "rect" and "text".

In the first example, I set up drag on "g" itself, ie. if you are anywhere in this group and drag it, it will drag the whole thing (both "rect" and "text") around the observation deck. http://jsfiddle.net/wup4d0nx/

var chart = d3.select("body").append("svg")
   .attr("height", 500)
   .attr("width", 500)
   .style("background", "lightgrey");

var group = chart.selectAll("g")
    .data(["Hello"])
    .enter()
    .append("g")
    .attr("id", function (d) { return d;});

var rect = group.append("rect")
    .attr("stroke", "red")
    .attr("fill", "blue")
    .attr("width", 200)
    .attr("height", 200)
    .attr("x", 10)
    .attr("y", 10);

var label = group.append("text")
    .attr("x", 40)
    .attr("y", 40)
    .attr("font-size", "22px")
    .attr("text-anchor", "start")
    .text(function (d) { return d;});

// Set up dragging for the entire group
var dragMove = function (d) {
    var x = d3.event.x;
    var y = d3.event.y;
    d3.select(this).attr("transform", "translate(" + x + "," + y + ")");
};


var drag = d3.behavior.drag()
    .origin(function (data) {
        var element = d3.select("#" + data);
        return {
            x: d3.transform(element.attr("transform")).translate[0],
            y: d3.transform(element.attr("transform")).translate[1]
        };
    })
    .on("drag", dragMove);

group.call(drag);

      

In the second example, which doesn't work and what interests me, I want ONLY TEXT to be something that the user can grab to drag the whole group around.

I've tried many tries. Some don't work at all, some do, but flicker like an example I provide here: http://jsfiddle.net/9xeo7ehf/

var chart = d3.select("body").append("svg")
    .attr("height", 500)
    .attr("width", 500)
    .style("background", "lightgrey");

var group = chart.selectAll("g")
    .data(["Hello"])
    .enter()
    .append("g")
    .attr("id", function (d) { return d;});

var rect = group.append("rect")
    .attr("stroke", "red")
    .attr("fill", "blue")
    .attr("width", 200)
    .attr("height", 200)
    .attr("x", 10)
    .attr("y", 10);

var label = group.append("text")
    .attr("x", 40)
    .attr("y", 40)
    .attr("font-size", "22px")
    .attr("text-anchor", "start")
    .text(function (d) { return d;});

// Set up dragging for the entire group USING THE LABEL ONLY TO DRAG
var dragMove = function (d) {
    var x = d3.event.x;
    var y = d3.event.y;
    d3.select(this.parentNode).attr("transform", "translate(" + x + "," + y + ")");
};


var drag = d3.behavior.drag()
    .origin(function (data) {
        var element = d3.select("#" + data);
        return {
            x: d3.transform(element.attr("transform")).translate[0],
            y: d3.transform(element.attr("transform")).translate[1]
        };
    })
    .on("drag", dragMove);

label.call(drag);

      

What is going on with this, what is it flickering and what am I doing wrong?

Any help would be greatly appreciated!

Thank!

+3


source to share


2 answers


I'm not sure why exactly it is flickering (since I am not too familiar with D3), but one way to stop it is to use the originating event for D3:

// 50 is the offset x/y position you set for your text
var x = d3.event.sourceEvent.pageX - 50;
var y = d3.event.sourceEvent.pageY - 50;

      



Edit: Even though the above code works, it causes the window to "jump" to the text coordinates first. The best fix should be to take your first example and just filter out our events that don't run on the text element. Try putting the following at the beginning of your method dragMove

:

if(d3.event.sourceEvent.target.nodeName !== 'text') {
    return;
}

      

0


source


Try the d3.event.sourceEvent.stopPropagation();

internal drag and drop function



0


source







All Articles