jsPlumb Javascript

JS連線繪圖函式庫jsPlumb 介紹與實作

張鈞名 2020/12/24 15:09:30
460

1. jsPlumb基本介紹:

  jsPlumb是一個強大的可繪製連線流程圖的函式庫,提供html元素的拖曳、連線等功能,它在圖形與連接線相關設定的可控參數都非常多,所以我們可用來客製各種需求的流程圖,它是開源且為MIT License的免費處理圖型相關的函式庫,並且它在github上的星星數有著6.2k之多,官方文件也較為齊全,在社群的活躍度也很高,所以相關討論的資訊很多。

 

2. 版本介紹及安裝與使用:

jsPlumb官網提供社群版Community Edition (開源版)Toolkit Edition 版本(付費)Toolkit Edition版本功能集成比較豐富,社群版本的話,因為是免費的,所以比較多功能沒有,需要自己來添加與實作,因為基於開源,所以我們就來使用免費的社群版本來實作。

社群版有分為兩個版,一個是2.x.x版,是2009年第一個jsPlumb版本以來以原生Javascript原始碼開發的延續,另一個版本為4.0.0-RC24版本dev / 4.x分支是用Typescript重寫的,所以2.15.3將是2.x分支的最終版本,由於4.0還在RC階段,我們就用2.15.3版本來實作。

 

2.x版使用方式:

 

Npm安裝方式:

npm install jsplumb

 

或是直接在html頁面引入cdn2.15.3版本連結

< script type= "text/javascript" src= "https://cdn.bootcss.com/jsPlumb/2.15.3/js/jsplumb.min.js"></ script>

 

3. 基礎知識:

基本元素組成:

1.      Source:來源對象

連線的來源節點,可以是id、元素,或是Endpoint

2.       Target:目標對象

連線的目標節點,可以是id、元素,或是Endpoint

       Source Target 都可以是任何元素,Source就是起點,Target就是終點,所以Connector的箭頭就是從Source指向Target

3.       Anchor:錨點

放置端點的位置,主要為一個元素的來源,也就是SourceTarget相連Connector的接點位置。

4.       Endpoint:端點

連接線的末端的視覺化顯示,可以建立並且連接這些端點,也可以讓它們支援拖曳效果。

5.       Connector:連接點

連接兩個Dom元素的連接線,有三種預設類型:Bezier曲線、Flowchart具有90度轉折的流程線、Straight直線。

6.       Overlay:添加到連接線上的附件,如箭頭或線上的文字標籤。

 

4. 基本函式功能介紹與實作:

我可以直接在htmlhead直接引入script即可來撰寫

<script type="text/javascript" src="https://cdn.bootcss.com/jsPlumb/2.15.3/js/jsplumb.min.js"></script>

再來撰寫一下基本的css

#container {

  padding: 20px;

  width: 100%;

  height: 300px;

  background-color: rgb(205, 201, 201);

  border: 1px solid gray;

}

 

.item-left {

  position: absolute;

  height: 100px;

  width: 100px;

  background-color: rgb(179, 229, 244);

  border: 1px solid gray;

}

 

.item-right {

  position: absolute;

  height: 100px;

  width: 100px;

  background-color: rgb(179, 229, 244);

  border: 1px solid gray;

  left: 150px;

}

 

初始化:

jsPlumb必須等到Dom初始化完成後才能使用,所以我使用jsPlumb.ready()函數來初始化jsPlumb

jsPlumb.ready(function () {

    // code

})

 

4.1 連接兩個節點

<div id="container">

    <div id="item_left" class="item-left"></div>

    <div id="item_right" class="item-right"></div>

</div>

 

jsPlumb.ready(function () {

  jsPlumb.connect({

    source: "item_left",

    target: "item_right",

    endpoint: "Dot", // 端點為圓形

  });

});

實際效果

 

4.2 可拖曳節點

可以使兩個元素節點可被拖曳。

jsPlumb.ready(function () {

  jsPlumb.connect({

    source: "item_left",

    target: "item_right",

    endpoint: "Rectangle", // 端點為矩形

  });

 

  jsPlumb.draggable("item_left");

  jsPlumb.draggable("item_right");

});

實際效果圖

 

 

4.3 連接線的其他參數

Connector可以設置連接線的外型,如直線或是曲線外型。

Anchors可以去設置多組錨點位置。

