天天看点

JointJS官方API的个人整理

由于JointJs官方API是英文,所以学习过程中对此进行部分(没有完全)汉化整理,以及一些个人理解。

锚点anchor

链接锚是一个链接想要到达的点(这意味着连接端点最终未必就落在上面)作为它的端点。

link.source(model, {

    anchor: {

        name: 'midSide',

        args: {

            rotate: true,

            padding: 20

        }

    }

});

注意:

  1. model:就是jointjs里规定的诸如矩形、椭圆等视图元素
  2. name:name值即锚点位置    

    备选项:   center modelCenter  perpendicular  midSide  bottom left right top bottomLeft bottomRight topLeft topRight                                               

  3. padding属性指偏移距离,另外还有dx,dy,意为横向和竖向偏移量,可以用数字和百分比字符串

连接点connectionPoints

连线连接点是连线路由的端点。这一点与链接锚点不同,因为它考虑了结束元素的存在。连接点通过连线末端定义中提供的connectionPoint属性设置(即提供给link.source()和link.target()函数的对象)。

link.source(model, {

    connectionPoint: {

        name: 'boundary',

        args: {

            sticky: true

        }

    }

});

注意:

  1. 在JointJS中有四个内置的连接点功能 anchor bbox boundary rectangle

    anchor——锚处的连接点;

    bbox ——bbox边界的默认连接点

    boundary——实际形状边界的连接点

    rectangle——非旋转bbox边界处的连接点

  2. Sticky:设置为true的话,使用结束元素边界上最近的点
  3. 还有其他属性比如:insideout extrapolate sticky precision selector stroke

连接策略connectionStrategies

当用户修改链接端点的位置时,连接策略就会起作用。

两种情况:

  1. 当用户拖动链接端点并将其连接到元素或其端口时,连接策略在用户拖动链接端点后确定终端锚。
  2. 当用户创建链接时,例如单击端口,连接策略决定新链路的源锚。

    1.有三种内置的连接策略:

    useDefaults

    pinAbsolute

    pinRelative

    2.默认连接策略在纸质设置中被指定为null,这相当于joint.connectionStrategies.useDefaults

      通过下方代码可以修改设置默认连接策略:

      paper.options.connectionStrategy = joint.connectionStrategies.pinAbsolute;

案例:

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。这个对象将被这个函数修改,然后作为返回值发送

endView  dia.ElementView 我们连接到的ElementView。元素模型可以访问为endView.model;这对于基于元素属性编写条件逻辑可能有用。

endMagnet  SVGElement  页面中的SVGElement包含连接到的磁铁(元素/子元素/端口)。

cords  g.Point  在调用连接策略时记录用户指针的x-y坐标的点对象。

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

});

以及三种默认连接器:

  1. jumpover

    “跳投”连接器以小弧代替链路交叉点画直线。(目前,它无法检测到具有“平滑”路由器链接的交叉点)。

    参数: size(The size of the jump,默认5) 和 jump(样式:arc,cubic,gap)

  2. normal 默认
  3. rounded

    “圆角”连接器提供直线路线点,同时平滑路线上的所有角落。

    参数:radius 圆角的曲线半径。默认是10。

  4. smooth

    平滑”连接器使用三次贝塞尔曲线插值路线点。

    或者

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。

图像上所有的图形单元存储在属性

cells

中。

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])  使用从制定元素开始的宽度优先搜索算法遍历图

下图显示了元素在图中遍历的顺序:

如果参数

inbound

 =true,则反向搜索;如果

outbound

 =true,搜索则遵循链接方向。

如果没有使用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])  在图中得到元素的所有邻居(不是连线是图形元素)。

如果参数

inbound

 =true,只有入站邻居元素会被返回

outbound

 =true,只有出站 邻居元素会被返回

deep

 =true,返回嵌入到元素中的所有元素的所有邻居

graph.getPredecessors(element [, opt])  返回元素的所有前任元素的数组(默认深度优先算法)

参数

breadthFirst

 =true,使用第一搜索算法。

参数deep设置为true,也要考虑到嵌入的元素。

graph.getSinks()  返回图中的所有叶子节点的数组

graph.getSources()  返回图的所有根节点的数组

graph.getSubgraph(cells [, opt])  返回一个单元格数组,该数组是查找与单元格数组中的任何单元格连接的元素/链接的结果

graph.getSuccessors(element [, opt])  返回元素的所有后续元素的数组

graph.isNeighbor(elementA, elementB [, opt])  如果elementB是elementA的邻居,返回true

同样有

deep

inbound

outbound

参数。

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 是 

joint

.

dia

.

Graph

模型的视图。继承 Backbone View,在其构造函数中接受具有众多设置的options对象

