由于JointJs官方API是英文,所以学习过程中对此进行部分(没有完全)汉化整理,以及一些个人理解。
锚点anchor 链接锚是一个链接想要到达的点(这意味着连接端点最终未必就落在上面)作为它的端点。 anchor: { name: 'midSide', args: { rotate: true, padding: 20 } } }); 注意:
|
连接点connectionPoints 连线连接点是连线路由的端点。这一点与链接锚点不同,因为它考虑了结束元素的存在。连接点通过连线末端定义中提供的connectionPoint属性设置(即提供给link.source()和link.target()函数的对象)。 link.source(model, { connectionPoint: { name: 'boundary', args: { sticky: true } } }); 注意:
|
连接策略connectionStrategies 当用户修改链接端点的位置时,连接策略就会起作用。 两种情况:
案例: Connecting to Ancestors:如果您的图表大量使用嵌套元素,那么始终将链接连接到顶级祖先元素 joint.connectionStrategies.topAncestor = function(end, endView) {
var ancestors = endView.model.getAncestors(); var numAncestors = ancestors.length; var end = numAncestors ? ancestors[numAncestors - 1] : end;
return end; }
paper.options.connectionStrategy = joint.connectionStrategies.topAncestor; Connecting to Ports:如果您的图表使用端口,您通常不希望链接能够连接到其他任何地方。解决方案与上面的类似 joint.connectionStrategies.firstPort = function(end, endView) {
var ports = endView.model.getPorts(); var numPorts = ports.length; var end = numPorts ? { id: end.id, port: ports[0].id } : end;
return end; }
paper.options.connectionStrategy = joint.connectionStrategies.firstPort; 其实总共可以在连接策略中可以有四个参数(上述案例都只用了两个参数): endDefinition object 一个对象,它至少包含我们连接到的元素的id。这个对象将被这个函数修改,然后作为返回值发送 |
Connectors 连接器 连接器获取一系列链接路由点并生成SVG路径命令,以便能够呈现链接。可以使用link.connector()函数访问链接的连接器属性。 自定义的连接器 joint.connectors.wobble = function(sourcePoint, targetPoint, vertices, args) {
var SPREAD = args.spread || 20;
var points = vertices.concat(targetPoint) var prev = sourcePoint; var path = new g.Path(g.Path.createSegment('M', prev));
var n = points.length; for (var i = 0; i < n; i++) {
var next = points[i]; var distance = prev.distance(next);
var d = SPREAD; while (d < distance) { var current = prev.clone().move(next, -d); current.offset( Math.floor(7 * Math.random()) - 3, Math.floor(7 * Math.random()) - 3 ); path.appendSegment(g.Path.createSegment('L', current)); d += SPREAD; }
path.appendSegment(g.Path.createSegment('L', next)); prev = next; }
return path; }
var link = new joint.shapes.standard.Link(); link.source(source); link.target(target);
link.connector('wobble', { spread: 10 }); 以及三种默认连接器:
|
dia.attributes 属性 dia.attributes.fill 填充属性只有在被定义为对象而不是通常的SVG语法时才会成为一个特殊属性。 示例如下: element.attr('rect/fill', { type: 'linearGradient', stops: [ { offset: '0%', color: '#E67E22' }, { offset: '20%', color: '#D35400' }, { offset: '40%', color: '#E74C3C' }, { offset: '60%', color: '#C0392B' }, { offset: '80%', color: '#F39C12' } ] }); dia.attributes.filter 阴影:只有在将filter属性定义为对象而不是通常的SVG语法时,它才会成为一个特殊的属性 示例如下: element.attr('rect/filter', { name: 'dropShadow', args: { dx: 2, dy: 2, blur: 3 } }); 当设置为true时,子元素可以在链路重连接期间成为链路的源/目标。 dia.attributes.magnet 当设置为true时,子元素可以在链路重连接期间成为链路的源/目标。对“端口”有用。 如果链接连接到一个磁铁,该磁铁也定义了端口对象,那么端口对象的id属性将复制到链接源/目标的端口属性。 |
Graph 图 joint.dia.Graph 是用于保存所有图形单元(包括elemen和link)的模型。 不仅为有向图提供了有效的存储,而且为遍历图提供了有用的算法。 本质就是一个 Backbone model。 图像上所有的图形单元存储在属性 events事件(顾名思义不做详解) 例如: graph.on('add', function(cell) { alert('New cell with id ' + cell.id + ' added to the graph.') }) Graphd的JSON格式: { cells: [// Array of cells (ie. links and elements). { id: '3d90f661-fe5f-45dc-a938-bca137691eeb',// Some randomly generated UUID. type: 'basic.Rect', attrs: { 'stroke': '#000' }, position: { x: 0, y: 50 }, angle: 90, size: { width: 100, height: 50 }, z: 2, embeds: [ '0c6bf4f1-d5db-4058-9e85-f2d6c74a7a30', 'cdbfe073-b160-4e8f-a9a0-22853f29cc06' ], parent: '31f348fe-f5c6-4438-964e-9fc9273c02cb' // ... and some other, maybe custom, data properties } ] } graph.addCell(cell) 向图中添加一个新单元格,用法简单 graph.addCells(cells[, opt]) 向图中添加新单元格数组 graph.addCells(cell, cell, ..[, opt]) graph. bfs (element, iteratee [, opt]) 使用从制定元素开始的宽度优先搜索算法遍历图 下图显示了元素在图中遍历的顺序: 如果参数 如果没有使用opt.inbound和opt.outbound,或者将这两个选项都设置为true,那么将在两个方向遍历图。 如果参数deep=true,则会考虑嵌套元素。 graph.clear([options) 从图中删除所有图形单元 graph.cloneCells(cells) 从cells数组中克隆所有的cell,并返回一个对象,该对象将原始cell ID映射到Clone对象 克隆对象格式:{ [original cell ID]: [clone] } graph.cloneSubgraph(cells [, opt]) 克隆整个子图,包括源/目标在子图中的所有连接链接。 这相当于调用graph.cloneCells(graph.getSubgraph(cells)) 如果参数.deep=true,则考虑子图单元格的内嵌单元图形 graph.dfs(element, iteratee [, opt]) 用法类似上面提到的bfs()方法 graph.disconnectLinks(element) 断开与元素的所有关联链接 graph.findModelsFromPoint(point) 查找图中某一点下的元素(joint.di . element实例) point是一个具有x和y属性的对象。返回其边框包含点的元素数组。注意,由于元素可能重叠,因此可以有多个元素
graph.findModelsInArea(rect) 在图中的某个区域中查找元素(joint.di . element实例) rect是一个具有x, y,宽度和高度属性的对象。返回一个元素数组,其边界框左上角坐标落在矩形矩形中。
graph.findModelsUnderElement(element [, opt]) 查找位于元素下面的所有元素(joint.di . element的实例) searchby参数可以选择确定一个元素在另一个元素下面意味着什么,可能的值是“bbox”(默认值)、“center”、“origin”、“corner”、“topRight”和“bottomLeft”
graph.fromJSON(jsonObject, [options]) 从JSON对象加载图表(不是字符串) 例如: var jsonString = JSON.stringify(graph.toJSON()); // ... send jsonString to the server // store jsonString to localStorage or do whatever you want // later on ... graph.fromJSON(JSON.parse(jsonString)); graph.getBBox(cells[, opt]) 返回包围所有给定单元格的包围框 graph.getCell(id) 从图中通过其id获取单元格。 graph.getCells() 获取图中的所有元素和链接 graph.getCommonAncestor(cells...) 返回作为参数传递的所有单元格的共同祖先 例如,如果元素B嵌入到元素A中,元素C也嵌入到元素A中,图形。graph.getCommonAncestor(B, C)将返回元素a graph.getConnectedLinks(element [, opt]) graph.getElements() graph.getLastCell() 在图中获得最后一个单元格(元素或链接)。(最后一个细胞被定义为具有最高z性质的细胞) graph.getLinks() graph.getNeighbors(element [, opt]) 在图中得到元素的所有邻居(不是连线是图形元素)。 如果参数
graph.getPredecessors(element [, opt]) 返回元素的所有前任元素的数组(默认深度优先算法) 参数 参数deep设置为true,也要考虑到嵌入的元素。 graph.getSinks() 返回图中的所有叶子节点的数组 graph.getSources() 返回图的所有根节点的数组 graph.getSubgraph(cells [, opt]) 返回一个单元格数组,该数组是查找与单元格数组中的任何单元格连接的元素/链接的结果 graph.getSuccessors(element [, opt]) 返回元素的所有后续元素的数组 graph.isNeighbor(elementA, elementB [, opt]) 如果elementB是elementA的邻居,返回true 同样有 graph.isPredecessor(elementA, elementB) 如果elementB是elementA的前身,返回true。 graph.isSink(element) 如果元素是叶子,返回true,也就是说,元素中没有出去的链接 graph.isSource(element) 如果元素是根元素,返回true,即没有指向元素的链接。 graph.isSuccessor(elementA, elementB) 如果elementB继承elementA,返回true graph.maxZIndex() 得到图中最大的Z值 graph.minZIndex() graph.removeCells(cells[, opt]) 从图中删除给定的图形单元数组 graph.removeCells(cell, cell, ..[, opt]) graph.removeLinks(element) 删除元素的所有关联链接 graph.resetCells(cells[, opt]) 在图中重置单元格 graph.resetCells(cell, cell, ..[, opt]) graph.search(element, iteratee [, opt]) 遍历图,从元素开始,然后是连线 graph.toJSON() 此方法不返回JSON字符串,而是返回一个JSON对象 graph.translate(tx, ty [, opt]) 将图中的所有单元格转换为tx和ty像素 |
Paper 画布 joint.dia.Paper 是 示例如下: var graph = new joint.dia.Graph var paper = new joint.dia.Paper({ el: $('#paper'), width: 600, height: 400, gridSize: 10, model: graph });
var rect = new joint.shapes.basic.Rect({ position: { x: 50, y: 70 }, size: { width: 100, height: 40 } });
graph.addCell(rect);
|
dia.Link 连线 图连线的基本模型。它继承了joint.dia,具有一些特定于链接的附加属性和方法。 两个关键属性: 单个连接实例提供以下属性:
也可以将定制属性传递给链接。 为了实现linkView的交互,这些可能对标识单个链接模型很有用。例如,只对link1启用自定义contextmenu交互,而不启用link2: var CustomLinkView = joint.dia.LinkView.extend({ contextmenu: function(evt, x, y) { if (this.model.get('customLinkInteractions')) { // only links with `customLinkInteractions: true` this.addLabel(x, y); } } });
var paper = new joint.dia.Paper({ //... linkView: CustomLinkView, interactive: function(cellView) { if (cellView.model.get('customLinkInteractions')) { // only links with `customLinkInteractions: true` return { vertexAdd: false }; } return true; // otherwise } });
var link1 = new joint.dia.Link({ //... customLinkInteractions: true // right-click adds a label });
var link2 = new joint.dia.Link({ //... customLinkInteractions: false // or omit completely }); Custom Link 自定义连线 通过继承joint.dia.Link,创建自定义链接的链接类。 自定义链接可以覆盖链接属性来分配自己的默认值。 示例如下: var CustomLink = joint.dia.Link.define('examples.CustomLink', { defaultLabel: { markup: [ { tagName: 'circle', selector: 'body' }, { tagName: 'text', selector: 'label' } ], attrs: { label: { text: '%', // default label text fill: '#ff0000', // default text color fontSize: 14, textAnchor: 'middle', yAlignment: 'middle', pointerEvents: 'none' }, body: { ref: 'label', fill: '#ffffff', stroke: '#000000', strokeWidth: 1, refR: 1, refCx: 0, refCy: 0 } }, position: { distance: 0.5, // place label at midpoint by default offset: { y: -20 // offset label by 20px upwards by default }, args: { absoluteOffset: true // keep offset absolute when moving by default } } } });
var link = new CustomLink({ //... }); Builtin Default Attributes 内置默认属性 为了确保向后兼容,接头。dia。链接类带有一个私有的内置defaultLabel属性。 dia.Link.events 连线事件
change:smooth:当链接切换插值时触发 change:manhattan:当链接切换到正交路由时触发 change:vertices:当链接改变其顶点数组时触发 change:z:当链接在z级移动时触发 transition:start:当过渡开始的时候触发 transition:end:当过渡结束时触发 dia.Link.labels 标签 一个链接可以有多个标签,每个标签可以有不同的属性。 JointJS识别的属性总结如下: { markup?: string | Array<{ tagName: SVGElement, selector?: string }>, attrs?: { [key: selector]: { [key: SVG attribute | JointJS attribute]: any } | null }, position?: number | { distance?: number, offset?: number | { x: number, y: number }, args?: { absoluteDistance?: boolean, reverseDistance?: boolean, absoluteOffset?: boolean } } } Markup 标记属性指定标签的标记。它可以作为可解析SVG提供(例如:' 如果标签上没有提供标记,则标记取自连线的defaultLabel.markup标记属性。 用户可以创建自定义链接类型,提供defaultLabel。 如果使用的链接类型不提供defaultLabel标记,则使用内置的默认链接标记(标记定义为带有“body”的JSON数组)。 Styling attrs属性是一个对象,其关键字是CSS选择器。 除了要分配的值,还应该包含指定本机SVG和/或JointJS特殊属性的对象。 如果链接类型提供defaultLabel.attrs,这些属性会和label.attrs合并。这允许您从label.attrs里的defaultLabel引用选择器。 (例如:attrs: { body: { stroke: 'black' } }) 如果使用内置默认标记,为了向后兼容,应用了几个内置的默认attrs。它们与defaultLabel.attrs合并,再与label.attrs(如果提供的话)合并。 Position position属性指定标签相对于链接的SVG路径的位置。 它可以定义为一个数字或一个具有距离和可选偏移量和args属性的对象。 如果没有提供位置,内置默认值({distance: 0.5})用于保持向后兼容。
dia.Link.presentation 一个链路的形状由五个属性决定: Source and Target 创建链接时必须提供源和目标属性。可以提供任何一个元素。 例如: link.source(rect); link.source({ id: rect.id });
link.source(new g.Point(100, 100)); link.source({ x: 100, y: 100 }); Anchor 链接端锚是链接路径想要连接到源/目标端的给定(子)元素中的一个点。 每个链接有两个锚;一个在源端,一个在目标端。如果链接端(源/目标)被指定为元素,链接端锚的精确位置可以由锚属性指定(如果链接端指定为一个点,那么它的坐标将直接用作它的锚)。 源锚和目标锚确定了基本的链接路径,然后,连接点、路由器和连接器的工作就是修改路径,使其看起来更好。 例如: link.source(rect, { anchor: { name: 'bottomLeft', args: { dx: 20, dy: -10 } } }); Connection Point 链路连接点是链路路径实际结束的点。 连接端的连接点可以由connectionPoint属性指定,每个链路有两个连接点;一个在源端,一个在目标端。并且连接点总是在链接路径上(将链接锚和顶点按顺序连接在一起的路径) 通过考虑连线路径和终端元素(大多情况下指图形单元)的期望特性(比如:bounding box, shape boundary, anchor)之间的交叉点来找到连接点。 Connection Strategy 连接策略指定应该为终端元素分配哪个锚点和connectionPoint属性以响应用户交互。 注意: 连接策略不是按单个连线分配的,而是画布级别的配置。 如下: paper.options.connectionStrategy = joint.connectionStrategies.pinAbsolute; 没有提供连接策略,即joint.connectionStrategies。默认情况下使用joint.connectionStrategies.useDefaults函数 Vertices 顶点数组是一个用户定义的链接通过的点数组。 在源锚和目标锚基础上,链接顶点确定基本链接路径。 可以使用links .vertices()函数和相关函数访问这些顶点。(后面会有详解) link.vertices(); link.vertices([{ x: 100, y: 120 }, { x: 150, y: 60 }]); Router 路由器接受一个链接顶点数组,并将它们转换成链接应该经过的路由点数组,然后使用此路由生成连接SVG路径命令。 可以使用link.router()函数访问链接的router属性。 (路由后续会有详解,不做展开) Connector 连接器获取一系列链接路由点并生成SVG路径命令,以便能够呈现链接。 可以使用link.connector()函数访问链接的连接器属性。 示例如下: link.connector('rounded', { raw: true, radius: 20 }); Styling 链接的样式包含在attrs属性中,其结构与元素的attrs属性完全相同。 link.addTo(graph) link.appendLabel(label [, opt]) 在标签数组的末尾添加一个新标签 link.attr(attrs) 例如: link.attr({ '.connection': { stroke: 'blue' }, '.marker-source': { fill: 'red', d: 'M 10 0 L 0 5 L 10 10 z' }, '.marker-target': { fill: 'yellow', d: 'M 10 0 L 0 5 L 10 10 z' } }); link.attr('.marker-source/fill', 'green');
link.clone() link.connector() 返回链接的连接器属性的拷贝 link.connector(connector [, opt]) 设置链接的连接器 link.connector(connectorName [, connectorArgs, opt]) 将链接的连接器设置为值{name: connectorName, args: connectorArgs} link.disconnect() 断开链接与源和目标元素的连接。 link.findView(paper) link.getAncestors() link.getSourceElement() link.getTargetElement() link.getTransitions() 返回所有活动转换(它们的路径)的数组 link.hasLoop([opt]) 如果此链接是循环链接,则返回true link.insertLabel(index, label [, opt]) 在索引处添加一个新标签 link.insertVertex(index, vertex [, opt] 在索引处添加一个新顶点。通过索引-1添加顶点数组末尾的顶点。 link.isEmbeddedIn(element [, opt]) 如果链接嵌入到元素元素中,则返回true link.label(index) 返回索引处的标签。 link.labels() 返回标签数组的拷贝 link.prop(properties) 在元素模型上设置属性(可能是嵌套的)。 link.remove() 从图中删除链接。 link.removeAttr(path [, opt]) 从链接中删除先前的set属性。 link.removeLabel(index [, opt]) 删除索引处的标签 link.removeVertex(index [, opt]) 删除顶点在索引 link.reparent() 自动找到并设置链接的最佳父元素,这样当父元素移动时,链接及其所有顶点也会移动 link.router() 返回链接的路由器属性的拷贝 link.router(router [, opt]) 设置链接的路由器 link.router(routerName [, routerArgs, opt]) 将链接的路由器设置为值{name: routerName, args: routerArgs}。 link.scale(sx, sy, origin [, opt]) 根据给定的原点缩放链接的点(顶点) link.source() 返回链接源属性的拷贝 link.source(source [, opt]) 设置链接的源。 例如: link.source(rect); link.source({ id: rect.id }); link.source(new g.Point(100, 100)); link.source({ x: 100, y: 100 }); link.source(rect, { selector: 'body', anchor: { name: 'bottomLeft', args: { dx: 20, dy: -10 } } });
link.stopTransitions([path]) 停止所有运行转换 link.target() 返回链接的目标属性的拷贝。 link.target(target [, opt]) 设置链接的目标。 link.target(rect); link.target({ id: rect.id }); link.target(new g.Point(100, 100)); link.target({ x: 100, y: 100 }); link.target(rect, { selector: 'body', anchor: { name: 'bottomLeft', args: { dx: 20, dy: -10 } } });
link.toBack() 移动链接,使其位于所有其他单元格(元素/链接)的后面 link.toFront() 与上相反 link.toJSON() 将连线转换成json对象 link.transition(path, value [, opt]) 允许在一段时间内逐渐改变链接属性 例如: //会在100ms内开始改变链路目标坐标,在500ms内执行弹跳效果 link.transition('target', { x: 250, y: 250 }, { delay: 100, duration: 500, timingFunction: joint.util.timing.bounce, valueFunction: joint.util.interpolate.object }); link.translate(tx, ty [, opt]) 将连线顶点转换为x轴上的tx像素和y轴上的ty像素 如果传递了opt对象,那么它可以包含传递给链接或图形上的change事件侦听器的数据
link.vertex(index) 返回索引处的顶点 link.vertex(index, vertex [, opt]) 用顶点的值更新索引处的顶点 例如: link.vertex(0, { x: 100, y: 200 }); link.vertices() 返回顶点数组的拷贝
|
dia.LinkView
在连接视图上添加连线工具 var verticesTool = new joint.linkTools.Vertices(); var segmentsTool = new joint.linkTools.Segments(); var boundaryTool = new joint.linkTools.Boundary();
// 2) creating a tools view var toolsView = new joint.dia.ToolsView({ name: 'basic-tools', tools: [verticesTool, segmentsTool, boundaryTool] });
// 3) attaching to a link view var linkView = link.findView(paper); linkView.addTools(toolsView); linkView.hideTools(); //添加监听 paper.on('link:mouseenter', function(linkView) { linkView.showTools(); });
paper.on('link:mouseleave', function(linkView) { linkView.hideTools(); }); 互相转换: Var linkview = link.findView(paper); Var link = linkview.model; Custom LinkView 自定义连线视图 doubleLinkTools:这个属性设置为true时就意味着在连线两端都呈现连线工具 示例: var CustomLinkView = joint.dia.LinkView.extend({ // custom interactions: pointerdblclick: function(evt, x, y) { this.addVertex(x, y); }, contextmenu: function(evt, x, y) { this.addLabel(x, y); },
// custom options: options: joint.util.defaults({ doubleLinkTools: true, }, joint.dia.LinkView.prototype.options) });
var paper = new joint.dia.Paper({ //... linkView: CustomLinkView, interactive: { vertexAdd: false } // disable default vertexAdd interaction }); linkView.addLabel(x, y [, opt]) 在提供的坐标处向链接添加一个新的默认标签。 例如: var CustomLinkView = joint.dia.LinkView.extend({ contextmenu: function(evt, x, y) { this.addLabel(x, y, { absoluteDistance: true, reverseDistance: true, absoluteOffset: true }); } }); linkView.addTools(toolsView) 添加工具视图到连线视图上(上面有实例) linkView.addVertex(x, y) 在提供的坐标上向链接添加一个新的默认顶点,并让linkView自动确定顶点数组中新顶点的索引。 linkView.getBBox() 返回linkView的绑定框 linkView.getClosestPoint(point) 返回最接近点的连接上的点 linkView.getClosestPointLength(point) 返回连接到最接近点的点的长度 linkView.getClosestPointRatio(point) 返回连接到最近点的比率(标准化长度)。返回的值位于区间[0,1](包括) linkView.getConnection() 返回连接的几何表示 linkView.getConnectionLength() 返回一个缓存的连接总长度(以像素为单位) linkView.getConnectionSubdivisions() 返回连接的段细分数组的缓存数组 linkView.getLabelCoordinates(labelPosition) 根据提供的labelPosition对象返回x和y坐标 linkView.getLabelPosition(x, y [, opt]) 根据提供的x和y坐标返回标签位置对象。 linkView.getPointAtLength(length) 返回从连接开始处开始的路径上的点 linkView.getPointAtRatio(ratio) 返回路径上与连接开始处的比值(标准化长度)的点 linkView.getSerializedConnection() 返回连接的缓存路径数据 linkView.getTangentAtLength(length) 返回一条与路径相切的直线,该线与连接开始处的长度相切 linkView.getTangentAtRatio(ratio) 返回一条与路径相切的直线,该直线与连接开始处的长度之比(标准化长度)成正比 linkView.getVertexIndex(x, y) 返回顶点数组索引,在该索引处插入具有所提供的x和y坐标的新顶点 linkView.hasTools() 如果此链接视图附带一个工具视图,则返回true。 linkView.hasTools(name) 如果该链接视图具有附加的所提供名称的工具视图,则返回true linkView.hideTools() linkView.removeRedundantLinearVertices([opt]) 从模型的顶点数组中删除任何冗余顶点 linkView.removeTools() 删除连接到此链接视图的tools视图 linkView.sendToken(token [, opt, callback]) 沿着链接发送一个令牌 例如: // Send an SVG circle token along the link. var vCircle = V('circle', { r: 7, fill: 'green' }); link.findView(paper).sendToken(vCircle, { duration: 500, direction: 'reverse' }, function() { console.log('animation end'); }); linkView.showTools() linkView.sourceAnchor 记录链路源锚位置的点 linkView.sourceBBox 记录源的位置和尺寸 linkView.sourcePoint 记录链路源连接点位置的点 linkView.targetAnchor linkView.targetBBox linkView.targetPoint |
linkTools 连线工具
Segments : 在链接段上添加句柄 SourceArrowhead : 在链接源上方添加一个句柄
TargetAnchor: 在链接目标锚上方添加一个句柄 Boundary : 显示链接bbox
要创建一个新的链接工具,我们调用它的构造函数 例如: var verticesTool = new joint.linkTools.Vertices({ snapRadius: 10 }); 要创建一个新的链接工具,我们调用它的构造函数 添加可定制的按钮 例如: var infoTool = new joint.linkTools.Button({ markup: [{ tagName: 'circle', selector: 'button', attributes: { 'r': 7, 'fill': '#001DFF', 'cursor': 'pointer' } }, { tagName: 'path', selector: 'icon', attributes: { 'd': 'M -2 4 2 4 M 0 3 0 0 M -2 -1 1 -1 M -1 -4 1 -4', 'fill': 'none', 'stroke': '#FFFFFF', 'stroke-width': 2, 'pointer-events': 'none' } }], distance: 60, offset: 0, action: function(evt) { alert('View id: ' + this.id + '\n' + 'Model id: ' + this.model.id); } }); 除了它们自己的参数外,所有内置链接工具都接受以下可选参数: focusOpacity:工具聚焦时的不透明度是多少 例如: var verticesTool = new joint.linkTools.Vertices({ focusOpacity: 0.5 }); linkTools.Boundary padding:这个选项决定边界区域是否应该在视觉上膨胀,如果是,要膨胀多少。默认是10。 例如: var boundaryTool = new joint.linkTools.Boundary({ focusOpacity: 0.5, padding: 20 }); linkTools.Button 按钮链接工具允许您在链接的给定位置呈现自定义按钮。 它接受5个额外的参数,这些参数可以作为对象传递给link工具构造函数 Distance:按钮放置的距离。(接受负数;然后从连杆的末端开始计算距离。默认值为0;也接受百分比的字符串。) Rotate:按钮是否应该根据连杆在距离指定位置的斜率旋转?默认的是假的。 Offset: 按钮与链接的相对偏移量。正数表示按钮应该偏移到链接的右侧(相对于从源到目标的方向);负数意味着按钮应该偏移到链接的左边(相对于从源到目标的方向)。默认值为0。 Action:当用户单击remove按钮时,会发生什么情况?默认值未定义(没有交互)。 Markup:按钮的标记,以JointJS JSON格式提供。默认是未定义的(没有内容) 示例如下: focusOpacity: 0.5, distance: 60, action: function(evt) { alert('View id: ' + this.id + '\n' + 'Model id: ' + this.model.id); }, markup: [{ tagName: 'circle', selector: 'button', attributes: { 'r': 7, 'fill': '#001DFF', 'cursor': 'pointer' } }, { tagName: 'path', selector: 'icon', attributes: { 'd': 'M -2 4 2 4 M 0 3 0 0 M -2 -1 1 -1 M -1 -4 1 -4', 'fill': 'none', 'stroke': '#FFFFFF', 'stroke-width': 2, 'pointer-events': 'none' } }] }); linkTools.Button类可以被继承,在joint.linkTools命名空间后创建可重用的新的按钮类型。 然后,可以通过调用其构造函数来获得自定义按钮类型的新实例。 例如: name: 'info-button', options: { focusOpacity: 0.5, distance: 60, action: function(evt) { alert('View id: ' + this.id + '\n' + 'Model id: ' + this.model.id); }, markup: [{ tagName: 'circle', selector: 'button', attributes: { 'r': 7, 'fill': '#001DFF', 'cursor': 'pointer' } }, { tagName: 'path', selector: 'icon', attributes: { 'd': 'M -2 4 2 4 M 0 3 0 0 M -2 -1 1 -1 M -1 -4 1 -4', 'fill': 'none', 'stroke': '#FFFFFF', 'stroke-width': 2, 'pointer-events': 'none' } }] } });
var infoButton = new joint.linkTools.InfoButton(); linkTools.Remove 删除链接工具在链接的给定位置呈现一个删除按钮。 它接受5个额外的参数,这些参数可以作为对象传递给link工具构造函数:和上述linkTools.Button的参数类型和作用一致。 示例如下: var removeButton = new joint.linkTools.Remove({ focusOpacity: 0.5, rotate: true, distance: -20, offset: 20 }); linkTools.Segments 段链接工具在链接的所有段上呈现句柄。 它接受四个额外的参数,这些参数可以作为对象传递给link工具构造函数: redundancyRemoval:如果用户安排了两个(或更多)段,使它们位于同一条线上,那么中间的段是否应该被认为是多余的并被删除?默认是true删除 segmentLengthThreshold:显示段句柄(防止句柄溢出其段)的最小段长度。默认是40 snapRadius:当用户移动段时,为了使自己与另一个段保持一致,段应该从多远的地方折断?默认的是10 snapHandle:如果snapRadius选项被设置为true,当用户移动段句柄时段段被按下,那么句柄应该跟着用户指针走,还是应该和段段一起被按下,直到它取消吸附?默认值为true,这意味着句柄与段相冲突。 示例如下: var segmentsTool = new joint.linkTools.Segments({ focusOpacity: 0.5, redundancyRemoval: false, segmentLengthThreshold: 50, snapHandle: false, snapRadius: 10 }); linkTools.SourceAnchor SourceAnchor link工具在链接的源锚上方呈现一个句柄。 它接受5个额外的参数,这些参数可以作为对象传递给link工具构造函数: redundancyRemoval:如果用户移动锚,使其位于具有两个(或更多)顶点的单行上,那么中间的那个(s)应该被认为是多余的并被删除吗?默认是正确的 restrictArea:是否只允许用户在受限区域(源磁铁的包围盒区域)移动锚点?默认是正确的。 areaPadding:如果restrictArea选项设置为true,用户只能在限定的区域内移动锚。 snapRadius:当用户移动锚点时,为了使其与锚点引用保持一致,段块应该在离锚点多远的地方折断?默认是10。 Snap:当用户移动锚点时,应该调用的snap函数 回调函数必须以g返回锚。点并具有签名function(coords, endView, endMagnet, endType, linkView, toolView) 示例如下: var sourceAnchorTool = new joint.linkTools.SourceAnchor({ focusOpacity: 0.5, redundancyRemoval: false, restrictArea: false, snapRadius: 20 }); 下面提供了一个有用的自定义snap函数示例,它将锚固定在限制区最近一侧的中心 var snapAnchor = function(coords, endView, endMagnet) {
// remove rotation of the restricted area var bbox = endView.getNodeUnrotatedBBox(endMagnet); var angle = endView.model.angle(); var origin = endView.model.getBBox().center(); coords.rotate(origin, angle);
// identify the side nearest to pointer coords var anchor; var side = bbox.sideNearestToPoint(coords); switch (side) { case 'left': anchor = bbox.leftMiddle(); break; case 'right': anchor = bbox.rightMiddle(); break; case 'top': anchor = bbox.topMiddle(); break; case 'bottom': anchor = bbox.bottomMiddle(); break; }
// rotate the anchor according to original rotation of restricted area return anchor.rotate(origin, -angle); };
var sourceAnchorTool = new joint.linkTools.SourceAnchor({ snap: snapAnchor; }); linkTools.SourceArrowhead 链接工具在链接的源连接点上方呈现一个类似箭头的句柄。 示例如下: var sourceArrowheadTool = new joint.linkTools.SourceArrowhead({ focusOpacity: 0.5 }); linkTools.TargetAnchor 接工具在链接的目标锚上方呈现一个句柄。 它接受5个额外的参数,这些参数可以作为对象传递给link工具构造函数:和linkTools.SourceAnchor的五个参数一样。 示例如下: focusOpacity: 0.5, redundancyRemoval: false, restrictArea: false, snapRadius: 20 }); 下面提供了一个有用的自定义snap函数示例。它将锚固定在限制区最近一侧的中心: var snapAnchor = function(coords, endView, endMagnet) {
// remove rotation of the restricted area var bbox = endView.getNodeUnrotatedBBox(endMagnet); var angle = endView.model.angle(); var origin = endView.model.getBBox().center(); coords.rotate(origin, angle);
// identify the side nearest to pointer coords var anchor; var side = bbox.sideNearestToPoint(coords); switch (side) { case 'left': anchor = bbox.leftMiddle(); break; case 'right': anchor = bbox.rightMiddle(); break; case 'top': anchor = bbox.topMiddle(); break; case 'bottom': anchor = bbox.bottomMiddle(); break; }
// rotate the anchor according to original rotation of restricted area return anchor.rotate(origin, -angle); };
var targetAnchorTool = new joint.linkTools.TargetAnchor({ snap: snapAnchor; }); linkTools.TargetArrowhead 链接工具在链接的目标连接点上方呈现一个类似箭头的手柄。 示例如下: var targetArrowheadTool = new joint.linkTools.TargetArrowhead({ focusOpacity: 0.5 }); linkTools.Vertices 顶点链接工具在链接的所有顶点之上呈现句柄。 它接受三个额外的参数,这些参数可以作为对象传递给link工具构造函数。 redundancyRemoval:如果用户排列了三个(或更多)顶点,使它们位于一行上,那么中间的顶点是否应该被认为是多余的并被删除了呢?默认是正确的 snapRadius:当用户移动顶点时,为了使自己垂直于另一个顶点,顶点应该从多远的地方折断?默认是20 vertexAdding:用户可以添加新的顶点(通过单击链接的一部分)吗?默认是正确的。 示例如下: var verticesTool = new joint.linkTools.Vertices({ focusOpacity: 0.5, redundancyRemoval: false, snapRadius: 10, vertexAdding: false, }); |
Routers 路由 路由器接受一个链接顶点数组,并将它们转换成链接应该经过的路由点数组。 可以使用link.router()函数访问链接的router属性。 顶点和路由的区别在于,顶点是用户定义的,而路由是计算出来的。 有五个内置路由器: 'manhattan' 'metro' 'normal' 'orthogonal' 'oneSide' 示例如下: link.router('orthogonal', { elementPadding: 10 }); 默认路由器为'normal';这可以通过defaultRouter 画布属性选项进行更改。 示例如下: paper.options.defaultRouter = { name: 'orthogonal', args: { elementPadding: 10 } }); 特性:
小贴士:正交线段就是两条线夹角成90°。
JointJS的模块化架构允许根据需要将路由器与连接器进行混合和匹配。 例如,可以指定一个连线在“manhattan”路由器之上使用“jumpover”连接器。 示例如下: var link = new joint.shapes.standard.Link(); link.source(rect); link.target(rect2); link.router('manhattan'); link.connector('jumpover'); routers.custom 自定义路由 方式:在joint.routers的命名空间下定义新路由,或者直接作为连线的路由器属性传递过去。 在任何一种情况下,router函数必须返回链接应该经过的路由点数组(不包括开始/结束连接点)。 函数类型格式如下:function( 参数: Vertices:路线的顶点。 Args:当用户调用路由器方法时,带有附加可选参数的对象。 linkView:连接的LinkView。 在joint.routers命名空间中定义的路由器的例子如下: joint.routers.randomWalk = function(vertices, args, linkView) {
var NUM_BOUNCES = args.numBounces || 20;
vertices = joint.util.toArray(vertices).map(g.Point);
for (var i = 0; i < NUM_BOUNCES; i++) {
var sourceCorner = linkView.sourceBBox.center(); var targetCorner = linkView.targetBBox.center();
var randomPoint = g.Point.random(sourceCorner.x, targetCorner.x, sourceCorner.y, targetCorner.y); vertices.push(randomPoint) }
return vertices; }
var link = new joint.shapes.standard.Link(); link.source(source); link.target(target);
link.router('randomWalk', { numBounces: 10 }); 下面提供了一个作为函数传递的路由器示例(注意:这种方法不支持传递自定义args,也不能使用graph.toJSON()函数对其进行序列化。): var link = new joint.shapes.standard.Link(); link.source(source); link.target(target);
link.router(function(vertices, args, linkView) {
var NUM_BOUNCES = 20;
vertices = joint.util.toArray(vertices).map(g.Point);
for (var i = 0; i < NUM_BOUNCES; i++) {
var sourceCorner = linkView.sourceBBox.center(); var targetCorner = linkView.targetBBox.center();
var randomPoint = g.Point.random(sourceCorner.x, targetCorner.x, sourceCorner.y, targetCorner.y); vertices.push(randomPoint) }
return vertices; }); routers.manhattan manhattan路由器是“orthogonal路由器的智能版本。 它用正交线段连接顶点,必要时插入路线点,同时避开路上的障碍物。 路由器有一些有用的选项来决定算法的行为。这些选项可以作为路由器传递,参数: Step:由“曼哈顿”寻路算法控制的虚拟网格大小,也是应用在开始/结束元素的填充大小(数字越小,复杂度越高)。 当与dia.Paper.option.gridSize相等时性能最佳,默认值是10. maximumLoops:寻路循环的最大迭代次数。 如果迭代次数超过这个最大值,就会中止寻路,而使用回退路由器(orthogonal)。更高的数字->更高的复杂性。默认是2000。 maxAllowedDirectionChange:manhattan路由方向的最大变化(以度计)。默认是90。 Perpendicular:linkView.perpendicular是否生效。这就导致路由器不能精确地链接到终端元素的锚点,而是连接到一个离他很近的正交的点。默认true。 excludeEnds:带有source、target的字符串数组,告诉算法给定的结束元素不应被视为障碍。默认空数组(两个都被视为障碍) excludeTypes:在计算路由时不应考虑障碍的元素类型数组。默认是['basic.Text'] startDirection:一个数组,指定元素可能的起始方向。默认为['left', 'right', 'top', 'bottom'](允许所有方向) 比如:['bottom'],总是从源元素的底部开始。 endDirection: 指定元素可能的结束方向的数组。 示例如下: link.router('manhattan', { excludeEnds: ['source'], excludeTypes: ['myNamespace.MyCommentElement'], startDirections: ['top'], endDirections: ['bottom'] }); routers.metro metro路由器是对“manhattan”路由器的一种改进,它能产生一个octolinear路径(由正交和对角线段组成的路线,类似于伦敦地铁地图的设计) 它还避免了障碍,并接受四个参数(相对于manhattan路由器有些改变): maximumLoops:如果在给定的迭代次数中找不到路径,不要使用orthogonal路由器作为后备,而是使用一个自定义的不能避免障碍的octolinear后备路线。 maxAllowedDirectionChange:默认更改为45。 startDirection,endDirection和manhattan路由一样。 示例如下: link.router('metro', { excludeEnds: ['source'], excludeTypes: ['myNamespace.MyCommentElement'], startDirections: ['top'], endDirections: ['bottom'] }); routers.normal 这是链接的默认路由器,也是最简单的路由器。 它没有任何选择,也不做任何事情;它返回传递给它的顶点,而不需要修改作为要采取的路由。 示例如下: link.router('normal'); routers.oneSide “oneSide路由器是orthogonal路由器的受限版本。 接受两个参数: Side:和manhattan一样。 Padding:连接点与第一个/最后一个顶点之间的最小间隙。默认值是40。 示例如下: link.router('oneSide', { side: 'top', padding: 30 }); routers.orthogonal orthogonal路由器返回具有正交线段的路由。 它产生额外的路线点,以便在路上创造正确的角度。它无法避免障碍。 只有一个可选参数: elementPadding:第一个/最后一个路径角可以放置元素的最小距离。默认是20。 示例如下: link.router('orthogonal', { elementPadding: 10 }); 为了向后兼容,orthogonal路由也可以通过设置link.manhattan属性为true实现。 示例如下: // deprecated link.set('manhattan', true);
|
ToolsView 连线工具组视图
两个属性: 示例如下: // 1) creating link tools var verticesTool = new joint.linkTools.Vertices(); var segmentsTool = new joint.linkTools.Segments(); var boundaryTool = new joint.linkTools.Boundary();
// 2) creating a tools view var toolsView = new joint.dia.ToolsView({ name: 'basic-tools', tools: [verticesTool, segmentsTool, boundaryTool] });
// 3) attaching to a link view var linkView = link.findView(paper); linkView.addTools(toolsView);
toolsView.focusTool(tool) 当工具聚焦时,这个工具视图中的所有其他工具都会被隐藏,并且根据工具的focus选项改变工具的不透明度。 toolsView.blurTool(tool) 与上相反 toolsView.getName() toolsView.hide() toolsView.show() ToolView 连线工具视图 其实在toolsview的例子中已经可以看出,一组工具由若干个独立的工具组成,这里的toolsview即为单个工具的视图。 用法和toolsview类似。 toolView.blur() toolView.focus() toolView.getName() 例如: 创建一个自定义的工具 joint.linkTools.InfoButton = joint.linkTools.Button.extend({ name: 'info-button', options: { markup: [{ tagName: 'circle', selector: 'button', attributes: { 'r': 7, 'fill': '#001DFF', 'cursor': 'pointer' } }, { tagName: 'path', selector: 'icon', attributes: { 'd': 'M -2 4 2 4 M 0 3 0 0 M -2 -1 1 -1 M -1 -4 1 -4', 'fill': 'none', 'stroke': '#FFFFFF', 'stroke-width': 2, 'pointer-events': 'none' } }], distance: 60, offset: 0, action: function(evt) { alert('View id: ' + this.id + '\n' + 'Model id: ' + this.model.id); } } }); toolView.hide() toolView.show() toolView.isVisible() 如果工具当前可见,返回true |
Cell dia.Cell.define 定义一个新的图形 // default attributes markup: [{ tagName: 'ellipse', selector: 'ellipse' // not necessary but faster} ], attrs: { ellipse: { fill: 'white', stroke: 'black', strokeWidth: 4, refRx: .5, refRy: .5, refCx: .5, refCy: .5 } } });
// Instantiate an element var ellipse = (new Ellipse()).position(100, 100).size(120, 50).addTo(graph); // Define a new ColoredEllipse class // Inherits from Ellipse var ColoredEllipse = Ellipse.define('examples.ColoredEllipse', { // overridden Ellipse default attributes // other Ellipse attributes preserved attrs: { ellipse: { fill: 'lightgray' } } }, { // prototype properties // accessible on `this.(...)` - as well as, more precisely, `this.prototype.(...)` // useful for custom methods that need access to this instance // shared by all instances of the class randomizeStrokeColor: function() { var randomColor = '#' + ('000000' + Math.floor(Math.random() * 16777215).toString(16)).slice(-6); return this.attr('ellipse/stroke', randomColor); } }, { // static properties // accessible on `this.constructor.(...)` // useful for custom methods and constants that do not need an instance to operate // however, a new set of static properties is generated every time the constructor is called // (try to only use static properties if absolutely necessary) createRandom: function() { return (new ColoredEllipse()).randomizeStrokeColor(); } });
// Instantiate an element var coloredEllipse = ColoredEllipse.createRandom().position(300, 100).size(120, 50).addTo(graph); dia.Cell.markup markup:指定JSON元素数组的XML字符串或JSON标记。用作模板,在呈现关联的cellView时动态构建DOM元素 xml字符串: Json数据: cell.getParentCell():返回单元格的父单元格,如果没有则返回null element.isLink() |
CellView 图形单元视图 是 joint.dia.Cell model的视图。 作用: 和linkview相对于link来说是一样的,有三点:
highlighter: { name: 'stroke', options: { width: 3 } } |
dia.Element 图形元素 图形元素的模型:继承自 joint.dia.Cell ,并且自带一些特定的属性和方法
2. Presentation 表现属性 |
dia.ElementView 图形元素视图 joint.dia.Element model 的视图,它继承了joint.dia.CellView ,其作用:
|
Shapes Devs devs插件 Devs插件为您提供了具有预定义的输入和输出端口组和简化API的现成形状。 joint.shapes.devs.Model 模型形状在JointJS内置端口上实现了简单的API。它将端口分为两个语义组(in和out),并为添加和删除端口添加了方便的方法。 element.addInPort(port, [opt]) 向' inPorts '数组中添加一个端口,其中' port '是端口的名称 element.addOutPort(port, [opt]) 向“outPorts”数组中添加一个端口,其中“port”是该端口的名称。 element.changeInGroup(properties, [opt]) 更改输入端口的设置,其中“properties”是具有组配置的对象。 默认情况下,它使用新配置扩展了以前的设置。通过选择使以前的设置无效来传递{rewrite: true}。 element.changeOutGroup(properties, [opt]) 类似上一个方法,只不过是对输出端口进行操作 element.removeInPort(port, [opt]) 从“inPorts”数组的元素中删除一个端口,其中“port”是该端口的名称 element.removeOutPort(port, [opt]) 从“outPorts”数组的元素中删除一个端口,其中“port”是该端口的名称。 joint.shapes.devs.Link devs.Link继承了joint.dia.Link,更改链接外观。 示例如下: var shape = new joint.shapes.devs.Model({ position: { x: 100, y: 100 }, inPorts: ['in1', 'in2'], outPorts: ['out1', 'out2'] });
shape.addTo(graph);
// adding/removing ports dynamically shape.addInPort('in3'); shape.removeOutPort('out1').addOutPort('out3');
var link = new joint.shapes.devs.Link({ source: { id: shape.id, port: 'out3' }, target: { x: 200, y: 300 } }); link.addTo(graph);
// moving the input ports from `left` to `top` shape.changeInGroup({ position: 'top' }); // moving the output ports 'right' to 'bottom' shape.changeOutGroup({ position: 'bottom' }); Hierarchical diagrams 层次图 作为插件开发工具的一部分,还有另外两种图形是为分层图设计的。devs.Atomic和devs.Coupled。 它们继承自devs.Model只有颜色和尺寸不同,这些图形的目的是使您能够根据其类型在应用程序中实现自定义逻辑。 层次图常用方法:
shapes.standard 标准插件 标准插件为您提供了最常见形状的现成、高性能版本。这些形状可以按原样使用,也可以作为创建定制形状。 常见标准图集预览: var standard = joint.shapes.standard; var rectangle = new standard.Rectangle(); var circle = new standard.Circle(); var ellipse = new standard.Ellipse(); var path = new standard.Path(); var polygon = new standard.Polygon(); var polyline = new standard.Polyline(); var cylinder = new standard.Cylinder(); var image = new standard.Image(); var borderedImage = new standard.BorderedImage(); var embeddedImage = new standard.EmbeddedImage(); var headeredRectangle = new standard.HeaderedRectangle(); var textBlock = new standard.TextBlock(); var link = new standard.Link(); var doubleLink = new standard.DoubleLink(); var shadowLink = new standard.ShadowLink(); shapes.standard.BorderedImage 带有边框和标签的图像。 示例如下: var borderedImage = new joint.shapes.standard.BorderedImage(); borderedImage.resize(150, 100); borderedImage.position(225, 410); borderedImage.attr('root/title', 'joint.shapes.standard.BoarderedImage'); borderedImage.attr('label/text', 'Bordered\nImage'); borderedImage.attr('border/rx', 5); borderedImage.attr('image/xlinkHref', 'image.png'); borderedImage.addTo(graph);
shapes.standard.Circle 带有标签的圆圈。 示例如下: var circle = new joint.shapes.standard.Circle(); circle.resize(100, 100); circle.position(250, 10); circle.attr('root/title', 'joint.shapes.standard.Circle'); circle.attr('label/text', 'Circle'); circle.attr('body/fill', 'lightblue'); circle.addTo(graph);
shapes.standard.Cylinder 带有标签的圆柱体。 用处较少(略)
shapes.standard.DoubleLink 双线链接。 示例如下: var doubleLink = new joint.shapes.standard.DoubleLink(); doubleLink.prop('source', { x: 500, y: 600 }); doubleLink.prop('target', { x: 450, y: 750 }); doubleLink.prop('vertices', [{ x: 500, y: 700 }]); doubleLink.attr('root/title', 'joint.shapes.standard.DoubleLink'); doubleLink.attr('line/stroke', '#30d0c6'); doubleLink.addTo(graph);
shapes.standard.Ellipse 带标签的椭圆。 示例如下: var ellipse = new joint.shapes.standard.Ellipse(); ellipse.resize(150, 100); ellipse.position(425, 10); ellipse.attr('root/title', 'joint.shapes.standard.Ellipse'); ellipse.attr('label/text', 'Ellipse'); ellipse.attr('body/fill', 'lightblue'); ellipse.addTo(graph);
shapes.standard.EmbeddedImage 嵌入带有标签的矩形的图像。 示例如下: var embeddedImage = new joint.shapes.standard.EmbeddedImage(); embeddedImage.resize(150, 100); embeddedImage.position(425, 410); embeddedImage.attr('root/title', 'joint.shapes.standard.EmbeddedImage'); embeddedImage.attr('label/text', 'Embedded\nImage'); embeddedImage.attr('image/xlinkHref', 'image.png'); embeddedImage.addTo(graph);
shapes.standard.HeaderedRectangle 带标题的矩形。 示例如下: var headeredRectangle = new joint.shapes.standard.HeaderedRectangle(); headeredRectangle.resize(150, 100); headeredRectangle.position(25, 610); headeredRectangle.attr('root/title', 'joint.shapes.standard.HeaderedRectangle'); headeredRectangle.attr('header/fill', 'lightgray'); headeredRectangle.attr('headerText/text', 'Header'); headeredRectangle.attr('bodyText/text', 'Headered\nRectangle'); headeredRectangle.addTo(graph);
shapes.standard.Image 带有标签的图像。 示例如下: var image = new joint.shapes.standard.Image(); image.resize(150, 100); image.position(25, 410); image.attr('root/title', 'joint.shapes.standard.Image'); image.attr('label/text', 'Image'); image.attr('image/xlinkHref', 'image.png'); image.addTo(graph);
shapes.standard.Link 单线链接。 示例如下: var link = new joint.shapes.standard.Link(); link.prop('source', { x: 450, y: 600 }); link.prop('target', { x: 400, y: 750 }); link.prop('vertices', [{ x: 450, y: 700 }]); link.attr('root/title', 'joint.shapes.standard.Link'); link.attr('line/stroke', '#fe854f'); link.addTo(graph);
shapes.standard.Path 带标签的路径。 示例如下: var path = new joint.shapes.standard.Path(); path.resize(100, 100); path.position(50, 210); path.attr('root/title', 'joint.shapes.standard.Path'); path.attr('label/text', 'Path'); path.attr('body/refD', 'M 0 5 10 0 C 20 0 20 20 10 20 L 0 15 Z'); path.addTo(graph);
shapes.standard.Polygon 带标签的多边形。 示例如下: var polygon = new joint.shapes.standard.Polygon(); polygon.resize(100, 100); polygon.position(250, 210); polygon.attr('root/title', 'joint.shapes.standard.Polygon'); polygon.attr('label/text', 'Polygon'); polygon.attr('body/refPoints', '0,10 10,0 20,10 10,20'); polygon.addTo(graph);
shapes.standard.Polyline 带有标签的折线 示例如下: var polyline = new joint.shapes.standard.Polyline(); polyline.resize(100, 100); polyline.position(450, 210); polyline.attr('root/title', 'joint.shapes.standard.Polyline'); polyline.attr('label/text', 'Polyline'); polyline.attr('body/refPoints', '0,0 0,10 10,10 10,0'); polyline.addTo(graph);
shapes.standard.Rectangle 带标签的矩形。 示例如下: var rectangle = new joint.shapes.standard.Rectangle(); rectangle.resize(100, 100); rectangle.position(50, 10); rectangle.attr('root/title', 'joint.shapes.standard.Rectangle'); rectangle.attr('label/text', 'Rectangle'); rectangle.attr('body/fill', 'lightblue'); rectangle.addTo(graph);
shapes.standard.ShadowLink 带阴影的粗线 示例如下: var shadowLink = new joint.shapes.standard.ShadowLink(); shadowLink.prop('source', { x: 550, y: 600 }); shadowLink.prop('target', { x: 500, y: 750 }); shadowLink.prop('vertices', [{ x: 550, y: 700 }]); shadowLink.attr('root/title', 'joint.shapes.standard.ShadowLink'); shadowLink.attr('line/stroke', '#5654a0'); shadowLink.addTo(graph);
shapes.standard.TextBlock 带有HTML标签的矩形 示例如下: var textBlock = new joint.shapes.tandard.TextBlock(); textBlock.resize(100, 100); textBlock.position(250, 610); textBlock.attr('root/title', 'joint.shapes.standard.TextBlock'); textBlock.attr('body/fill', 'lightgray'); textBlock.attr('label/text', 'Hyper Text Markup Language'); // Styling of the label via `style` presentation attribute (i.e. CSS). textBlock.attr('label/style/color', 'red'); textBlock.addTo(graph); |
JointJs提供的一些工具方法 util.breakText util.breakText(text, size [, attrs, opt]) 将文本分成几行,使文本适合于按大小定义的边框。宽度和高度(可选) 示例如下: joint.util.breakText('this is quite a long text', { width: 50 }) 该方法接受以下参数:
util.cancelFrame util.cancelFrame(requestId) 通过调用joint.util.nextFrame取消requestId预先计划的动画帧请求
util.dataUriToBlob util.dataUriToBlob(dataUri) 将数据URI字符串转换为Blob对象。
util.downloadBlob util.downloadBlob(blob, fileName) 提供的Blob对象作为一个文件下载,并给定文件名
util.downloadDataUri util.downloadDataUri(dataUri, fileName) 下载提供的数据URI字符串作为具有给定文件名的文件。
util.flattenObject util.flattenObject(object, delim, stop) 将嵌套对象销毁,直到stop函数返回true为止 stop function函数接受当前遍历的节点的值 delim是结果对象中组合键的分隔符。 示例如下: joint.util.flattenObject({ a: { a1: 1, a2: 2, a3: { a31: 5, a32: { a321: { a3211: 5 } } } }, b: 6 }, '/', function(v) { return !!v.a321; });
/* { "a/a1": 1, "a/a2": 2, "a/a3/a31": 5, "a/a3/a32": { "a321": { "a3211": 5 } }, "b": 6 } */ util.getByPath util.getByPath(object, path, delim) 在嵌套对象的路径中返回值,delim是路径中使用的分隔符, 示例如下: joint.util.getByPath({ a: { aa: { aaa: 3 } } }, 'a/aa/aaa', '/'); // 3
util.getElementBBox util.guid() 返回页面的唯一标识符
util.imageToDataUri util.imageToDataUri(url, callback) 将url处的图像转换为数据URI方案 (如果您需要将图像直接嵌入到图表中,而不是让它们在外部引用,那么这是非常有用的。) 回调函数格式: function(
util.isPercentage util.isPercentage(val) 当val是一个百分比的字符串(比如:“10%”)时,返回true。
util.nextFrame util.nextFrame(callback [, context]) 告诉浏览器在下一次重新绘制之前调度回调函数
util.normalizeSides util.normalizeSides(box) 返回表单的新对象格式如:{top: Number, right: Number, bottom: Number, left: Number} 如果box是一个数字,那么四个边的值就是这个数字 示例如下: joint.util.normalizeSides() // { top: 0, right: 0, bottom: 0, left: 0 } joint.util.normalizeSides(5) // { top: 5, right: 5, bottom: 5, left: 5 } joint.util.normalizeSides({ horizontal: 5 }) // { top: 0, right: 5, bottom: 0, left: 5 } joint.util.normalizeSides({ left: 5 }) // { top: 0, right: 0, bottom: 0, left: 5 } joint.util.normalizeSides({ horizontal: 10, left: 5 }) // { top: 0, right: 10, bottom: 0, left: 5 } joint.util.normalizeSides({ horizontal: 0, left: 5 }) // { top: 0, left: 5, right: 0, bottom: 0 }
util.sanitizeHTML util.sanitizeHTML(html) 清理提供的HTML(字符串),以防止XSS攻击 示例如下: joint.util.sanitizeHTML(' Hello Hello joint.util.sanitizeHTML(' Hello Hello joint.util.sanitizeHTML(' Hello Hello joint.util.sanitizeHTML(' Hello Hello
util.setAttributesBySelector util.setAttributesBySelector(el, attrs) 根据attrs对象中的选择器,在DOM元素(SVG或HTML) el及其派生元素上设置属性 示例如下: var myEl = document.querySelector('.mydiv'); joint.util.setAttributesBySelector(myEl, { '.myDiv': { 'data-foo': 'bar' }, // Note the reference to the myEl element itself. 'input': { 'value': 'my value' } });
util.setByPath util.setByPath(object, path, value, delim) 在嵌套对象中的路径上设置值。delim是路径中使用的分隔符。 示例如下: joint.util.setByPath({ a: 1 }, 'b/bb/bbb', 2, '/'); /* { "a": 1, "b": { "bb": { "bbb": 2 } } } */
util.shapePerimeterConnectionPoint util.shapePerimeterConnectionPoint(linkView, view, magnet, ref) 该函数可直接应用于画布中的linkConnectionPoint参数。 链接将尝试在连接形状的周长上找到最佳的连接点,而不仅仅是在边界框上。 示例如下: var paper = new joint.dia.Paper({ // ... linkConnectionPoint: joint.util.shapePerimeterConnectionPoint // ... })
util.sortElements util.sortElements(elements, comparator) 根据比较器(elementA, elementB)函数改变元素的顺序 比较器: function compare(a, b) { if (a is less than b by some ordering criterion) { return -1; } if (a is greater than b by the ordering criterion) { return 1; } // a must be equal to b return 0; }
util.toggleFullScreen util.toggleFullScreen([element]) 使得(或取消)一个元素显示全屏(默认元素是window.top.document.body) 例如:joint.util.toggleFullScreen(paper.el);
util.unsetByPath util.uuid() 返回一个pseudo-UUID(通用唯一标识符(Universally Unique Identifier))。
util.format.number util.format.number(specifier, value) 根据Python格式规范迷你语言中定义的说明符的格式化数字 示例如下: joint.util.format.number('.2f', 5) // 5.00 joint.util.format.number('03d', 5) // 005 joint.util.format.number('.1%', .205) // 20.5% joint.util.format.number('*^9', 5) // ****5****
|