一、基本知识

  • Source:源节点
  • Target:目标节点
  • Anchor:锚点
  • Endpoint:端点,连接的起点或终点
  • Connector:连线,连接两个节点的直观表现
  • Overlay:装饰连接器的组件,类似箭头之类
  • Group:包含在某个其他元素中的一组元素,可以折叠,导致与所有组成员的连接被合并到折叠的组容器上。

jsPlumb通过元素id来和所有的元素进行交互,如果没有为元素设置id,0jsPlumb就会为元素创建一个id。建议为用户界面上的每个元素设置一个合适的id。

由于jsPlumb使用元素id和元素进行交互,因此当你的元素id发生改变的时候,你需要告诉jsPlumb。有两种方法通知jsPlumb元素id发生了改变:

  1. jsPlumb.setId(el,newId)
  2. jsPlumb.setIdChanged(oldId,newId)

jsPlumb提供了拖动方法:

var firstInstance=jsPlumb.getInstance();
firstInstance.draggable("ele_id");

每次使用连线时,都会导致相关联的元素重绘,但当加载大量数据时,可以使用:

jsPlumb.setSuspendDrawing(true);
jsPlumb.setSuspendDrawing(false,true);

第二个参数设置为true,会使整个jsPlumb立即重绘。也可以使用batch:

jsPlumb.batch(fn,[doNotRepaintAfterwards]);

这个函数也一样,可以先将所有的连接全部注册好,再一次重绘。


1.1 默认参数

Anchor : "BottomCenter",//端点的定位点的位置声明(锚点):left,top,bottom等
Anchors : [ null, null ],//多个锚点的位置声明
ConnectionsDetachable   : true,//连接是否可以使用鼠标默认分离
ConnectionOverlays  : [],//附加到每个连接的默认重叠
Connector : "Bezier",//要使用的默认连接器的类型:折线,流程等
Container : null,//设置父级的元素,一个容器
DoNotThrowErrors  : false,//如果请求不存在的Anchor,Endpoint或Connector,是否会抛出
DragOptions : { },//用于配置拖拽元素的参数
DropOptions : { },//用于配置元素的drop行为的参数
Endpoint : "Dot",//端点(锚点)的样式声明(Dot)
Endpoints : [ null, null ],//多个端点的样式声明(Dot)
EndpointOverlays : [ ],//端点的重叠
EndpointStyle : { fill : "#456" },//端点的css样式声明
EndpointStyles : [ null, null ],//同上
EndpointHoverStyle : null,//鼠标经过样式
EndpointHoverStyles : [ null, null ],//同上
HoverPaintStyle : null,//鼠标经过线的样式
LabelStyle : { color : "black" },//标签的默认样式。
LogEnabled : false,//是否打开jsPlumb的内部日志记录
Overlays : [ ],//重叠
MaxConnections : 1,//最大连接数
PaintStyle : { lineWidth : 8, stroke : "#456" },//连线样式
ReattachConnections : false,//是否重新连接使用鼠标分离的线
RenderMode : "svg",//默认渲染模式
Scope : "jsPlumb_DefaultScope"//范围,标识

就开了;就开了;就开了; 分为全局默认参数和连线默认参数。

如果是全局参数可以使用:

jsPlumb.importDefaults({···})

也可以在实例化时,重新定义:

jsPlumb.getInstance({···})

1.2 锚点(Anchors)

坐落在一个元素身上,用于多个元素之间相互连线的点,主要分为以下四类:

  • 静态(Static):固定在元素的某个点上,不能移动,可以使用字符串来指定他们,以确定jsPlumb所附带的默认值,或描述该位置的数组
  • 动态(Dynamic):这是静态锚的列表,每次连接绘制时,jsPlumb从中选择最合适的点
  • 周边锚(Perimeter anchors):这些锚点符合某些给定形状的周长,它们的本质是动态锚,其位置从底层形状的周边中选择
  • 连续锚(Continuous anchors):这些锚不固定在任何特定位置,它们被分配到元素的四个面之一,者取决于该元素与关联连接中另一个元素的方向

需要注意的是连接点分为动态连接点和静态连接点。当指定一个数组作为连接点时,该连接点为动态连接点,连线时会自动选择最近的连接点连接;当指定一个坐标或者固定位置(TopRight、RightMiddle等)作为连接点时,该连接点为静态连接点,不管怎么连线都不会移动

静态锚

jsplumb有9个默认的锚点位置,具体有:TopLeft、TopCenter、TopRight、LeftMiddle、RightMiddle、BottonLeft、BottomCenter、BottomRight、Center.

