Home
tags: jsPlumb
jsPlumb Community edition provides a means for a developer to visually connect elements on their web pages, using SVG. jsPlumb 社区版为开发人员提供了一种方法,使用 SVG 可视化地连接网页上的元素的方法。
jsPlumb has no external dependencies. jsPlumb 并不依赖于其他的库。
The 1.7.x line of releases were the last ones to support IE8. From version 2.0.0, the Community edition works only in modern browsers that support SVG. 1.7.x版本是支持IE8的最新jsPlumb版本。从版本2.0.0开始仅适用于支持SVG的现代浏览器。
引入和设置
It is a good idea to read this entire page. There are a few things you need to know about integrating jsPlumb with your UI. 这个页面会介绍有关将jsPlumb与界面(UI)结合在一起的步骤。
浏览器兼容性
jsPlumb 1.7.x runs on everything from IE6 up. jsPlumb 2.x runs on everything from IE9 up. jsPlumb 1.7.x可以运行在IE6以上的浏览器,jsPlumb 2.x仅仅可以运行在IE9以上了。(chrome之类的浏览器应该是可以的)
Setup
设置
Doctype
text/html
If you're serving your pages with content type text/html, as most people are, then you should use this doctype: 如果你正在使用的网页类型为text/html,那么应该使用下诉文档类型
<!doctype html>
This gives you Standards mode in all browsers and access to HTML5. 这是一种标准模式在所有浏览器上支持HTML5。
必须引入
No required imports. 不需要import
<script src="PATH_TO/jsplumb.min.js "></script>
Initializing jsPlumb
初始化jsPlumb
You should not start making calls to jsPlumb until the DOM has been initialized - perhaps no surprises there. To handle this, you should bind to the ready event on jsPlumb (or the instance of jsPlumb you are working with):
在DOM初始化之前,您不应该使用jsPlumb,因为它还无法使用。下面这种方法可以解决这个问题,你应该绑定ready
事件到jsPlumb(或者你正在使用jsPlumb的实例)
jsPlumb.bind("ready", function() {
...
// your jsPlumb related init code goes here
...
});
There's a helper method that can save you a few precious characters: 有另一个帮助方法可以简写:
jsPlumb.ready(function() {
...
// your jsPlumb related init code goes here
...
});
If you bind to the ready event after jsPlumb has already been initialized, your callback will be executed immediately.
如果您在ready
事件绑定了回调函数,您的回调函数会立刻执行。
Multiple jsPlumb instances
多个jsPlumb实例
jsPlumb is registered on the browser's window by default, providing one static instance for the whole page to use. You can also instantiate independent instances of jsPlumb, using the getInstance method, for example:
默认情况下,jsPlumb在浏览器窗口中注册,为整个页面提供一个静态实例,你还可以使用getInstance
方法独立初始化实例,例如:
var firstInstance = jsPlumb.getInstance();
The variable firstInstance can now be treated exactly as you would treat the jsPlumb variable - you can set defaults, call the connect method, whatever:
变量firstInstance
现在可以像处理jsPlumb变量一样处理-您可以设置默认值,调用connect方法,像这样
firstInstance.importDefaults({
Connector : [ "Bezier", { curviness: 150 } ],
Anchors : [ "TopCenter", "BottomCenter" ]
});
firstInstance.connect({
source:"element1",
target:"element2",
scope:"someScope"
});
getInstance optionally takes an object that provides the defaults:
getInstance
可以选择一个对象作为默认值。
var secondInstance = jsPlumb.getInstance({
PaintStyle:{
strokeWidth:6,
stroke:"#567567",
outlineStroke:"black",
outlineWidth:1
},
Connector:[ "Bezier", { curviness: 30 } ],
Endpoint:[ "Dot", { radius:5 } ],
EndpointStyle : { fill: "#567567" },
Anchor : [ 0.5, 0.5, 1, 1 ]
});
secondInstance.connect({
source:"element4",
target:"element3",
scope:"someScope"
});
It is recommended to use separate instances of jsPlumb wherever possible. 推荐尽可能使用jsPlumb的单独实例。
Element Ids
元素ID
jsPlumb uses the id attribute of any element with which it interacts. If id is not set, jsPlumb will create an id for the element. It is recommended that you set appropriate ids for the elements in your UI yourself.
jsPlumb使用ID
属性与其交互。如果ID
没有设置,jsPlumb会为这个元素创建一个ID
,但是建议您自己为您的元素设置一个ID。
Changing Element Id
更改元素ID
Because of the fact that jsPlumb uses element ids, you need to tell jsPlumb if an element id changes. There are two methods to help you do this: 因为jsPlumb使用元素id,如果您改变ID需要告诉jsPlumb,有两种方法可以帮助你这样做:
jsPlumb.setId(el, newId)
Use this if you want jsPlumb to take care of changing the id in the DOM. It will do so, and then update its references accordingly.jsPlumb.setId(el, newId)
如果你要jsPlumb改变DOM中的id,可以这样使用,它会自动更新引用。jsPlumb.setIdChanged(oldId, newId)
Use this if you have already changed the element's ID, and you just want jsPlumb to update its references.jsPlumb.setIdChanged(oldId, newId)
如果您已经改变了元素ID,那么只需要让jsPlumb更新器引用。
Method Arguments
方法参数
Almost every method in jsPlumb that operates on elements supports multiple formats for specifying the element(s) on which to operate. 几乎jsPlumb所有的方法都在元素上操作,支持多种格式来指定要运行的元素。
NodeLists/Selectors
NodeLists/选择器
In the jsPlumb documentation you will see references to the concept of a selector
. This is a list of elements that match
some CSS spec. In modern browsers you can get one of these via a call like:
在jsPlumb文档中,你可以看到一个selector
概念引用,这是一些符合css规范的元素列表,在现在浏览器中,您可以通过下列方法获得其中一个。
someElement.querySelectorAll('.someSelector')
The native element that querySelectorAll
returns is a NodeList
.
querySelectorAll
返回的元素是一个NodeList
Although jsPlumb has no dependency on jQuery, it also supports jQuery selectors as arguments for elements (vanilla jsPlumb
because jQuery's selector object is list-like, ie. it has a length
property and indexed accessors). So this will
also work, if you happen to be using jQuery in your page:
尽管jsPlumb不依赖于jQuery,但它也支持jQuery选择器作为元素的参数(普通jsPlumb,因为jQuery的选择器对象类似列表,它拥有length
属性和索引的访问器)。如果你刚好在页面中使用jQuery,你可以这样做:
$(someElement).find(".someSelector")
Element Ids
元素ID
Passing a single string as argument will cause jsPlumb to treat that string as an element id. 传递单个字符串作为参数,会让jsPlumb认为该字符串是元素的ID。
Elements
元素
You can pass DOM elements as arguments. This will probably not surprise you. 您可以将DOM元素作为参数传递,这应该不会让你感觉到惊讶。
Arrays
数组
You can also pass an array of any or all of the types we just listed. The contents of the array can be mixed - they do not have to be all one type. 您还可以使用刚刚我们列出的任何类型或者数组,数组的内容可以是混合的,他们不一定包含了所有类型。
Z-index Considerations
Z-index 注意事项
You need to pay attention to the z-indices of the various parts of your UI when using jsPlumb, in particular to ensure that the elements that jsPlumb adds to the DOM do not overlay other parts of the interface. 你需要注意界面中各个部分的Z-index,确保jsPlumb添加到DOM中的元素不会覆盖到其他部分的界面。
jsPlumb adds an element to the DOM for each Endpoint, Connector and Overlay. So for a Connection having visible Endpoints at each end and a label in the middle, jsPlumb adds four elements to the DOM. jsPlumb为每个端点、连接器、覆盖层向DOM添加一个元素。所以对于一个连接器,每端都有可见的端点,中间还有一个标签,jsPlumb会向DOM添加四个元素。
To help you organise z-indices correctly, jsPlumb adds a CSS class to each type of element it adds. They are as follows: 为了帮助您正确使用z-index,jsPlumb为每个类型的元素添加了一个css类,如下:
Component | Class |
Endpoint | jtk-endpoint |
Connector | jtk-connector |
Overlay | jtk-overlay |
组件 | Class |
端点/瞄点 | jtk-endpoint |
连接器 | jtk-connector |
覆盖 | jtk-overlay |
In addition, whenever the mouse is hovering over an Endpoint or Connection, that component is assigned the class jtk-hover
.
For more information about styling jsPlumb with CSS, see this page.
此外,当鼠标悬停在端点、连接器,这个组件会自动添加一个jtk-hover
的class,有关更多jsPlumb中的 CSS,请看此页面
Where does jsPlumb add elements?
jsPlumb在哪里添加元素?
It's important to understand where in the DOM jsPlumb will add any elements it creates. If you want a TL;DR version, then it boils down to this: 比较重要的是理解jsPlumb如何添加DOM元素的位置,如果你想要一个TL,TR版本,那么将它归结为:
- It is strongly recommended that you set a Container before you begin plumbing.
- A Container is some element that jsPlumb will use as the parent for all of the artefacts it adds to the UI. Typically, you would make this the parent element of the nodes you are connecting.
If you do not specify a Container, jsPlumb will infer that the Container should be the
offsetParent
of the first element on which you calladdEndpoint
,makeSource
ormakeTarget
, or theoffsetParent
of the source element in the firstconnect
call - whichever happens first.强烈建议你开始画之前设置容器
- jsPlumb会使用所有artefacts添加到界面作为一些元素,通常,您需要让它成为您要连接的节点父元素
- 如果你不指定容器,jsPlumb将推断容器应该是
offsetParent
,调用的第一个元素addEndpoint
,makeSource
、makeTarget
、offsetParent
或者第一个使用connect
调用的。
Let's discuss this in more detail. 让我们更详细讨论这个问题。
Early versions of jsPlumb added everything to the body element. This has the advantage of(占优势) being the most flexible (灵活的) arrangement(安排;排列;约定;改编) in terms of(依据) supporting which elements can be connected(连接), but in certain use cases produced unexpected results. jsPlumb早期版本将所有的内容添加到body元素中,在支持元素连接方面,这是具有灵活优势的,但是在某些用法中会有意想不到的结果。
Consider the arrangement where you have some connected elements in a tab: you would expect jsPlumb to add elements inside
the tab, so that when the user switches tabs and the current one is hidden, all the jsPlumb stuff is hidden too. But
when the elements are on the body, this does not happen!
考虑到一个选项卡中有一些连接元素的安排:您希望jsPlumb在选项卡中添加元素,以便当用户切换选项卡并将当前元素隐藏时,所有的jsPlumb都会被隐藏,但是在body的元素并不会被隐藏。
It is also quite common for jsPlumb to be used in a page in which the diagram is contained within some element that should show scrollbars when its content overflows. Appending elements to the document body prevents this from occurring automatically. 当包含的jsPlumb的页面超过可视区高度时候,有一些内容应该包含在页面可视区范围内,超过的部分在滚动滚动条的时候应该可以看见。将元素添加到文档正文中会阻止这种情况自动发生。
Container
容器
You can - and should - instruct jsPlumb to use some element as the parent of everything jsPlumb adds to the UI
through usage of the setContainer
method in jsPlumb, or by providing the Container in the parameters to a jsPlumb.getInstance
call.
你应该使用setContainer
方法告诉jsPlumb使用哪些元素作为jsPlumb的元素,然后添加到相应的界面,或者通过jsPlumb.getInstance
调用参数提供容器。
Important This is a change from versions of jsPlumb prior to 1.6.2. In versions prior to 1.6.2 you could assign the
Container directly via the jsPlumb.Defaults.Container
property. You can still do this - we're in Javascript here of
course, it's a free-for-all - but it will be ignored.
重要说明这是从1.6.2版本之后的更改,在1.6.2之前的版本,您可以通过jsPlumb.Defaults.Container
的property分配容器。您还可以这样做,这是JavaScript提供的一个特性,但是这将会被忽略。
Also Important If you happen to be using jsPlumb's draggable
method to make other parts of your UI draggable (ie.
not just things you're plumbing together), be careful not to call draggable
on the element that is acting as the
Container
for the current instance, or you will see some odd situations occur when dragging. It is suggested that
the best thing to do if you wish to use jsPlumb to enable dragging on non-plumbed elements is to create a new instance:
同样重要如果你在使用draggable
方法使其可以移动,(不仅仅是您正在管理的东西),请小心不要调用 draggable
作为 Container
当前实例的元素,或者你看到一些奇怪的情况,我们的建议是,如果您希望在jsPlumb使用非plumbed元素的拖动,最好的解决办法是创建一个新的实例:
var nonPlumbing = jsPlumb.getInstance();
nonPlumbing.draggable("some element");
Some examples
例子
- Set a container to use as the default container:
- 设置一个默认容器
jsPlumb.setContainer(document.getElementById("foo"));
...
jsPlumb.addEndpoint(someDiv, { endpoint options });
- Set a container to use as the default container, using an element id, and then connect two elements. The elements created in this example will be children of the element with id "containerId":
使用ID设置默认容器和连接两个元素,在这个例子中创建的元素是ID为"containerId"的子元素。
jsPlumb.setContainer("containerId"); ... jsPlumb.connect({ source:someDiv, target:someOtherDiv });
Get a new instance of jsPlumb and specify the container to use in the constructor params:
- 获取一个新的jsPlumb实例,并在指定在构造函数参数中使用的容器。
var j = jsPlumb.getInstance({
Container:"foo"
});
...
jsPlumb.addEndpoint(someDiv, { endpoint:options });
Container CSS
容器CSS
The container you choose should have position:relative
set on it, because it is the origin of that element that jsPlumb
will use to compute the placement of the artefacts it adds to the DOM, and jsPlumb uses absolute positioning.
您的容器应该设置position:relative
,因为jsPlumb会计算位置添加到DOM中,并且jsPlumb是使用绝对定位的。
Element Dragging
拖动元素
A common feature of interfaces using jsPlumb is that the elements are draggable. You should use jsPlumbInstance.draggable
to configure this:
使用jsPlumbInstance.draggable
配置来设置元素可以拖动,如:
myInstanceOfJsPlumb.draggable("elementId");
...because if you don't, jsPlumb won't know that an element has been dragged, and it won't repaint the element. 因为如果你不这么做,jsPlumb不会知道这个元素可以拖动,并且不会重绘该元素。
Dragging is covered in detail on this page. 此页面详细介绍了拖动。
Performance
性能
The speed at which jsPlumb executes, and the practical limit to the number of manageable connections, is greatly affected by the browser upon which it is being run. At the time of writing, it will probably not surprise you to learn that jsPlumb runs fastest in Chrome, followed by Safari/Firefox, and then IE browsers in descending version number order. jsPlumb执行的速度、连接数的限制很大程度受到浏览器的影响,在写本文时,jsPlumb在chrome性能最高,依次是Safari/Firefox,其次是低版本的IE浏览器。
停止绘图
Every connect
or addEndpoint
call in jsPlumb ordinarily causes a repaint of the associated element, which for many
cases is what you want. But if you are performing some kind of "bulk" operation - like loading data on page load
perhaps - it is recommended that you suspend drawing before doing so:
每当jsPlumb调用connect
或者 addEndpoint
的时候,会导致相关元素的重绘,但是在很多情况下是您不希望重绘的。但是如果你在执行某种操作,例如在页面中加载数据,那么建议您在这个操作前停止绘图。
jsPlumb.setSuspendDrawing(true);
...
- load up all your data here -
...
jsPlumb.setSuspendDrawing(false, true);
Notice the second argument in the last call to setSuspendDrawing
: it instructs jsPlumb to immediately perform a full
repaint (by calling, internally, repaintEverything
).
注意上面调用的第二个参数setSuspendDrawing
:它告诉jsPlumb立即执行完全重绘(通过调用 repaintEverything
)
I said above it is recommended that you do this. It really is. It makes an enormous difference to the load time when you're dealing with a lot of Connections on slower browsers. 我上面说了建议这样做,当您在较慢的浏览器处理很多连接的时候,对加载时间有很大的影响。
batch
批量
This function abstracts out the pattern of suspending drawing, doing something, and then re-enabling drawing: 该函数抽象出了图形做完某事后,重新启用绘图的模式。
jsPlumb.batch(fn, [doNotRepaintAfterwards]);
Example usage: 例子:
jsPlumb.batch(function() {
// import here
for (var i = 0, j = connections.length; i < j; i++) {
jsPlumb.connect(connections[i]);
}
});
Here, we've assumed that connections
is an array of objects that would be suitable to pass to the connect
method, for example:
在这里,我们假设connections
是一个合适传递给 connect
方法的对象,例如:
{ source:"someElement", target:"someOtherElement" }
By default, this will run a repaint at the end. But you can suppress that, should you want to: 默认情况下,这会在最后重绘,但是你可以禁止,你需要:
jsPlumb.batch(function() {
// import here
}, true);
Note this method used to be called doWhileSuspended
and was renamed in version 1.7.3.
注意以前被叫做doWhileSuspended
的方法在1.7.3中被重命名。
Anchor Types
瞄点类型
Continuous anchors are the type that require the most maths, because they have to calculate their position every time a paint cycle occurs. 连续瞄点是需要最多数学的类型,因为他发生重绘的时候都需要计算他们的位置。
Dynamic and Perimeter anchors are the next slowest (with Perimeter being slower than most Dynamic Anchors as they are
actually Dynamic Anchors that have, by default, 60 locations to choose from).
动态和边界瞄点是更慢的类型(边界比大多数动态瞄点要慢,因为默认情况下有60个位置可以选择),
Static anchors like Top
, Bottom
etc are the fastest.
如Top
, Bottom
等静态瞄点都是最快的。