示例如下:

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,具有一些特定于链接的附加属性和方法。

两个关键属性:

source

 and 

target

单个连接实例提供以下属性:

markup

 :提供自定义链接标记。

attrs

 :提供自定义链接属性

vertices

 :提供一个顶点数组

vertexMarkup

 :提供自定义顶点标记(悬停时)

toolMarkup

 :提供自定义工具标记(悬停)

doubleToolMarkup

 :为第二组工具提供自定义标记(如果linkView.doubleLinkTools=true,在悬停时的样式)

arrowheadMarkup

 :提供自定义箭头标记(悬停)

labels

 :提供一个标签数组,每个都可以指定自己的标记、位置和属性。

也可以将定制属性传递给链接。

为了实现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

 :为链接上的任何更改而触发的通用事件

change:source

change:target

change:attrs

(简单,不做详解)

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提供(例如:'<rect /><text />'),或者JSON数组(例如:[{ tagName: 'rect' }, { tagName: 'text' }])。

如果标签上没有提供标记,则标记取自连线的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

target

vertices

connector

 and 

router

.

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

连线视图的三大作用:

1.  在画布上渲染和绘制连线;

2.  对连线相关事件进行监听和处理

  1. 提供各种方法访问和处理连线属性

在连接视图上添加连线工具

// 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);

linkView.hideTools();

//添加监听

paper.on('link:mouseenter', function(linkView) {

    linkView.showTools();

});

paper.on('link:mouseleave', function(linkView) {

    linkView.hideTools();

});

关于link和linkview:

互相转换:

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  连线工具

Vertices

 :在链接顶点上添加句柄

Segments : 在链接段上添加句柄

SourceArrowhead : 在链接源上方添加一个句柄

TargetArrowhead

 :在链接目标上方添加一个句柄

SourceAnchor

 :在链接源锚上方添加一个句柄

TargetAnchor: 在链接目标锚上方添加一个句柄

Boundary : 显示链接bbox

Remove

 : 添加一个交互式删除按钮

要创建一个新的链接工具,我们调用它的构造函数

例如:

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

边界链接工具呈现一个矩形边框来显示链接的边界框。

它接受一个额外的参数,这个参数可以作为对象传递给link工具构造函数

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格式提供。默认是未定义的(没有内容)

示例如下:

