Visualizing Arbitrary Objects
A GraphComponent can display visualizations for arbitrary objects, not just graph elements. In this section, we describe the steps required to insert a visualization for an arbitrary object into the view with a detailed explanation on what is happening for each step.
To visualize an arbitrary object, you need to add a new ICanvasObject to one of the ICanvasObjectGroup instances of your GraphComponent. ICanvasObjectGroup offers method addChild for this purpose:
This poses the following questions for developers:
- Which group to choose to add the canvas object to?
- What is the user object that is passed to addChild?
- What is the descriptor that is passed to addChild?
- What is the returned ICanvasObject?
Choosing the Group to Add the Visualization to
There are several predefined groups in a GraphComponent that are described in The main canvas object groups. The most important ones are
- the backgroundGroup for background visualizations (background images, maps),
- the inputModeGroup for input-related decorations (e.g. handles, ghost visualizations), and
- visualizations which should be in front of everything can be added to the rootGroup.
Instead of using one of the predefined ICanvasObjectGroups, you can create a new group (in one of the predefined groups) using method addGroup.
Providing a User Object and Choosing a Descriptor
User object and descriptor can be seen as a pair: the user object represents the object to render and the descriptor knows how to render the object. The descriptor implements ICanvasObjectDescriptor. Its methods receive the user object as a parameter and provide implementations that render the user object.
ICanvasObjectDescriptor provides descriptors for the most common use cases. It is almost never required to implement a custom ICanvasObjectDescriptor:
- DYNAMIC_DIRTY_INSTANCE and ALWAYS_DIRTY_INSTANCE
- the user object is an IVisualCreator that is responsible for creating the
desired visualization.
// myVisualCreator is the custom IVisualCreator const canvasObject = graphComponent.backgroundGroup.addChild( myVisualCreator, ICanvasObjectDescriptor.ALWAYS_DIRTY_INSTANCE )
- DYNAMIC_DIRTY_LOOKUP and ALWAYS_DIRTY_LOOKUP
- the user object implements ILookup. Its lookup method has to provide
an IVisualCreator implementation for creating the desired visualization.
This is the case for graph items like nodes, for instance (although graph items typically use a specific descriptor that directly queries the style).
// the node provides an IVisualCreator via its lookup const canvasObject = graphComponent.backgroundGroup.addChild(node, ICanvasObjectDescriptor.ALWAYS_DIRTY_LOOKUP)
- VISUAL
- the user object is already the Visual to display.
Using visuals directly is a quick and handy way of adding a custom visualization. Keep in mind, however, that it does not work well when the whole visualization is re-created for other purposes, e.g. image export. In that case you may either get exceptions or the visuals disappear from the control, since they can only exist in one place at the same time.const image = window.document.createElementNS('http://www.w3.org/2000/svg', 'image') image.setAttributeNS('http://www.w3.org/1999/xlink', 'href', 'resources/background.png') image.x.baseVal.value = 1 image.y.baseVal.value = 1 image.width.baseVal.value = 100 image.height.baseVal.value = 100 const visual = new SvgVisual(image) graphComponent.rootGroup.addChild(visual, ICanvasObjectDescriptor.VISUAL)
Keep the Reference to the Canvas Object
addChild returns an instance of type ICanvasObject. This type represents the entity that is drawn in the view and connects your object to its visualization.
You can use the ICanvasObject to manipulate the rendering of the object further. You can reorder the object in its layer, make it temporarily invisible (visible), remove it from the view entirely, change the previously set ICanvasObjectDescriptor, etc.
Example and Demo
The following sample shows how to add and remove a custom visualization of a rectangle in the background of a GraphComponent. The implementation of the IVisualCreator is shown in the example A custom IVisualCreator implementation.
A more complex implementation of an IVisualCreator that visualizes the layers of a Hierarchical Layout is part of the Interactive Hierarchic Layout demo.