documentationfor yFiles for HTML 2.6

HTML Rendering

yFiles for HTML uses SVG as the main rendering technique. SVG has many advantages like styling with CSS, crisp text rendering, and support for animations and hover effects. On the other hand, visualizations that require complex visual layouts, or many text elements with responsive wrapping, or interactive elements like input or button elements, take a lot of effort in SVG but are easy to implement based on HTML markup.

Usages of HTML visuals
HTML Controls
HTML Label Style
Data Table
React Component Node Style

Using HTML markup also eases the styling of graph items with regard to existing design frameworks which usually operate on HTML markup as well.

Using HtmlVisual

The HtmlVisual works the same as the SvgVisual and can be used similarly: when implementing the IVisualCreator interface, you can return an HtmlVisual that wraps HTML markup, just like an SvgVisual would wrap SVG content.

Basic Usage of HtmlVisual in a Node Style Implementation
class SimpleHtmlNodeStyle extends NodeStyleBase {
  /**
   * @param {!IRenderContext} context
   * @param {!INode} node
   * @returns {?Visual}
   */
  createVisual(context, node) {
    const div = document.createElement('div')
    const { x, y, width, height } = node.layout

    // size and positioning
    const style = div.style
    style.position = 'absolute'
    style.left = `${x}px`
    style.top = `${y}px`
    style.width = `${width}px`
    style.height = `${height}px`

    // a sample text
    div.innerHTML = `
      <div style='box-sizing: border-box; height: 100%; overflow: hidden; border: 1px solid red;'>
        <span>Hello World</span>
      </div>
    `

    return new HtmlVisual(div)
  }
}

class SimpleHtmlNodeStyle extends NodeStyleBase {
  protected createVisual(context: IRenderContext, node: INode): Visual | null {
    const div = document.createElement('div')
    const { x, y, width, height } = node.layout

    // size and positioning
    const style = div.style
    style.position = 'absolute'
    style.left = `${x}px`
    style.top = `${y}px`
    style.width = `${width}px`
    style.height = `${height}px`

    // a sample text
    div.innerHTML = `
      <div style='box-sizing: border-box; height: 100%; overflow: hidden; border: 1px solid red;'>
        <span>Hello World</span>
      </div>
    `

    return new HtmlVisual(div)
  }
}

There are convenience methods to properly arrange Html Elements according to a node’s layout. yFiles for HTML offers static utility methods on HtmlVisual to this end. With it, a node style can be efficiently implemented with a proper updateVisual method:

Basic Usage of HtmlVisual for an efficient NodeStyleBase<TVisual> implementation
class EfficientHtmlNodeStyle extends NodeStyleBase {
  /**
   * @param {!IRenderContext} context
   * @param {!INode} node
   * @returns {!HtmlVisual}
   */
  createVisual(context, node) {
    const div = document.createElement('div')
    div.innerHTML = `
    <div style='box-sizing: border-box; width: 100%; height: 100%; overflow: hidden; border: 1px solid red;'>
      <span>Hello World</span>
    </div>
  `

    const visual = HtmlVisual.from(div)
    HtmlVisual.setLayout(div, node.layout)
    return visual
  }

  /**
   * @param {!IRenderContext} context
   * @param {!HtmlVisual} oldVisual
   * @param {!INode} node
   * @returns {!HtmlVisual}
   */
  updateVisual(context, oldVisual, node) {
    HtmlVisual.setLayout(oldVisual.element, node.layout)
    return oldVisual
  }
}

class EfficientHtmlNodeStyle extends NodeStyleBase {
  protected createVisual(context: IRenderContext, node: INode): HtmlVisual {
    const div = document.createElement('div')
    div.innerHTML = `
    <div style='box-sizing: border-box; width: 100%; height: 100%; overflow: hidden; border: 1px solid red;'>
      <span>Hello World</span>
    </div>
  `

    const visual = HtmlVisual.from(div)
    HtmlVisual.setLayout(div, node.layout)
    return visual
  }

  protected updateVisual(context: IRenderContext, oldVisual: HtmlVisual, node: INode): HtmlVisual {
    HtmlVisual.setLayout(oldVisual.element, node.layout)
    return oldVisual
  }
}

Consider setting box-sizing to border-box to ensure the visualization is contained within the node’s layout.

When should I use HTML rendering?

HTML rendering naturally lends itself to visualizations comprising mostly text, or for integration with HTML-based front-end frameworks. For example, wrapping text or positioning elements based on their intrinsic sizes with CSS-based layouts is much easier. SVG also does not offer input elements, scrollbars, or tables, all of which work natively in HTML.

Additionally, compared with SVG text rendering performance, HTML often performs better for visualizations with lots of text.

When should I avoid HTML rendering?

While HTML works very well in browsers, yFiles for HTML primarily exports SVG images. SVG supports embedding non-SVG content with the foreignObject element, which is how HTML elements are exported as part of the SVG. The foreignObject element, however, is only supported by (most) browsers. If you need exported SVG images that work well in non-browser image editors, you can either enable the rasterizeHtmlVisuals property, which will convert them to bitmaps, or avoid HTML-based visuals entirely.

While HTML-based visuals are well suited for the use cases described above, there are visualizations that are better implemented using actual image formats like SVG. This includes complex geometric content, and in general visualizations that can be considered more image-like.

Browsers also optimize HTML aggressively and tend to restrict the size and positioning of HTML elements to integral coordinate values. This means that visualizations that should have fractional positions or sizes will be rounded to integral ones, which will sometimes be apparent when moving or resizing HTML nodes in a zoomed-in view.

We recommend using SVG-based implementations whenever feasible.