2014-12-11 7 views
0

저는 arbor.js와 함께 논쟁의 네트워크를 구축하고 있습니다. 긴 라벨이있는 노드가 몇 개있을 때 캔버스의 테두리는 존중되지 않습니다. 가장자리의 길이를 어떻게 바꿀 수 있습니까? 아니면 아버가 캔버스의 한계를 존중하게하려면 어떻게해야합니까?Arbor.js edges length

내 코드 :

<html lang="fr"> 
    <head> 
     <script language="javascript" type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script> 
     <script language="javascript" type="text/javascript" src="path/to/arbor.js" ></script> 
     <script language="javascript" type="text/javascript" src="path/to/arbor-tween.js" ></script> 
     <script language="javascript" type="text/javascript" src="path/to/graphics.js" ></script> 
     <script language="javascript" type="text/javascript" src="renderer.js" ></script> 
     <style> 
      canvas.linkable{cursor: pointer;}  
     </style>   
    </head> 

<body> 
    <canvas id="viewport" width="940" height="600"></canvas> 
    <script language="javascript" type="text/javascript"> 

    var colour = { 
     orange:"#EEB211", 
     darkblue:"#21526a", 
     purple:"#941e5e", 
     limegreen:"#c1d72e", 
     darkgreen:"#619b45", 
     lightblue:"#009fc3", 
     pink:"#d11b67",  
    } 
    var data = { 
     nodes:{ 
     principal:{ 'label':'Fins de la sélection', 
        'color':colour.darkblue, 'alpha': 0, link:'http://controverses.sciencespo-toulouse.fr/angr/' }, 
     controverse2:{ 'label':'La sélection, symbole du modèle productiviste de l\'agriculture ?', 
        'color':colour.darkblue, 'alpha': 0, link:'http://controverses.sciencespo-toulouse.fr/angr/' }, 
     controverse3:{ 'label':'Les objectifs de la sélection entrent-ils en conflit avec ceux de la conservation ?', 
        'color':colour.darkblue, 'alpha': 0, link:'http://controverses.sciencespo-toulouse.fr/angr/' }, 
     controverse4:{ 'label':'Race pure ou race croisée ?', 
        'color':colour.darkblue, 'alpha': 0, link:'http://controverses.sciencespo-toulouse.fr/angr/' },  

     }, 
     edges:{ 
     principal:{ controverse2:{}, 
       controverse3:{}, 
       controverse4:{} }, 
     } 
    } 

    // Initialise arbor 
    var sys = arbor.ParticleSystem() 
    sys.parameters({stiffness:900, repulsion:2000, gravity:false, dt:0.015}) 
    sys.renderer = Renderer("#viewport"); 
    sys.graft(data); 
    /* 
    var nav = Nav("#nav") 
    $(sys.renderer).bind('navigate', nav.navigate) 
    $(nav).bind('mode', sys.renderer.switchMode) 
    nav.init()*/ 
    </script> 

</body> 
</html> 

내 renderer.js는 :

