documentationfor yFiles for HTML 2.6

Customizing Predefined Styles

Customizing the existing styles in yFiles for HTML is a great example of the usefulness of distinct style and renderer implementations. yFiles for HTML offers a number of predefined styles for nodes, edges, and labels. Instead of implementing a new style and renderer from scratch, you may want to consider customizing the existing styles of yFiles for HTML for your needs and benefit from advanced default implementation for the application logic. This is especially the case if your desired style is just a minor deviation of how an existing style looks and works.

All of yFiles for HTML’s predefined style renderers implement the interfaces mentioned in the section Refining a Style’s Behavior directly, i.e., the interfaces IHitTestable, IMarqueeTestable, ILassoTestable, IVisibilityTestable, and IBoundsProvider as well as IShapeGeometry for node styles and IPathGeometry for edge styles.

The default implementations for these interfaces can be changed for any predefined renderer by subclassing the renderer and either overriding the interface methods directly or returning a custom instance via one of the renderer interface’s getter methods.

Additionally, each renderer provides a protected configure method that is meant to be used by subclasses to inject custom logic when a renderer is being initialized.

The renderer properties of styles in yFiles for HTML are immutable, because changing the renderer of a style at runtime can lead to unforeseen inconsistencies in the rendering engine. Renderers can only be passed to the style interface by calling the appropriate constructor overload.

There are also properties and methods that you can override in the renderer classes that are specific to the style.

For example, the CollapsibleNodeStyleDecoratorRenderer is a renderer for a decorating style that adds a button to another style implementation. This renderer provides the createButton method that you can override to create a custom appearance for the expand/collapse button.

Customizing the Default Edge Style

A more complicated example is the way edges are rendered in yFiles for HTML. There are two styles and corresponding renderer classes, PolylineEdgeStyleRenderer and ArcEdgeStyleRenderer, which both inherit from the PathBasedEdgeStyleRenderer<TStyle> class.

The default implementation of the rendering process for edges in yFiles for HTML uses the source and target ports and the list of bends to create the edge path (represented in yFiles for HTML by the GeneralPath class), which is then drawn onto the canvas. The renderers are responsible for creating this path and this process can be easily customized.

For example, the PolylineEdgeStyleRenderer interprets the edge path as a straight line for each edge segment, while the ArcEdgeStyleRenderer interprets the edge segment as a curved line between the start and end point of the edge and disregards bends completely.

While the renderer instances of both styles are quite different in implementation and resulting visualization, the styles themselves differ only in a few properties. This is an example for the separation of state and logic in style and renderer classes.

You can override the following methods in PathBasedEdgeStyleRenderer<TStyle> in order to manipulate the GeneralPath that is ultimately drawn.

createPath()
The method that interprets the edge path and creates the GeneralPath that is then drawn onto the canvas.
cropPath(GeneralPath)
Trims the ends of the edge path to the points where the edge should visually end, which is the border of the node in most cases. The default implementation queries the lookup of the edge’s source and target port for an instance of IEdgePathCropper.
createSelfLoopPath(boolean)
Defines how self-loops should look like. Self-loops are edges where the source and target ports belong to the same owner. Common implementations either use a rectangular or circular path. By overriding this method you can change how the self-loops look like. Note that this method is not called for edges with two or more bends since two bends are sufficient to define a proper self-loop path on their own.