可以使用基于数组的形式来定义锚点的位置:[x,y,dx,dy,offsetX,offsetY]。x表示锚点在横轴上的距离,y表示锚点在纵轴上的距离,这两个值可以从0到1来设置,0.5为center。dx表示锚点向横轴射出线,dy表示锚点向纵轴射出线,由0、-1、1三个值来设置,0表示不放射线。offsetX表示锚点偏移量x(px),offsetY表示锚点的偏移量y(px)。

动态锚

这些都是可以在若干位置之一定位的锚点,当你每次移动一个元素时,会自动选择一个最合适的位置,没有特殊的语法来创建一个DynamicAnchor,你只需要提供一个独立的锚位置。jsPlumb提供了一个默认的动态锚,定名为“AutoDefault”,其包含的锚点位置有:TopCenter、BottomCenter、LeftMiddle、RightMiddle。

使用方法:

jsPlumb.connect({
    anchor:"AutoDefault",
})

周边锚(Perimeter anchors)

jsPlumb提供了六种形状:Circle、Ellipse、Triangle、Diamond、Rectangle、Square。

连续锚(Continuous anchors)

anchor:"Continuous"
//or
anchor:["Continuous",{faces:["top","left"]}]

 faces有四个值:top、left、right、bottom

1.3 连接器(Connectors)

链接的线,实际上是界面上的各个元素的连接线,jsPlumb有三种连接器:直线、Bezier曲线、折线。

  • 直线 (Straight)。直接连接两个端点,没有构造函数的参数支持,使用参数endpointStyle定义连接样式或添加端点时定义连接线样式
  • Bezier曲线(Bezier)。贝塞尔曲线提供了两个端点之间的立方体路径,它支持一个构造函数参数(curviness ,弯曲度,可选,默认为150,定义了Bezier的控制点与锚点的距离)
  • 流程图(Flowchart)。这种类型的连接器是由一系列垂直或水平线段组合而成,支持一个单一的构造函数参数
  • 状态器(StateMachine):支持在同一元素上开始和结束的连接,支持的参数有:margin,默认为5;curviness,默认为10,proximityLimit,默认为80;

可以有选择的设置一个连接器,通过设置“connector”来定义;或者在添加端点时设置连接线。

1.4 端点(Endpoints)

一个端点的UI组件,标志着一个锚的位置,是连接器连接的点,jsPlumb有四个端点实现:点、矩形、图形和空白。

可以在使用connect()、addEndpoint()、makeSource()或jsPlumb.makeTarget时使用endpoint参数指定Endpoint属性

给端点进行配置:

  • jsPlumb.connect(),创建连接的时候可以配置端点的属性
  • jsPlumb.addEndpoint(),创建一个新的端点时配置属性
  • jsPlumb.makeSource(),配置元素并随后从该元素中拖动连接时,将创建并分配一个新的端点

端点的预设类型:

jsPlumb.connect({
    //Rectangle可以设置:width,height,cssClass,hoverClass
    endpoint:["Rectangle",{height:10,width:10}],
})
jsPlumb.connect({
    //Dot可以设置:radius,cssClass,hoverClass
    endpoint:["Dot",{radius:5}],
})
jsPlumb.connect({
    endpoint:["Image",{url:"02.jpg"}]
})

1.5 叠加层(Overlays)

jsPlumb有五种类型的叠加:

  • 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:颜色等边框参数

也可以使用getLabel和setLabel来获取和设置label的文本

  • PlainArrow:箭头形状为三角形

知识Arrow的foldback为1时的例子,参数与Arrow相同

  • Diamond:菱形

同样是Arrow的foldback为2时的例子,参数与Arrow相同

  • Custom:自定义

允许创建自定义的叠加层,需要使用create()来返回DOM元素或者有效的选择器ID

所有叠加层都支持:getLocation()返回当前位置,setLocation()设置当前位置

<style>
    .item{
        width:50px;
        height:50px;
        border:1px solid black;
        position:absolute;/*注意这里*/
    }
</style>
<div id="diagramContainer">
    <div id="item_left" class="item"></div>
    <div id="item_right" class="item" style="left: 150px;"></div>
</div>
<script src="jquery-3.0.0.js"></script>
<script src="jquery-ui.min.js"></script>
<script src="jsplumb.min.js"></script>
<script>
    jsPlumb.ready(function(){
        var firstInstance=jsPlumb.getInstance();
        firstInstance.connect({
            source:"item_left",
            target:"item_right",
            paintStyle:{
                stroke:"red",
                strokeWidth:2
            },
            overlays:[
                ["Arrow",{location:0.1}],
                ["Label",{location:0.3,label:"测试"}],
                ["PlainArrow",{location:0.5}],
                ["Diamond",{location:0.7}],
                ["Custom", {
                    create:function(component) {
                        return $("<select id='myDropDown'><option value='foo'>foo</option><option value='bar'>bar</option></select>");
                    },
                    location:0.9,
                    id:"customOverlay"/*作为唯一标识*/
                }]
            ]
        })
    })
