
Separating Style and Renderer
NodeStyleBase<TVisual> simplifies the implementation of multiple interfaces, offering convenience for application developers. The primary method you need to implement is createVisual, making it a convenient starting point for creating your own styles.
In yFiles for HTML’s rendering engine, IVisualCreator instances generate the visual representations of an item. During graph element visualization, these IVisualCreator instances are returned for a specific object by style renderers. The style interfaces only hold a suitable renderer instance. For example, INodeStyle has a renderer property that returns an object of type INodeStyleRenderer. Each style interface in yFiles for HTML has a corresponding renderer interface: (INodeStyleRenderer for INodeStyle, ILabelStyleRenderer for ILabelStyle and so on).
To get the visual representation of an element, the framework requests the renderer from the style, and calls the appropriate methods on the IVisualCreator returned by the renderer.

Note
|
The abstract style classes hide this separation for convenience and simplicity. However, separating the style and its renderer has advantages in certain use cases. |
The styles have only one method to provide the style renderer (e.g., INodeStyle.renderer ). The style itself should hold the state needed for rendering. Clients should be able to control rendering properties on the style, such as the colors or stroke used.
Renderers contain the logic that converts the state held by the style into a visualization on the canvas. The yFiles for HTML rendering engine uses this renderer to handle application logic that depends on aspects of the visualization (such as hit testing or visibility checks). Because of this, the renderer interfaces are broader than necessary for just rendering items. Besides the IVisualCreator, the renderer classes provide IHitTestable, IMarqueeTestable, ILassoTestable, IVisibilityTestable, and IBoundsProvider implementations. Additionally, the renderer of INodeStyles and IEdgeStyles provides implementations of the IShapeGeometry and the IPathGeometry interface, respectively. These interfaces are discussed in Refining a Style’s Behavior.
When separating style and renderer classes, a flyweight pattern can be implemented where renderers can be shared among styles. Two styles of the same type can be created with different renderers to interpret their properties differently, or an existing style and renderer pair can be customized.
Visuals can and should share information where applicable. Store the relevant information on the renderer instance from which the Visuals were created.
Tip
|
Sharing data between Visuals speeds up the creation and updating process of new Visuals because resources can be allocated efficiently, which improves your application’s memory usage. |