var infoButton = new joint.linkTools.Button({

    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命名空间后创建可重用的新的按钮类型。

然后,可以通过调用其构造函数来获得自定义按钮类型的新实例。

例如:

joint.linkTools.InfoButton = joint.linkTools.Button.extend({

    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的五个参数一样。

示例如下:

var targetAnchorTool = new joint.linkTools.TargetAnchor({

    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

    }

});

特性:

  1. manhattan和metro路由器是智能路由器;他们会自动避开路上的障碍(图形元素Element)。
  2. orthogonal、manhattan和“oneSide路由器产生的路由完全由垂直和水平段组成。“metro”路由器生成由正交和对角线段组成的路由。

小贴士:正交线段就是两条线夹角成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

)

参数:

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  连线工具组视图

joint

.

dia

.

ToolsView

 类是一组链接工具的容器。当把toolsview添加到linkview时,将把工具以组的形式渲染出来。

两个属性:

示例如下:

// 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

图单元格的基本模型。

本质:就是一个带着一些附加的属性和方法的backbone的model

另外,每个cell都会有一个唯一的id

dia.Cell.define

定义一个新的图形

var Ellipse = joint.dia.Element.define('examples.Ellipse', {

    // 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

cell.isElement():判断是否是图形元素(link则返回false)

element.isLink()

cell.parent():返回单元格的父属性

CellView  图形单元视图

是 joint.dia.Cell model的视图。

作用:

和linkview相对于link来说是一样的,有三点:

  1. 在纸内绘制单元格
  2. 处理单元格的指针事件
  3. 提供使用单元格的各种方法(可视化)

怎么找到与特定单元格(模型)关联的视图?

方法:var cellView = paper.findViewByModel(cell);

cellView.highlight([el[, options]])

el:如果没有写的话,则默认使用cell view的el

option:

上述:

  name:即高亮的名称

  options:该属性会传递给name制定的高亮样式中

  type:高亮的类型(embedding, connecting, magnetAvailability, or elementAvailability)

高亮的样式也是可以定义的,例如:

cellView.highlight(null, {

    highlighter: {

        name: 'stroke',

        options: {

            width: 3

        }

}

});

cellView.unhighlight([el[, options]]) : 取消高亮显示

注意: 如果使用自定义选项突出显示单元格,则在使用unhighlight方法时必须提供完全相同的选项。

dia.Element 图形元素

图形元素的模型:继承自 joint.dia.Cell ,并且自带一些特定的属性和方法

这些特定是性质可以分为三类:

  1. Geometry 几何属性

    比如position,angle,size

    上面三种属性都可以通过get()/set()方法设置和获取,同时其各自都有自己专属的访问方法,如下:

    position:  translate ,angle:  rotate ,size: resize(后面会展开)

2. Presentation 表现属性

  另一个重要属性是attrs,它是一个对象,其键表示匹配子元素的选择器和将设置在子元素上的SVG属性值。这些属性决定最终图形元素的展示样式。

   不建议直接更改attrs对象,而是使用attr方法。

3. Nesting 嵌套

  元素的最后两个属性是嵌入和父元素。这两个属性与包含或包含在构成层次结构的其他元素中的元素相关。

dia.Element.events 元素事件

例如:

// Listening for changes of the position to a single element

element1.on('change:position', function(element1, position) {

  alert('element1 moved to ' + position.x + ',' + position.y);

});

// All elements events are also propagated to the graph.

graph.on('change:position', function(element, position) {

  console.log('Element ' + element.id + 'moved to ' + position.x + ',' + position.y);

});

// Using the option parameter and a custom attribute

graph.on('change:custom', function(element, custom, opt) {

  if (opt.consoleOutput) {

    console.log('Custom attribute value changed to "' + custom + '"');

  }

});

element2.prop('custom', 'myValue', { consoleOutput: true });

dia.Element.ports 端口

定义一个端口,并且给一个图形元素添加端口

// Single port definition

var port = {

    // id: 'abc', // generated if `id` value is not present

    group: 'a',

    args: {}, // extra arguments for the port layout function, see `layout.Port` section

    label: {

        position: {

            name: 'right',

            args: { y: 6 } // extra arguments for the label layout function, see `layout.PortLabel` section

        },

        markup: '<text class="label-text" fill="blue"/>'

    },

    attrs: { text: { text: 'port1' } },

    markup: '<rect width="16" height="16" x="-8" strokegit ="red" fill="gray"/>'

};

// a.) add a port in constructor.

var rect = new joint.shapes.standard.Rectangle({

    position: { x: 50, y: 50 },

    size: { width: 90, height: 90 },

    ports: {

        groups: {

            'a': {}

        },

        items: [port]

    }

});

// b.) or add a single port using API

rect.addPort(port);

定义一组端口

// Define ports and port groups in element constructor.

   var groupA;

   var rect = new joint.shapes.basic.Rect({

        // ...

        ports: {

            groups: {

                'group1': groupA,

                // 'group2': ...,

                // 'group3': ...,

            },

            items: []

        }

    });

    groupA = {

            position: {

                name: 'string', // layout name

                args: {}, // arguments for port layout function, properties depends on type of layout

            },

            label: {

                // ....

            },

            attrs: {},

            markup: '<rect width="10" height="10" stroke="red"/>'

        };

Custom markup

自定义端口,端口和端口标签都可以自定义

var rect = new joint.shapes.basic.Rect({

        // ...

    });

    rect.addPort({ markup: '<rect width="10" height="10" fill="blue"/>' })

rect.addPort({ markup: '<rect width="15" height="15" fill="red"/>', label: { markup: '<text fill="#000000"/>' }})

可以将其设置为元素模型上的默认端口标记/端口标签标记

var rect = new joint.shapes.basic.Rect({

        portMarkup: '<rect width="20" height="20" fill="black"/>',

        portLabelMarkup: '<text fill="yellow"/>',

        // ...

    });

element.addPort(port, [opt]) 添加一个端口

element.addPorts(ports, [opt]) 添加一组端口

element.addTo(graph) 向图中添加元素,相当于调用graph.addCell(元素)

element.angle() 返回元素的旋转度(0°- 360°)

element.attr(attrs)  在元素上设置SVG属性(和JointJS特殊属性)

例如:

element.attr({

    rect: { fill: 'blue' },

    text: { fill: 'white', 'font-size': 15 },

    '.myrect2': { fill: 'red' }

});

使用字符串路径

element.attr('text/font-size', 12);

element.clone(options)   返回具有相同属性的元素的新实例

element.embed(cell)  将后者嵌套进前者(即前者是后者的父元素,当一个父元素被移动(翻译)时,嵌入到该父元素中的所有单元也会移动)

element.findView(paper) 在画布上找到图形元素的元素视图

element.fitEmbeds([opt])  调整元素的大小,使其适合其内部的所有嵌入元素

element.getAncestors()  返回这个元素的所有祖先的数组,从最直接的父元素一直到最遥远的祖先。

element.getBBox()  以g.rect对象的形式返回元素的边框边界

例如:

element.getEmbeddedCells([opt])  返回元素的所有嵌入单元格的数组。

element.getPort(id)  返回id指定的端口

element.getPortIndex(portId)  返回端口项数组中的端口索引

element.getPorts()  返回元素上所有端口的数组。如果没有端口,则返回空数组

element.getPortsPositions(groupName)  返回组中所有端口的位置和角度,相对于元素位置。

element.getTransitions()  返回所有活动转换的数组

element.hasPort(id)  检查元素是否包含id端口

element.hasPorts()  检查元素是否定义了任何端口。返回布尔值

element.isEmbeddedIn(element [, opt])  如果元素嵌入到另一个元素元素中,则返回true。如果选择属性deep=false,只会检查直接的亲子关系。(Deep属性默认为true)

element.portProp(portId, path, [value])  在元素端口上设置属性(可能是嵌套的)

例如:

element.portProp('port-id', 'attrs/circle/fill', 'red');

element.portProp('port-id', 'attrs/circle/fill');  // 'red'

element.portProp('port-id', 'attrs/circle', { r: 10, stroke: 'green' });

element.portProp('port-id', 'attrs/circle'); // { r: 10, stroke: 'green', fill: 'red' }

element.position(x, y, [opt])  设置元素位置为x和y坐标

element.prop(properties)  在元素模型上设置属性(可能是嵌套的)

element.remove(options)  从图中删除元素

element.removeAttr(path, [options])  从元素中删除先前的set属性。

element.removePort(port, [opt])  从元素中删除端口,其中端口是端口对象或portId

element.resize(width, height [, opt])  调整元素的大小

element.rotate(deg, [absolute, origin, opt])  每执行一次以10度旋转一个元件,使其围绕中心旋转

element.scale(sx, sy, origin[, opt])  根据给定的原点缩放元素的位置和大小。

element.stopTransitions([path])  停止所有运行转换

element.toBack([opt])  移动元素,使其位于所有其他单元格(元素/链接)的后面

element.toFront([opt]) 与上相反

element.toJSON()  返回用于JSON序列化的元素属性的副本

element.transition(path, value [, opt])  允许在一段时间内逐渐改变元素的属性

例如:

1.element.transition('position/x', 250, {

    delay: 100,

    duration: 500,

    timingFunction: function(t) { return t*t; },

    valueFunction: function(a, b) { return function(t) { return a + (b - a) * t }}

});

// will start changing the element's x-coordinate in 100ms, for period of 500ms.

2. element.transition('attrs/text/font-size', '1em', {

    valueFunction: joint.util.interpolate.unit,

    timingFunction: joint.util.timing.bounce

});

// will start changing the current font size value to 1em in the bounce fashion.

element.translate(tx, [ty], [opt])  

element.unembed(cell)  从其父元素释放嵌入单元格。

dia.ElementView  图形元素视图

 joint.dia.Element model 的视图,它继承了joint.dia.CellView ,其作用:

  1. 在纸内绘制元素
  2. 处理元素的指针事件
  3. 提供使用元素的各种方法(可视化)

    查找视图的方法:

    var elementView = paper.findViewByModel(element);

    elementView.getBBox([opt])  返回元素视图的包围框。

    elementView.getNodeBBox(magnet)  返回作为磁铁(元素视图的元素/子元素/端口)提供的SVGElement的边界框

    elementView.getNodeUnrotatedBBox(magnet)  返回作为磁铁(元素视图的元素/子元素/端口)提供的未旋转的SVGElement边界框。

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只有颜色和尺寸不同,这些图形的目的是使您能够根据其类型在应用程序中实现自定义逻辑。

层次图常用方法:

coupled.embed(atomic)

  这可以将“atomic”形状放入“coupled中

coupled.fitEmbeds()

 这将调整coupled形状的大小,因此它将直观地包含嵌入其中的所有形状

link.reparent()

   这将根据源元素和目标元素为“链接”找到最好的父元素

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

该方法接受以下参数:

separator

 :一个字符串或正则表达式,表示如何将文本拆分为单词。默认为' '

eol

 :表示行符号结束的字符串。默认为'\n'

svgDocument

 :用于附加用于度量的内部创建的SVG文本元素的SVG文档

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

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(

err

,

 dataUri

)

{}.

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('<html><body><p>Hello</p></body></html>') === '<p>Hello</p>'

joint.util.sanitizeHTML('<p>Hello</p><script>alert("Hacked");</script>') === '<p>Hello</p>'

joint.util.sanitizeHTML('<p>Hello</p><img οnlοad="alert(&quot;Hacked&quot;);">') === '<p>Hello</p><img>'

joint.util.sanitizeHTML('<p>Hello</p><img src="javascript:alert(&quot;Hacked&quot;);">') === '<p>Hello</p><img>'

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, '/');

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****