Skip to main content

Vertex avoidance

You can instruct VisuallyJs to attempt to route edges around vertices, either for all edges in your app or just for some specific type(s) of edge.

Example​

import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
connector: "Orthogonal",
avoidVertices: true
},
grid: {
size: {
width: 20,
height: 20
}
}
})

The key option being avoidVertices in the edges config. Internally, vertex avoidance is computed using an A* algorithm, which is based upon a grid, and so we do recommend you use a grid in your app if you've got avoidVertices set. Without a grid set you can sometimes see an effect where a path segment's location changes as you drag an element, and then snaps back to some multiple of the A* grid. The A* grid has a cell size of 10 pixels and so the best results are obtained from setting your own grid to a multiple of that.

Path constrainment​

You can constrain the travel of the path in a few different ways.

Orthogonal routing​

Orthogonal routing constrains path segments to travel either horizontally or vertically, as shown at the top of the page.

import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
avoidVertices: true,
connector: {
type: "Straight",
options: {
constrain: "orthogonal"
}
}
},
zoomToFit: true,
grid: {
size: {
width: 20,
height: 20
}
}
})

Any angle​

import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
avoidVertices: true,
connector: {
type: "Straight",
options: {
constrain: "none"
}
}
},
grid: {
size: {
width: 20,
height: 20
}
}
})

With this setup path segments can travel at any angle:

Smooth connectors​

For some applications the above can look a little jerky, and so one thing you can do is set smooth on your connector, to get that Graphviz effect:

import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
avoidVertices: true,
connector: {
type: "Straight",
options: {
smooth: true
}
}
},
zoomToFit: true,
grid: {
size: {
width: 20,
height: 20
}
}
})
info

Straight connectors with smooth:true set are aliased in VisuallyJs to the connector name Smooth:

import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
avoidVertices: true,
connector: "Smooth"
},
grid: {
size: {
width: 20,
height: 20
}
}
})

Metro routing​

"Metro" routing constrains path segments to travel either horizontally, vertically, or at 45 degrees.

import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
avoidVertices: true,
connector: {
type: "Straight",
options: {
constrain: "metro"
}
}
},
zoomToFit: true,
grid: {
size: {
width: 20,
height: 20
}
}
})

Applying to specific edge types only​

If you want to setup your app such that only specific edge types will use the A* router, you can do this via your view. In this example, we map two edge types, and the orthogonal edge type has this key set:

{
avoidVertices:true
}
import { newInstance } from "@visuallyjs/browser-ui"

const model = newInstance()

const surface = model.render({
edges: {
connector: {
type: "Straight",
options: {
constrain: "orthogonal"
}
}
},
grid: {
size: {
width: 20,
height: 20
}
},
view: {
edges: {
straight: {
connector: "Straight",
paintStyle: {
stroke: "red",
strokeWidth: 2
}
},
orthogonal: {
avoidVertices: true,
connector: "Orthogonal",
paintStyle: {
stroke: "red",
strokeWidth: 2
}
}
}
}
})

So the red lines - with the straight connector - travel through vertices without avoiding them, while the green lines route themselves around vertices: