UNPKG

jointjs

Version:

JavaScript diagramming library

299 lines (262 loc) 8.14 kB
Port layouts are functions that accept an array of port's `args` and return an array of port positions. Positions are relative to the element model bounding box. For example if we have an element at position `{ x:10, y:20 }` with a relative port position `{ x:1, y:2 }`, the absolute port position will be `{ x:11, y:22 }`. Port layout can be defined only at the `group` level. Optionally you can pass some additional arguments into the layout function via `args`. The `args` is the only way to adjust port layout from the port definition perspective. ```javascript var rect = new joint.shapes.basic.Rect({ // ... ports: { groups: { 'a': { position: { name: 'layoutType', args: {}, } } }, items: [ // initialize 'rect' with port in group 'a' { group: 'a', args: {} // overrides `args` from the group level definition. }, // ... other ports ] } }); // .... // add another port to group 'a'. rect.addPort({ group:'a' }); ``` ### Pre-defined layouts: #### On sides A simple layout suitable for rectangular shapes. It evenly spreads ports along a single side. <table> <tr> <td><b>name</b></td> <td><i>string</i></td> <td> Can be either `left`, `right`, `top`, `bottom`. </td> </tr> <tr> <td><b>args</b></td> <td><i>object</i></td> <td> <table> <tr> <td><b>x</b></td> <td>number</td> <td>Overrides the `x` value calculated by the layout function</td> </tr> <tr> <td><b>y</b></td> <td>number</td> <td>Overrides the `y` value calculated by the layout function</td> </tr> <tr> <td><b>dx</b></td> <td>number</td> <td>Added to the `x` value calculated by the layout function</td> </tr> <tr> <td><b>dy</b></td> <td>number</td> <td>Added to the `y` value calculated by the layout function</td> </tr> <tr> <td><b>angle</b></td> <td>number</td> <td>The port rotation angle.</td> </tr> </table> </td> </tr> </table> ```javascript { name: 'left', args: { x: 10, y: 10, angle: 30, dx: 1, dy: 1 } } ``` #### Line A layout which evenly spreads ports along a line defined by a `start` and en `end` point. <table> <tr> <td><b>name</b></td> <td><i>string</i></td> <td> `line` </td> </tr> <tr> <td><b>args</b></td> <td><i>object</i></td> <td> <table> <tr> <td><b>start</b></td> <td>{ x:number, y:number }</td> <td>The line starting point</td> </tr> <tr> <td><b>end</b></td> <td>{ x:number, y:number }</td> <td>The line end point</td> </tr> </table> </td> </tr> </table> ```javascript { name: 'line', args: { start: { x: 10, y: 10 }, end: { x: 20, y: 50 } } } ``` #### Absolute It lay a port out at the given position (defined as a `x`, `y` coordinates or percentage of the element dimensions). <table> <tr> <td><b>name</b></td> <td><i>string</i></td> <td> `absolute` </td> </tr> <tr> <td><b>args</b></td> <td><i>object</i></td> <td> <table> <tr> <td><b>x</b></td> <td>number | string</td> <td>Sets the port's `x` coordinate. Can be defined as a percentage string ('50%') or as a number</td> </tr> <tr> <td><b>y</b></td> <td>number | string</td> <td>Sets the port's `y` coordinate. Can be defined as a percentage string ('50%') or as a number</td> </tr> <tr> <td><b>angle</b></td> <td>number</td> <td>The port rotation angle.</td> </tr> </table> </td> </tr> </table> ```javascript { name: 'absolute', args: { x: '10%', y: 10, angle: 45 } } ``` #### Radial Suitable for circular shapes. The `ellipseSpreads` evenly spreads ports along an ellipse. The `ellipse` spreads ports from the point at `startAngle` leaving gaps between ports equal to `step`. <table> <tr> <td><b>name</b></td> <td><i>string</i></td> <td> Can be either `ellipse`, `ellipseSpread`. </td> </tr> <tr> <td><b>args</b></td> <td><i>object</i></td> <td> <table> <tr> <td><b>x</b></td> <td>number</td> <td>Overrides the `x` value calculated by the layout function</td> </tr> <tr> <td><b>y</b></td> <td>number</td> <td>Overrides the `y` value calculated by the layout function</td> </tr> <tr> <td><b>dx</b></td> <td>number</td> <td>Added to the `x` value calculated by the layout function</td> </tr> <tr> <td><b>dy</b></td> <td>number</td> <td>Added to the `y` value calculated by the layout function</td> </tr> <tr> <td><b>dr</b></td> <td>number</td> <td>Added to the port delta rotation</td> </tr> <tr> <td><b>startAngle</b></td> <td>number</td> <td>Default value is `0`.</td> </tr> <tr> <td><b>step</b></td> <td>number</td> <td> Default `360 / portsCount` for the `ellipseSpread`, `20` for the `ellipse` </td> </tr> <tr> <td><b>compensateRotation</b></td> <td>boolean</td> <td>set `compensateRotation:true` when you need to have ports in the same angle as an ellipse tangent at the port position.</td> </tr> </table> </td> </tr> </table> ```javascript { name: 'ellipseSpread', args: { dx: 1, dy: 1, dr: 1, startAngle: 10, step: 10, compensateRotation: false } } ``` <iframe src="about:blank" data-src="demo/layout/Port/portRotationComp.html" style="height: 534px; width: 803px;"></iframe> ### Custom layout An alternative for built-in layouts is providing a function directly, where the function returns an array of port positions. ```javascript /** * @param {Array<object>} portsArgs * @param {g.Rect} elBBox shape's bounding box * @param {object} opt Group options * @returns {Array<g.Point>} */ function(portsArgs, elBBox, opt) { // ports on sinusoid return _.map(portsArgs, function(portArgs, index) { var step = -Math.PI / 8; var y = Math.sin(index * step) * 50; return g.Point({ x: index * 12, y: y + elBBox.height }); }); } ``` ### Port layouts demo <iframe src="about:blank" data-src="demo/layout/Port/port.html" style="height: 442px; width: 803px;"></iframe>