</script>

运行结果:

 、

1.6 Groups

相当于给节点之间加入了分组的概念,一旦分组,那么就可以使用组来控制组下的所有元素

1.7 Grag

如果不使用jsPlumb提供的拖动,则需要使用repaint()来对拖动之后的连线进行重绘。而当修改了节点的层级,或者偏移则需要使用revalidate(container)来刷新。

1.8 建立连接

 可以使用jsPlumb.connect({...})来创建连接,这种方式创建的连接线一旦移除,则创建的端点也会自动移除。如果不想端点被移除,则可以继续加参数,将deleteEndpointsOnDetach设为false。

/*引用jquery.jsplumb.js*/
var firstInstance=jsPlumb.getInstance();
var test=firstInstance.connect({
    source:"item_left",
    target:"item_right",
    deleteEndpointsOnDetach:false,
});

如果不想鼠标能够移除连接线,则可以在局部配置中将ConnectionsDetachable设为false,或者在connect时,加入detachable:false。

        var firstInstance=jsPlumb.getInstance();
        var test=firstInstance.connect({
            source:"item_left",
            target:"item_right",
            detachable:false
        });

1.9 拖放连接

 一开始就要创建一个端点作为源点,这样就可以从该端点拉线出去。如果给另一个端点添加isTarget:true,则可以连入这个点。

var endpoint1 = jsPlumb.addEndpoint('elementId',{isSource:true})
var endpoint2 = jsPlumb.addEndpoint('elementId',{isTarget:true})

也可以使用makeSource和makeTarget来创建。

可以使用maxConnections来配置最大连线数。如果超出了该数目,会执行配置的onMaxConections回调函数。makeTarget也有onMaxConnections方法。

        var firstInstance=jsPlumb.getInstance();
        firstInstance.makeSource("item_left",{
            anchor:"Continuous",
            maxConnections:1,
            onMaxConnections:function(){
                alert("超出连线")
            }
        })
        firstInstance.makeTarget("item_right",{
            anchor:"Continuous",
            maxConnections:1
        })

某个元素通过makeTarget或addEndpoint方法设置为“连线终点”,如果不想造成回环,则可以在makeTarget()中设置allowLopback:false,如果只想产生一个端点,而不是多个端点,则需要使用uniqueEndpoint:true

如果既配置了元素可拖动,又设置了元素可拖放连接,那jsPlumb没有办法区分拖动元素和从元素中拖动连接,所以它提供了filter方法。

jsPlumb.makeSource("foo",{
  filter:"span",/*"span"表示标签,".className"表示类,"#id"表示元素id*/
  filterExclude:true
});

如果设置“filterExclude:true”,则表示除span元素的其他元素都可以创建拖放连接;如果设置"filterExclude:false"则表示通过拖动span元素创建连接,filterExclude默认为false。filter也接受函数。filter:function(event,element).

也可以使用isTarget("id"),isSource("id")来判断节点是否成为了源点。

如果配置了source和target之后,想切换源的激活状态,则可以使用setTargetEnabled(id),setSourceEnabled(id)

如果想取消makeTargetmakeSource所创建的源点,可以使用:

  • unmakeTarget("id")
  • unmakeSource("id")
  • unmakeEveryTarget
  • unmakeEverySource

 


二、简单例子

2.1 连接两个节点

<style>
    .item{
        float:left;
        width:50px;
        height:50px;
        border:1px solid black;
    }
</style>
<div id="diagramContainer">
    <div id="item_left" class="item"></div>
    <div id="item_right" class="item" style="margin-left: 50px;"></div>
</div>
<script src="jsplumb.min.js"></script>
<script>
    jsPlumb.ready(function(){
        jsPlumb.connect({
            source:"item_left",
            target:"item_right",
            endpoint:"Dot"
        })
    })
</script>

效果图:

参数说明:

参数参数类型是否必须说明
sourceString,Object,Endpoint连线源的标识,可以是id, element, 或者Endpoint
targetString,Object,Endpoint连线目标的标识,可以是id, element, 或者Endpoint
endpointString可选端点类型,形状

2.2 可拖动节点

<style>
    .item{
        width:50px;
        height:50px;
        border:1px solid black;
        position:absolute;/*注意这里*/
    }
</style>
<div id="diagramContainer">
    <div id="item_left" class="item"></div>
    <div id="item_right" class="item" style="left: 150px;"></div>
</div>
<script src="jsplumb.min.js"></script>
<script>
    jsPlumb.ready(function(){
        jsPlumb.connect({
            source:"item_left",
            target:"item_right",
            endpoint:"Dot"
        })
        jsPlumb.draggable('item_left')
        jsPlumb.draggable('item_right')
    })
</script>