(function(){ 

    Renderer = function(canvas){ 
    var canvas = $(canvas).get(0) 
    var ctx = canvas.getContext("2d"); 
    var gfx = arbor.Graphics(canvas) 
    var particleSystem = null 
    var dom = $(canvas) 

    var that = { 
     init:function(system){ 
     particleSystem = system 
     particleSystem.screenSize(canvas.width, canvas.height) 
     particleSystem.screenPadding(40) 

     that.initMouseHandling() 
     }, 

     redraw:function(){ 
     if (!particleSystem) return 

     gfx.clear() // convenience ƒ: clears the whole canvas rect 

     // draw the nodes & save their bounds for edge drawing 
     var nodeBoxes = {} 
     particleSystem.eachNode(function(node, pt){ 
      // node: {mass:#, p:{x,y}, name:"", data:{}} 
      // pt: {x:#, y:#} node position in screen coords 

      // determine the box size and round off the coords if we'll be 
      // drawing a text label (awful alignment jitter otherwise...) 
      var label = node.data.label||"" 
      var w = ctx.measureText(""+label).width + 10 
      if (!(""+label).match(/^[ \t]*$/)){ 
      pt.x = Math.floor(pt.x) 
      pt.y = Math.floor(pt.y) 
      }else{ 
      label = null 
      } 

      // draw a rectangle centered at pt 
      if (node.data.color) ctx.fillStyle = node.data.color 
      else ctx.fillStyle = "rgba(0,0,0,.2)" 
      if (node.data.color=='none') ctx.fillStyle = "white" 

      if (node.data.shape=='dot'){ 
      gfx.oval(pt.x-w/2, pt.y-w/2, w,w, {fill:ctx.fillStyle}) 
      nodeBoxes[node.name] = [pt.x-w/2, pt.y-w/2, w,w] 
      }else{ 
      gfx.rect(pt.x-w/2, pt.y-10, w,20, 4, {fill:ctx.fillStyle}) 
      nodeBoxes[node.name] = [pt.x-w/2, pt.y-11, w, 22] 
      } 

      // draw the text 
      if (label){ 
      ctx.font = "12px Helvetica" 
      ctx.textAlign = "center" 
      ctx.fillStyle = "white" 
      if (node.data.color=='none') ctx.fillStyle = '#333333' 
      ctx.fillText(label||"", pt.x, pt.y+4) 
      ctx.fillText(label||"", pt.x, pt.y+4) 
      } 
     })    


     // 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 
    var mouse_is_down = false; 
    var mouse_is_moving = false 


    // set up a handler object that will initially listen for mousedowns then 
    // for moves and mouseups while dragging 
    var handler = { 
     mousemove:function(e){ 
     if(!mouse_is_down){ 
      var pos = $(canvas).offset(); 
      _mouseP = arbor.Point(e.pageX-pos.left, e.pageY-pos.top) 
      nearest = particleSystem.nearest(_mouseP); 

      if (!nearest.node) return false 
      selected = (nearest.distance < 50) ? nearest : null 
      if(selected && selected.node.data.link){ 
      dom.addClass('linkable') 
      } else { 
      dom.removeClass('linkable') 
      } 
     } 
     return false 
     }, 
     clicked:function(e){ 
     var pos = $(canvas).offset(); 
     _mouseP = arbor.Point(e.pageX-pos.left, e.pageY-pos.top) 
     nearest = particleSystem.nearest(_mouseP); 

     if (!nearest.node) return false 
     selected = (nearest.distance < 50) ? nearest : null 

     if (nearest && selected && nearest.node===selected.node){ 
      var link = selected.node.data.link 
      if (link.match(/^#/)){ 
      $(that).trigger({type:"navigate", path:link.substr(1)}) 
      }else{ 
      window.open(link, "frame3") 
      } 
      return false 
     } 
     }, 
     mousedown: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 

     mouse_is_down = true 
     mouse_is_moving = false 

     $(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) 

     mouse_is_moving = true 

     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 = 50 
     dragged = null 
     selected = null 
     $(canvas).unbind('mousemove', handler.dragged) 
     $(window).unbind('mouseup', handler.dropped) 
     _mouseP = null 

     if(mouse_is_moving){ 
      // console.log("was_dragged") 
     } else { 
      handler.clicked(e) 
     } 

     mouse_is_down = false 

     return false 
     } 
    } 
    $(canvas).mousedown(handler.mousedown); 
    $(canvas).mousemove(handler.mousemove); 

    } 

} 
    // 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 
    }  

})() 

나는 예를 들어, 직접 스크립트에서 모서리의 길이를 수정 시도했다 :

edges:{ 
     principal:{ controverse2:{length:1}, 
       controverse3:{length:1}, 
       controverse4:{length:1} }, 
     } 

작동하지 않습니다.

도움 주셔서 감사합니다.

답변

0

집합 입자 시스템

sys.parameters({ repulsion: 1000, gravity: false, dt: 0.35 })

이 파라미터