documentationfor yFiles for HTML 3.0.0.1

Canvas Rendering

yFiles for HTML primarily uses SVG as its rendering technology. SVG offers several advantages, including styling with CSS, crisp text rendering, and support for animations and hover effects. Moving or resizing elements can also be very fast. However, for very large diagrams, the SVG DOM can become quite large, potentially leading to performance degradation.

Therefore, yFiles provides alternative rendering methods that render into Canvas (<canvas>) elements using either the Canvas API, the WebGL 1 API, or the WebGL 2 API. Drawing on a Canvas can improve performance for large graphs that do not require highly detailed item visualizations.

The Canvas Rendering API

Styles or renderers that use the Canvas API must return a subclass of the abstract HtmlCanvasVisual class in their implementation of the createVisual method. Subclasses of HtmlCanvasVisual must implement the render method.

class NodeCanvasVisual extends CanvasVisual {
  /**
   * @param {IRectangle} layout
   */
  constructor(layout) {
    super()
    this.layout = layout
  }

  /**
   * Draw a simple rectangle with a solid orange fill.
   * @param {IRenderContext} renderContext
   * @param {CanvasRenderingContext2D} ctx
   */
  render(renderContext, ctx) {
    ctx.fillStyle = 'rgba(255,140,0,1)'
    const l = this.layout
    ctx.fillRect(l.x, l.y, l.width, l.height)
  }
}

The render method is called every time the visualization needs to be updated. The ctx parameter provides the Canvas context (canvas.getContext("2d")) for the Canvas to paint on.

When should I use Canvas rendering?

Canvas rendering offers advantages for the following use cases:

  • Large diagrams
  • Simple rendering

Canvas rendering is most effective when rendering many elements with a simple visualization. In other words, it is ideal for large diagrams with few details. This makes it especially suitable for zoom-level dependent rendering (level-of-detail rendering): at low zoom levels, when the number of visible elements is high and a simple visualization is sufficient, the style renderer provides Canvas-based rendering. At higher zoom levels, it uses more sophisticated SVG-based styles (for example, with fine details, gradients, drop shadows, etc.).

When should I avoid Canvas rendering?

Canvas rendering may not work or may perform poorly in the following use cases:

  • Wrapping or decorating graph item styles: All style decorators are SVG-based and expect that a decorated style creates a visualization that consists of an actual SVG element. Although HtmlCanvasVisual extends Visual, it doesn’t provide such an element. Thus, decorating styles that provide Canvas rendering will fail.
  • Mixing SVG-based styles and Canvas-based styles: yFiles for HTML provides a hybrid rendering mechanism that can render both Canvas-based styles and SVG-based styles simultaneously. Internally, HtmlCanvasVisual are drawn on one Canvas if possible. If an SVG style is drawn between Canvas-based styles (with respect to their z-order), the styles behind the SVG are drawn on one Canvas, and the ones before are drawn on another Canvas. Mixing Canvas and SVG-based styles might result in generating a large number of Canvas elements, which will negatively impact memory consumption and performance. Note that nodes, edges, labels, and decorations like handles are drawn on separate layers. Thus, mixing a Canvas-based node style and a built-in label style won’t be a problem, for example.
  • Complex painting: Since the Canvas has to be completely re-rendered at each repaint, a complex rendering might reduce performance compared to SVG-based rendering. Another drawback of Canvas rendering is the handling of native mouse and touch events: the Canvas will either catch all of these events or let them pass through. In the first case, SVG elements won’t get hover effects if a Canvas level is drawn in front. In the latter case, you will get hover effects even for elements that are hidden behind a Canvas node. Note that the mouse and touch events provided by the CanvasComponent are not affected.