效果图:

2.3 连接的其它参数

connector:设置链接线的形状,比如直线或者曲线

anchor:设置锚点的位置

jsPlumb.connect({
    source:"item_left",
    target:"item_right",
    endpoint:"Rectangle",
    connector:['Bezier'],
    anchor:['Left','Right']
})

2.4 设置连接的默认使用

可以将相同配置提取出来作为一个单独的变量,作为connect的第二个参数传入。

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')
})

2.5 给连接加上样式

jsPlumb.connect({
  source: 'item_left',
  target: 'item_right',
  paintStyle: { stroke: 'lightgray', strokeWidth: 3 },
  endpointStyle: { fill: 'lightgray', outlineStroke: 'darkgray', outlineWidth: 2 }
}, common)

2.6 给连接加上箭头

通过overlays设置,可以设置箭头的长宽和箭头的位置

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)

location=0.5表示箭头位于中间,location=1表示箭头设置在连线末端。一根连线可以添加多个箭头

2.7 增加一个端点

jsPlumb.ready(function () {
      jsPlumb.addEndpoint('item_left', {
        anchors: ['Right']
      })
})

2.8 拖动创建连接

设置isSource和isTarget为true时,用户就可以拖动创建连接

<div id="diagramContainer">
    <div id="item_left" class="item"></div>
    <div id="item_right" class="item" style="left: 150px;"></div>
</div>

<script src="jsplumb.min.js"></script>
<script>
    jsPlumb.ready(function () {
        jsPlumb.setContainer('diagramContainer')

        var common = {
            isSource: true,
            isTarget: true,
            connector: ['Bezier']
        }

        jsPlumb.addEndpoint('item_left', {
            anchors: ['Right']
        }, common)

        jsPlumb.addEndpoint('item_right', {
            anchor: 'Left'
        }, common)

        jsPlumb.addEndpoint('item_right', {
            anchor: 'Right'
        }, common)
        
        jsPlumb.draggable('item_left')
        jsPlumb.draggable('item_right')
    })
</script>

一般情况下,拖动创建的连接,可以再次拖动,让连接断开。如果不想触发这种行为,可以设置:

jsPlumb.importDefaults({
    ConnectionsDetachable: false/*设置为false,靠拖动无法取消连接*/
  })

2.9 给端点增加样式

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 节点改变尺寸

jsplumb实际上是不支持改变大小,实际上只能通过jquery ui的resizable()方法去改变

2.11 限制节点拖动区域(有些问题)

默认情况下,节点可以被拖动到区域外边,如果想只能在区域内拖动,需要设置containment,这样节点就只能在固定区域内移动

<style>
    #diagramContainer{
        margin-top: 50px;
        padding:50px;
        width: 500px;
        height: 500px;
        border: 1px solid red;
    }
    .item{
        width:50px;
        height:50px;
        border:1px solid black;
        position:absolute;
    }
</style>
<div id="diagramContainer">
    <div id="item_left" class="item"></div>
    <div id="item_right" class="item" style="left: 150px;"></div>
</div>
<script src="jquery-3.0.0.js"></script>
<script src="jquery-ui.min.js"></script>
<script src="jquery.jsplumb.js"></script>
<script>
    jsPlumb.ready(function () {
        jsPlumb.connect({
            source: 'item_left',
            target: 'item_right',
            endpoint: 'Rectangle'
        })

        jsPlumb.draggable('item_left', {containment: 'parent'})
        jsPlumb.draggable('item_right', {containment: 'parent'})
    })
</script>

2.12 节点网格对齐

<style>
    #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;
}
</style>
<script>
    jsPlumb.draggable('item_left', {
      containment: 'parent',
      grid: [10, 10]/*对齐网格*/
    })
</script>

2.13 点击删除连线

// 单点击了连接线, 
jsPlumb.bind('click', function (conn, originalEvent) {
  if (confirm('确定删除所点击的链接吗?')) {
    jsPlumb.detach(conn)
  }
})

2.14 删除节点,包括节点相关的连接

// nodeId为节点id, remove方法可以删除节点以及和节点相关的连线
jsPlumb.remove(nodeId)

2.15 通过编码连接endpoint

需要在addEndpoint时,就给该断点加上一个uuid, 然后通过connect()方法,将两个断点链接上。

jsPlumb.addEndpoint(id, {
    anchors: 'Top',
    uuid: uuid() // 这里需要唯一的一个Id, 
}, config)

jsPlumb.connect({ uuids: [fromId, toId] })

参考链接:

jsplumb简单功能介绍

jsPlumb.jsAPI阅读笔记(官方文档翻译)

实战项目链接

https://github.com/wangduanduan/visual-ivr

Logo

权威|前沿|技术|干货|国内首个API全生命周期开发者社区

更多推荐