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
recordsdistance
absolutely (as distance from beginning of link)reverseDistance: true
switchesdistance
to be calculated from end of link, ifabsoluteDistance
absoluteOffset: true
recordsoffset
absolutely (asx
andy
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 atposition.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, ifkeepGradient
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])
Return a bounding box of the link view.
If opt.useModelGeometry
option is set to true
, the resulting bounding box is calculated based on the dimensions of the link model. (This means that a simplified polyline is used and portions of curved links may be sticking out of the reported bounding box.) This behavior is similar to the link.getBBox
function – but the linkView
function transforms the bounding box to match joint.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 pointx,y
.offset
- the distance between the closest point and the pointx,y
.angle
- the angle of the label relative to the connection line, as determined by theangle
parameter, or0
ifangle
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
- recorddistance
absolutely (as absolute distance from beginning of link, a positive number)reverseDistance: true
- ifabsoluteDistance: true
, recorddistance
absolutely from end of link (as a negative number)absoluteOffset: true
- recordoffset
absolutely (asx
andy
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 atposition.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, ifkeepGradient
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: '<g class="label"><circle /><path /></g>',
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.