Simple GoJS application: Palette and finishing touches

Tomasz Świstak
Jun 18, 2018
2
min read

Enhance your GoJS diagram with a palette for inserting nodes, grid snapping, and auto-layouts for a polished, interactive application.

Recently I’ve explained how to create a GoJS diagram, as well as how to set and style edges. In order to make the diagram fully interactive, we still need to give the option of inserting elements. To do this, we’ll create a palette built into GoJS.

Figure 1. Diagram after proper configuration of the ports

A palette is a separate canvas that displays all the nodes defined in it and allows you to transfer them to the main diagram. It is configured in a manner analogical to the diagram, but through the creation of a go.Palette object. However, in order to do this, we should first add an additional div to the HTML file where the palette will be contained. We can also add a function to initialize the palette in the JS file, which we will also make available outside (initPalette). In our example, we’ll put the palette next to the diagram. Here’s how we will edit the HTML file:

Listing 1. Adding the palette to the HTML file

<div id="palette-content" style="height: 800px; width: 200px; display: inline-block; border: 1px solid black"></div><div id="diagram-content" style="height: 800px; width: calc(100% - 220px); display: inline-block; border: 1px solid black;"></div><script>window.onload = function() {diagram.initDiagram();diagram.initPalette();};</script>

view rawindex.html hosted with ❤ by GitHub

The next step is to complete the initPalette function we’ve created. As I mentioned earlier, initialization of the palette isn’t very different from initialization of the diagram. Here we will use our getTemplates() function for the second time – when we do this, we don’t have to define the appearance of the shapes again, just for the palette. However, it should be stressed that we can create still other appearances for shapes – when moving to the diagram, what’s important is the element’s category, not its appearance. In addition, to enable transfer from the palette to the diagram, we need to add the allowDrop field to the diagram initialization and set its value to true. Here’s what the code should look like:

Listing 2. Initialization of the palette

var initDiagram = function () {diagram = $(go.Diagram,'diagram-content', {initialContentAlignment: go.Spot.Center,allowDrop: true});// ...}var initPalette = function () {palette = $(go.Palette, 'palette-content');getTemplates().forEach(x => palette.nodeTemplateMap.add(x.category, x.template));palette.model.nodeDataArray = [{key: 1, category: 'first'},{key: 2, category: 'second'},{key: 3, category: 'third'}]}

view rawdiagram.js hosted with ❤ by GitHub

Now here’s what the application will look like:

Figure 2. Diagram with added palette

At the end, in order to improve the appearance of the application, let’s add two more things: a grid the elements will be snapped to, and their auto-positioning.

Let's start with the grid. You’ll find it under diagram.grid, and the only thing we have to do is change its visible property to true. In order to add dragging, it has to be configured in the built-in drag tool available under diagram.toolManager.draggingTool. We can use two properties here: isGridSnapEnabled to enable dragging and gridSnapCellSize to define the size of the grid (for our example let’s define a size of 50x50). If we’re using node size modification (resizingTool), we would set analogous fields in it as well. Here’s the code that will be responsible for setting the grid:

Listing 3. Setting the grid on the diagram

diagram.grid.visible = true;diagram.toolManager.draggingTool.isGridSnapEnabled = true;diagram.toolManager.draggingTool.gridSnapCellSize = new go.Size(50, 50);

view rawdiagram.js hosted with ❤ by GitHub

The easiest way to position the elements is by changing the layout of the diagram. The default layout does not define any automatic arrangement of elements – it only arranges them so that they don’t overlap each other. However, this is offered by other layouts: GridLayout (placement on the grid), TreeLayout (tree), ForceDirectedLayout (graphs pushing the elements away from each other), LayeredDigraphLayout (graph arranged in columns and rows) and CircularLayout (arrangement of nodes on a circle).

Figure 3. Diagram with enabled grid and set LayeredDigraphLayout

We set the layout as another field during initialization of the diagram – a layout we pass a new instance of the selected layout to, along with its possible configuration. Here’s an example of how we can implement it for LayeredDigraphLayout:

Listing 4. Setting of Layered Digraph layout for the diagram

diagram = $(go.Diagram,'diagram-content', {initialContentAlignment: go.Spot.Center,allowDrop: true,layout: $(go.LayeredDigraphLayout)});

view rawdiagram.js hosted with ❤ by GitHub

The effect is presented in Figure 3.

You can also check out other available layouts, but you need to keep their limitations in mind. For example, TreeLayout won’t be able to handle a situation where two edges lead to one node.

Results of the whole tutorial you can check on the GitHub repository or on Codepen:

SUMMARY

As you’ve definitely understood reading this article, we have developed an advanced application without a lot of work, using just the functionality of the GoJS library without additional hacking. There’s a total of around 120 lines of JavaScript code, which shows clearly that we haven’t done anything difficult. GoJS allows us to save a lot of time that we would otherwise spend on creating a palette, handling elements on the canvas, or other nontrivial things like automatic positioning of elements. This library also offers other advantages, such as transparent documentation, lots of ready examples, and very good support from the producer. TypeScript users will be also satisfied because official typings are made available, as well as free extensions of the library written in TypeScript.

As much as we’d like to, it was impossible to present all the capabilities of the library in this series of articles. We strongly encourage you to go through the examples available on the developer's website.

This post was also published on ITNEXT.

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:
White Dribbble logo

Get inspired by over 70 Dribbble shots of our interactive data visualizations

Go to Dribbble
Graphic encouraging users to get inspired by examples of interactive data visualizations, featuring a variety of user interfaces with more posted on Dribbble.

Articles you might be interested in

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

Angular vs. React: Which technology is more efficient?

Compare the performance of Angular and React in large apps, focusing on memory usage and optimization needs. Learn when to choose each in the upcoming webinar.

Kacper Cierzniewski
Aug 4, 2021