# jsplumb-demo
**Repository Path**: zouren827268/jsplumb-demo
## Basic Information
- **Project Name**: jsplumb-demo
- **Description**: jsplumb 学习
- **Primary Language**: Unknown
- **License**: MIT
- **Default Branch**: master
- **Homepage**: None
- **GVP Project**: No
## Statistics
- **Stars**: 6
- **Forks**: 2
- **Created**: 2021-12-30
- **Last Updated**: 2025-04-12
## Categories & Tags
**Categories**: Uncategorized
**Tags**: None
## README
- [1. jsplumb 中文基础教程](#1-jsplumb-中文基础教程)
- [1.1. 什么是jsplumb?](#11-什么是jsplumb)
- [1.2. jsplumb能干什么?](#12-jsplumb能干什么)
- [1.3. 基本概念](#13-基本概念)
- [1.3.1. Anchors [todo]](#131-anchors-todo)
- [1.3.2. Connectors [todo]](#132-connectors-todo)
- [1.3.3. Endpoints [todo]](#133-endpoints-todo)
- [1.3.4. Overlays [todo]](#134-overlays-todo)
- [1.3.5. Groups [todo]](#135-groups-todo)
- [1.4. 样式设置 [todo]](#14-样式设置-todo)
- [2. 基础demos](#2-基础demos)
- [2.1. 连接两个节点](#21-连接两个节点)
- [2.2. 可拖动节点](#22-可拖动节点)
- [2.3. 连接的其他参数](#23-连接的其他参数)
- [2.4. 设置连接的默认值](#24-设置连接的默认值)
- [2.5. 给连接加上样式](#25-给连接加上样式)
- [2.6. 给连接加上箭头](#26-给连接加上箭头)
- [2.7. 增加一个端点](#27-增加一个端点)
- [2.8. 拖动创建连接](#28-拖动创建连接)
- [2.9. 给端点增加样式](#29-给端点增加样式)
- [2.10. 节点改变尺寸](#210-节点改变尺寸)
- [2.11. 限制节点拖动区域](#211-限制节点拖动区域)
- [2.12. 节点网格对齐](#212-节点网格对齐)
- [2.13. 给连接添加点击事件:点击删除连线](#213-给连接添加点击事件点击删除连线)
- [2.14. 删除节点,包括节点相关的连接](#214-删除节点包括节点相关的连接)
- [2.15. 通过编码连接endPoint](#215-通过编码连接endpoint)
- [2.16. 连接前的检查,判断是否建立连接](#216-连接前的检查判断是否建立连接)
- [2.17. 一个端点如何拖拽出多条连线](#217-一个端点如何拖拽出多条连线)
- [2.18. 整个节点作为source或者target](#218-整个节点作为source或者target)
- [2.19. 节点缩放](#219-节点缩放)
- [3. jsPlumb事件列表](#3-jsplumb事件列表)
- [3.1. 常用事件](#31-常用事件)
- [3.1.1. connection 连接建立时触发](#311-connection-连接建立时触发)
- [3.1.2. connectionDetached 连接断开时触发](#312-connectiondetached-连接断开时触发)
- [3.1.3. connectionMoved 连接移动事件](#313-connectionmoved-连接移动事件)
- [3.1.4. connectionAborted 连接取消事件](#314-connectionaborted-连接取消事件)
- [3.1.5. click 连接点击事件](#315-click-连接点击事件)
- [3.1.6. dblclick 连接双击事件](#316-dblclick-连接双击事件)
- [3.1.7. connectionDrag 连接拖动事件](#317-connectiondrag-连接拖动事件)
- [3.1.8. connectionDragStop 连接停止拖动事件](#318-connectiondragstop-连接停止拖动事件)
- [3.1.9. endpointClick 端点单击事件](#319-endpointclick-端点单击事件)
- [3.1.10. endpointDblClick 端点双击事件](#3110-endpointdblclick-端点双击事件)
- [3.1.11. contextmenu 鼠标右键事件](#3111-contextmenu-鼠标右键事件)
- [3.1.12. beforeDrop 连接建立前事件](#3112-beforedrop-连接建立前事件)
- [3.1.13. beforeDetach 连接断开前事件](#3113-beforedetach-连接断开前事件)
- [3.1.14. zoom 缩放事件](#3114-zoom-缩放事件)
- [3.2. 其他事件](#32-其他事件)
- [3.2.1. Connection Events](#321-connection-events)
- [3.2.2. Endpoint Events](#322-endpoint-events)
- [3.2.3. Overlay Events](#323-overlay-events)
- [4. jsPlumb默认配置简介](#4-jsplumb默认配置简介)
- [5. 工具函数](#5-工具函数)
- [5.1. 重绘某个元素 jsPlumb.revalidate](#51-重绘某个元素-jsplumbrevalidate)
- [5.2. 重绘所有元素 jsPlumb.repaintEverything](#52-重绘所有元素-jsplumbrepainteverything)
- [5.3. 重设节点ID jsPlumb.setId](#53-重设节点id-jsplumbsetid)
- [5.4. 删除节点 jsPlumb.remove](#54-删除节点-jsplumbremove)
- [5.5. 清空所有节点连接和端点 jsPlumb.empty](#55-清空所有节点连接和端点-jsplumbempty)
- [5.6. 移除连线 jsPlumb.detach](#56-移除连线-jsplumbdetach)
- [5.7. 移除某个节点上的所有连线 jsPlumb.deleteConnectionsForElement](#57-移除某个节点上的所有连线-jsplumbdeleteconnectionsforelement)
- [5.8. 移除所有节点上的连线 jsPlumb.deleteEveryConnection()](#58-移除所有节点上的连线-jsplumbdeleteeveryconnection)
- [5.9. 移除某个节点上的端点](#59-移除某个节点上的端点)
- [5.10. 移除所有节点上的端点](#510-移除所有节点上的端点)
- [5.11. 元素的显示与隐藏](#511-元素的显示与隐藏)
- [6. 样式修改](#6-样式修改)
- [6.1. 通过css添加样式](#61-通过css添加样式)
- [6.2. paintStyle属性添加](#62-paintstyle属性添加)
- [7. 查询 [todo]](#7-查询-todo)
- [8. 视图与数据结构同步](#8-视图与数据结构同步)
- [9. 有没有稍微复杂一点,带有拖放的栗子?](#9-有没有稍微复杂一点带有拖放的栗子)
- [10. 还有哪些类似的图形连线可视化项目](#10-还有哪些类似的图形连线可视化项目)
- [10.1. G6 AntV](#101-g6-antv)
- [10.2. VivaGraphJS](#102-vivagraphjs)
- [10.3. springy](#103-springy)
- [10.4. graphviz](#104-graphviz)
- [10.5. visjs](#105-visjs)
- [11. 参考资源](#11-参考资源)
# 1. jsplumb 中文基础教程
后续更新会在仓库:https://github.com/wangduanduan/jsplumb-chinese-tutorial.git
> 阅读建议:由于本教程目录太多,建议安装谷歌浏览器插件[Smart TOC](https://chrome.google.com/webstore/detail/smart-toc/lifgeihcfpkmmlfjbailfpfhbahhibba),方便目录按照目录跳转查看。
## 1.1. 什么是jsplumb?
你有没有想过在你的网站上展示图表或者甚至在浏览器应用程序中使用它?用jsPlumb你可以!它是完全免费的,并根据MIT许可证提供。您可以直接从jsPlumb github网站下载框架。
该项目主要由Simon Porritt开发,他在澳大利亚西德尼担任网络开发人员。 jsPlumb由他积极开发。作为许多优秀的开发人员,他似乎更喜欢开发代码而不是编写教程,这就是为什么我提供一个简单的入门教程。

## 1.2. jsplumb能干什么?
那么如果你应该使用它取决于你想用jsPlumb做什么。该框架适用于必须绘制图表的Web应用程序,例如类似于Visio的应用程序或工作流程设计器等。由于图表项目和连接的所有参数都是非常精细可控的,因此您可以绘制您可以想到的任何类型的图表的!
## 1.3. 基本概念
- Souce 源节点
- Target 目标节点
- Anchor 锚点 锚点位于源节点或者目标节点上
- Endpoint 端点 端点位于连线上
- Connector 连接 或者也可以理解是连接线
- Overlays 可以理解为在连接线上的文字或者箭头之类的东东

### 1.3.1. Anchors [todo]
锚点类型:
- 静态锚点
- 动态锚点
- 边缘锚点
- 固定锚点
### 1.3.2. Connectors [todo]
连线类型:
- Bezier 贝塞尔曲线
- Straight 直线
- Flowchart 90度转角线
- State Machine 状态机
### 1.3.3. Endpoints [todo]
端点类型:
- Dot 圆点
- Rectangle 矩形
- Image 图像
- Blank 空白
### 1.3.4. Overlays [todo]
Overlays可以理解为在连接线上的文字或者箭头之类的东东
Overlays类型
- Arrow
- Label
- PlainArrow
- Diamond
- Custom
```js
// 连线上overlay可以多个,
// 每个overlay可以指定相对位置
// label类型的overlay实际上可以在里面直接写html
//
jsPlumb.connect({
...
connectorOverlays: [
['Arrow', {
width: 10,
length: 10,
location: 1
}],
['Label', {
label: '',
cssClass: '',
labelStyle: {
color: 'red'
},
events: {
click: function (labelOverlay, originalEvent) {
console.log('click on label overlay for :' + labelOverlay.component)
console.log(labelOverlay)
console.log(originalEvent)
}
}
}]
]
});
```
### 1.3.5. Groups [todo]
## 1.4. 样式设置 [todo]
# 2. 基础demos
## 2.1. 连接两个节点
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/01.html
jsPlumb.ready方法和jquery的ready方法差不多的功能,jsPlumb.connect用于建立连线

```
```
参数说明:
jsPlumb.connect(config) return connection
| 参数 | 参数类型 | 是否必须 | 说明 |
| -------- | ---------------------- | -------- | ----------------------------------------------- |
| source | String,Object,Endpoint | 是 | 连线源的标识,可以是id, element, 或者Endpoint |
| target | String,Object,Endpoint | 是 | 连线目标的标识,可以是id, element, 或者Endpoint |
| endpoint | String | 可选 | 端点类型,形状 |
[>>> connect方法详情](https://github.com/jsplumb/jsplumb/blob/da6688b86fbfba621bf3685e4431a4d9be7213b4/doc/api/jsplumb-api.js#L76)
## 2.2. 可拖动节点
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/02.html
使用draggable可以让节点被拖动,[draggable方法参考](https://github.com/jsplumb/jsplumb/blob/da6688b86fbfba621bf3685e4431a4d9be7213b4/doc/api/jsplumb-api.js#L690)

```
```
## 2.3. 连接的其他参数
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/03.html
可以通过connector去设置连接线的形状,如直线或者曲线之类的。anchor可以去设置锚点的位置。
jsplumb连线的样式有四种
- `Bezier`: 贝塞尔曲线
- `Flowchart`: 具有90度转折点的流程线
- `StateMachine`: 状态机
- `Straight`: 直线

```
```
## 2.4. 设置连接的默认值
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/04.html
很多连线都是相同设置的情况下,可以将配置抽离出来,作为一个单独的变量,作为connect的第二个参数传入。实际上connect的第二个参数会和第一个参数merge,作为一个整体。
```
```
## 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有五种类型,下面给出简介。具体使用方法参见 http://jsplumb.github.io/jsplumb/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方法可以用来增加端点,[具体使用请看](https://github.com/jsplumb/jsplumb/blob/da6688b86fbfba621bf3685e4431a4d9be7213b4/doc/api/jsplumb-api.js#L57)

```
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)
})
```
`一般来说拖动创建的连接,可以再次拖动,让连接断开。如果不想触发这种行为,可以设置。`
```js
jsPlumb.importDefaults({
ConnectionsDetachable: false
})
```
`如果你需要在连接被拖动建立后,更新数据模型,则需要订阅connection事件`, 回调函数的info对象里,有你所需的任何数据。比如说从哪个节点拖动到哪个节点的。
关于事件,可以参考事件章节。
```js
jsPlumb.bind("connection", function(info, originalEvent) {
.. update your model in here, maybe.
});
```
## 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 方法去改变。

```
```
## 2.11. 限制节点拖动区域
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/11.html
默认情况下,节点可以被拖动到区域外边,如果想只能在区域内拖动,需要设置containment,这样节点只能在固定区域内移动。
实际上上这个功能是使用jQueryUI的功能,所以函数的使用可以参考jQueryUI的文档。https://jqueryui.com/draggable/#constrain-movement

```
jsPlumb.draggable('item_left', {containment: 'parent'})
jsPlumb.draggable('item_right', {containment: 'parent'})
jsPlumb.draggable('some-id', {containment: "#containment-wrapper"})
```
## 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(./images/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://github.com/jsplumb/jsplumb/blob/da6688b86f/doc/wiki/events.md
## 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方法有些情况下是无法删除干净连线的,[详情](https://github.com/jsplumb/jsplumb/blob/da6688b86fbfba621bf3685e4431a4d9be7213b4/doc/api/jsplumb-api.js#L648)
## 2.15. 通过编码连接endPoint
demo: https://wdd.js.org/jsplumb-chinese-tutorial/demos/15.html

初始化数据后,给节点加上了endPoint, 如果想编码让endPoint连接上。需要在addEndpoint时,就给该断点加上一个uuid, 然后通过connect()方法,将两个断点连接上。建议使用[node-uuid](https://github.com/kelektiv/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. 一个端点如何拖拽出多条连线
demo https://wdd.js.org/jsplumb-chinese-tutorial/demos/17.html
默认情况下,`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://github.com/jsplumb/jsplumb/blob/da6688b86f/doc/wiki/anchors.md
```
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事件列表
## 3.1. 常用事件
具体事件中回调函数中参数的字段含义,参见
绑定事件的方式, 以connection事件为例子
```js
jsPlumb.bind("connection", function(info) {
.. update your model in here, maybe.
});
```
### 3.1.1. connection 连接建立时触发
`connection(info, originalEvent)`
- info.connection
- info.sourceId
- info.targetId
- info.source
- info.target
- info.sourceEndpoint
- info.targetEndpoint
- originalEvent: 原始事件。只有用户拖动创建的连接,originalEvent才存在。
**注意事项**:通过编码连接节点,也会触发connection事件,如果只想处理用户拖动创建建立的连接,可以判断第二个参数originalEvent是否存在。
### 3.1.2. connectionDetached 连接断开时触发
`connectionDetached(info, originalEvent)`
- info.connection
- info.sourceId
- info.targetId
- info.source
- info.target
- info.sourceEndpoint
- info.targetEndpoint
- originalEvent
**注意事项**:当拖动一个连线出现后,却没有连接到目标端点就放弃时,不会触发connectionDetached事件,会触发connectionAborted事件
### 3.1.3. connectionMoved 连接移动事件
`connectionMoved(info, originalEvent)`
### 3.1.4. connectionAborted 连接取消事件
`connectionAborted(connection, originalEvent)`
### 3.1.5. click 连接点击事件
`click(connection, originalEvent)`
### 3.1.6. dblclick 连接双击事件
`dblclick(connection, originalEvent)`
### 3.1.7. connectionDrag 连接拖动事件
`connectionDrag(connection)`
### 3.1.8. connectionDragStop 连接停止拖动事件
`connectionDragStop(connection)`
### 3.1.9. endpointClick 端点单击事件
`endpointClick(endpoint, originalEvent)`
### 3.1.10. endpointDblClick 端点双击事件
`endpointDblClick(endpoint, originalEvent)`
### 3.1.11. contextmenu 鼠标右键事件
`contextmenu(component, originalEvent)`
### 3.1.12. beforeDrop 连接建立前事件
`beforeDrop(info)` 注意如果这个回调函数返回false, 那么连接将不会被建立,可以用来连接建立的拦截
### 3.1.13. beforeDetach 连接断开前事件
`beforeDetach(connection)`
### 3.1.14. zoom 缩放事件
`zoom(value)`
## 3.2. 其他事件
### 3.2.1. Connection Events
在获得一个连接后,可以单独给某个连接绑定事件
```js
var connection = jsPlumb.connect({source:"d1", target:"d2"});
connection.bind("click", function(conn) {
console.log("you clicked on ", conn);
});
```
当获取到连接后,连接还可以绑定其他事件
- click(connection, originalEvent) - notification a Connection was clicked.
- dblclick(connection, originalEvent) - notification a Connection was double-clicked.
- contextmenu(connection, originalEvent) - a right-click on the Connection.
- mouseover(connection, originalEvent) - notification the mouse is over the Connection's path.
- mouseout(connection, originalEvent) - notification the mouse has exited the Connection's path.
- mousedown(connection, originalEvent) - notification the mouse button was pressed on the Connection's path.
- mouseup(connection, originalEvent) - notification the mouse button was released on the Connection's path.
### 3.2.2. Endpoint Events
```js
var endpoint = jsPlumb.addEndpoint("d1", { someOptions } );
endpoint.bind("click", function(endpoint) {
console.log("you clicked on ", endpoint);
});
```
- click(endpoint, originalEvent) - notification an Endpoint was clicked.
- dblclick(endpoint, originalEvent) - notification an Endpoint was double-clicked.
- contextmenu(endpoint, originalEvent) - a right-click on the Endpoint.
- mouseover(endpoint, originalEvent) - notification the mouse is over the Endpoint.
- mouseout(endpoint, originalEvent) - notification the mouse has exited the Endpoint.
- mousedown(endpoint, originalEvent) - notification the mouse button was pressed on the Endpoint.
- mouseup(endpoint, originalEvent) - notification the mouse button was released on the Endpoint.
- maxConnections(info, originalEvent) - notification the user tried to drop a Connection on an Endpoint that already has the maximum number of Connections. info is an object literal containing these values:
- info.endpoint : Endpoint on which the Connection was dropped
- info.connection : The Connection the user tried to drop
- info.maxConnections : The value of maxConnections for the Endpoint
### 3.2.3. Overlay Events
可以把Overlay理解为连线上的文字或者图标,可以给这些overlays单独绑定事件。
```
jsPlumb.connect({
source:"el1",
target:"el2",
overlays:[
[ "Label", {
events:{
click:function(labelOverlay, originalEvent) {
console.log("click on label overlay for :" + labelOverlay.component);
}
}
}],
[ "Diamond", {
events:{
dblclick:function(diamondOverlay, originalEvent) {
console.log("double click on diamond overlay for : " + diamondOverlay.component);
}
}
}]
]
});
```
# 4. jsPlumb默认配置简介
参考地址: https://github.com/jsplumb/jsplumb/blob/da6688b86f/doc/wiki/defaults.md
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` 渲染模式,默认是svg
- `Scope` 作用域,用来区分哪些端点可以连接,作用域相同的可以连接
```
// 可以使用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" }]
});
```
# 5. 工具函数
## 5.1. 重绘某个元素 jsPlumb.revalidate
```js
jsPlumb.revalidate(el)
```
关于 el:
- a string, representing the id of some element
- a list of strings, representing the ids of some elements
- a DOM element
- a list of DOM elements
- a selector from your underlying library
## 5.2. 重绘所有元素 jsPlumb.repaintEverything
```js
jsPlumb.repaintEverything()
```
## 5.3. 重设节点ID jsPlumb.setId
节点的ID对jsPlumb的重要性不言而喻,有时候我们需要改变节点的id, 那么需要显式的告诉jsPlumb节点id改变了。
```js
jsPlumb.setId(el, newId);
// 或者
jsPlumb.setIdChanged(oldId, newId);
```
## 5.4. 删除节点 jsPlumb.remove
```js
var conn = jsPlumb.connect({source:"element1", target:"element2"});
...
jsPlumb.remove("element1");
```
## 5.5. 清空所有节点连接和端点 jsPlumb.empty
```js
var conn = jsPlumb.connect({source:"one", target:"someOtherElement"});
...
jsPlumb.empty("list");
```
## 5.6. 移除连线 jsPlumb.detach
```js
var conn = jsPlumb.connect({ some params});
...
jsPlumb.detach(conn);
```
## 5.7. 移除某个节点上的所有连线 jsPlumb.deleteConnectionsForElement
```js
jsPlumb.deleteConnectionsForElement(el, [params])
```
## 5.8. 移除所有节点上的连线 jsPlumb.deleteEveryConnection()
```js
jsPlumb.deleteEveryConnection()
```
## 5.9. 移除某个节点上的端点
```js
var ep = jsPlumb.addEndpoint(someElement, { ... });
...
jsPlumb.deleteEndpoint(ep);
```
## 5.10. 移除所有节点上的端点
```js
jsPlumb.deleteEveryEndpoint();
```
## 5.11. 元素的显示与隐藏
```js
jsPlumb.hide("window5"); // 隐藏节点的所有连线
jsPlumb.hide("window5", true); // 隐藏节点的所有端点
jsPlumb.show("window5"); // 显示节点的所有连线
jsPlumb.toggleVisible("window5"); // 反转显示节点的连线
jsPlumb.show("window5", true); // 显示节点的所有连线和端点
```
# 6. 样式修改
## 6.1. 通过css添加样式
参考:http://jsplumb.github.io/jsplumb/styling-via-css.html
## 6.2. paintStyle属性添加
参考:http://jsplumb.github.io/jsplumb/paint-styles.html
```js
jsPlumb.connect({
source:"el1",
target:"el2",
paintStyle:{ stroke:"blue", strokeWidth:10 }
});
```
# 7. 查询 [todo]
# 8. 视图与数据结构同步
**首先,jsplumb并不维护你的数据结构。** 你的数据结构你自己维护,如果页面发生改变,jsplumb会通过事件通知你。你通过事件去改变你的数据。
熟悉react或者vue的,会有点熟悉,这不就是单向数据流吗?
1. 通过渲染逻辑将基本数据结构渲染成连线图
2. 连线图发生改变,如发生连线之类的,jsplumb会通过事件告诉你
3. 你需要处理jsplumb给你的事件,然后修改你的基本数据

```js
[
{
id: 1,
link: ''
},
{
id: 2,
link: ''
}]
```
当你收到连接建立事件后,例如1连接到了2, 你需要修改这个数据结构。
```js
[
{
id: 1,
link: '2'
},
{
id: 2,
link: ''
}]
```
# 9. 有没有稍微复杂一点,带有拖放的栗子?
项目地址:https://github.com/wangduanduan/visual-ivr
在线demo: https://wdd.js.org/visual-ivr/

上图是基于jsplumb做的最基础的demo版本。
下图是是最近优化后的版本

******
模仿官网database-visualizer实现sqlflow数据血缘流程图的demo
项目地址:https://github.com/mizuhokaga/jsplumb-dataLineage

# 10. 还有哪些类似的图形连线可视化项目
## 10.1. G6 AntV
https://github.com/antvis/g6

## 10.2. VivaGraphJS
https://github.com/anvaka/VivaGraphJS


## 10.3. springy
https://github.com/dhotson/springy

## 10.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的绘图




## 10.5. visjs
http://visjs.org/index.html
该项目看起来不错,github上将近有7000 star, 但是它的开发者似乎没时间维护该项目了,正在给该项目找下家。

# 11. 参考资源
- [官方文档](http://jsplumb.github.io/jsplumb/home.html)
# jsPlumb 基本概念
------
## 一、默认属性
- `Anchor`:锚点(连接点位置),可以设置在任何没有锚点的目标上(`endPoint`)
- `Anchors`:设置在connect的源和目标点的连接点位置,默认是 `BottomCenter`
- `Connector`:连接线(比如:`["Bezier", {curviness: 63}]`为贝塞尔曲线)
- `ConnectionsDetachable`:是否在连接点可以用鼠标拖动[`true/false`]
- `Container`:容器
- `DoNotThrowErrors`:设置当锚点(`Anchor`)、端点(`endPoint`)和连接器(`Connector`)不存在的时候是否抛出异常
- `ConnectionOverlays`:默认覆盖附着在每个连接器
- `DragOptions`:为 被 `jsPlumb.draggable` 设置了拖拽的元素拖拽时设置的css样式.eg:
hoverClass: "dropHover",//释放时指定鼠标停留在该元素上使用的css class;
activeClass: "dragActive"//可拖动到的元素使用的css class
- `Endpoint`: 端点的形状定义,比如圆:`[ "Dot", { radius:5 } ]`;正方形:`Rectangle`
- `Endpoints`:设置了连接器的源和目标端点的形状,eg圆: `[ [ "Dot", { radius:7 } ], [ "Dot", { radius:11 } ] ]`
- `EndpointOverlays`:默认覆盖附着在每个端点
- `EndpointStyle`:端点的默认样式
- `EndpointStyles`:设置了连接器的源和目标端点的样式
- `EndpointHoverStyle`:端点的hover状态样式
- `EndpointHoverStyles` :设置了连接器的源和目标端点端点的hover状态样式
- `HoverPaintStyle` :
- `LogEnabled`:jsPlumb内部日志是否开启。
- `Overlays`:默认覆盖连接器和端点样式,装饰连接器,如标签、箭头等
- `MaxConnections` :设置连接点最多可以连接几条线
- `PaintStyle` :设置连接点的样式
- `connectorStyle`:设置连接线样式
- `ReattachConnections` :
- `RenderMode` :默认渲染模式
- `Scope`:连接点的标识符,只有标识符相同的连接点才能连接
## 二、锚点(Anchor)
### 1 . 默认锚位置:
- Top (TopCenter)
- TopRight
- Right (RightMiddle)
- BottomRight
- Bottom (BottomCenter)
- BottomLeft
- Left (LeftMiddle)
- TopLeft
- Center
eg:
```cpp
//定义了一个在底部中间的锚点位置
jsPlumb.connect({...., anchor:"Bottom", ... });
```
### 2 . 基于数组的语法 [x,y,dx,dy]
- x-相对该锚点在x轴坐标比例(最大1)
- y-相对该锚点y轴坐标比例(最大1)
- dx-控制锚的方向
- dy-同上
eg:
```cpp
//定义了一个在底部中间的锚点位置
jsPlumb.connect({...., anchor:[ 0.5, 1, 0, 1 ], ... });
```
如果锚点位置无法满足你的需求,还可以设置锚点的偏移量[x,y,dx,dy,offSetX,offSetY] ,下面设置了Y轴偏移50px,锚点Y坐标会+50px:
```undefined
jsPlumb.connect({...., anchor:[ 0.5, 1, 0, 1, 0, 50 ], ... });
```
### 3 . 动态锚
- 数组定义
没有特殊的语法来创建一个动态锚;可以提供一个静态数组锚规格,如:
```csharp
var dynamicAnchors = [ [ 0.2, 0, 0, -1 ], [ 1, 0.2, 1, 0 ], [ 0.8, 1, 0, 1 ], [ 0, 0.8, -1, 0 ] ];
jsPlumb.connect({...., anchor:dynamicAnchors, ... });
```
或者组合:
```csharp
var dynamicAnchors = [ [ 0.2, 0, 0, -1 ], [ 1, 0.2, 1, 0 ], "Top", "Bottom" ];
jsPlumb.connect({...., anchor:dynamicAnchors, ... });
```
这样锚点会根据位置自动调整到最合适的位置(定义的数组里几个点中)
- 默认定义
jsPlumb提供了一个动态锚 `AutoDefault` 选择从 前 , 右 , 底 和 左 :
```bash
jsPlumb.connect({...., anchor:"AutoDefault", ... });
```
### 4 . 多边形锚
- Circle(圆)
- Ellipse(椭圆)
- Triangle(三角形)
- Diamond(菱形)
- Rectangle(矩形)
- Square(正方形)
#### (1) 单个多边形
eg:
```css
jsPlumb.addEndpoint("someElement", {
endpoint:"Dot",
anchor:[ "Perimeter", { shape:"Circle" } ]
});
```
如果锚点的宽高一样,该锚点位置为动态圆周。宽高不同为椭圆,类似正方形和矩形。
默认情况下,锚点个数为60,我们还可以手动指定:
eg(指定150个动态锚点):
```css
jsPlumb.addEndpoint("someDiv", {
endpoint:"Dot",
anchor:[ "Perimeter", { shape:"Square", anchorCount:150 }]
});
```
#### (2) 组合锚点(三角形与菱形):
```css
jsPlumb.connect({
source:"someDiv",
target:"someOtherDiv",
endpoint:"Dot",
anchors:[
[ "Perimeter", { shape:"Triangle" } ],
[ "Perimeter", { shape:"Diamond" } ]
]
});
```
#### (3) 自定义角度多边形锚点
```css
jsPlumb.connect({
source:"someDiv",
target:"someOtherDiv",
endpoint:"Dot",
anchors:[
[ "Perimeter", { shape:"Triangle", rotation:25 } ],
[ "Perimeter", { shape:"Triangle", rotation:-335 } ]
]
});
```
上面定义了两个三角形旋转不同角度得到的组合图形(旋转适用带角度的多边形)。
### 5. CSS类和锚点
#### (1)介绍
锚点的不同位置可以有多种css样式,那就要有不同的css类提供支持。
被写入到锚点的CSS类和元素与jsPlumb实例相关联的前缀默认的前缀:
```undefined
jsplumb-endpoint-anchor-
```
eg:
```csharp
var ep = jsPlumb.addEndpoint("someDiv", {
anchor:[0.5, 0, 0, -1, 0, 0, "top" ]
};
```
jsPlumb将会分配这个类给创建的 `endpoint` 和元素 `someDiv`:
```undefined
jsplumb-endpoint-anchor-top
```
#### (2)示例
一个使用动态锚的例子:
```csharp
var ep = jsPlumb.addEndpoint("someDiv", {
anchor:[
[ 0.5, 0, 0, -1, 0, 0, "top" ],
[ 1, 0.5, 1, 0, 0, 0, "right" ]
[ 0.5, 1, 0, 1, 0, 0, "bottom" ]
[ 0, 0.5, -1, 0, 0, 0, "left" ]
]
});
```
这里的类分配给端点和元素循环这些值作为锚位置的变化:
```swift
jsplumb-endpoint-anchor-top
jsplumb-endpoint-anchor-right
jsplumb-endpoint-anchor-left
jsplumb-endpoint-anchor-bottom
```
如果您提供多个类名,jsPlumb不会预先考虑类中的每个词的前缀:
```csharp
var ep = jsPlumb.addEndpoint("someDiv", {
anchor:[ 0.5, 0, 0, -1, 0, 0, "foo bar" ]
});
```
会导致2个类被添加到端点和元素:
```undefined
jsplumb-endpoint-anchor-foo 和 bar
```
#### (3)改变锚类前缀
前缀 `endpointAnchorClass` 用于锚类存储为jsPlumb的成员,这个前缀是可更改的:
```bash
jsPlumb.endpointAnchorClass = "anchor_";
```
或者
```csharp
var jp = jsPlumb.getInstance();
jp.endpointAnchorClass = "anchor_";
```
## 三、连接线(器)(Connectors)
### 1. 简介
jsPlumb提供了四种连接线:
- `straight`(直线)
- `Bezier`(贝塞尔曲线)
- `flowchart`(流程图)
- `state machine`
### straight
在两个端点之间画一条直线。 它支持两个构造函数参数:
- `stub`:可选的,默认值为0。此参数的任何正值将导致在与连接线的两端产生一段不可改变方向的线段
- `gap`:可选,默认为0像素。在连接线的一端和连接的元素之间指定一个间隙。
### Bezier
贝塞尔提供了一个立方的贝塞尔曲线。 它支持一个构造函数参数:
- `curviness`:参数可选,默认为150。 定义了曲线的弯曲程度。
### flowchart
垂直或水平的连接线,提供了四个参数:
- `stub`:这是最小长度,以像素为单位,最初的存根,源自一个端点。这是一个可选的参数,并且可以是一个整数,它指定了连接器的每个末端的存根,或是一个整数数组,指定[源目标]端点的连接。默认值为30像素的整数
- `alwaysRespectStubs` :可选,默认为false。
- `gap`:可选,默认为0像素。在连接线的一端和连接的元素之间指定一个间隙。
- `midpoint`:可选,默认为0.5。这是一个流程图中最长的部分将被绘制的2个元素之间的距离。
- `cornerRadius`:默认为0。此参数的正值将改变弯角的度数。
### state machine
略微弯曲的线(实际上是二次Bezier曲线),类似于状态机的连接器,支持的构造函数参数:
- `margin`:可选;默认为5。定义连接线开始/结束的元素的距离。
- `curviness`:可选的,默认为10,定义了曲线的弯曲程度。
- `proximityLimit` : 可选,默认为80。 连接线的两端之间的最小距离 它描绘为一条直线而非二次贝塞尔曲线。
## 四、端点(Endpoints)
### 简介
端点是连接里的一个端点外观和行为表现的集合,jsPlumb实现了四个端点:
- Dot(点)
- Rectangle(矩形)
- Blank(空)
- image(图像)
### 创建
有不同的方式创建 `endpoint`:
#### (1)connect
并通过一个元素id或DOM元素作为源/目标,创建并分配一个新的端点
eg:
```css
jpInstance.connect({
source: "state1",
target: "state2",
scope: "state3"
});
```
#### (2)addEndpoint
创建一个新的端点
```bash
jpInstance.addEndpoint("myDivId", EndpointConfig)
```
#### (3)makeSource()
```css
jpInstance.makeSource(...)
```
### 类型
#### (1)Dot
就是在屏幕上画一个点,它支持三个构造函数参数:
- `radius`:可选,默认为10像素。 定义点的半径
- `cssClass` :可选,端点元素的CSS类。
- `hoverClass` 可选的,元素或连线的hover属性样式类
#### (2)Rectangle
绘制一个矩形。 支持构造函数参数有:
- `width`:可选的,默认为20像素。定义矩形的宽度。
- `height`:可选的,默认为20像素。定义矩形的高。
- `cssClass` :可选的,端点元素的CSS类。
- `hoverClass` :可选的,元素或连线的hover属性样式类
#### (3)Image
从一个指定的URL加载图像,这个端点支持三种构造函数参数:
- `src`:图片的url
- `cssClass` :可选的,端点元素的CSS类。
- `hoverClass` :可选的,元素或连线的hover属性样式类
## 五、覆盖(连接元素)(Overlays)
### 简介
jsPlumb带有五个类型的覆盖图:
- Arrow(箭头) :一个可配置的箭头,在某些点上涂上了一个可配置的箭头。你可以控制箭头的长度和宽度,“折返”点一点尾巴分折回来,和方向(允许值为1和1;1是默认的,意味着在连接点方向)
- Label(标签):一个可配置的连线标签
- PlainArrow(平原箭头):没有监听的三角形箭头
- Diamond(钻石):钻石箭头
- Custom(自定义):可自定义DOM元素
### 位置
位置表明连接元素在连接线的位置,通常有三种表明方式:
- [0 . . 1]范围内的十进制数,表明在连接线的位置比例,默认0.5
- [1 . . . ] (>1)的数字表明沿着连接线的绝对路径的像素
- 小于零的整数数组:
(1):指定一个覆盖在端点的中心位置:
```css
location:[ 0.5, 0.5 ]
```
(2):沿着x轴从左上角叠加5像素
```css
location: [ 5, 0 ]
```
(3):沿着x轴从右下角叠加放置5像素
```css
location: [ -5, 0 ]
```
对于位置的操作,jsPlumb提供了两个方法:
- getLocation ——返回当前位置
- setLocation ——设置当前位置
### 使用
使用场景(出现以下调用的时候):
- `jsPlumb.connect`
- `jsPlumb.addEndpoint`
- `jsPlumb.makeSource`
注: 没有 `jsPlumb.makeTarget`
#### 1. 在 `jsPlumb.connect` 被调用时使用
(1). 下面指定了 一个默认配置的箭头和一个文字为foo的标签文本:
```csharp
jsPlumb.connect({
...
overlays:[
"Arrow",
[ "Label", { label:"foo", location:0.25, id:"myLabel" } ]
],
...
});
```
此连接的箭头在连接线的中间,lable标签则是在连接线的四分之一处;这里添加了一个id,它可以在以后移除或修改标签时使用。
(2). 箭头位置位于连接线距离50像素(绝对位置):
```csharp
jsPlumb.connect({
...
overlays:[
"Arrow",
[ "Label", { label:"foo", location:50, id:"myLabel" } ]
],
...
});
```
#### 2. 在 `jsPlumb.addEndpoint` 被调用时使用
此连接将有10x30像素箭坐落在连接头,标签“foo”则位于中点。端点本身也有一个覆盖,位于[ - 0.5 *宽,- 0.5 *高]相对于端点的左上角。
```csharp
jsPlumb.addEndpoint("someDiv", {
...
overlays:[
[ "Label", { label:"foo", id:"label", location:[-0.5, -0.5] } ]
],
connectorOverlays:[
[ "Arrow", { width:10, length:30, location:1, id:"arrow" } ],
[ "Label", { label:"foo", id:"label" } ]
],
...
});
```
注:在addEndpoint 使用 `connectorOverlays` 代替 `overlays`,因为 `overlays`指向端点覆盖。
#### 3. 在 jsPlumb.makeSource
同样使用 `connectorOverlays`,而且 `makeSource` 支持 `endpoint` 参数。
此连接将有10x30像素箭坐落在连接头,标签“foo”位于中点。
```csharp
jsPlumb.makeSource("someDiv", {
...
endpoint:{
connectorOverlays:[
[ "Arrow", { width:10, length:30, location:1, id:"arrow" } ],
[ "Label", { label:"foo", id:"label" } ]
]
}
...
});
```
#### 4. `addOverlay` 方法
`Endpoints` 和 `Connections` 都有一个方法: `addOverlay`,它提供一个单一的方法定义一个 覆盖(Overlays):
```csharp
var e = jsPlumb.addEndpoint("someElement");
e.addOverlay([ "Arrow", { width:10, height:10, id:"arrow" }]);
```
### Overlay Types(覆盖类型)
#### 1. Arrow(箭头)
一个箭头 使用四个点:头、两个尾点和一个foldback(监听),它允许箭头的箭尾缩进。此覆盖的可用构造函数参数:
- width:宽度
- length:长度
- location:在连接线上的位置
- direction:默认1-向前,-1向后
- foldback:箭头沿轴到尾点的监听。默认是0.623
- paintStyle:`Endpoints` 和 `Connectors` 的样式对象
#### 2. PlainArrow(平原箭头)
这其实就是一个 foldback=1 的 Arror;继承Arror的构造函数
#### 3. Diamond(菱形)
这其实就是一个 foldback=2 的 Arror;继承Arror的构造函数
#### 4. Label(标签)
(1) 介绍
提供装饰连接器的文本标签。可用的构造函数参数是:
- label : 文本显示。 您可以提供一个函数,而不是纯文本:连接作为一个参数传递,它应该返回一个字符串。
- cssClass :可选的css类使用的标签。现在优先使用 labelStyle 参数。
- labelStyle : 可选参数标签的外观。 可用参数有:
- font :一种适用于画布元素的字体字符串
- fillStyle :标签的背景颜色填充,可选。
- color :字体颜色,可选
- padding :表示标签的宽度的比例,而不是px和ems。
- borderWidth :标签的边框宽度,默认0
- borderStyle :标签边框的样式,可选
- location :标签位置
(2). `getLabel` 和 `setLabel`
标签覆盖提供了两个方法 `getLabel` 和 `setLabel` 用于动态地get/set标签内容:
```swift
var c = jsPlumb.connect({
source:"d1",
target:"d2",
overlays:[
[ "Label", {label:"FOO", id:"label"}]
]
});
...
var label = c.getOverlay("label");
console.log("Label is currently", label.getLabel());
label.setLabel("BAR");
console.log("Label is now", label.getLabel());
```
这个例子里,标签被赋予一个id ‘label’,然后检索这个id动态设置lable的值。
Connections 和 Endpoints 都支持 标签覆盖:
```tsx
var conn = jsPlumb.connect({
source:"d1",
target:"d2",
label:"FOO"
});
...
console.log("Label is currently", conn.getLabel());
conn.setLabel("BAR");
console.log("Label is now", conn.getLabel());
```
(3). 动态设置label
```jsx
var conn = jsPlumb.connect({
source:"d1",
target:"d2"
});
...
conn.setLabel(function(c) {
var s = new Date();
return s.getTime() + "milliseconds have elapsed since 01/01/1970";
});
console.log("Label is now", conn.getLabel());
```
#### 5. Custom(自定义)
jsPlumb允许自定义一个 OverLays,你只需要实现 create(component):
```jsx
var conn = jsPlumb.connect({
source:"d1",
target:"d2",
paintStyle:{
strokeStyle:"red",
lineWidth:3
},
overlays:[
["Custom", {
create:function(component) {
return $("");
},
location:0.7,
id:"customOverlay"
}]
]
});
```
注意 此处的id为 `customeOverlay` ,你可以在 Connection 或者 Endpoint上使用 `getOverlay(id)` 方法。
### 隐藏/显示 Overlays(覆盖)
可以使用 `setVisible` 方法控制 `Overlays` 的显示属性,或者在一个连接上使用 `showOverlay(id)` 和 `hideOverlay(id)`。
(1). 使用id:
```dart
var connection = jsPlumb.connect({
...
overlays:[
"Arrow",
[ "Label", { label:"foo", location:0.25, id:"myLabel" } ]
],
...
});
// time passes
var overlay = connection.getOverlay("myLabel");
// now you can hide this Overlay:
overlay.setVisible(false);
// there are also hide/show methods:
overlay.show();
overlay.hide();
```
(2). 使用 `showOverlay(id)` 和 `hideOverlay(id)`:
Connection 和 Endpoint 可以使用`showOverlay(id)` 和 `hideOverlay(id)`:
```csharp
var connection = jsPlumb.connect({
...
overlays:[
"Arrow",
[ "Label", { label:"foo", location:-30 , id:"myLabel" }]
],
...
});
// time passes
connection.hideOverlay("myLabel");
// more time passes
connection.showOverlay("myLabel");
```
### 删除 Overlays(覆盖)
```csharp
var connection = jsPlumb.connect({
...
overlays:[
"Arrow",
[ "Label", { label:"foo", location:0.25 , id:"myLabel"} ]
],
...
});
// time passes
connection.removeOverlay("myLabel");
```
链接:https://www.jianshu.com/p/0e7bb5c081c8
##### jsPlumb事件
要在jsPlumb本身(或jsPlumb实例)上绑定事件,请使用jsPlumb.bind(event, callback)
```jsx
jsPlumb.bind("connection", function(info) {
.. update your model in here, maybe.
});
```
可以在jsPlumb类上绑定的事件:
###### connection(info, originalEvent)- 通知连接建立
info具有的属性:
- `connection`: 新连接,可以注册监听
- `sourceId`: 连接的源元素id
- `targetId`: 连接的目标元素id
- `source`: 连接的源元素
- `target`: 连接的目标元素
- `sourceEndpoint`: 连接的源端点
- `targetEndpoint`: 连接的目标端点
originalEvent:建立连接的原始鼠标事件。
`注: jsPlumb.connect或者鼠标连线时触发此事件`
###### connectionDetached(info,originalEvent)- 通知连接断开
info具有的属性:
- `connection`: 已分离的连接
- `sourceId`: 分离之前连接的源元素id
- `targetId`: 分离之前连接的目标元素id
- `source`: 分离之前连接的源元素
- `target`: 分离之前连接的目标元素
- `sourceEndpoint`: 分离之前连接的源端点
- `targetEndpoint`: 分离之前连接的目标端点
连接到某个节点之前放弃新拖动的Connection时不会触发此事件,可以使用connectionAborted捕获。
originalEvent:断开连接的原始鼠标事件。
###### connectionMoved(info,originalEvent)- 通知已将现有连接的源或目标端点拖动到某个新位置
info具有的属性:
- `index`: 源端点为0,目标端点为1
- `originalSourceId`: 移动前连接的源元素id
- `newSourceId`: 移动后连接的源元素id
- `originalTargetId`: 移动前连接的目标元素id
- `newTargetId`: 移动后连接的目标元素id
- `originalSourceEndpoint`: 移动前的源端点
- `newSourceEndpoint`: 移动后的源端点
- `originalTargetEndpoint`: 移动前的目标端点
- `newTargetEndpoint`: 移动后的目标端点
###### connectionAborted(connection,originalEvent)在连接到端点或目标元素之前放弃拖动连接时触发
###### connectionDrag(connection)- 正在拖动现有连接
```
注:当此事件触发时,连接的目标端点是jsPlumb用于拖动的瞬态元素,随后在建立或中止连接时将从DOM中删除。
```
###### connectionDragStop(connection)- 连接拖动结束
###### click(connection, originalEvent)- 单击连接
###### dblclick(connection, originalEvent)- 双击连接
###### endpointClick(connection, originalEvent)- 单击端点
###### endpointDblClick(connection, originalEvent)- 双击端点
###### contextmenu(connection, originalEvent)- 右键单击某个给定组件jsPlumb将报告对Connections和Endpoints的右键单击
###### beforeDrop(info)- 删除新连接或现有连接时触发此事件
info具有的属性:
- `index`: 源端点为0,目标端点为1
- `sourceId`: 连接的源元素id
- `targetId`: 连接的目标元素id
- `scope`: 连接的范围
- `connection`: 实际的Connection对象。可以访问Connection中的“端点”数组,以获取连接中涉及的端点,但注意,在拖动连接时,目标端点将始终是仅在拖动的生命周期内存在的瞬态端点。要获取正在删除的连接端点,请使用dropEndpoint。
- `dropEndpoint`: 这是删除连接的实际端点。可能为null,因为如果在已调用makeTarget的元素上删除Connection,则不会设置它
- `targetEndpoint`: 分离之前Connection中的目标端点
###### beforeDetach(connection)- 断开连接时触发此事件。connection参数为刚断开的Connection。如果此拦截器返回false将会中止连接断开。
###### beforeDrag(connection)- 开始拖动新连接时触发此事件。
- `endpoint`: 拖动连接的端点
- `source`: 端点所属的源
- `sourceId`: 端点所属的源ID
`beforeDrag`与其他拦截器的操作略有不同:从拦截器函数返回false将取消当前拖动,也可以从拦截器返回一个对象,此对象将作为`data`被传进新连接的构造函数中:
```jsx
jsPlumbInstance.bind("beforeDrag", function(params) {
return {
foo:"bar"
}
});
```
如果已定义参数化连接类型,此功能特别有用。使用此机制,可以使用选择的数据填充新拖动的连接。
`注: 1.7.6之前的所有jsPlumb版本,新的连接拖动以及拖动现有的连接都会触发beforeDetach。从1.7.6开始,后一种行为已被移至 beforeStartDetach拦截器。`
###### beforeStartDetach(connection)- 开始拖动现有连接时触发此事件。
- `endpoint`: 拖动连接的端点
- `source`: 端点所属的源
- `sourceId`: 端点所属的源ID
- `connection`: 即将被拖动的连接
返回false,取消拖动。
##### 连接事件
绑定到Connection上的事件,还可以使用以下bind方法:
```jsx
var connection = jsPlumb.connect({source:"d1", target:"d2"});
connection.bind("click", function(conn) {
console.log("you clicked on ", conn);
});
```
这些是可以绑定到连线事件:
- `click(connection, originalEvent)` - 单击连接。
- `dblclick(connection, originalEvent)` - 双击连接。
- `contextmenu(connection, originalEvent)` - 右键单击连线。
- `mouseover(connection, originalEvent)` - 鼠标放在连线上。
- `mouseout(connection, originalEvent)` - 鼠标移出连线。
- `mousedown(connection, originalEvent)` - 连接上的鼠标按钮被按下。
- `mouseup(connection, originalEvent)` - 连接上的鼠标按钮被释放。
##### 端点事件
绑定到端点上的事件,使用以下bind方法:
```jsx
var endpoint = jsPlumb.addEndpoint("d1", { someOptions } );
endpoint.bind("click", function(endpoint) {
console.log("you clicked on ", endpoint);
});
```
这些是可以绑定到端点的事件:
- `click(endpoint, originalEvent)` - 单击端点。
- `dblclick(endpoint, originalEvent)` - 双击端点。
- `contextmenu(endpoint, originalEvent)` - 右键单击端点。
- `mouseover(endpoint, originalEvent)` - 鼠标放在端点上。
- `mouseout(endpoint, originalEvent)` - 鼠标移出端点。
- `mousedown(endpoint, originalEvent)` - 端点上的鼠标按钮被按下。
- `mouseup(endpoint, originalEvent)` - 端点上鼠标按钮被释放。
- ```
maxConnections(info, originalEvent)
```
\- 在已具有最大连接数的端点上删除连接。
info具有的属性:
- endpoint:删除连线的端点
- connection:删除的连接
- maxConnections:端点的maxConnections值
##### 覆盖事件
在Overlay上注册事件侦听器是一个稍微不同的过程 - 将它们作为Overlay构造函数的参数。
以下是在Overlay上注册点击监听器的方法:
```jsx
jsPlumb.connect({
source:"el1",
target:"el2",
overlays:[
[ "Label", {
events:{
click:function(labelOverlay, originalEvent) {
console.log("click on label overlay for :" + labelOverlay.component);
}
}
}],
[ "Diamond", {
events:{
dblclick:function(diamondOverlay, originalEvent) {
console.log("double click on diamond overlay for : " + diamondOverlay.component);
}
}
}]
]
});
```
##### 解除绑定事件
在jsPlumb对象以及Connections和Endpoints上,可以使用unbind方法删除监听器。
```jsx
//取消绑定事件
jsPlumb.unbind("click");
或者
//解除所有事件
var e = jsPlumb.addEndpoint("someDiv");
e.bind("click", function() { ... });
e.bind("dblclick", function() { ... });
...
e.unbind("click");
```
链接:https://www.jianshu.com/p/c2c4f7fdffa1
## 连接方法 connect()
```dart
jsPlumb.connect({
source:'d1', //开始位置(id)
target:'js2', //结束位置(id)
endpoint:[ "Rectangle", { //点样式
cssClass:"myEndpoint",
width:1,
height:1
}],
/**
Dot{
radius,默认为10px,定义圆点的半径
cssClass,附加到Endpoint创建的元素的CSS类
hoverClass,一个CSS类,当鼠标悬停在元素或连接的线上时附加到EndPoint创建的元素
}
Rectangle{
width,默认为20,定义矩形的宽度
height,默认为20,定义矩形的高度
cssClass,附加到Endpoint创建的元素的CSS类
hoverClass,当鼠标悬停在元素或连接的线上时附加到EndPoint创建的元素
}
image{
src,必选,指定要使用的图像的URL,
cssClass,附加到Endpoint创建的元素的CSS类
hoverClass,当鼠标悬停在元素或连接的线上时附加到EndPoint创建的元素,
}从给定的URL中绘制图像
*/
connector:['Flowchart'], //连接线样式
/**
Bezier(curviness弯度=150,stub曲线离开始点距离=0): 贝塞尔曲线,
Flowchart(
stub两端的短截线的最小长度=30,
alwaysRespectStubs是否始终绘制端截线=false,
gap线和被连接元素之间间隙=0,
midpoint连接线位于短截线位置=0.5,
cornerRadius直角弧度=0): 具有90度转折点的流程线,
StateMachine(
curviness曲度=10,
margn线和被连接元素之间间隙=5,
proximityLimit最近距离限制=80,
loopbackRadius环回连接器的半径=25,
showLoopback连接线默认会跟着模块拖动改变=true,orientation="clockwise"环回连 clockwise顺时针:anticlockwise逆时针): 状态机(环回连就是被连接元素拖动时线绕着元素旋转),
Straight(
stub被连接元素沿生距离(直线)=0,
sourceStub仅适用于源端点的可选存根(基本无用不用管)
targetStub仅用于目标端点的可选存根(基本无用不用管)
gap端点和连接器的起点之间间隙=0
sourceGap仅限源端点的可选间隙(基本无用不用管)
targetGap仅限目标端点的可选间隙(基本无用不用管)
): 直线
*/
anchor :['TopCenter','BottomLeft'], //连接点样式
/**
Top,TopRight,TopLeft,Right,Bottom,BottomRight,BottomLeft,Left,center
[x,y,dx,dy,offsetX,offsetY]
x:点横轴的距离,
y:点纵轴的距离(0-1 .5居中),
dx dy表示射出线,0 -1 1,0没有线,
offsetX offsetY:点偏移量
*/
paintStyle: { stroke: '#c04f4f', strokeWidth: 3 ,dashstyle: "2"}, //线的宽度和颜色 dashstyle虚线
endpointStyle: { fill: '#ffffff', outlineStroke: 'darkgray', outlineWidth: 2 }, //端点默认样式
container :'ul', //父容器
overlays: [ ['Arrow', { width: 12, length: 12, location: 0.5 }] ],
/**
Arrow{
width,箭头尾部的宽度
length,从箭头的尾部到头部的距离
location,位置,建议使用0~1之间,当作百分比,便于理解
direction,方向,默认值为1(表示向前),可选-1(表示向后)
foldback,折回,也就是尾翼的角度,默认0.623,当为1时,为正三角
paintStyle,样式对象
}箭头
Label{
label,要显示的文本
cssClass,Label的可选css
labelStyle,标签外观的可选参数:font,适应canvas的字体大小参数;
color,标签文本的颜色;
padding,标签的可选填充,比例而不是px;
borderWidth,标签边框的可选参数,默认为0;
borderStyle,颜色等边框参数
location,位置,默认0.5
}在连接点的可配置标签,也可以使用getLabel,和setLabel,来获取和设置label的文本,可传函数
PlainArrow{同Arrow}箭头形状为三角形
Diamond{同Arrow}棱形
Custom:自定义
允许创建自定义的叠加层,需要使用create(),来返回DOM元素或者有效的选择器(ID)
overlays:[
["Custom", {
create:function(component) {
return $("");
},
location:0.7,
id:"customOverlay"
}]
]
*/
isSource:true, //创建可连接源(isSource,isTarget都为true就可以动态拖动连接了)
isTarget:true //注册连接源
maxConnections:1, //能连接的最大线数 如果-1就可以连无线条(但如果-1脸上的线就无法移除)
})
```
3.添加端点 addEndpoint()
```dart
jsPlumb.addEndpoint('item_left', {
anchors: ['Right']
},common)
```
第三参数为添加样式入参为集合内容和 2 中的参数名相同
4.改变尺寸(其实是使用的Jquery的方法)
```dart
$('.item').resizable({
resize: function (event, ui) {
jsPlumb.repaint(ui.helper)
}
})
```
5.限制可拖动区域
jsPlumb.setContainer('area-id') //id
6.拖动
```dart
jsPlumb.draggable('item_left', {
containment: 'parent',
grid: [10, 10] //会按10px的移动
})
```
原文链接:https://blog.csdn.net/shenqikai0319/article/details/86631797