2015-08-25 37 views
1

我有下面的代码,我已经动态地创建了拖动山墙的圆。我需要使用js在两个拖曳轮圈之间创建一个连接器。我正在使用d3库。点击我得到协调,但不知道如何进一步进行。当两次点击任何一个动态创建的圆圈时,应该创建一个连接器并且它也应该是可拖动的。在两个鼠标点击javascript上绘制连接器

<!DOCTYPE html> 
<html lang="en"> 
    <head> 
     <meta charset="utf-8"> 
     <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> 
     <style type="text/css"> 
    .mybutton { 
    background:#0000FF; 
    width:40px; 
    height:40px; 
    border-radius:20px; 
    -khtml-user-drag: element; 
    -webkit-user-drag: element; 
    } 
    #root { 
    background:#FFFF00; 
    } 
    #service{ 
    background:#00FF00; 
    } 
    #divContainer, #divResize { 
      border:dashed 1px #CCC; 
      width:120px; 
      height:120px; 
      padding:5px; 
      margin:5px; 
      font:13px Arial; 
      cursor:move; 
      float:left 
     } 
    .division{ 
     border:solid 3px #CCC; 
     width:90%; 
     height:750px; 
     float:right; 
    }  
    </style> 

    </head> 
    <body> 
     <div id="drawArea" class="division" ></div> 
     <div id="firstDivision" > 
     <form id="test2"> 
     <input type="button" id="root" class="mybutton" /> Root <p> 
     <input type="button" id="service" class="mybutton"/ > Service<p> 
     <input type="button" id="action1" class="mybutton" draggable="true"/ > Action 
     </form> 
     </div> 
     <canvas id="example" class="division"> 

     </canvas> 
     <script type="text/javascript"> 

      // Create a svg canvas 
      var svg = d3.select("#drawArea") 
      .append("svg") 
      .attr("width", 700) 
      .attr("height", 500); 

      //Drag nodes 
      var drag = d3.behavior.drag() 
       .on("dragstart", function() { 
        d3.event.sourceEvent.stopPropagation(); 
        d3.select(this).classed("dragging", true); 
       }) 
       .on("drag", dragmove) 
       .on("dragend",dragended); 

      //First circle 
      var g1 = svg.append("g") 
      .attr("transform", "translate(" + 150 + "," + 100 + ")") 
      .attr("class", "first") 
      .call(drag) 
      .append("circle").attr({ 
       r: 20, 
      }) 
      .style("fill", "#FFFF00") 

      //Second cicle 
      var g2 = svg.append("g") 
      .attr("transform", "translate(" + 250 + "," + 300 + ")") 
      .attr("class", "second") 
      .call(drag) 
      .append("circle").attr({ 
       r: 20, 
      }) 
      .style("fill", "#00FF00") 

     svg.on('dblclick', function() { 
      var coords = d3.mouse(this); 
      console.log(coords); 
      drawCircle(coords[0], coords[1]); 
     }); 
     svg.on('click',function(){ 
      var coords = d3.mouse(this); 
      var classFirst = d3.select(this).attr("class"); 
      drawConnector(coords[0], coords[1]); 
     }); 

     //draw connector 
     function drawConnector(x, y) { 
     var c=document.getElementById("example"); 
     var ctx=c.getContext("2d"); 
     ctx.beginPath(); 
     ctx.moveTo(150,100); 
     ctx.lineTo(250,300); 
     ctx.stroke(); 
     } 

     //third circle on click  
     function drawCircle(x, y) { 
      var g2 = svg.append("g") 
      .attr("transform", "translate(" + x + "," + y + ")") 
      .attr("class", "action") 
      .call(drag) 
      .append("circle").attr({ 
       r: 20, 
      }) 
      .style("fill", "#00F");  
     } 


      //Drag handler 
      function dragmove(d) { 
       var x = d3.event.x; 
       var y = d3.event.y; 
       d3.select(this).attr("transform", "translate(" + x + "," + y + ")"); 
       if(d3.select(this).attr("class") == "first") { 
       /*line.attr("x1", x); 
       line.attr("y1", y);*/ 
       d3.select(this).attr("cx", x); 
       d3.select(this).attr("cy", y);    
       } else { 
       d3.select(this).attr("cx", x); 
       d3.select(this).attr("cy", y); 
       /*line.attr("x2", x); 
       line.attr("y2", y);*/ 
       } 
      } 

    function dragended(d) { 
    d3.select(this).classed("dragging", false); 
    }   

     </script> 
    </body> 
</html> 

回答

0

g1和g2正在设置为圆形元素,因此它们在未经调整的情况下无法使用。现在我们可以使用g1和g2来获取圆形容器的翻译,并用它来画线。

// Create a svg canvas 
 
var svg = d3.select("#drawArea") 
 
.append("svg") 
 
.attr("width", 700) 
 
.attr("height", 500); 
 

 
//Drag nodes 
 
var drag = d3.behavior.drag() 
 
.on("dragstart", function() { 
 
    d3.event.sourceEvent.stopPropagation(); 
 
    d3.select(this).classed("dragging", true); 
 
}) 
 
.on("drag", dragmove) 
 