jsPlumb.ready(function () {

  jsPlumb.connect({

    source: "item_left",

    target: "item_right",

    endpoint: "Rectangle",

    connector: "Bezier",

    anchors: ["Right", "Left"],

  });

 

  jsPlumb.draggable("item_left");

  jsPlumb.draggable("item_right");

});

anchors: ["Top", "Left"]錨點上跟左的效果圖

connector: "Bezier"效果圖

connector: "Flowchart"效果圖

connector: "StateMachine"效果圖

connector: "Straight"效果圖

 

4.4 設定連接線的預設值

我們可以將連線參數抽離出來當作預設連線的變數,將connect第二個參數傳入即可。

jsPlumb.ready(function () {

  const defaultCommon = {

    endpoint: "Dot",

    connector: ["Flowchart"],

    anchors: ["Bottom", "Left"],

  };

 

  jsPlumb.connect(

    {

      source: "item_left",

      target: "item_right",

    },

    defaultCommon

  );

 

  jsPlumb.draggable("item_left");

  jsPlumb.draggable("item_right");

});

 

實際效果圖

 

4.5 連接線增加樣式

我們也可以將連線設定不同的樣式,如顏色粗細之類的。

paintStyle線條樣式、endpointStyle端點樣式。

jsPlumb.ready(function () {

  const defaultCommon = {

    endpoint: "Dot",

    connector: ["Flowchart"],

    anchors: ["Bottom", "Left"],

  };

 

  jsPlumb.connect(

    {

      source: "item_left",

      target: "item_right",

      paintStyle: { stroke: "red", strokeWidth: 5 },

      endpointStyle: {

        fill: "red",

        outlineStroke: "white",

        outlineWidth: 3,

      },

    },

    defaultCommon

  );

 

  jsPlumb.draggable("item_left");

  jsPlumb.draggable("item_right");

});

 

效果圖

 

4.6 連接線增加箭頭樣式

連接線的箭頭是透過overlays屬性去設定的,可以設定箭頭的長寬跟位置,location屬性值0.5代表位於連接線的中間,location1的時候表示位置在連接線的尾端。

 

location屬性值為0.5時效果:

location屬性值為1時效果:

overlays有五種類型:

1. Arrow可設定的箭頭的類型

2. Label文字標籤

3. PlainArrow箭頭形狀為三角形的類型

4. Diamond 菱形的箭頭類型

5. Custom 自定義類型

 

jsPlumb.connect(

    {

      source: "item_left",

      target: "item_right",

      paintStyle: { stroke: "red", strokeWidth: 5 },

      endpointStyle: {

        fill: "red",

        outlineStroke: "white",

        outlineWidth: 3,

      },

      overlays: [["Arrow", { width: 30, length: 30, location: 1 }]],

    },

    defaultCommon

  );

 

Label文字標籤的使用方式:

overlays:[

        "Arrow",

          [ "Label", { label:"TEST LABEL", location:0.25, id:"myLabel" } ]

      ],

效果圖:

 

PlainArrow箭頭形狀為三角形使用方式:

也就是Arrowfoldback1時的例子

overlays: [

        ["Arrow", { width: 30, length: 30, location: 1, foldback: 1 }],

      ],

效果圖:

 

Diamond 菱形的箭頭的使用方式:

也就是Arrowfoldback2時的例子

overlays: [

        ["Arrow", { width: 30, length: 30, location: 1, foldback: 2 }],

      ],

效果圖:

 

Custom 自定義箭頭的方法:

可讓您創建自己的疊加層,您需要實現一種方法-createcomponent),將覆蓋層所在的組件作為參數傳遞給該組件,並從基礎庫返回DOM元素或有效選擇器:

overlays: [

        [

          "Custom",

          {

            create: function (component) {

              return $(

                "<select id='myDropDown'><option value='foo'>foo</option><option value='bar'>bar</option></select>"

              );

            },

            location: 0.7,

            id: "customOverlay",

          },

        ],

效果圖:

這樣我們可以在連接上加上客製的下拉選單,或是你想要的任何html結構元素,如按鈕、輸入框。

 

4.7 增加一個端點

我們可以根據需求來決定增加端點在哪個位置。

addEndpoint第一個參數為元素的id,第二參數為錨點參數

jsPlumb.ready(function () {

  jsPlumb.addEndpoint("item_left", {

    anchors: ["Top"],

  });

});

效果圖

 

4.8 拖曳建立的連接線

我們可以拖曳來源點的端點連接線,到想要連接的目標的端點。

我們先不建立連線,來建立端點,利用端點來做連線效果。

我們設定isSourceisTarget屬性設定為true,就可以達到這種效果

jsPlumb.ready(function () {

  const defaultCommon = {

    isSource: true,

    isTarget: true,

    connector: ["Straight"],

  };

 

  jsPlumb.addEndpoint(

    "item_left",

    {

      anchors: ["Right"],

    },

    defaultCommon

  );

 

  jsPlumb.addEndpoint(

    "item_right",

    {

      anchor: "Left",

    },

    defaultCommon

  );

 

  jsPlumb.draggable("item_left");

  jsPlumb.draggable("item_right");

});

效果圖:

 

如果只想端點相連後不能取消,我們可以設定ConnectionsDetachable屬性為false

jsPlumb.ready(function () {

  jsPlumb.importDefaults({

    ConnectionsDetachable: false,

  });

     .

     .

});

 

4.9 限制節點拖曳區域

我們可以設定限制,讓節點只能在固定區域拖曳移動。

draggable增加{ containment: true }參數

jsPlumb.ready(function () {

  jsPlumb.setContainer("container");

  jsPlumb.connect({

    source: "item_left",

    target: "item_right",

    endpoint: "Dot",

  });

  jsPlumb.draggable("item_left", { containment: true });

  jsPlumb.draggable("item_right", { containment: true });

});

 

4.10 連接線增加點擊事件,並刪除連接線

我們使用deleteConnection方法來刪除連接線

jsPlumb.bind("click", function (conn, originalEvent) {

    if (window.confirm("你確定要刪除此連接線嗎?")) {

      jsPlumb.deleteConnection(conn);

      return true;

    }

  });

 

 

4.11 刪除節點,與相關連接線

我們將左邊的元素新增一個刪除按鈕

<div id="container">

      <div id="item_left" class="item-left">

        <button id="btn-left">X</button>

      </div>

      <div id="item_right" class="item-right"></div>

    </div>

點擊X按鈕後將其元素及連接線刪除

jsPlumb.ready(function () {

  jsPlumb.connect({

    source: "item_left",

    target: "item_right",

    endpoint: "Rectangle",

  });

 

  jsPlumb.draggable("item_left");

  jsPlumb.draggable("item_right");

});

 

$(document).ready(function () {

  $("#btn-left").click(function () {

    jsPlumb.remove("item_left");

  });

});

 

效果圖

 

 

 

4.12 連線事件

有時候我們會需要知道連線的事件,讓我們可以處理一些連線的商業邏輯判斷

我們來增加三個元素,分別為ABC三個節點,增加邏輯判斷,讓A節點不能連到C節點。

jsPlumb.ready(function () {

  const defaultCommon = {

    isSource: true,

    isTarget: true,

    connector: ["Straight"],

  };

 

  jsPlumb.addEndpoint(

    "item_A",

    {

      anchor: "Right",

    },

    defaultCommon

  );

 

  jsPlumb.addEndpoint(

    "item_B",

    {

      anchor: "Left",

    },

    defaultCommon

  );

 

  jsPlumb.addEndpoint(

    "item_C",

    {

      anchor: "Top",

    },

    defaultCommon

  );

 

  jsPlumb.draggable("item_A");

  jsPlumb.draggable("item_B");

  jsPlumb.draggable("item_C");

 

  jsPlumb.bind("beforeDrop", function (evt) {

    let from = evt.sourceId;

    let to = evt.targetId;

    if (from === "item_A" && to === "item_C") {

      alert("A節點不能連到C節點!");

      return false;

    } else {

      return true;

    }

  });

});

效果圖:

 

4.13 連接線的數量

通常預設的連線數量為1,也就是一個來源點只能連一個目標點,我們可以設定其maxConnections連線數量,若設定為-1則不限制數量。

const defaultCommon = {

      isSource: true,

      isTarget: true,

      connector: ["Straight"],

      maxConnections: -1

    };

效果圖:

 

5.  總結:

jsPlumb可以很方便的實作元素連線、元素拖曳、事件綁定或是改變樣式等功能,能客製的細節很多,這樣就能滿足我們專案上的各種不同的複雜需求。

 

張鈞名