Alexander Ceballos
Alexander Ceballos

Reputation: 760

Drag Event on element already drawn

I have problem with the drag event on elemets already drawn, if I need to move them I have to click "Circle" Link and then works, the event dissapears after select another option.

It is important that event stays binded althought another option be selected.

I tried adding this line but doesn't work.

d3.select(this).call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended));

Link Example

Code:

<!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head>
            <meta charset="UTF-8"/>
            <title>FAM</title>
            <script type="text/javascript" src="jquery-min.js"></script>
            <script type="text/javascript" src="d3.v4.min.js"></script>
            <script type="text/javascript">
                $(function () {
                    var svg = d3.select('#svf');//.on("mousedown", mousedown).on("mouseup", mouseup);
                    var container = svg.append('g');
                    var pxy = new Array(), line, i = 0, j = 0;

                    for (i = 0; i < 500; i = i + 10) {
                        container.append('line').attr('x1', i).attr('y1', 0).attr('x2', i).attr('y2', 500).attr('stroke', '#CFCECE').attr('stroke-width', 1).attr('fill', 'none');
                    }

                    for (j = 0; j < 500; j = j + 10) {
                        container.append('line').attr('x1', 1).attr('y1', j).attr('x2', 500).attr('y2', j).attr('stroke', '#CFCECE').attr('stroke-width', 1).attr('fill', 'none');
                    }

                    function main() {
                        pxy = new Array();
                        var coords = d3.mouse(this), x = coords[0], y = coords[1];
                        var lnk = $('#dv_conv').find('a[data-pressed="1"]');
                        var conv = lnk.attr('data-conv');

                        if (conv == 1) {
                            pxy = new Array();
                            container.append('circle').attr('cx', x).attr('cy', y).attr('r', 30).attr('stroke-width', 2).attr('stroke', '#000').attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
                        }

                        if (conv == 2) {
                            pxy = new Array();
                            container.append('rect').attr('x', x).attr('y', y).attr('width', 60).attr('height', 60).attr('stroke-width', 2).attr('stroke', '#000').attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
                        }

                        if (conv == 3) {

                        }

                        if (conv == 4) {
                            pxy[pxy.length] = x;
                            pxy[pxy.length] = y;

                            pxy[pxy.length] = x;
                            pxy[pxy.length] = y + 30;

                            pxy[pxy.length] = x + 160;
                            pxy[pxy.length] = y + 30;

                            pxy[pxy.length] = x + 160;
                            pxy[pxy.length] = y;

                            container.append('polyline').attr("stroke", '#000').attr('stroke-width', 1).attr('fill', 'transparent').on('click', clicked).attr('points', pxy).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
                            pxy = new Array();
                        }
                    }

                    svg.on('click', main);

                    function mousedown() {
                        var m = d3.mouse(this);
                        line = container.append("line")
                                .attr("x1", m[0])
                                .attr("y1", m[1])
                                .attr("x2", m[0])
                                .attr("y2", m[1]).attr('stroke', '#000').attr('stroke-width', 2).attr('fill', 'transparent').on('click', clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
                        svg.on('mousemove', mousemove);
                    }

                    function mousemove() {
                        var m = d3.mouse(this);
                        line.attr('x2', m[0]).attr('y2', m[1]);
                    }

                    function mouseup() {
                        svg.on('mousemove', null);
                        svg.on('click', null);
                        console.log('...');
                    }

                    function dragstarted(d) {
                        d3.select(this).raise().classed('active', true);
                    }

                    function dragged(d) {
                        var lnk = $('#dv_conv').find('a[data-pressed="1"]');
                        var conv = lnk.attr('data-conv');

                        if (conv == 1) {
                            d3.select(this).attr('cx', +d3.select(this).attr('cx') + d3.event.dx);
                            d3.select(this).attr('cy', +d3.select(this).attr('cy') + d3.event.dy);
                        }

                        if (conv == 2) {
                            d3.select(this).attr('x', +d3.select(this).attr('x') + d3.event.dx);
                            d3.select(this).attr('y', +d3.select(this).attr('y') + d3.event.dy);
                        }

                        if (conv == 3 || conv == 4) {
                            this.x = this.x || 0;
                            this.y = this.y || 0;
                            this.x += d3.event.dx;
                            this.y += d3.event.dy;
                            d3.select(this).attr('transform', 'translate(' + this.x + ',' + this.y + ')');
                        }
                    }


                    function dragended(d) {
                        d3.select(this).classed('active', false);
                    }

                    d3.select('body').on('keydown', function () {
                        if (d3.event.keyCode === 27) {
                            pxy = new Array();
                            $('#lnk_circle').attr('data-pressed', 0);
                            $('#lnk_rectangle').attr('data-pressed', 0);
                            $('#lnk_polyline').attr('data-pressed', 0);
                            svg.on('mousemove', null);

                            var lnk = $('#dv_conv').find('a[data-pressed="1"]');
                            var conv = lnk.attr('data-conv');
                            if (conv == 3) {
                                svg.on('click', mousedown);
                            }
                        }
                    });

                    function clicked(d, i) {
                        var lnk = $('#dv_conv').find('a[data-pressed="1"]');
                        var conv = lnk.attr('data-conv');
                        if (conv == 20) {
                            d3.select(this).remove();
                        } else {
                         /*This line doesn´t work*/
                            var element = $(this).prop('tagName');
                            if (element == 'circle' || element == 'rect') {
                                d3.select(this).call(d3.drag().on('start', dragstarted).on('drag', dragged).on('end', dragended));
                            }
                        }
                    }

                    $('#lnk_circle').click(function () {
                        svg.on('click', main);
                        $('#lnk_rectangle').attr('data-pressed', 0);
                        $('#lnk_line').attr('data-pressed', 0);
                        $('#lnk_polyline').attr('data-pressed', 0);
                        $(this).attr('data-pressed', 1);
                        return false;
                    });

                    $('#lnk_rectangle').click(function () {
                        svg.on('click', main);
                        $('#lnk_circle').attr('data-pressed', 0);
                        $('#lnk_polyline').attr('data-pressed', 0);
                        $('#lnk_line').attr('data-pressed', 0);
                        $(this).attr('data-pressed', 1);
                        return false;
                    });

                    $('#lnk_polyline').click(function () {
                        svg.on('click', main);
                        $('#lnk_circle').attr('data-pressed', 0);
                        $('#lnk_rectangle').attr('data-pressed', 0);
                        $('#lnk_line').attr('data-pressed', 0);
                        $(this).attr('data-pressed', 1);
                        return false;
                    });

                    $('#lnk_line').click(function () {
                        svg.on('click', mousedown).on("dblclick", mouseup);
                        $('#lnk_circle').attr('data-pressed', 0);
                        $('#lnk_rectangle').attr('data-pressed', 0);
                        $('#lnk_polyline').attr('data-pressed', 0);
                        $(this).attr('data-pressed', 1);
                        return false;
                    });

                    $('#lnk_erase').click(function () {
                        svg.on('click', null);
                        $('#lnk_circle').attr('data-pressed', 0);
                        $('#lnk_rectangle').attr('data-pressed', 0);
                        $('#lnk_polyline').attr('data-pressed', 0);
                        $('#lnk_line').attr('data-pressed', 0);
                        $(this).attr('data-pressed', 1);
                        return false;
                    });

                    //$('#svg').find('g').find('circle,rect,line').on("dblclick", clicked).call(d3.drag().on("start", dragstarted).on("drag", dragged).on("end", dragended));
                });
            </script>
            <style>
                line,circle,rect,polyline{ shape-rendering:crispEdges;} 
            </style>                
        </head>
        <body>
            <div id="dv_conv" style="float: left;width:200px;border:1px solid #000;margin-right: 1px">
                <a href="#" id="lnk_circle" data-pressed="0" data-conv="1">Circle</a><br/>
                <a href="#" id="lnk_rectangle" data-pressed="0" data-conv="2">Rectangle</a><br/>
                <a href="#" id="lnk_line" data-pressed="0" data-conv="3">Line</a><br/>
                <a href="#" id="lnk_polyline" data-pressed="0" data-conv="4">PolyLine</a><br/>
                <a href="#" id="lnk_erase" data-pressed="0" data-conv="20">Erase</a><br/>
            </div>

            <div id="dv_familiogram" style="float: left;width:500px;height: 500px;border:1px solid #000;overflow: hidden">

                <svg id="svf"  style="width:500px;height:500px"></svg>

            </div>
        </body>
    </html>

Upvotes: 0

Views: 85

Answers (1)

Stepan
Stepan

Reputation: 1054

The problem is that you select actions in dragged function based on Link which was clicked, not based on type of shape you have dragged.

You can replace your dragged function with a number of functions (each for a certain shape type):

function dragged_conv1(d) {
        d3.select(this).attr('cx', +d3.select(this).attr('cx') + d3.event.dx);
        d3.select(this).attr('cy', +d3.select(this).attr('cy') + d3.event.dy);
}

function dragged_conv2(d) {
        d3.select(this).attr('x', +d3.select(this).attr('x') + d3.event.dx);
        d3.select(this).attr('y', +d3.select(this).attr('y') + d3.event.dy);
}

function dragged_conv34(d) {
        this.x = this.x || 0;
        this.y = this.y || 0;
        this.x += d3.event.dx;
        this.y += d3.event.dy;
        d3.select(this).attr('transform', 'translate(' + this.x + ',' + this.y + ')');
}

and bind each function to each shape in your main function:

if (conv == 1) {
    pxy = new Array();
    container.append('circle') ... .on("drag", dragged_conv1)...;
}

if (conv == 2) {
    pxy = new Array();
    container.append('rect') ... .on("drag", dragged_conv2)...;
}

if (conv == 4) {
// ... some code here ...

    container.append('polyline') ... .on("drag", dragged_conv34)...;
    pxy = new Array();
}

Upvotes: 1

Related Questions