.on("dragend", dragended); 
 

 
// ADDED c1 AND c2 below. g1 AND g2 WERE BEING SET TO CIRCLES. 
 

 
//First circle 
 
var g1 = svg.append("g") 
 
.attr("transform", "translate(" + 150 + "," + 100 + ")") 
 
.attr("class", "first") 
 
.call(drag); 
 
var c1= g1.append("circle").attr({ 
 
    r: 20, 
 
}) 
 
.style("fill", "#FFFF00") 
 

 
//Second cicle 
 
var g2 = svg.append("g") 
 
.attr("transform", "translate(" + 250 + "," + 300 + ")") 
 
.attr("class", "second") 
 
.call(drag); 
 
var c2 = g2.append("circle").attr({ 
 
    r: 20, 
 
}) 
 
.style("fill", "#00FF00"); 
 

 
// ADD LINE ELEMENT 
 
var line = svg.append("line") 
 
.attr({x1: 150, y1: 100, x2: 250, y2: 300}) 
 
.attr({"stroke-width": 2, stroke: "red"}); 
 

 
svg.on('dblclick', function() { 
 
    var coords = d3.mouse(this); 
 
    console.log(coords); 
 
    drawCircle(coords[0], coords[1]); 
 
}); 
 
svg.on('click', function() { 
 
    var coords = d3.mouse(this); 
 
    var classFirst = d3.select(this).attr("class"); 
 
    drawConnector(coords[0], coords[1]); 
 
}); 
 

 
//draw connector 
 
function drawConnector(g1, g2) { 
 
    // MOVE LINE WITH TRANSFORMS OF G ELEMENTS. 
 
    var t1 = g1.attr("transform").replace(/[^\d.,]/g, "").split(","); 
 
    var t2 = g2.attr("transform").replace(/[^\d.,]/g, "").split(","); 
 
    line.attr({x1: t1[0], y1: t1[1], x2: t2[0], y2: t2[1]}); 
 
} 
 

 
//third circle on click  
 
function drawCircle(x, y) { 
 
    var g2 = svg.append("g") 
 
    .attr("transform", "translate(" + x + "," + y + ")") 
 
    .attr("class", "action") 
 
    .call(drag) 
 
    .append("circle").attr({ 
 
    r: 20, 
 
    }) 
 
    .style("fill", "#00F"); 
 
} 
 

 

 
//Drag handler 
 
function dragmove(d) { 
 
    var x = d3.event.x; 
 
    var y = d3.event.y; 
 
    d3.select(this).attr("transform", "translate(" + x + "," + y + ")"); 
 
    if (d3.select(this).attr("class") == "first") { 
 
    /*line.attr("x1", x); 
 
      line.attr("y1", y);*/ 
 
    d3.select(this).attr("cx", x); 
 
    d3.select(this).attr("cy", y); 
 
    } else { 
 
    d3.select(this).attr("cx", x); 
 
    d3.select(this).attr("cy", y); 
 
    /*line.attr("x2", x); 
 
      line.attr("y2", y);*/ 
 
    } 
 
    drawConnector(g1, g2); 
 
} 
 

 
function dragended(d) { 
 
    d3.select(this).classed("dragging", false); 
 
}
.mybutton { 
 
    background: #0000FF; 
 
    width: 40px; 
 
    height: 40px; 
 
    border-radius: 20px; 
 
    -khtml-user-drag: element; 
 
    -webkit-user-drag: element; 
 
} 
 
#root { 
 
    background: #FFFF00; 
 
} 
 
#service { 
 
    background: #00FF00; 
 
} 
 
#divContainer, 
 
#divResize { 
 
    border: dashed 1px #CCC; 
 
    width: 120px; 
 
    height: 120px; 
 
    padding: 5px; 
 
    margin: 5px; 
 
    font: 13px Arial; 
 
    cursor: move; 
 
    float: left 
 
} 
 
.division { 
 
    border: solid 3px #CCC; 
 
    width: 90%; 
 
    height: 750px; 
 
    float: right; 
 
}
<!DOCTYPE html> 
 
<html lang="en"> 
 

 
<head> 
 
    <meta charset="utf-8"> 
 
    <script type="text/javascript" src="http://d3js.org/d3.v3.min.js"></script> 
 

 
</head> 
 

 
<body> 
 
    <div id="drawArea" class="division"></div> 
 
    <div id="firstDivision"> 
 
    <form id="test2"> 
 
     <input type="button" id="root" class="mybutton" />Root 
 
     <p> 
 
     <input type="button" id="service" class="mybutton" />Service 
 
     <p> 
 
      <input type="button" id="action1" class="mybutton" draggable="true" />Action 
 
    </form> 
 
    </div> 
 
    <canvas id="example" class="division"></canvas> 
 
</body> 
 

 
</html>

+0

感谢。但是我正在寻找的是:单击任何两个圆圈,我应该可以在它们之间绘制一个连接器(线)。例如:我点击圆圈“秒”,然后点击动态创建的圆圈“第三个”(在dblclick函数上),应该在第二个和第三个圆圈之间创建一个连接器(线),它与圆圈一起拖动。这适用于所有动态创建的圆。练习的最终产品是一个可拖拽的树形结构。 – Harsha