Skip to main content

Add an editing overlay

Our users need a way to interact with Elements and Links beyond simple dragging. This can be achieved with the Halo plugin of JointJS+. The plugin renders an editing overlay component that surrounds the selected Element or Link with button tools, where each of these tools allows the user to trigger a different action on the Element or Link in question.

What are the default Halo tools?

For Elements, the Halo component provides buttons for seven interactions by default. Starting from the top-left corner in the default arrangement and continuing clockwise, they are:

  • remove, which removes the Element.
  • clone, which clones the Element and starts dragging the clone.
  • fork, which clones the Element, creates a Link from the current Element to the clone, and starts dragging the clone.
  • link, which creates a Link from the current Element and starts dragging the Link target.
  • resize, which starts resizing the Element.
  • rotate, which starts rotating the Element.
  • unlink, which removes all Links to/from the Element. (It is automatically hidden when there are no Links.)

For Links, the Halo component provides buttons for two interactions by default. They are:

  • remove, which removes the Link.
  • direction, which changes the direction of the Link.

In either case, it is possible to hide or reorder some of these default tools and/or to replace them with your own custom tools.

Unlike Stencil, we only create a Halo when the user clicks a Cell. We define a helper function to do that for us, openHalo(), where the cellView refers to the rendered view of an Element or Link which we get from the event:

function openHalo(cellView) {
new ui.Halo({ cellView: cellView }).render();
}

paper.on('cell:pointerup', (cellView) => {
openHalo(cellView);
});
Don't we need to close the Halo when the user is done?

No, we don't need to worry about closing the Halo explicitly. The component gets removed automatically whenever the user interacts with another part of the diagram.

While we are at it, let's also tell our program to open a Halo when the user first opens the application. We can reference the view corresponding to a specific Element or Link via the paper.findViewByModel() function:

openHalo(paper.findViewByModel(rect1));

Finally, note that some default Halo tools (fork, link) create new Links, and that they do so according to the Paper options. Specifically, to make new Links look like the Link we already have in our example, the defaultRouter and defaultConnector Paper options have to match the existing Link's router and connector values:

const paper = new dia.Paper({
el: document.getElementById('paper'),
model: graph,
width: 300,
height: 300,
background: { color: '#F5F5F5' },
cellViewNamespace: namespace,
defaultRouter: { name: 'orthogonal' },
defaultConnector: { name: 'straight', args: { cornerType: 'line' }}
});

See it in action

Click an Element or Link in the example below and try playing around with the various Halo tools:

💡 Would you prefer to learn more about Interaction tools? We have many demos illustrating them on our Demos & examples page.