2013-03-04 25 views
11

Tôi đang cố gắng tìm ra cách để thêm neo điểm cuối động vào vùng chứa jsPlumb.jsPlumb - neo điểm cuối động trên mỗi bên

Tôi muốn có điểm cuối nguồn ở phía bên trái và điểm cuối mục tiêu chỉ ở bên phải.

Vấn đề là, tôi đã không thể tìm thấy bất kỳ cách nào để làm như vậy, mà không cần đến một số hack, như tôi đang làm bây giờ.

jsTrụ hỗ trợ Continuous Anchors, nhưng vị trí của neo riêng lẻ sẽ được tính toán lại dựa trên hướng giữa các đầu nối và số lượng neo liên tục. Điều này có nghĩa là cả hai điểm cuối nguồn và đích đều có thể chia sẻ cùng một phía của vùng chứa, đây là điều tôi muốn tránh.

Đây là một jsFiddler code I came up with

Đây là một phần của mã Tôi đang sử dụng hack và tính toán lại neo vị trí bản thân mình (khi Add button được click), với một số kết quả buggy :(

function fixEndpoints(endpoints) { 

      //there are 2 types - input and output 

      var inputAr = $.grep(endpoints, function (elementOfArray, indexInArray) { 
       return elementOfArray.isSource; //input 
      }); 

      var outputAr = $.grep(endpoints, function (elementOfArray, indexInArray) { 
       return elementOfArray.isTarget; //output 
      }); 

      calculateEndpoint(inputAr, true); 
      calculateEndpoint(outputAr, false); 
     } 

     function calculateEndpoint(endpointArray, isInput) { 

      //multiplyer 
      var mult = 1/endpointArray.length; 

      for (var i = 0; i < endpointArray.length; i++) { 

       if (isInput) { 
        endpointArray[i].anchor.x = 1; 
        endpointArray[i].anchor.y = mult * i;//, 1, 0] }; 
       } 
       else { 
        endpointArray[i].anchor.x = 0; 
        endpointArray[i].anchor.y = mult * i;//, -1, 0] }; 
       } 
      } 
     } 



     //Add additional anchor 
     $(".button_add").live("click", function() { 

      var parentnode = $(this)[0].parentNode.parentNode; 

      jsPlumb.addEndpoint(
       parentnode, 
       anEndpointSource 
      ); 

      jsPlumb.addEndpoint(
       parentnode, 
       anEndpointDestination 
      ); 

      //get list of current endpoints 
      var endpoints = jsPlumb.getEndpoints(parentnode); 

      //fix endpoints 
      fixEndpoints(endpoints); 

      jsPlumb.recalculateOffsets(); 
      jsPlumb.repaint(parentnode); 
     }); 

Expected result

Như bạn có thể thấy trên hình bên trên, bên trái chỉ có điểm cuối nguồn (Dot) và bên phải (Hộp) chỉ nhắm mục tiêu điểm cuối, khi điểm cuối mới được thêm vào, neo được tính toán lại dựa trên số lượng neo trên e bên.

Tác phẩm này vẫn còn lỗi: vị trí chỉ được cập nhật khi tôi di chuyển vùng chứa và kết nối giữa các vùng chứa cũng không chính xác.

Những gì tôi muốn làm, là một cách để cho nó hoạt động và kết nối các mặt hàng một cách chính xác (tốt nhất là sử dụng mã jsPlumb đúng mà không cần đến hacks)

Trả lời

11

cuối cùng tôi đã tìm ra cách để làm điều đó. Nó dễ hơn tôi tưởng.

Mã là cơ bản giống với một vài thay đổi, here is updated fiddler sample

<!DOCTYPE html> 
<html> 
<head> 
<title>JS plumb test</title> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js"></script> 
    <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.23/jquery-ui.min.js"></script> 
    <script type="text/javascript" src="./include/jquery.jsPlumb-1.3.16-all-min.js"></script> 

<style> 
    .window { 
     background-color: #EEEEEF; 
     border: 1px solid #346789; 
     border-radius: 0.5em; 
     box-shadow: 2px 2px 5px #AAAAAA; 
     color: black; 
     height: 5em; 
     position: absolute; 
     width: 5em; 
    } 

    .window:hover { 
     box-shadow: 2px 2px 19px #AAAAAA; 
     cursor: pointer; 
    } 


    .button_add, .button_add_window, .button_remove, .button { 
     background-color: deepskyblue; 
     text-align: center; 
     border: 1px solid; 
    } 

    .button_container { 
     margin: 5px; 
     background-color: #aaaaaa 
    } 
</style> 

<script> 

    jsPlumb.ready(function() { 


     //FIX DOM: 
     $(("#container1"))[0].innerHTML = $(("#container0"))[0].innerHTML; 

     //all windows are draggable 
     jsPlumb.draggable($(".window")); 


     var anEndpointSource = { 
      endpoint: "Rectangle", 
      isSource: true, 
      isTarget: false, 
      maxConnections: 1, 

      anchor: [1, 0, 1, 0] 
     }; 

     var anEndpointDestination = { 
      endpoint: "Dot", 
      isSource: false, 
      isTarget: true, 
      maxConnections: 1, 

      anchor: [0, 1, -1, 0] 
     }; 


     //Fixes endpoints for specified target 
     function fixEndpoints(parentnode) { 

      //get list of current endpoints 
      var endpoints = jsPlumb.getEndpoints(parentnode); 

      //there are 2 types - input and output 

      var inputAr = $.grep(endpoints, function (elementOfArray, indexInArray) { 
       return elementOfArray.isSource; //input 
      }); 

      var outputAr = $.grep(endpoints, function (elementOfArray, indexInArray) { 
       return elementOfArray.isTarget; //output 
      }); 

      calculateEndpoint(inputAr, true); 
      calculateEndpoint(outputAr, false); 

      jsPlumb.repaintEverything(); 
     } 

     //recalculate endpoint anchor position manually 
     function calculateEndpoint(endpointArray, isInput) { 

      //multiplyer 
      var mult = 1/(endpointArray.length+1); 

      for (var i = 0; i < endpointArray.length; i++) { 

       if (isInput) { 

        //position 
        endpointArray[i].anchor.x = 1; 
        endpointArray[i].anchor.y = mult * (i + 1); 
       } 
       else { 

        //position 
        endpointArray[i].anchor.x = 0; 
        endpointArray[i].anchor.y = mult * (i + 1); 
       } 
      } 
     } 



     //Add additional anchor 
     $(".button_add").live("click", function() { 

      var parentnode = $(this)[0].parentNode.parentNode; 

      jsPlumb.addEndpoint(
       parentnode, 
       anEndpointSource 
      ); 

      jsPlumb.addEndpoint(
       parentnode, 
       anEndpointDestination 
      ); 

      fixEndpoints(parentnode); 
     }); 

     //Remove anchor 
     $(".button_remove").live("click", function() { 

      var parentnode = $(this)[0].parentNode.parentNode; 

      //get list of current endpoints 
      var endpoints = jsPlumb.getEndpoints(parentnode); 

      //remove 2 last one 

      if (endpoints.length > 1) { 
       jsPlumb.deleteEndpoint(endpoints[endpoints.length - 2]); 
      } 

      if (endpoints.length > 0) { 
       jsPlumb.deleteEndpoint(endpoints[endpoints.length - 1]); 
      } 

      fixEndpoints(parentnode); 
     }); 


     //adds new window 
     $(".button_add_window").click(function() { 

      var id = "dynamic_" + $(".window").length; 

      //create new window and add it to the body 
      $('<div class="window" id="' + id + '" >').appendTo('body').html($(("#container0"))[0].innerHTML); 

      //set jsplumb properties 
      jsPlumb.draggable($('#' + id)); 
     }); 
    }); 
</script> 

</head> 
<body > 

    <!-- Adds new windows to the page --> 
    <div class="window" style="left: 600px" id="details"> 
     <p style="text-align: center">Window</p> 
     <div class="button_container"> 
      <div class="button_add_window">Add</div> 
     </div> 
    </div> 

    <!-- Primary window - used as html templated for descendants --> 
    <div class="window" style="left: 20px" id="container0"> 
     <div class="button_container"> 
      <div class="button_add">Add</div> 
      <div class="button_remove">Remove</div> 
     </div> 
    </div> 

    <div class="window" style="left: 200px" id="container1"> 
    </div> 


</body> 
</html> 

Những thay đổi mà tôi đã thực hiện:

  1. Bây giờ tôi chỉ định neo endpoint bù đắp khi tôi thêm nó, tôi chỉ tính toán vị trí neo , do đó bù trừ không bao giờ thay đổi, nó luôn chính xác ngay từ đầu:

    var anEndpointSource = { 
        endpoint: "Rectangle", 
        isSource: true, 
        isTarget: false, 
        maxConnections: 1, 
    
        anchor: [1, 0, 1, 0] 
    }; 
    
  2. Khi endpoint được thêm vào, tôi tính lại vị trí neo và cuộc gọi (điều này sẽ sơn lại các kết nối):

    jsPlumb.repaintEverything();

Dưới đây là kết quả cuối cùng:

endpoints correctly connected

+0

thực hiện rất tốt :) Có cách nào để "xóa" nút (đã chọn) không? Tôi tr để tạo ra một trình soạn thảo máy nhà nước w/jsplumb nhưng chỉ đấu tranh w/tự động thêm/xóa các nút và các kết nối. Một jsfiddle sẽ rất tuyệt vời :) – Dominik

