简体   繁体   中英

d3js zoom + drag causes conflict

I am trying to apply the zoom behaviour to a svg where certain elements in the svg are already bound with drag behaviour. without the zoom behaviour drag works fine, without the drag behaviour zoom works fine. When I have both of them it conflicts. When I drag a circle all the other circles starts to drag with it.

Here is the fiddle .

can anyone help me to figure out the issue?

<svg height="600" width="600" style="background: black">

<g>
    <rect x="0" y="0" , width="600" height="40" style="fill:gold;"></rect>
    <circle id='drag' cx="15" cy="20" init-cx="15" init-cy="20" r="10"
            style="stroke: white; stroke-width: 2px; fill:blue"/>

</g>

<g id="playground">
    <g>
        <circle class='top' cx="180" cy="120" r="30" style="stroke: white; stroke-width: 2px; fill:white"/>
    </g>
    <g>
        <circle class='top' cx="200" cy="220" r="30" style="stroke: white; stroke-width: 2px; fill:white"/>
    </g>
    <g>
        <circle class='top' cx="320" cy="150" r="50" style="stroke: white; stroke-width: 2px; fill:white"/>
    </g>
</g>

var zoom = d3.behavior.zoom()
        .scaleExtent([-1, 8])
        .on("zoom", function () {

            var graph = d3.select('svg');

            graph
                .select('#playground')
                .selectAll('circle')
                .select(function () {
                    return this.parentNode;
                })
                .attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
        });


    var move = d3.behavior.drag()

        .on('drag', function () {

            console.log('dragging');

            var curr = d3.select(this)
                .attr({
                    cx: d3.mouse(this)[0],
                    cy: d3.mouse(this)[1]
                })


        })
        .on('dragend', function () {

            var curr = d3.select(this);

            d3.select('#playground')
                .append('circle')
                .attr({
                    cx: curr.attr('cx'),
                    cy: curr.attr('cy'),
                    r: curr.attr('r')
                })
                .style({
                    fill: 'white',
                    stroke: 'red',
                    'stroke-width': '2px'
                })
            ;

            curr.attr({
                cx: curr.attr('init-cx'),
                cy: curr.attr('init-cx')
            });
        })
        ;


    d3.select('#drag').call(move);

    d3.select('.top')
        .call(d3.behavior.drag().on('drag', function () {
            d3.select(this)
                .attr({
                    cx: d3.mouse(this)[0],
                    cy: d3.mouse(this)[1]
                })
            ;
        }));
    d3.select('svg').call(zoom);

I have implemented individual dragging of nodes working along with overall zooming and panning functionality. Used stopPropagation of the event in dragstart event of circles.

Hope this helps.

var move = d3.behavior.drag()
    .on("dragstart", function() {
        d3.event.sourceEvent.stopPropagation();
    });

Working JSFiddle

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM