Skip to main content
Version: 4.1

LinkView

The view for the joint.dia.Link model. It inherits from joint.dia.CellView and is responsible for:

  • Rendering a link inside a paper
  • Handling the link's pointer events
  • Providing various methods for working with the link (visually)

To find the view associated with a specific link model, use the paper.findViewByModel() method:

const linkView = paper.findViewByModel(link);
// const linkView = link.findView(paper); // alternatively

Custom LinkView

It is possible to use a custom default link view for all your links in a paper. This can be set up via the linkView option on the paper object.

A custom LinkView type may also override default LinkView event handlers, or provide new ones. It may be necessary to modify the interactive paper option to prevent interference from builtin event handlers.

Example:

const CustomLinkView = dia.LinkView.extend({
// custom interactions:
pointerdblclick: function(evt, x, y) {
this.addVertex(x, y);
},

contextmenu: function(evt, x, y) {
this.addLabel(x, y);
}
});

const paper = new dia.Paper({
//...
linkView: CustomLinkView,
});

Methods

addLabel()

linkView.addLabel(x, y [, angle, opt])

Add a new default label to the link at the (x,y) coordinates provided. See also the link.appendLabel() function.

linkView.addLabel(point [, angle, opt])

Add a new default label to the link at the coordinates specified by point. See also the link.appendLabel() function.

In either case, this method uses the linkView.getLabelPosition() function to determine the new label's position. By default, position.distance is recorded relative to connection length (as a number in the [0,1] range), and position.offset is set relative to the connection (as a number). This behavior may be changed by providing an opt object with some of the accepted boolean flags:

  • absoluteDistance: true records distance absolutely (as distance from beginning of link)
  • reverseDistance: true switches distance to be calculated from end of link, if absoluteDistance
  • absoluteOffset: true records offset absolutely (as x and y from connection)

The angle parameter, if provided, is saved as position.angle attribute inside the returned object. Two additional flags, which may be passed in the opt object, provide more control over label rotation:

  • keepGradient: true - adjust the rotation of the label to match the angle of incline of the path at position.distance
  • ensureLegible: true - if the label text ends up being upside-down, rotate the label by additional 180 degrees to ensure that the text stays legible, if keepGradient

The opt object passed to the label is recorded as label.position.args. The label uses these options during subsequent labelMove interactions.

This function is useful within custom linkView event listener definitions:

var CustomLinkView = joint.dia.LinkView.extend({
contextmenu: function(evt, x, y) {
this.addLabel(x, y, 45, {
absoluteDistance: true,
reverseDistance: true, // applied only when absoluteDistance is set
absoluteOffset: true,
keepGradient: true,
ensureLegibility: true // applied only when keepGradient is set
});
}
});

var paper = new joint.dia.Paper({
// ...
linkView: CustomLinkView
});

addTools()

linkView.addTools(toolsView)

Add the provided toolsView (of the joint.dia.ToolsView type) to the link view.

Adding a tools view to a link view is the last (third) step in the process of setting up link tools on a link view:

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

Every link view we want to attach to requires its own tools view object (ToolsView objects are automatically reassigned to the last link view they are added to). Similarly, every tools view we create requires its own set of tools (ToolView objects are automatically reassigned to the last toolsView.tools array they were made part of).

The link tools are added in the visible state. Use the linkView.hideTools function if this behavior is not desirable (e.g. if you want the link tools to appear in response to user interaction). Example:

linkView.addTools(toolsView);
linkView.hideTools();

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

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

Note that the above example may not work as expected if toolsView includes the SourceArrowhead tool and/or the TargetArrowhead tool - the link tools view might not be hidden when the link is reconnected to a topic. See our link tools tutorial for more information.

addVertex()

linkView.addVertex(x, y)

Add a new default vertex to the link at the coordinates provided, and let the linkView automatically determine the index of the new vertex in the vertices array. If you need to add the vertex at a custom index, use the link.insertVertex() function instead.

This method uses the linkView.getVertexIndex() function to determine the index of the new vertex in the vertices array. The linkView checks the distance of vertices in the link.vertices array from the beginning of path and compares it to the distance of the added vertex. The new vertex is inserted before the first farther vertex in the vertices array.

This function is useful within custom linkView event listener definitions. The following example adds a new vertex on a double click event, instead of a pointerdown event (which is the default behavior):

var CustomLinkView = joint.dia.LinkView.extend({
pointerdblclick: function(evt, x, y) {
this.addVertex(x, y);
}
});

var paper = new joint.dia.Paper({
// ...
linkView: CustomLinkView
});

findLabelNode()

linkView.findLabelNode(index)

Return the root SVGElement of the label at given index. If label at index doesn't exist, null is returned.

linkView.findLabelNode(index, selector)

Return an SVGElement|HTMLElement referenced by selector of the label at given index. If there is no label at index or no DOM node was found by the selector, null is returned.

The available selectors are defined by the markup attribute of the label from which the label was built.

findLabelNodes()

linkView.findLabelNodes(index, groupSelector)

Return an array of SVGElement|HTMLElement referenced by groupSelector of the label at given index. If there is no label at index or no DOM node was found by the groupSelector, an empty array is returned.

The available groupSelectors are defined by the markup attribute of the label from which the label was built.

getBBox()

linkView.getBBox([opt])

Returns the bounding box of the link view.

When the opt.useModelGeometry option is set to true, the bounding box is calculated using the dimensions of the link model, with a simplified polyline. This may cause parts of curved links to extend beyond the reported bounding box.

This behavior is similar to the link.getBBox() but the linkView function applies transformations to account for dia.Paper translation and scaling.

getClosestPoint()

linkView.getClosestPoint(point)

Return the point on the connection that lies closest to point.

getClosestPointLength()

linkView.getClosestPointLength(point)

Return the length of the connection up to the point that lies closest to point.

getClosestPointRatio()

linkView.getClosestPointRatio(point)

Return the ratio (normalized length) of the connection up to the point that lies closest to point. The returned value lies in the interval [0,1] (inclusive).

getConnection()

linkView.getConnection()

Return a geometric representation of the connection (instance of g.Path).

getConnectionLength()

linkView.getConnectionLength()

Return a cached total length of the connection in pixels.

getConnectionSubdivisions()

linkView.getConnectionSubdivisions()

Return a cached array of segment subdivision arrays of the connection. (See g.Path.prototype.getSegmentSubdivisons() documentation for more information.)

getLabelCoordinates()

linkView.getLabelCoordinates(labelPosition)

Return the x and y coordinates based on the provided labelPosition object.

See link.label() documentation for more information about the position object.

An object in the format { x: number, y: number } is returned.

getLabelPosition()

linkView.getLabelPosition(x, y [, angle, opt])

Return a label position object based on the x and y coordinates provided.

The function translates the provided coordinates and angle into an object with three fields:

  • distance - the distance (following the line) of the point on the line that is closest to point x,y.
  • offset - the distance between the closest point and the point x,y.
  • angle - the angle of the label relative to the connection line, as determined by the angle parameter, or 0 if angle was not specified.

By default, position.distance is calculated as relative to connection length (as a number in the [0,1] range that records the length ratio), and position.offset is calculated as relative to the connection (as a number recording the perpendicular distance). The user may change this behavior by providing an opt object with some of the following accepted boolean flags:

  • absoluteDistance: true - record distance absolutely (as absolute distance from beginning of link, a positive number)
  • reverseDistance: true - if absoluteDistance: true, record distance absolutely from end of link (as a negative number)
  • absoluteOffset: true - record offset absolutely (as x and y distance from closest point)

Please note that if the absoluteOffset flag is not set, label can only be placed/moved in the area that is reachable by lines perpendicular to the link (that is, the label can never be moved beyond link endpoints).

Two additional flags, which may be passed in the opt object, provide control over label rotation:

  • keepGradient: true - adjust the rotation of the label to match the angle of incline of the path at position.distance
  • ensureLegible: true - if the label text ends up being upside-down, rotate the label by additional 180 degrees to ensure that the text stays legible, if keepGradient

The opt object passed to the label is recorded as label.position.args. The label uses these options during subsequent labelMove interactions.

An object in the following format is returned:

{
distance: number,
offset: number | { x: number, y: number },
angle: number,
args?: {
absoluteDistance?: boolean,
reverseDistance?: boolean, // applied only when absoluteDistance is set
absoluteOffset?: boolean,
keepGradient?: boolean,
ensureLegible?: boolean // applied only when keepGradient is set
}
}

See link.label() documentation for more information about the position object.

This function can be used to add a custom label to the link.labels array, in situations when the linkView.addLabel() function is not sufficient. For example:

var CustomLinkView = joint.dia.LinkView.extend({
contextmenu: function(evt, x, y) {
var idx = -1; // add at end of `labels`
var label = {
markup: [{
tagName: 'circle',
selector: 'circle'
}, {
tagName: 'path',
selector: 'path'
}],
attrs: {
circle: {
r: 15,
fill: 'lightgray',
stroke: 'black',
strokeWidth: 2
},
path: {
d: 'M 0 -15 0 -35 20 -35',
stroke: 'black',
strokeWidth: 2,
fill: 'none'
}
},
position: this.getLabelPosition(x, y, 45, {
absoluteOffset: true,
keepGradient: true,
ensureLegible: true
})
}
this.model.addLabel(idx, label);
}
});

var paper = new joint.dia.Paper({
// ...
linkView: CustomLinkView
});

getNodeBBox()

elementView.getNodeBBox(magnet)

Return the bounding box of the SVGElement provided as magnet (model of this link view).

Use the paper.localToPaperRect function to transform the returned bounding box to match the paper's translation and scaling.

getNodeUnrotatedBBox()

elementView.getNodeUnrotatedBBox(magnet)

Return the unrotated bounding box of the SVGElement provided as magnet (model of this link view).

Use the paper.localToPaperRect function to transform the returned bounding box to match the paper's translation and scaling.

getPointAtLength()

linkView.getPointAtLength(length)

Return the point on the path that lies length away from the beginning of the connection.

getPointAtRatio()

linkView.getPointAtRatio(ratio)

Return the point on the path that lies ratio (normalized length) away from the beginning of the connection.

getSerializedConnection()

linkView.getSerializedConnection()

Return a cached path data of the connection (the value of the 'd' SVGPathElement attribute).

getTangentAtLength()

linkView.getTangentAtLength(length)

Return a line tangent to the path at point that lies length away from the beginning of the connection.

getTangentAtRatio()

linkView.getTangentAtRatio(ratio)

Return a line tangent to the path at point that lies ratio (normalized length) away from the beginning of the connection.

getVertexIndex()

linkView.getVertexIndex(x, y)

Return the vertices array index at which to insert a new vertex with the provided x and y coordinates.

The linkView finds the point on the connection that lies closest to the point x,y. Then, the linkView iterates over the vertices in the link.vertices array until one is found that lies farther than the identified closest point. The index of the farther point is returned.

The returned index can be used as the first argument of the link.insertVertex function.

hasTools()

linkView.hasTools()

Return true if this link view has a tools view attached.

linkView.hasTools(name)

Return true if this link view has a tools view of the provided name attached.

hideTools()

linkView.hideTools()

Hide all tools attached to this link view.

removeRedundantLinearVertices()

linkView.removeRedundantLinearVertices([opt])

Remove any redundant vertices from the model's vertices array. Return the number of removed vertices.

A vertex is considered redundant if it lies on the straight line formed by the vertex that immediately precedes it and the vertex that immediately follows it. (Intuitively speaking, a vertex is considered redundant if its removal from the link does not change the shape of the link.)

removeTools()

linkView.removeTools()

Remove the tools view attached to this link view.

requestConnectionUpdate()

linkView.requestConnectionUpdate()

Schedule an update of the connection (anchors, connection points, route and connector) of this link view in the next animation frame (for paper async mode) or run immediately (for paper sync mode). Useful for links with an automatic router (such as manhattan) if the route has to be recalculated due to another element in the graph changing its position.

sendToken()

linkView.sendToken(token [, opt, callback])

Send a token along the link. token is an SVG element (or Vectorizer element) that will be animated along the link path for opt.duration milliseconds (default is 1000ms). The callback function will be called once the token reaches the end of the link path.

opt.direction specifies whether the animation should be played forwards ('normal' - from the link source to target, the default) or backwards ('reverse').

Use opt.connection to specify the SVGPathElement for the token to follow. It expects a string selector, e.g. '.connection'.

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

Note that in the code above, we use the Vectorizer mini-library to create the SVG circle element.

See the Petri Net simulator demo for a full working example.

showTools()

linkView.showTools()

Show all tools attached to this link view.

Properties

sourceAnchor

linkView.sourceAnchor

A prototype variable. Contains a g.Point that records the position of the source anchor of the link, as determined by the anchor/linkAnchor function specified on the link's source.

sourceBBox

linkView.sourceBBox

A prototype variable. Contains a g.Rect that records the position and dimensions of the bounding box of the source magnet (element/subelement/port), as determined by the link's source definition.

If the source is defined as a point, a g.Rect is returned that records the position of the point and has the dimensions (1,1).

sourcePoint

linkView.sourcePoint

A prototype variable. Contains a g.Point that records the position of the source connection point of the link, as determined by the connection point function specified on the link's source.

targetAnchor

linkView.targetAnchor

A prototype variable. Contains a g.Point that records the position of the target anchor of the link, as determined by the anchor/linkAnchor function specified on the link's target.

targetBBox

linkView.targetBBox

A prototype variable. Contains a g.Rect that records the position and dimensions of the bounding box of the target magnet (element/subelement/port), as determined by the link's target definition.

If the target is defined as a point, a g.Rect is returned that records the position of the point and has the dimensions (1,1).

targetPoint

linkView.targetPoint

A prototype variable. Contains a g.Point that records the position of the target connection point of the link, as determined by the connection point function specified on the link's target.