Fawzan
Fawzan

Reputation: 4849

Connecting two rectangles in d3js

I am trying to connect two rectangles with a line in d3. The behaviour should be like this,

Let's say we have rectangles A & B. We have to first click a rectangle and when we move the mouse the line has to move with the mouse, When I click B. Line should connect A & B.

This is what I have now. I can't update the line. It keeps adding new line objects.

 <svg id="main" width="500" height="500" style="background-color: red">
    <rect id="a" x="100" y="100" height="50" width="50" style="fill: blue"></rect>
    <rect id="b" x="400" y="400" height="50" width="50" style="fill: blue"></rect>
</svg>

<script>


    d3.select("#a")
            .on('click', function(d){

                var elem = d3.select(this);
                var mouseLoc = d3.mouse(this);

                d3.select("#main")
                        .on('mousemove', function(d){

//                            d3.select('#li').remove();
                            d3.select('#main').append("line")
                                    .attr('id', 'li')
                                    .attr('x1', elem.attr('x'))
                                    .attr('y1', elem.attr('y'))
                                    .attr('x2', d3.mouse(this)[0]+5)
                                    .attr('y2', d3.mouse(this)[1]+5)
                                    .attr("stroke", function (d) { return "black"; })
                                    .style("stroke-width", function(d) { return "1 px"; });

                        })

                ;

                console.log('clicked');
            });





</script>

Upvotes: 1

Views: 1287

Answers (1)

Cyril Cherian
Cyril Cherian

Reputation: 32327

The problem in your code is that you are appending new lines on mouse move, but you should have just updated the line.

I have written a fiddle for the requirement you have posted also added comments for your help.

http://jsfiddle.net/cyril123/fy4cv1ab/6/

d3.select("#a").on('mousedown', function(d){
     d3.select("#c").style("display","");//make the line visible when mouse click is down.
});
d3.select("#b").on('mouseup', function(d){
     d3.select('#c')
        .attr('x2', 400)
        .attr('y2', 400);
//remove all the listeners as we have made the connection line    
    d3.select("#main").on('mousemove',null);
    d3.select("#a").on('mousedown',null);
    d3.select("#b").on('mouseup',null);
});
d3.select("#main").on('mousemove', function(d){
    //on mouse move update the line.
    var mouseLoc = d3.mouse(this);
    d3.select('#c')
        .attr('x2', mouseLoc[0]-5)
        .attr('y2', mouseLoc[1]-5);

});
<svg id="main" width="500" height="500" style="background-color: white">
    <rect id="a" x="100" y="100" height="50" width="50" style="fill: blue"></rect>
    <rect id="b" x="400" y="400" height="50" width="50" style="fill: blue"></rect>
    <line id="c" x1="100" y1="100"  y2="400" x2="400" style="stroke:rgb(255,0,0);stroke-width:2;display:none"></line>
</svg>

Upvotes: 1

Related Questions