https://wdd.js.org/jsplumb-chinese-tutorial/#/
1. jsplumb 中文基礎教程
后續更新會在倉庫:https://github.com/wangduanduan/jsplumb-chinese-tutorial.git
本文的圖片是托管於七牛雲的,由於使用的是測試域名,可能不知道哪天,圖片就無法顯示了。不過每個例子都有簡單的在線demo, demo剩千圖,還是能看懂的。
1.1. 什么是jsplumb?
你有沒有想過在你的網站上展示圖表或者甚至在瀏覽器應用程序中使用它?用jsPlumb你可以!它是完全免費的,並根據MIT許可證提供。您可以直接從jsPlumb github網站下載框架。
該項目主要由Simon Porritt開發,他在澳大利亞西德尼擔任網絡開發人員。 jsPlumb由他積極開發。作為許多優秀的開發人員,他似乎更喜歡開發代碼而不是編寫教程,這就是為什么我提供一個簡單的入門教程。
1.2. jsplumb能干什么?
那么如果你應該使用它取決於你想用jsPlumb做什么。該框架適用於必須繪制圖表的Web應用程序,例如類似於Visio的應用程序或工作流程設計器等。由於圖表項目和連接的所有參數都是非常精細可控的,因此您可以繪制您可以想到的任何類型的圖表的!
1.3. 基本概念
- Souce 源節點
- Target 目標節點
- Anchor 錨點
- Endpoint 端點
- Connector 連接
2. 基礎demos
2.1. 連接兩個節點
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/01.html
jsPlumb.ready方法和jquery的ready方法差不多的功能,jsPlumb.connect用於建立連線
<div id="diagramContainer"> <div id="item_left" class="item"></div> <div id="item_right" class="item"style="margin-left:50px;"></div> </div> <script src="https://cdn.bootcss.com/jsPlumb/2.6.8/js/jsplumb.min.js"></script> <script>/* global jsPlumb */ jsPlumb.ready(function () { jsPlumb.connect({ source: 'item_left', target: 'item_right', endpoint: 'Dot' }) }) </script>
參數說明: jsPlumb.connect(config) return connection
參數 | 參數類型 | 是否必須 | 說明 |
---|---|---|---|
source | String,Object,Endpoint | 是 | 連線源的標識,可以是id, element, 或者Endpoint |
target | String,Object,Endpoint | 是 | 連線目標的標識,可以是id, element, 或者Endpoint |
endpoint | String | 可選 | 端點類型,形狀 |
2.2. 可拖動節點
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/02.html
使用draggable可以讓節點被拖動,draggable方法參考
<div id="diagramContainer"> <div id="item_left" class="item"></div> <div id="item_right" class="item"style="left:150px;"></div> </div> <script src="https://cdn.bootcss.com/jsPlumb/2.6.8/js/jsplumb.min.js"></script> <script>/* global jsPlumb */ jsPlumb.ready(function () { jsPlumb.connect({ source: 'item_left', target: 'item_right', endpoint: 'Rectangle' }) jsPlumb.draggable('item_left') jsPlumb.draggable('item_right') }) </script>
2.3. 連接的其他參數
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/03.html
可以通過connector去設置鏈接線的形狀,如直線或者曲線之類的。anchor可以去設置錨點的位置。
jsplumb連線的樣式有四種
Bezier
: 貝塞爾曲線Flowchart
: 具有90度轉折點的流程線StateMachine
: 狀態機Straight
: 直線
<div id="diagramContainer"> <div id="item_left" class="item"></div> <div id="item_right" class="item"style="left:150px;"></div> </div> <script src="https://cdn.bootcss.com/jsPlumb/2.6.8/js/jsplumb.min.js"></script> <script>/* global jsPlumb */ jsPlumb.ready(function () { jsPlumb.connect({ source: 'item_left', target: 'item_right', endpoint: 'Rectangle', connector: ['Bezier'], anchor: ['Left', 'Right'] }) jsPlumb.draggable('item_left') jsPlumb.draggable('item_right') }) </script>
2.4. 設置連接的默認值
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/04.html
很多連線都是相同設置的情況下,可以將配置抽離出來,作為一個單獨的變量,作為connect的第二個參數傳入。實際上connect的第二個參數會和第一個參數merge,作為一個整體。
<script>/* global jsPlumb */ jsPlumb.ready(function () { var common = { endpoint: 'Rectangle', connector: ['Bezier'], anchor: ['Left', 'Right'] } jsPlumb.connect({ source: 'item_left', target: 'item_right' }, common) jsPlumb.draggable('item_left') jsPlumb.draggable('item_right') }) </script>
2.5. 給連接加上樣式
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/05.html
例如給連線設置不同的顏色,設置不同的粗細之類的。
jsPlumb.connect({
source: 'item_left',
target: 'item_right',
paintStyle: { stroke: 'lightgray', strokeWidth: 3 },
endpointStyle: { fill: 'lightgray', outlineStroke: 'darkgray', outlineWidth: 2 }
}, common)
2.6. 給連接加上箭頭
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/06.html
箭頭實際上是通過設置overlays
去設置的,可以設置箭頭的長寬以及箭頭的位置,location 0.5表示箭頭位於中間,location 1表示箭頭設置在連線末端。 一根連線是可以添加多個箭頭的。
overlays
也是一個比較重要的概念,overlays可以理解為遮罩層。遮罩層不僅僅可以設置箭頭,也可以設置其他內容。
overlays有五種類型,下面給出簡介。具體使用方法參見 https://jsplumbtoolkit.com/community/doc/overlays.html
Arrow
一個可配置的箭頭Label
標簽,可以在鏈接上顯示文字信息PlainArrow
原始類型的箭頭Diamond
菱形箭頭Custom
自定義類型
jsPlumb.connect({
source: 'item_left',
target: 'item_right',
paintStyle: { stroke: 'lightgray', strokeWidth: 3 },
endpointStyle: { fill: 'lightgray', outlineStroke: 'darkgray', outlineWidth: 2 },
overlays: [ ['Arrow', { width: 12, length: 12, location: 0.5 }] ]
}, common)
2.7. 增加一個端點
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/07.html
addEndpoint方法可以用來增加端點,具體使用請看
jsPlumb.ready(function () {
jsPlumb.addEndpoint('item_left', {
anchors: ['Right']
})
})
2.8. 拖動創建連接
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/08.html
如果你將isSource
和isTarget
設置成true,那么久可以用戶在拖動時,自動創建鏈接。
jsPlumb.ready(function () {
jsPlumb.setContainer('diagramContainer')
var common = {
isSource: true,
isTarget: true,
connector: ['Straight']
}
jsPlumb.addEndpoint('item_left', {
anchors: ['Right']
}, common)
jsPlumb.addEndpoint('item_right', {
anchor: 'Left'
}, common)
jsPlumb.addEndpoint('item_right', {
anchor: 'Right'
}, common)
})
一般來說拖動創建的鏈接,可以再次拖動,讓鏈接斷開。如果不想觸發這種行為,可以設置。
jsPlumb.importDefaults({
ConnectionsDetachable: false
})
2.9. 給端點增加樣式
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/09.html
通過設置各種 *Style
來改變鏈接或者端點的樣式。
jsPlumb.ready(function () {
jsPlumb.setContainer('diagramContainer')
var common = {
isSource: true,
isTarget: true,
connector: 'Straight',
endpoint: 'Dot',
paintStyle: {
fill: 'white',
outlineStroke: 'blue',
strokeWidth: 3
},
hoverPaintStyle: {
outlineStroke: 'lightblue'
},
connectorStyle: {
outlineStroke: 'green',
strokeWidth: 1
},
connectorHoverStyle: {
strokeWidth: 2
}
}
jsPlumb.addEndpoint('item_left', {
anchors: ['Right']
}, common)
jsPlumb.addEndpoint('item_right', {
anchor: 'Left'
}, common)
jsPlumb.addEndpoint('item_right', {
anchor: 'Right'
}, common)
})
2.10. 節點改變尺寸
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/10.html
jsplumb實際上不支持改變節點大小,實際上只能通過jquery ui resizable 方法去改變。
<div id="diagramContainer"> <div id="item_left" class="item"></div> <div id="item_right" class="item"style="left:150px;"></div> </div> <script src="https://code.jquery.com/jquery-1.11.3.js"></script> <script src="https://code.jquery.com/ui/1.12.1/jquery-ui.js"></script> <script src="./lib/jquery.jsplumb.js"></script> <script>/* global jsPlumb, $ */ $('.item').resizable({ resize: function (event, ui) { jsPlumb.repaint(ui.helper) } }) jsPlumb.ready(function () { jsPlumb.connect({ source: 'item_left', target: 'item_right', endpoint: 'Rectangle' }) jsPlumb.draggable('item_left') jsPlumb.draggable('item_right') }) </script>
2.11. 限制節點拖動區域
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/11.html
默認情況下,節點可以被拖動到區域外邊,如果想只能在區域內拖動,需要設置containment,這樣節點只能在固定區域內移動。
jsPlumb.setContainer('area-id')
2.12. 節點網格對齊
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/12.html 網格對齊實際上是設置了grid
屬性,使移動只能按照固定的尺寸移動。然后用一張圖作為背景鋪開作為網格來實現的。
#diagramContainer {
padding: 20px;
width: 80%;
height: 400px;
border: 1px solid gray;
background-image: url(http://p3alsaatj.bkt.clouddn.com/20180227163310_1bVYeW_grid.jpeg);
background-repeat: repeat;
}
jsPlumb.draggable('item_left', {
containment: 'parent',
grid: [10, 10]
})
2.13. 給鏈接添加點擊事件:點擊刪除連線
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/13.html
// 請單點擊一下連接線,
jsPlumb.bind('click', function (conn, originalEvent) {
if (window.prompt('確定刪除所點擊的鏈接嗎? 輸入1確定') === '1') {
jsPlumb.detach(conn)
}
})
jsPlumb支持許多事件
jsPlumb Events列表
- connection
- connectionDetached
- connectionMoved
- click
- dblclick
- endpointClick
- endpointDblClick
- contextmenu
- beforeDrop
- beforeDetach
- zoom
- Connection Events
- Endpoint Events
- Overlay Events
- Unbinding Events
參考用法參考:https://jsplumbtoolkit.com/community/doc/events.html#jsPlumbEvents
2.14. 刪除節點,包括節點相關的連接
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/14.html
// nodeId為節點id, remove方法可以刪除節點以及和節點相關的連線
console.log('3 秒后移除左邊節點包括它的連線')
setTimeout(function () {
jsPlumb.remove('item_left')
}, 3000)
注意remove方法有些情況下是無法刪除干凈連線的,詳情
2.15. 通過編碼連接endPoint
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/15.html
初始化數據后,給節點加上了endPoint, 如果想編碼讓endPoint鏈接上。需要在addEndpoint時,就給該斷點加上一個uuid, 然后通過connect()方法,將兩個斷點鏈接上。建議使用node-uuid給每個斷點都加上唯一的uuid, 這樣以后鏈接就方便多了。
jsPlumb.addEndpoint('item_left', {
anchors: ['Right'],
uuid: 'fromId'
})
jsPlumb.addEndpoint('item_right', {
anchors: ['Left'],
uuid: 'toId'
})
console.log('3 秒后建立連線')
setTimeout(function () {
jsPlumb.connect({ uuids: ['fromId', 'toId'] })
}, 3000)
2.16. 連接前的檢查,判斷是否建立連接
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/16.html
有時候當用戶從A端點鏈接到B端點時,需要做一些檢查,如果不符合條件,就不讓鏈接建立。
// 當鏈接建立前
jsPlumb.bind('beforeDrop', function (info) {
var a = 10
var b = 2
if (a < b) {
console.log('鏈接會自動建立')
return true // 鏈接會自動建立
} else {
console.log('鏈接取消')
return false // 鏈接不會建立,注意,必須是false
}
})
2.17. 一個端點如何拖拽出多條連線
默認情況下,maxConnections
的值是1,也就是一個端點最多只能拉出一條連線。
你也可以設置成其他值,例如5,表示最多可以有5條連線。
如果你想不限制連線的數量,那么可以將該值設置為-1
var common = {
isSource: true,
isTarget: true,
connector: ['Straight'],
maxConnections: -1
}
jsPlumb.addEndpoint('item_left', {
anchors: ['Right']
}, common)
2.18. 整個節點作為source或者target
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/18.html
整個節點作為source或者target, 並且將錨點設置成Continuous,那么錨點就會隨着節點的位置改變而改變自己的位置。
jsPlumb的錨點分為四類
Static
靜態 固定位置的錨點Dynamic
jsPlumb自動選擇合適的錨點,動態錨點Perimeter
邊緣錨點,會根據節點形狀去改變位置Continuous
根據節點位置,自動調整位置的錨點
詳情:https://jsplumbtoolkit.com/community/doc/anchors.html
window.jsPlumb.ready(function () {
var jsPlumb = window.jsPlumb
jsPlumb.makeSource('A', {
endpoint:"Dot",
anchor: "Continuous"
})
jsPlumb.makeTarget('B', {
endpoint:"Dot",
anchor: "Continuous"
})
jsPlumb.draggable('A')
jsPlumb.draggable('B')
})
2.19. 節點縮放
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/19.html
window.jsPlumb.ready(function () {
var jsPlumb = window.jsPlumb
jsPlumb.setContainer("diagramContainer")
jsPlumb.connect({
source: 'A',
target: 'B',
endpoint: 'Dot'
})
var baseZoom = 1
setInterval(() => {
baseZoom -= 0.1
if (baseZoom < 0.5) {
baseZoom = 1
}
zoom(baseZoom)
}, 1000)
})
function zoom (scale) {
$("#diagramContainer").css({
"-webkit-transform": `scale(${scale})`,
"-moz-transform": `scale(${scale})`,
"-ms-transform": `scale(${scale})`,
"-o-transform": `scale(${scale})`,
"transform": `scale(${scale})`
})
jsPlumb.setZoom(0.75);
}
3. jsPlumb默認配置簡介
參考地址: https://jsplumbtoolkit.com/community/doc/defaults.html
jsPlumb的配置項有很多,如果你不主動去設置,那么jsPlumb就使用默認的配置。
另外建議你不要修改默認的配置,而是使用自定義的方式。
另外一點要注意,如果你想修改默認配置,那么使用importDefaults方法,並且屬性的首字母要大寫。如果你用addEndpoint, 並使用類似maxConnections的屬性,那么首字母要小寫。
參見demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/17.html demo上需要你自己手動拖動創建鏈接。
var common = {
isSource: true,
isTarget: true,
connector: ['Straight'],
maxConnections: -1
}
jsPlumb.addEndpoint('item_left', {
anchors: ['Right']
}, common)
Anchor : "BottomCenter",
Anchors : [ null, null ],
ConnectionsDetachable : true,
ConnectionOverlays : [],
Connector : "Bezier",
Container : null,
DoNotThrowErrors : false,
DragOptions : { },
DropOptions : { },
Endpoint : "Dot",
Endpoints : [ null, null ],
EndpointOverlays : [ ],
EndpointStyle : { fill : "#456" },
EndpointStyles : [ null, null ],
EndpointHoverStyle : null,
EndpointHoverStyles : [ null, null ],
HoverPaintStyle : null,
LabelStyle : { color : "black" },
LogEnabled : false,
Overlays : [ ],
MaxConnections : 1,
PaintStyle : { strokeWidth : 8, stroke : "#456" },
ReattachConnections : false,
RenderMode : "svg",
Scope : "jsPlumb_DefaultScope"
你也可以從jsPlumb.Defaults
對象中查看默認的配置。如果你想要更加個性化的設置連線,那么最好可以了解一下,它的默認設置有哪些,從而方便的來完成自己的設計需求。
默認參數的簡介:
Anchor
錨點,即端點鏈接的位置Anchors
多個錨點 [源錨點,目標錨點].Connector
鏈接ConnectionsDetachable
節點是否可以用鼠標拖動使其斷開,默認為true。即用鼠標鏈接上的連線,也可以使用鼠標拖動讓其斷開。設置成false,可以讓其拖動也不會自動斷開。Container
連線的容器DoNotThrowErrors
是否拋出錯誤ConnectionOverlays
鏈接遮罩層DragOptions
拖動設置DropOptions
拖放設置Endpoint
端點Endpoints
數組形式的,[源端點,目標端點]EndpointOverlays
端點遮罩層EndpointStyle
端點樣式EndpointStyles
[源端點樣式,目標端點樣式]EndpointHoverStyle
端點鼠標經過的樣式EndpointHoverStyles
[源端點鼠標經過樣式,目標端點鼠標經過樣式]HoverPaintStyle
鼠標經過鏈接線時的樣式LabelStyle
標簽樣式LogEnabled
是否啟用日志Overlays
連接線和端點的遮罩層樣式MaxConnections
端點最大連接線數量默認為1, 設置成-1可以表示無數個鏈接PaintStyle
連線樣式ReattachConnections
端點是否可以再次重新鏈接RenderMode
渲染模式,默認是svgScope
作用域,用來區分哪些端點可以鏈接,作用域相同的可以鏈接
// 可以使用importDefaults,來重寫某些默認設置
jsPlumb.importDefaults({
PaintStyle : {
strokeWidth:13,
stroke: 'rgba(200,0,0,0.5)'
},
DragOptions : { cursor: "crosshair" },
Endpoints : [ [ "Dot", { radius:7 } ], [ "Dot", { radius:11 } ] ],
EndpointStyles : [{ fill:"#225588" }, { fill:"#558822" }]
});
4. 有沒有稍微復雜一點,帶有拖放的栗子?
項目地址:https://github.com/wangduanduan/visual-ivr ,將views目錄下的drag-drop-demo.html拖放到瀏覽器中,就可以愉快的玩耍了。
從該demo中除了可以學到基本的jsplumb的api, 也可以學到其他的關於拖放的知識點。其中目前只做了語音節點的拖放,其他的還時間做。該demo沒有使用webpack打包,代碼寫的有點亂,大家湊合着看,有問題可以提issue, 或者評論。
5. 實戰項目 一個可視化IVR編輯器
項目地址:https://github.com/wangduanduan/visual-ivr 該項目還在開發完善中,不過已經具備基本功能。
該項目是用webpack打包的項目,所有文件都在src目錄下。
圖1是基於jsplumb做的最基礎的版本,圖2是最近優化后的版本,該版本未開源。
【圖1】
【圖2】
6. 還有哪些類似的圖形連線可視化項目
6.1. G6 AntV
6.2. VivaGraphJS
https://github.com/anvaka/VivaGraphJS
6.3. springy
https://github.com/dhotson/springy
6.4. graphviz
https://www.graphviz.org/about/
中文有個基本的介紹文檔寫的不錯,參考:https://casatwy.com/shi-yong-dotyu-yan-he-graphvizhui-tu-fan-yi.html
graphviz可以把你寫的.dot文件渲染成一張圖。
mac上首先要安裝:brew install graphviz
然后如果你用vscode的話,vscode上又graphviz的擴展插件,可以預覽你的dot文件。
總體來說,graphviz的功能十分強大,同時它也提供了其他語言的腳本api來方便繪圖。總之,如果你不想通過拖拉拽來繪制一些流程圖,又對圖形布局不是很感興趣的話,graphviz是一個免費而且效率高而且能裝逼的工具
再貼幾張graphviz的繪圖
6.5. visjs
該項目看起來不錯,github上將近有7000 star, 但是它的開發者似乎沒時間維護該項目了,正在給該項目找下家。