The shape of the link is determined by the `vertices`, `connector` and `router` properties.

The `vertices` array contains a list of points which are the points which the link should cross.

    link.get('vertices')
    link.set('vertices', [{ x: 100, y: 120 }, { x: 150, y: 60 }])

A `router` takes an array of vertices defined on the model and transforms them to an array of points (route) that the link should go through. The difference between vertices and the route is that vertices are user-defined whilst route is computed.

There are four built-in routers (manhattan, metro, orthogonal and oneSide) to your disposal. The first two are so called "smart routers" and they automatically avoid elements that are in their way.

The `orthogonal`, `manhattan` and `oneSide` routers generate points that can be connected by vertical and horizontal line segments only. The `metro` router generates points that can be connected also with diagonal line segments.

    link.set('router', { name: 'manhattan' });
    link.set('router', { name: 'oneSide' }});
    link.set('router', { name: 'metro' });
    link.set('router', { name: 'orthogonal' });

To keep backwards compatible it's possible to set the `manhattan` property to `true` in order to enable the orthogonal routing.

    // old approach
    link.set('manhattan', true)

The `manhattan` router has some additional useful options that determine how the algorithm behaves. These options can be passed into the `args` property and are:

- `excludeTypes` - an array of element types that should not be considered obstacles
- `excludeEnds` - either `'source'` or `'target'` string that tells the algorithm that the element at that specified end of the link should not be considered an obstacle
- `startDirections` - an array of sides of the link source element that the link can start from. The default is all the sides `['left', 'right', 'top', 'bottom']`. Change this in situations where you want the link to e.g. always start at the bottom of the source element (the value would be `['bottom']`)
- `endDirections` - an array of sides of the link target element that the link can stick to. The default is all the sides `['left', 'right', 'top', 'bottom']`

Example:

    link.set('router', {
        name: 'manhattan',
        args: {
            startDirections: ['top'],
            endDirections: ['bottom'],
            excludeTypes: ['myNamespace.MyCommentElement']
        }
    });

Complete list of options for `manhattan`:

startDirection | Array<string> | Possible starting directions from an element. Default is `['left', 'right', 'top', 'bottom']`.
endDirection | Array<string> | Possible ending directions to an element. Default is `['left', 'right', 'top', 'bottom']`.
excludeTypes | Array<string> | Should be any element with a certain type not to be consider as an obstacle.
step | number | Size of the step to find a route. Lower number -> higher complexity. `manhattan` performs the best when `step` has the same value as `dia.Paper.option.gridSize`.
perpendicular | boolean | Use of the perpendicular linkView option to connect center of element with first vertex.
maximumLoops | number | If number of route finding loops exceed the maximum, stops searching and returns fallback route. Higher number -> higher complexity.
excludeEnds | Array<string> | Should be source or target not to be consider as an obstacle.
maxAllowedDirectionChange | number | Maximum change of the direction.

The `oneSide` routes the link in a given direction, creating exactly three orthogonal segments. It accepts the following options.

- `side` - the direction of the route. Either `'left'`, `'right'`, `'top'` or `'bottom'` (default).
- `padding` - a minimal gap between a connection point and the first/last vertex. It defaults to `40`.

Example:

    link.set('router', {
        name: 'oneSide',
        args: {
            side: 'top',
            padding: 30
        }
    });

New routers can be defined in the `joint.routers.[name of your router]` namespace or passed directly as functions to the `router` property of your links. The router is a function of the form `function(vertices, args, linkView)` and must return an array of vertices that the link should go through.

A `connector` takes points returned by a router and generate SVG path commands so the link can be rendered. There are four connectors (normal, smooth, rounded and jumpover) to your disposal.

The `normal` connector connects points with straight lines. The `rounded` connector does the same but it smooths all the edges. The `smooth` connector interpolates the points using a cubic bezier curve.

    link.set('connector', { name: 'normal' });
    link.set('connector', { name: 'smooth' });

The curve of edges can be specified by `radius` argument passed to the `rounded` connector.

    link.set('connector', { name: 'rounded', args: { radius: 10 }});

The `jumpover` connector draws straight lines with small arcs at positions, where a link crosses an another. It accepts the following options.

- `size` - the size of the jump. It defaults to `5`.
- `jump` - the style of the jump. Either `'arc'` (default), `'cubic'` (similar to arc, but uses normalized path data commands only) or `'gap'`.

    link.set('connector', { name: 'jumpover', args: { type: 'gap' }});

To keep backwards compatible it's possible to set the `smooth` property to `true` in order to enable smooth connector.

    // old approach
    link.set('smooth', true)

Note that code responsible for routing and rendering links is completely pluggable so the family of routers and connectors can be easily extended.

New connectors can be defined (similarly to routers) in the `joint.connectors.[name of your connector]` namespace or passed directly as functions to the `connector` property of your links. The connector is a function of the form `function(sourcePoint, targetPoint, vertices, args, linkView)` and must return a string representing the SVG path data that will be used to render the link.

Styling of the link is contained in the `attrs` property which has exactly the same structure as the `attrs` property of elements. Please refer to the joint.dia.Element section and joint.dia.Link sections of this page for more information on this.

Links also have the `z` property which is the z-level of the link. `z` property has exactly the same meaning as the `z` property of elements.