title: dynamically connect nodes in arbor.js
body: <p>I am new to javascript and I am using arbor.js so create a graph, but i would like to be able to be able to connect nodes based on proximity or be able to drag edges to connect nodes. I have linked a json file to the js which contains the node information.</p>
  
  <p>I am new to this and this seems like a pretty daunting task any help to get in the right didrection would be greatly appreciated.</p>
  
  <p>here is a portion of the renderer.js code for the halfviz demo. tis is my custom graph: <a href="http://arborjs.org/halfviz/#/NTQ5Ng" rel="nofollow">http://arborjs.org/halfviz/#/NTQ5Ng</a></p>
  
  <pre><code>    // draw the edges
      particleSystem.eachEdge(function(edge, pt1, pt2){
        // edge: {source:Node, target:Node, length:#, data:{}}
        // pt1:  {x:#, y:#}  source position in screen coords
        // pt2:  {x:#, y:#}  target position in screen coords
  
        var weight = edge.data.weight
        var color = edge.data.color
  
        if (!color || (""+color).match(/^[ \t]*$/)) color = null
  
        // find the start point
        var tail = intersect_line_box(pt1, pt2, nodeBoxes[edge.source.name])
        var head = intersect_line_box(tail, pt2, nodeBoxes[edge.target.name])
  
        ctx.save() 
          ctx.beginPath()
          ctx.lineWidth = (!isNaN(weight)) ? parseFloat(weight) : 1
          ctx.strokeStyle = (color) ? color : "#cccccc"
          ctx.fillStyle = null
  
          ctx.moveTo(tail.x, tail.y)
          ctx.lineTo(head.x, head.y)
          ctx.stroke()
        ctx.restore()
  
        // draw an arrowhead if this is a -&gt; style edge
        if (edge.data.directed){
          ctx.save()
            // move to the head position of the edge we just drew
            var wt = !isNaN(weight) ? parseFloat(weight) : 1
            var arrowLength = 6 + wt
            var arrowWidth = 2 + wt
            ctx.fillStyle = (color) ? color : "#cccccc"
            ctx.translate(head.x, head.y);
            ctx.rotate(Math.atan2(head.y - tail.y, head.x - tail.x));
  
            // delete some of the edge that's already there (so the point isn't hidden)
            ctx.clearRect(-arrowLength/2,-wt/2, arrowLength/2,wt)
  
            // draw the chevron
            ctx.beginPath();
            ctx.moveTo(-arrowLength, arrowWidth);
            ctx.lineTo(0, 0);
            ctx.lineTo(-arrowLength, -arrowWidth);
            ctx.lineTo(-arrowLength * 0.8, -0);
            ctx.closePath();
            ctx.fill();
          ctx.restore()
        }
      })
  
  
  
    },
    initMouseHandling:function(){
      // no-nonsense drag and drop (thanks springy.js)
      selected = null;
      nearest = null;
      var dragged = null;
      var oldmass = 1
  
      // set up a handler object that will initially listen for mousedowns then
      // for moves and mouseups while dragging
      var handler = {
        clicked:function(e){
          var pos = $(canvas).offset();
          _mouseP = arbor.Point(e.pageX-pos.left, e.pageY-pos.top)
          selected = nearest = dragged = particleSystem.nearest(_mouseP);
  
          if (dragged.node !== null) dragged.node.fixed = true
  
          $(canvas).bind('mousemove', handler.dragged)
          $(window).bind('mouseup', handler.dropped)
  
          return false
        },
        dragged:function(e){
          var old_nearest = nearest &amp;&amp; nearest.node._id
          var pos = $(canvas).offset();
          var s = arbor.Point(e.pageX-pos.left, e.pageY-pos.top)
  
          if (!nearest) return
          if (dragged !== null &amp;&amp; dragged.node !== null){
            var p = particleSystem.fromScreen(s)
            dragged.node.p = p
          }
  
          return false
        },
  
        dropped:function(e){
          if (dragged===null || dragged.node===undefined) return
          if (dragged.node !== null) dragged.node.fixed = false
          dragged.node.tempMass = 1000
          dragged = null
          selected = null
          $(canvas).unbind('mousemove', handler.dragged)
          $(window).unbind('mouseup', handler.dropped)
          _mouseP = null
          return false
        }
      }
      $(canvas).mousedown(handler.clicked);
  
    }
  
  }
  
  // helpers for figuring out where to draw arrows (thanks springy.js)
  var intersect_line_line = function(p1, p2, p3, p4)
  {
    var denom = ((p4.y - p3.y)*(p2.x - p1.x) - (p4.x - p3.x)*(p2.y - p1.y));
    if (denom === 0) return false // lines are parallel
    var ua = ((p4.x - p3.x)*(p1.y - p3.y) - (p4.y - p3.y)*(p1.x - p3.x)) / denom;
    var ub = ((p2.x - p1.x)*(p1.y - p3.y) - (p2.y - p1.y)*(p1.x - p3.x)) / denom;
  
    if (ua &lt; 0 || ua &gt; 1 || ub &lt; 0 || ub &gt; 1)  return false
    return arbor.Point(p1.x + ua * (p2.x - p1.x), p1.y + ua * (p2.y - p1.y));
  }
  
  var intersect_line_box = function(p1, p2, boxTuple)
  {
    var p3 = {x:boxTuple[0], y:boxTuple[1]},
        w = boxTuple[2],
        h = boxTuple[3]
  
    var tl = {x: p3.x, y: p3.y};
    var tr = {x: p3.x + w, y: p3.y};
    var bl = {x: p3.x, y: p3.y + h};
    var br = {x: p3.x + w, y: p3.y + h};
  
    return intersect_line_line(p1, p2, tl, tr) ||
          intersect_line_line(p1, p2, tr, br) ||
          intersect_line_line(p1, p2, br, bl) ||
          intersect_line_line(p1, p2, bl, tl) ||
          false
  }
  
  return that
    }    
  
  })()
  </code></pre>