Simple GoJS application: Setting and editing edges

Tomasz Świstak
Jun 13, 2018
2
min read

Learn how to use ports in GoJS diagrams to customize edge connections, ensuring precise and interactive links between nodes.

In the last post I showed you how to get started with a GoJS application. I explained how to create a diagram and how to present data using it. Let’s go a step further.

Figure 1. Diagram with three templates for nodes

While our diagram is starting to look better, there are a few issues that stick out. First – it can’t be edited (the only thing you can do is move the nodes around and clone them using the CTRL key), and second – we might want the edges to be drawn between specific points of the nodes. This is particularly visible in the objects that were created from the SVG paths – the best thing would be to set the entry from the left and set the exit from the right. But to do this, we first need to define the ports.

Ports are parts of nodes with only one function – setting the edges in relation to the rest of the object. They may consist of elements of nodes that already exist (even an entire node), or they can be new elements created especially for this purpose. Ports are defined by setting a value for the portId field. There are some other things we can do, for example: define whether we can create new links from the port (fromLinkable field) and whether we can attach new links to it (toLinkable). For the purposes of this example, the ports will be defined as visible shapes, but they can be any objects (including invisible ones).

In case of first node template (black circle), we want to put the port right in the middle. In order to make it clear that this is where the edges go, we will change the color of the circle and set a fixed size for it. We’ll also configure it to make it possible to create connections from this port in both directions. Here’s how we’ll define the shape in this case:

Listing 1. Definition of the shape expanded with a port

$(go.Node, 'Auto',$(go.Shape,'Circle', {width: 100,height: 100,fill: 'white'}),$(go.Shape,'Rectangle', {portId: '',width: 20,height: 20,fill: 'black',fromLinkable: true,toLinkable: true}))

view rawdiagram.js hosted with ❤ by GitHub

Like I already mentioned, it’s important for the portId field to have a set value. However, this value can be an empty string. If we assign an empty string, this port will be the default port.

For the second node template (SVG path), we want to define the port on its left and right side. This can be done in two ways: by changing the arrangement of elements to Horizontal and setting the shapes in the order of port-main shape-port, or by changing to Spot, then setting the ports to the Left and Right positions with the main shape in Center. The second way is more flexible, so it’s the one we will use. On the left side, we will insert the same rectangle as on the first shape and setting it so that you can only link to it. On the right side, we will insert a rectangle from which we can only lead the edges. In order to distinguish them, we should give them different identifiers than an empty string (e.g., entry and exit). Here’s what this definition looks like:

Listing 2. Definition of the shape expanded with two ports

$(go.Node,'Spot',$(go.Shape, {// ...}),$(go.Shape,'Rectangle', {portId: 'entry',width: 20,height: 20,fill: 'black',alignment: go.Spot.Left,fromLinkable: false,toLinkable: true}),$(go.Shape,'Rectangle', {portId: 'exit',width: 20,height: 20,fill: 'black',alignment: go.Spot.Right,fromLinkable: true,toLinkable: false}))

view rawdiagram.js hosted with ❤ by GitHub

For the third template (two rectangles), let’s modify only the square on the top. We’ll make it a port by adding a portId with an empty string, and we’ll set fromLinkable and toLinkable to true. After creating the ports, here’s what the diagram should look like:

Figure 2. Diagram with preliminary configuration of the ports

As the figure above shows us, the ports work perfectly in the case of the first and third category, but they don’t work for the second one. The same thing happens when it comes to drawing links. Drawing between the first and third category is no problem, but with the second category the edges jump out of the ports. There are two reasons why this happens. First, we haven’t defined in the link model which ports the connections should occur between. Second, we haven’t set in the model how to store connections between ports. So let's go back to initDiagram and the definition of the model. We need to add two fields to GraphLinksModellinkFromPortIdProperty and linkToPortIdProperty. These determine how we define the ports used in the model. Additionally, we should define in linkDataArray how the edges for nodes 2 and 3 (those belonging to the second category) will be done. Here’s what these changes should look like:

Listing 3. Changes in the model allowing for the use of ports

diagram.model = $(go.GraphLinksModel, {linkFromPortIdProperty: 'fromPort',linkToPortIdProperty: 'toPort',nodeDataArray: [// ...],linkDataArray: [{from: 1, to: 2, toPort: 'entry'},{from: 2, to: 3, fromPort: 'exit', toPort: 'entry'},{from: 1, to: 3, toPort: 'entry'},{from: 3, to: 4, fromPort: 'exit'}]});

view rawdiagram.js hosted with ❤ by GitHub

Now here’s what the edges on the diagram should look like:

Figure 3. Diagram after proper configuration of the ports

In the next post we’ll put the finishing touches on this diagram. Follow us on Facebook for notifications.

This post was also published on ITNEXT. 

You can check the result of the tutorial here:

Contact details
By sending a message you allow Synergia Pro Sp. z o.o., with its registered office in Poland, Wroclaw (51-607) Czackiego Street 71, to process your personal data provided by you in the contact form for the purpose of contacting you and providing you with the information you requested. You can withdraw your consent at any time. For more information on data processing and the data controller please refer to our Privacy policy.
*Required
Thank you! Your submission has been received!
Oops! Something went wrong while submitting the form.
Tomasz Świstak
JavaScript Developer at Synergy Codes

He’s primarily working with React and NestJS but is open to new frameworks and libraries, whatever suits the project the best. Tomasz is also keen on algorithmic and researching optimal ways to solve complex problems, despite his expertise in Web applications. Implementing complex features and applying scientific theory practically is his main area of interest. 

Get more from me on:
Share:

Articles you might be interested in

The ultimate guide to optimize React Flow project performance [E-BOOK]

Follow these step-by-step process to enhance your React Flow project's performance.

Łukasz Jaźwa
Jan 23, 2025

10 tips for better initial configuration of full-stack apps

Follow these tips for configuring full-stack apps, from using a monorepo with Nx to setting up code formatting and CI/CD pipelines, ensuring smooth development.

Tomasz Świstak
Aug 12, 2022

Effective front-end development with GoJS

Learn how GoJS enhances front-end development by creating interactive diagrams with flexibility and performance for complex data visualizations.

Content team
Oct 1, 2021