3

我是 javascript 新手,我正在使用 arbor.js 所以创建一个图表,但我希望能够根据邻近度连接节点或能够拖动边来连接节点。我已将一个 json 文件链接到包含节点信息的 js。

我对此并不陌生,这似乎是一项非常艰巨的任务,任何有助于获得正确方向的帮助将不胜感激。

这是 halfviz 演示的一部分 renderer.js 代码。这是我的自定义图表:http ://arborjs.org/halfviz/#/NTQ5Ng

    // 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 -> 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 && 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 && 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 < 0 || ua > 1 || ub < 0 || ub > 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
  }    

})()
4

0 回答 0