D3.js: Dragging everything in group ('g') by element contained in the group using origin() function

霸气de小男生 提交于 2019-12-10 21:32:10

问题


I am not sure what's going on, but I have 2 very simple examples set up to show what I am asking.

Both examples have a 'g' that contains a 'rect' and 'text'.

In the 1st example, I am setting up drag on the 'g' itself, i.e., if you mousedown anywhere in that group and drag, it will drag the entire thing (both 'rect' and 'text') around the viewpoint. 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 2nd example, which doesn't work and is what I am interested in, I want ONLY THE TEXT to be something the user can grab to drag the entire group around.

I tried many attempts. Some don't work at all, some work but flicker like the 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's going on with this that it flickers and what am I doing wrong?

Any help would be greatly appreciated!

Thanks!


回答1:


I'm not sure exactly why it is flickering (as I am not too familiar with D3), but one way to get it to stop is to use the source 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: While the above code works, it causes the box to initially "jump" to the coordinates of the text, A better fix would be to take your first example and just filter our events that aren't executed on the text element. Try putting the following at the top of the dragMove method:

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



回答2:


Try d3.event.sourceEvent.stopPropagation(); inside on-drag function



来源:https://stackoverflow.com/questions/30132344/d3-js-dragging-everything-in-group-g-by-element-contained-in-the-group-usin

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!