Javascript 在d3js中移动连通矩形

Javascript 在d3js中移动连通矩形,javascript,svg,d3.js,Javascript,Svg,D3.js,我正在尝试连接d3js中的两个可拖动矩形。我的要求是 有不同的矩形(如A、B、C) 所有的矩形都应该是可拖动的 当我点击一个矩形时,它应该开始画一条线 (例如,如果我单击第一个,线条应从A.x、A.y开始。线条末端应随鼠标点移动) 在第二个矩形上单击时,该行应以该元素结尾 (例如,如果我在A之后单击B,A&B现在应该已连接) 到目前为止,我可以拖动矩形,如果它们是静态的,我可以连接它们。但是当我在连接矩形之后移动它们时,直线应该随着矩形移动 这是我的工作重点。有人能带我到这里吗 <svg

我正在尝试连接d3js中的两个可拖动矩形。我的要求是

  • 有不同的矩形(如A、B、C)
  • 所有的矩形都应该是可拖动的
  • 当我点击一个矩形时,它应该开始画一条线 (例如,如果我单击第一个,线条应从A.x、A.y开始。线条末端应随鼠标点移动)
  • 在第二个矩形上单击时,该行应以该元素结尾 (例如,如果我在A之后单击B,A&B现在应该已连接)
  • 到目前为止,我可以拖动矩形,如果它们是静态的,我可以连接它们。但是当我在连接矩形之后移动它们时,直线应该随着矩形移动

    这是我的工作重点。有人能带我到这里吗

    <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>
    
        function move() {
            d3.select(this)
                    .attr('x', d3.event.x -   parseInt(d3.select(this).attr("width")) / 2)
                    .attr('y', d3.event.y - parseInt(d3.select(this).attr("height")) / 2);
    
    
        }
    
     var drag = d3.behavior.drag().on('drag', move);
    
    d3.select("#a").on('mousedown', function(d){
         d3.select("#c").style("display","");//make the line visible when mouse click is down.
    }) .call(drag);
    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);
    }) .call(drag);
    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);
    
    });
    
    
    函数move(){
    d3.选择(本)
    .attr('x',d3.event.x-parseInt(d3.select(this.attr(“width”))/2)
    .attr('y',d3.event.y-parseInt(d3.select(this.attr)('height'))/2);
    }
    var drag=d3.behavior.drag().on('drag',move);
    d3.在('mousedown',函数(d)上选择('a'){
    d3.选择(“#c”).style(“display”,”“);//当鼠标点击时,使线条可见。
    }).呼叫(拖动);
    d3.在('mouseup',函数(d)上选择('b'){
    d3.选择(“#c”)
    .attr('x2',400)
    .attr('y2',400);
    //删除所有侦听器,因为我们已经建立了连接线
    d3.在('mousemove',null)上选择('main');
    d3.选择('mousedown',空);
    d3.在('mouseup',null)上选择('b');
    }).呼叫(拖动);
    d3.选择('mousemove',函数(d)上的('main'){
    //在鼠标移动时更新该行。
    var mouseLoc=d3.mouse(this);
    d3.选择(“#c”)
    .attr('x2',鼠标[0]-5)
    .attr('y2',mouseLoc[1]-5);
    });
    
    您需要使用相应的属性更新该行

    以下是一个例子:

    您可以使用myMapLookup来创建带有源矩形和目标矩形的行。 这样,您可以有n个矩形和n条线,并且相同的拖动代码可以跨多个矩形和n条线工作

    var myMapLookup = {c:{ source:'a', target:'b'}};//this will map the line id to its source and target rectangles. this help you track which line is linked to which 2 rectangles.
    function move(lineID, me) {
        //lineID will gve the id of the line.
        var nx = d3.event.x-parseInt(d3.select(me).attr("width"))/2
        var ny = d3.event.y-parseInt(d3.select(me).attr("height"))/2
        d3.select(me).attr('x', nx)
                       .attr('y', ny);
        //change the line's x and y on dragging
        //if source update the x1 and y1
        if(d3.select(me).attr('id') == myMapLookup.c.source){
            d3.select('#' + lineID).attr('x1', nx).attr('y1', ny);
        }
        //if source update the x2 and y2
        if(d3.select(me).attr('id') == myMapLookup.c.target){
            d3.select('#' + lineID).attr('x2', nx).attr('y2', ny);
        }
    
    }
    
    d3.select("#a").on('mousedown', function(d){
         d3.select("#c").style("display","");//make the line visible when mouse click is down.
        d3.select("#c").data({src: 'a', target: 'b'})
    });
    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);
    //attach drag listener to all rectangles
    
        var dragA = d3.behavior.drag().on("drag", function(){move('c', this)});
        d3.select("#a").call(dragA);
        var dragB = d3.behavior.drag().on("drag", function(){move('c', this)});
        d3.select("#b").call(dragB);
    });
    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);
    
    });