How to manually trigger the drag event of d3
Asked Answered
P

1

0

All:

Suppose there are two layers( the top one is SVG:PATH, the bottom layer is a SVG:RECT, the top layer covers the bottom layer), I want to apply D3 drag to the RECT layer and mouseover to PATH layer, could anyone show me how to do that?

THE CODE BELOW CAN ONLY WORK WITH THE path LAYER:

        var svg = d3.select("svg");
        svg.style("width", "400px")
            .style("height", "400px")
            .style("border", "1px solid grey");

        var r = svg.select("rect")
            .attr("width", "300px")
            .attr("height", "300px")
            .attr("x", "50px")
            .attr("y", "50px")
            .style("fill", "whitesmoke");


        var p = svg.select("path")
            .attr("d", function(){
                return "M0 0 L380 0 L300 300L0 380Z";
            })
            .style("fill", function(){
                return "rgba(10,10,10,0.2)";
            })
            .on("mousedown", function(){

            });
var drag = d3.behavior.drag();

var dragstart = function(){
    alert("drag start");
};

drag.on("dragstart", );

r.call(drag);

Thanks

Parathyroid answered 14/4, 2015 at 0:4 Comment(5)
What have you tried? If you don't try, first, you risk downvotes. (For doing something similar with a force layout, see the answer to this question.)Milliemillieme
Exactly what youve said. Call drag on the rect, so select(RECT).on('drag', drag); then set up drag function to call. And then select(PATH).on('mouseover', whateveryouwanttocallhere);Ethelind
@Milliemillieme as you requested, I have added what I have done, this code can only work on path layer, how can I drag the element below it?Parathyroid
@Ethelind Sounds interesting. But could you show me an example?Parathyroid
@Milliemillieme The post of your link seems slightly diff from my situation, the inner circle is above the outter circle which is easy for drag behavior to triggerParathyroid
E
1

I changed your drag. Also changed it to a function :

function drag(){
  console.log('dragging');
    return d3.behavior.drag()
             .origin(function() {
                var g = this;
                return {x: d3.transform(g.getAttribute("transform")).translate[0],
                        y: d3.transform(g.getAttribute("transform")).translate[1]};
            })
            .on("drag", function(d) {

                g = this;
                translate = d3.transform(g.getAttribute("transform")).translate;

                x = d3.event.dx + translate[0],
                y = d3.event.dy + translate[1];


                d3.select(g).attr("transform", "translate(" + x + "," + y + ")");
                d3.event.sourceEvent.stopPropagation();             
            });
}

For some reason this doesnt work on 'codepen' so i put it on JSFiddle and it works fine :)) The problem you had was you had no logic in your Drag functions. So nothing was happening.

Updated fiddle : http://jsfiddle.net/qqb6357j/1/

Here I have just called drag on both the path and rectangle at the bottom of the JS: http://jsfiddle.net/qqb6357j/2/

Just change the selection and call drag on it to give it drag capability :)

If you want to go one step further and stop all interaction with the 'path' give it no interactivity (you have to give it a class so css can select it):

#path{
    pointer-events:none;
}

Updated fiddle : http://jsfiddle.net/qqb6357j/3/

Now, what you asked for. You said you wanted when mouseover you want to highlight a number of things but be able to drag the layers below it. You can't just turn pointer-event to none as you still want to have 'hover' ability so i created a timeout. This is so when you hover over it, pointer-event=none; for 1 second and after 1 second : pointer-events= all;

Here is the code :

.on('mouseover', function(){
    p.classed('path', true);
    setTimeout(function() {
        p.classed('path', false);
    }, 1000) //timeout function
    //r.call(drag);
})

Here is the class that gets put on for 1 second :

.path{
    pointer-events:none;
    opacity: 0.2;
}

Final working fiddle : http://jsfiddle.net/qqb6357j/6/

Ethelind answered 14/4, 2015 at 15:37 Comment(8)
what I want to do is enabling the drag behavior on the RECT when the gray layer is above it.Parathyroid
youre drag has no logic :/Ethelind
Right now, the logic is just simply drag it and move with mouse and drop the RECT at new position when drag end. But I do not know how to implement that. Could you help with that?Parathyroid
Could you tell me why I should call drag on svg level to make it work?Parathyroid
Thanks so much. My question is sort of how to combine the first fiddle and the last: being able to drag the RECT(bottom layer) when the PATH(top layer) totally cover it and keep the PATH being able to respond to mouseover event.Parathyroid
sorted :) glad i could help :)Ethelind
Sorry, I did not catch your last reply. My question is how to combine the effect in first fiddle( it can drag the RECT layer but only without blocking of PATH layer) and last( it can drag the RECT but only sacrifice the responding ability of PATH layer), make both layer can respond to certain mouse eventParathyroid
Let us continue this discussion in chat.Ethelind

© 2022 - 2024 — McMap. All rights reserved.