0

Bạn có thể xóa tiểu bang bằng cách nhấp đúp bằng cách thêm

     newState.dblclick(function(e) { 
         alert("This will delete the state and its connections"); 
         instance.detachAllConnections($(this)); 
         $(this).remove(); 
         e.stopPropagation(); 
        }); 

hoạt động với hàm jsPlumb.ready của bạn.bạn có thể thêm điều này vào tất cả các tiểu bang của mình bằng cách thêm

var windows = jsPlumb.getSelector(".statemachine-demo .state"); 
      windows.dblclick(function(e) { 
      alert("This will delete the state and its connections"); 
      instance.detachAllConnections($(this)); 
      $(this).remove(); 
      e.stopPropagation(); 
     }); 

đây statemachine-demo là id của div trong contaner và trạng thái của bạn là loại div nhà nước.

0

cảm ơn vì giải pháp, nó hoạt động tốt khi mặt neo được xác định trước, như ở đây nguồn luôn ở bên trái và mục tiêu luôn ở bên phải.

Nhưng nếu chúng năng động, chúng ta cũng cần thực hiện lựa chọn bên cạnh mình?

Cách giải quyết những gì tôi đã làm là đặt nhiều vị trí neo có thể có trong cấu hình mặc định. Có ý tưởng nào tốt hơn không?

cảm ơn

Các vấn đề liên quan