Magnetizer
The magnetizer is a core piece of Toolkit UI functionality, which inter-operates with layouts to provide a means to nudge elements around in your UI so that things don't overlap. There are a few different ways to use the magnetizer.
Auto magnetization
All layouts support the option of switching on magnetization, which is run after the layout runs. For some layouts this ability is theoretically of no use, for instance the Force directed layout, because in that layout the elements in your UI have already been moved apart by the layout itself. But if you're using, for instance, the Absolute layout, then there is a chance one or more elements are overlapping.
You can switch on magnetization in a layout by setting it as a layout option:
{
layout:{
type:"Absolute",
options:{
magnetize:true
}
}
}
Each time the layout runs, the magnetizer will be run afterwards.
Adhoc magnetization
You can instruct the Surface widget to run the magnetizer over the entire contents of the UI at any time via the magnetize
method:
magnetize(focus?:string|Vertex):void
By default, the magnetizer will use the computed center of all the elements as its origin, and all elements will be pushed away from that point, as in this call:
surface.magnetize()
An alternative, though, is to supply a vertex that you wish to act as the origin, and which you do not wish to move:
surface.magnetize("nodeId")
Here we passed the ID of some node, but we could also have passed the node itself. The signature of the magnetize
method is:
magnetize(focus?:string|Vertex):void
Setting a vertex position and magnetizing
Another feature the Surface offers is the ability to set the position of some element and to immediately magnetize the UI after setting the element's position, using that element as the focus:
setMagnetizedPosition(element:string|Vertex, x:number, y:number):void
This is effectively the same as:
surface.setPosition(element, x, y)
surface.magnetize(element)
This operation is wrapped in a transaction on the Toolkit so if undo is called then every element affected by the magnetize is relocated to its original position.
Magnetizer options
Aside from the setMagnetizedPosition
method, the Surface offers a few different options for configuring the magnetizer automatically:
Interface SurfaceMagnetizeOptions
Members
afterGroupShrink
and afterGroupGrow
afterDrag
is true, when the magnetizer is run after a drag it will be the recently dragged element that moves
in precedence to the other elements. By default, the recently dragged element is _not_ moved by the magnetize operation - it stays
where you dragged it.These options should be supplied as the render options for a Surface, either in a render
call when using vanilla Toolkit:
myToolkit.render(someElement, {
magnetize:{
...
}
})
or as the render options you pass in to a Surface component when using Angular, React, Vue or Svelte.
Gathering Elements
The magnetizer can also gather elements to bring them closer together around some origin. Internally this works by pulling each affected element in on its radial from the origin to the element's center, and then running the magnetizer to nudge everything back out so that nothing overlaps.
gather(focus?:string|Vertex):void
To gather all the elements in the UI around their computed center, don't supply a focus element:
surface.gather()
To gather all the elements in the UI around some focus element:
surface.gather(idOrVertex)