Using SVG Templates in Styles
If you want to use native SVG templates as part of your visualization, yFiles for HTML ships with predefined style implementations for nodes, labels, ports, and stripes that support this:
Each of these styles has an property to provide the id of the render template element that should be used for visualization, for example styleResourceKey. Note that the id key can also be passed as constructor parameter.
Render templates are pre-defined SVG snippets that are defined in one or more
script elements that act as a container to provide the snippets.
A <script>
element containing templates needs to be included in an application’s
main HTML file and is identified by the value "text/yfiles-template"
in its type
attribute.
During runtime, the child elements of the template scripts are parsed and made available
for the template styles. All top-level child elements with an 'id' attribute can be
referenced by their id.
The contents of top-level <defs>
elements in the template script can be referenced by all
templates that are defined within the same script. This way, resources can be shared among multiple
templates.
The following example shows a template SVG with a simple render template for nodes:
With this template script included in an application’s main HTML file, the unique ID of the enclosing <g> element can be used as the key when creating a new TemplateNodeStyle instance:
Using Strings as Templates
Besides the template styles introduced above, yFiles for HTML ships with style implementations which support SVG snippets provided as strings:
The string has to be set to the svgContent property or passed to the constructor.
Note that the SVG snippet does not declare the SVG namespace itself. After parsing the resulting SVG elements are automatically created in the SVG namespace before they are added to the DOM.
Using Data Binding
Template styles also provide a mechanism for data binding.
SVG attribute values can be bound to any property available in the graph element’s
tag property as well as certain standard template properties such as itemSelected
and itemFocused
available in the template context.
If the bound object provides the method addPropertyChangedListener(listener: function)
,
or implements the IPropertyObservable
interface, and calls the registered listeners, changes to the bound property are immediately reflected in the
visualization.
Binding also provides support for converters and converter parameters as well as binding property paths.
Bindings are dynamically replaced with the bound values by the binding engine at runtime.
"Normal" bindings are resolved on the graph element’s tag property.
For example, if there is an object stored in the element’s tag that has the property
width
, you can bind to the value of this property with the string "{Binding width}":
Bindings work on all standard SVG attributes.
Adding a binding using the custom attribute data-content
sets the content of the
element to the bound value.
The following example sets the content of the <text> element to the value of
the property name
(of an object stored in the element’s tag).
The tag object itself can be bound by omitting to specify the binding property. Please note though that assigning a different object to the graph item’s tag will not automatically update the bindings.
The following example will result in <text>Lorem ipsum</text>
Template Binding
Template bindings are resolved on a graph element’s template context. This can be used to modify the element based on its selection state, for example. Also, custom data can be stored in the template style’s styleTag property, which you can also bind to using a template binding.
Property | Purpose |
---|---|
In a label template, template bindings are resolved on an extended label template context that provides the following additional properties:
Property | Purpose |
---|---|
The following template binding sets the fill
to the value stored in the style’s
styleTag property:
The template binding in the data-content
attribute sets the content of the SVG
group to the value stored in the template style’s styleTag
property (this can be an SVG element!):
Bindings in String Template Styles
In string template styles, bindings work just the same as described above. The string template example mentioned in Using Strings as Templates is easily adapted to using bindings:
Property Paths
The binding engine supports property paths. This means, bindings can not only be resolved directly on the properties of the bound objects, but on properties of objects stored in properties of the bound objects, etc., also.
The following example binds the property color
of the object that is stored in
the styleTag property.
Converters
Bindings can specify converters and converter parameters.
Converters are simple functions with the signature function(value:Object, parameter:Object):Object
.
A converter has to be registered under its name either in the converter store or with the
window
object before it can be used. The converter store is shared among all TemplateStyles.
It can be accessed by the static property CONVERTERS
on the respective TemplateStyle class.
At runtime, the converter method is located by name in the converter store - if it is not found
there the function is located on the window
object.
The converter is called with the resolved binding value an optionally the
converter parameter. The converter is in charge of returning an object that is used as the value of the
attribute containing the binding.
Note that, if the binding was specified in a data-content
attribute, the converter
may also return an SVG element that is set as a child node to the element in the
DOM containing the data binding.
Using a simple conversion function and registering it with the converter store:
Using the converter in a binding within a render template:
Using a converter with a converter parameter to prefix the bound value with the string "http://":
The definition of the converter shows how the converter parameter is used in the convert method:
Notifying of Property Changes
If the bound object provides the method addPropertyChangedListener(listener: function)
,
or implements the IPropertyObservable interface, it
should call the registered listeners when a property value has changed.
The binding mechanism registers a listener and updates the template instance
if the name given in the listener argument matches the property’s name.
To allow the binding mechanism to properly clean up unused bindings, the bound
object should also provide the method removePropertyChangedListener(listener: function)
which should remove the given listener.
An arbitrary object can also be made observable for the binding engine by using one of the
static makeObservable
convenience methods of the template style implementations. In this case, the update
has to be triggered by calling the function firePropertyChanged(propertyName)
on the bound object
when the value of a bound property has changed.
State Dependent CSS classes
Depending on the state of the item, the following CSS classes are added to the root element of the template:
yfiles-selected
yfiles-focused
yfiles-highlighted
Text Wrapping in a Template Style
TextWrapConverter
is a built-in converter function which emits wrapped text as svg elements.
It can be used to display wrapped text in a template style.
To use the TextWrapConverter
the template style must include a <g>
element that binds a
property containing the text to be wrapped to data-content
. As Converter function
TextWrapConverter
must be specified. The converter’s parameters are passed using a shorthand notation
for width, height, font, trimming and color.
The shorthand syntax must satisfy the following expression:
width height [;font[;trimming[;color]?]?]?
where:
"width" is an integer
"height" is an integer
"font" is a css-like font shorthand
"trimming" is "none"|"word"|"character"|"character-ellipsis"|"word-ellipsis"
"color" is a css color shorthand
A full template might look like this:
Tutorial Demo Code
The Organization Chart demo shows how to use a TemplateNodeStyle for a complex node visualization. It also demonstrates the aspects of data binding and converters.