一、Overlay的功能
叠层(Overlay)可以是任意的DOM元素,用于叠加在Connection或Endpoint元素上--绝大部分都是用于叠加在线条上。jsPlumb把Overlay分为了五类:Arrow
、Label
、PlainArrow
、Diamond
、Custom
。
除了Custom
和Label
类型,其他三类就是jsPlumb提供的可以直接使用的图形;Label
类型可以直接提供字符串文案,jsPlumb就可以生成对应的Overlay
并显示;而Custom
类型就是自定义DOM。
二、Overlay的使用
创建Overlay有多种方式:
创建连线时创建Overlay
jsPlumb.value.connect({
source: node1.value,
target: node2.value,
anchors: ['Right', 'Left'],
connector: StraightConnector.type,
overlays: [
{
type: 'Arrow',
options: {
location: 1,
},
},
{
type: 'PlainArrow',
options: {
location: 0.25,
},
},
{
type: 'Diamond',
options: {
location: 0.75,
id: 'diamondOverlay'
},
},
{
type: 'Label',
options: {
label: 'myLabel',
location: 0.5,
},
},
],
});
其中的location
属性就是设置Overlay在线条上位置。如果location在[0,1]
之间,代表的就是长度比例,例如0.5=中间,0.25=起始点1/4处,0.75=目的点1/4处,1=目的点;如果location>1
,就是到起始点的距离px。
属性id
就是给Overlay一个全局唯一ID,后续可以通过这个ID查询到该Overlay,从而进行操作--删除/更新等。
另外就是在创建Endpoint的时候可以使用connectorOverlays
参数来创建Overlay:
const endpoint3 = jsPlumb.value.addEndpoint(node3.value, {
source: true,
endpoint: 'Rectangle',
anchor: AnchorLocations.Right,
connectorOverlays: [
{ type: 'PlainArrow', options: { location: 1 } },
{ type: 'Label', options: { label: 'From Node3', id: 'node3-overlay' } },
],
});
const endpoint4 = jsPlumb.value.addEndpoint(node4.value, {
target: true,
endpoint: 'Dot',
anchor: AnchorLocations.Left,
});
但是这样配置的Overlay不是立刻创建并显示的,而是要等到以endpoint3为起始点进行连线的时候才会出来,也就是在连线的同时创建出Overlay。
并且如果把
connectorOverlays
配置到只能作为目的点的Endpoint的话是没用的。connectorOverlays
只能在source=true
时才会在连线时生效。
官方文档中说addEndpoint
的参数中可以使用overlays
来配置,实际使用中是不能使用overlays
参数的,只有connectorOverlays
可以使用。
还有就是jsPlumb的线条实例可以直接调用addOverlay来创建:
const conn_5_6 = jsPlumb.value.connect({
source: node5.value,
target: node6.value,
anchors: ['Top', 'Top'],
connector: 'Flowchart',
});
conn_5_6.addOverlay({
type: 'PlainArrow',
options: { location: 1 },
});
三、Overlay的配置
各种类型的Overlay都有一个配置参数就是location,指定Overlay所处的位置。而PlainArrow
和Diamond
都是一种Arrow
,就是某一项参数--foldback
的配置值不同而已。
Arrow有以下配置参数:
width
:设置箭头的宽度length
:设置箭头的长度。结合width
参数就可以用来设置箭头的大小。location
: 指定位置direction
: 指定箭头的方向,取值只能是1或-1
。1
代表向前(指向目的点),-1
代表向后(指向起始点)。foldback
: 设置一个数值,用于控制箭头的形状。
前四个参数的含义都很明确也很好理解,关于foldback
参数,用图解释:
图中的红色点,就是foldback
指定的数值。Arrow
类型foldback=0.623
,PlainArrow
类型foldback=1
,Diamond
类型foldback=2
。其实本质就是一个四边形,三个点固定,第四个点可以沿着对角线移动,从而可以形成不同的形状。
如果觉得jsPlumb提供的箭头不好看,就可以微调这个参数的值。因此PlainArrow
和Diamond
出了foldback
参数,其余可配参数与Arrow
一致。
Label类型
Label
类型的Overlay并不是图形,而是文案。因此配置项不同:
label
:指定文案内容。cssClass
:配置Overlay样式。(官方文档中说建议使用labelStyle
配置,但没有找到哪里可以使用labelStyle
)location
:指定Overlay的位置。
const conn_7_8 = jsPlumb.value.connect({
source: node7.value,
target: node8.value,
connector: 'Flowchart',
anchors: ['Top', 'Top'],
overlays: [
{
type: 'Label',
options: {
location: 0.3,
label: 'Label1',
cssClass: 'label-e1',
id: 'lab1',
},
},
{
type: 'Label',
options: {
location: 0.6,
label: 'Label2',
labelStyle: { color: 'blue' },
id: 'lab2',
},
},
],
});
.label-e1 {
color: red;
padding: 4px;
background-color: blue;
height: 40px;
}
官方文档中写的,通过Overlay实例可以调用setLabel()和getLabel()方法,在实际jsPlumb的overlay.d.ts源代码中,Overlay实例并没有提供这两个API。
由于在连线上创建Label是非常常用的,jsPlumb提供了更加简便的创建Label的方式:
const conn_7_8_1 = jsPlumb.value.connect({
source: node7.value,
target: node8.value,
connector: 'Flowchart',
anchors: ['Bottom', 'Bottom'],
label: 'label by connect',
});
Custom
自定义Overlay,可以将Overlay设置成按钮/下拉框/输入框等任意元素。
import {
newInstance,
BrowserJsPlumbInstance,
AnchorLocations,
StraightConnector,
Component,
} from '@jsplumb/browser-ui';
jsPlumb.value.connect({
source: node9.value,
target: node10.value,
anchors: ['Top', 'Top'],
connector: 'Flowchart',
overlays: [
{ type: 'Arrow', options: { location: 1 } },
{
type: 'Custom',
options: {
create: (component: Component) => {
console.log(component);
const d = document.createElement('span');
d.setAttribute('class', 'line-btn');
d.addEventListener('click', (event: MouseEvent) => {
event.stopPropagation();
alert('btn click');
});
d.innerHTML = '按钮';
return d;
},
location: 0.5,
},
},
],
});
.line-btn {
color: white;
background-color: #40bdec;
font-size: 12px;
border-radius: 4px;
padding: 3px;
cursor: pointer;
}
配置项create
为一个方法,方法最后需要返回一个DOM即可,不管是简单的还是复杂的。
四、Overlay的操作
除了Overlay的创建,还有一些其他的API操作,例如显示/隐藏、移除。通过持有Overlay实例或Connection实例就可以调用这些方法:
// 隐藏所有overlay
conn_7_8.hideOverlays();
// 显示所有overlay
conn_7_8.showOverlays();
// 通过线条实例来显示/隐藏overlay
conn_7_8.hideOverlay("lab1");
conn_7_8.showOverlay("lab1");
// 通过overlay实例来显示/隐藏label
const lab2Overlay = conn_7_8.getOverlay("lab2");
lab2Overlay.setVisible(false);
lab2Overlay.setVisible(true);
官方文档中写的Overlay实例有hide()和show()方法,实际代码中并没有这两个API
五、总结
文章中的完整演示代码地址在此,jsPlumb中的几个关键概念的基本使用方式就已经介绍完了,使用这些基本用法就可以创建一个简单的流程图功能,但是还不足以实际完成一个项目。接下来会介绍常用的事件与拦截器。