Add port to selected nodes:

Double-click in the diagram background in order to add a new node there. In this sample you can add ports to a selected node by clicking the above buttons or by using the context menu. Draw links between ports by dragging between ports. If you select a link you can relink or reshape it. Right-click or touch-hold on a port to bring up a context menu that allows you to remove it or change its color.

The diagram also uses a custom link to allow for special routing to help parallel links avoid each other using overridden Link.computeEndSegmentLength, Link.hasCurviness, and Link.computeCurviness functions.

See the Ports Intro page for an explanation of GoJS ports.

Diagram Model saved in JSON format:
{ "class": "go.GraphLinksModel", "copiesArrays": true, "copiesArrayObjects": true, "linkFromPortIdProperty": "fromPort", "linkToPortIdProperty": "toPort", "nodeDataArray": [ {"key":1, "name":"Unit One", "loc":"101 204", "leftArray":[ {"portColor":0, "portId":"left0"} ], "topArray":[ {"portColor":1, "portId":"top0"} ], "bottomArray":[ {"portColor":2, "portId":"bottom0"} ], "rightArray":[ {"portColor":3, "portId":"right0"},{"portColor":0, "portId":"right1"} ] }, {"key":2, "name":"Unit Two", "loc":"320 152", "leftArray":[ {"portColor":0, "portId":"left0"},{"portColor":0, "portId":"left1"},{"portColor":0, "portId":"left2"} ], "topArray":[ {"portColor":3, "portId":"top0"} ], "bottomArray":[ {"portColor":2, "portId":"bottom0"},{"portColor":3, "portId":"bottom1"},{"portColor":0, "portId":"bottom2"} ], "rightArray":[ ] }, {"key":3, "name":"Unit Three", "loc":"384 319", "leftArray":[ {"portColor":0, "portId":"left0"},{"portColor":0, "portId":"left1"},{"portColor":0, "portId":"left2"} ], "topArray":[ {"portColor":0, "portId":"top0"} ], "bottomArray":[ {"portColor":2, "portId":"bottom0"} ], "rightArray":[ ] }, {"key":4, "name":"Unit Four", "loc":"138 351", "leftArray":[ {"portColor":0, "portId":"left0"} ], "topArray":[ {"portColor":0, "portId":"top0"} ], "bottomArray":[ {"portColor":2, "portId":"bottom0"} ], "rightArray":[ {"portColor":0, "portId":"right0"},{"portColor":0, "portId":"right1"} ] } ], "linkDataArray": [ {"from":4, "to":2, "fromPort":"top0", "toPort":"bottom0"}, {"from":4, "to":2, "fromPort":"top0", "toPort":"bottom0"}, {"from":3, "to":2, "fromPort":"top0", "toPort":"bottom1"}, {"from":4, "to":3, "fromPort":"right0", "toPort":"left0"}, {"from":4, "to":3, "fromPort":"right1", "toPort":"left2"}, {"from":1, "to":2, "fromPort":"right0", "toPort":"left1"}, {"from":1, "to":2, "fromPort":"right1", "toPort":"left2"} ]}

### GoJS Features in this sample

#### Table Panels

The "Table" Panel, Panel.Table, arranges objects in rows and columns. Each object in a Table Panel is put into the cell indexed by the value of GraphObject.row and GraphObject.column. The panel will look at the rows and columns for all of the objects in the panel to determine how many rows and columns the table should have. More information can be found in the GoJS Intro.

Related samples

#### Item Arrays

It is sometimes useful to display a variable number of elements in a node by data binding to a JavaScript Array. In GoJS, this is simply achieved by binding (or setting) Panel.itemArray. The Panel will create an element in the panel for each value in the Array. More information can be found in the GoJS Intro.

Related samples

#### Links

The Link class is used to implement a visual relationship between nodes. Links are normally created by the presence of link data objects in the GraphLinksModel.linkDataArray or by a parent key reference as the value of the TreeModel.nodeParentKeyProperty of a node data object in a TreeModel. More information can be found in the GoJS Intro.

Related samples

#### Ports in Nodes

Specific elements of a Node at which links may connect are called ports. There may be any number of ports in a node. By default there is just one port, the whole node, which results in the effect of having the whole node act as the port. Port-like GraphObjects can only be in Nodes or Groups, not in Links or Adornments or simple Parts.

More information can be found in the GoJS Intro.

Related samples

#### Context Menus

A GoJS context menu is an Adornment that is shown when the user context-clicks (right mouse click or long touch hold) an object that has its GraphObject.contextMenu set. The context menu is bound to the same data as the part itself.

It is typical to implement a context menu as a "ContextMenu" Panel containing "ContextMenuButton"s, as you can see in the code below in the assignment of the Node's GraphObject.contextMenu and Diagram.contextMenu properties. Each "ContextMenu" is just a "Vertical" Panel Adornment that is shadowed. Each "ContextMenuButton" is a Panel on which you can set the GraphObject.click event handler. In the event handler `obj.part` will be the whole context menu Adornment. `obj.part.adornedPart` will be the adorned Node or Link. The bound data is `obj.part.data`, which will be the same as `obj.part.adornedPart.data`.

More information can be found in the GoJS Intro.

Related samples

#### Buttons

GoJS defines several Panels for common uses. These include "Button", "TreeExpanderButton", "SubGraphExpanderButton", "PanelExpanderButton", "ContextMenuButton", and "CheckBoxButton". "ContextMenuButton"s are typically used inside of "ContextMenu" Panels; "CheckBoxButton"s are used in the implementation of "CheckBox" Panels.

These predefined panels can be used as if they were Panel-derived classes in calls to GraphObject.make. They are implemented as simple visual trees of GraphObjects in Panels, with pre-set properties and event handlers.

More information can be found in the GoJS Intro.

Related samples

#### Theming

GoJS allows diagrams to be themed. This is commonly used to provide a light and dark mode for diagrams.

The Diagram.themeManager handles themes within a Diagram. The ThemeManager can by shared by multiple diagrams, and is responsible to managing the current theme and default theme, along with any theme updates. More information can be found in the GoJS Intro.

Related samples