JS連線繪圖函式庫jsPlumb 介紹與實作
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安裝方式:
或是直接在html頁面引入cdn2.15.3版本連結
3. 基礎知識:
基本元素組成:
1. Source:來源對象
連線的來源節點,可以是id、元素,或是Endpoint。
2. Target:目標對象
連線的目標節點,可以是id、元素,或是Endpoint。
Source 和 Target 都可以是任何元素,Source就是起點,Target就是終點,所以Connector的箭頭就是從Source指向Target。
3. Anchor:錨點
放置端點的位置,主要為一個元素的來源,也就是Source跟Target相連Connector的接點位置。
4. Endpoint:端點
連接線的末端的視覺化顯示,可以建立並且連接這些端點,也可以讓它們支援拖曳效果。
5. Connector:連接點
連接兩個Dom元素的連接線,有三種預設類型:Bezier曲線、Flowchart具有90度轉折的流程線、Straight直線。
6. Overlay:添加到連接線上的附件,如箭頭或線上的文字標籤。
4. 基本函式功能介紹與實作:
我可以直接在html的head直接引入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代表位於連接線的中間,location為1的時候表示位置在連接線的尾端。
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箭頭形狀為三角形使用方式:
也就是Arrow的foldback為1時的例子
overlays: [
["Arrow", { width: 30, length: 30, location: 1, foldback: 1 }],
],
效果圖:
Diamond 菱形的箭頭的使用方式:
也就是Arrow的foldback為2時的例子
overlays: [
["Arrow", { width: 30, length: 30, location: 1, foldback: 2 }],
],
效果圖:
Custom 自定義箭頭的方法:
可讓您創建自己的疊加層,您需要實現一種方法-create(component),將覆蓋層所在的組件作為參數傳遞給該組件,並從基礎庫返回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 拖曳建立的連接線
我們可以拖曳來源點的端點連接線,到想要連接的目標的端點。
我們先不建立連線,來建立端點,利用端點來做連線效果。
我們設定isSource和isTarget屬性設定為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 連線事件
有時候我們會需要知道連線的事件,讓我們可以處理一些連線的商業邏輯判斷
我們來增加三個元素,分別為A、B、C三個節點,增加邏輯判斷,讓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可以很方便的實作元素連線、元素拖曳、事件綁定或是改變樣式等功能,能客製的細節很多,這樣就能滿足我們專案上的各種不同的複雜需求。