Understanding custom node rendering

Advanced custom node rendering can be performed either by using a node rendering function or a custom rendering class.

Using a custom rendering class

A custom nodes rendering can be specified through the nodeRendererClass property which contains a factory for node renderers. The Class must extend the DisplayObject class. It will be used in combination with the nodeRendererDataSource class to feed each element with its visual content. The following example shows how to use a simple custom item renderer:

<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:visualizer="fr.kapit.visualizer.*">
	<fx:Declarations>
		<fx:XML id="dp" xmlns="">
			<graphml>
				<node id="n1" name="Michael" age="30"/>	
				<node id="n2" name="Jack" age="45"/>	
				<node id="n3" name="Steeve" age="25"/>
				<edge id="e1" source="n1" target="n2"/>
				<edge id="e2" source="n1" target="n3"/>
			</graphml>
		</fx:XML>
	</fx:Declarations>
	
	<visualizer:Visualizer width="100%" height="100%"
						   layout="hierarchicalTree" 
						   dataProvider="{dp}" 
						   nodeRendererClass="{CustomSimpleNodeRenderer}"
						   />
</s:Application>
The following file defines the CustomSimpleNodeRenderer used in the previous example:
<?xml version="1.0" encoding="utf-8"?>
<s:Button xmlns:fx="http://ns.adobe.com/mxml/2009" 
		  xmlns:s="library://ns.adobe.com/flex/spark" 
		  width="50" height="50">
</s:Button>

According to visualization needs, it is recommended to let the class implement some useful interfaces for additional functionalities :

To have more details about these interfaces please refer to following sections.

Using a node rendering function

A node rendering function can be specified via the nodeRendererFunction property. The function takes as input the node data and returns a custom visual content (MXML component, Video, Image...) for each node given its data. It is called at rendering time for each node or when setting this property.

According to visualization needs, it is recommended to let the returned instances implement some useful interfaces for extra functionalities :

The following file gives an example of using a nodeRenderingFunction property:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009" 
			   xmlns:s="library://ns.adobe.com/flex/spark" 
			   xmlns:mx="library://ns.adobe.com/flex/mx" minWidth="955" minHeight="600" xmlns:visualizer="fr.kapit.visualizer.*">
	<fx:Script>
		<![CDATA[
			private function nodeRendererFunction(data:Object):CustomSimpleNodeRenderer
			{
				var renderer:CustomSimpleNodeRenderer = new CustomSimpleNodeRenderer();
				if(data['age']>30)
					renderer.enabled=false;
				else
					renderer.enabled=true;
				return renderer;
			}
		]]>
	</fx:Script>
	<fx:Declarations>
		<fx:XML id="dp" xmlns="">
			<graphml>
				<node id="n1" name="Michael" age="30"/>	
				<node id="n2" name="Jack" age="45"/>	
				<node id="n3" name="Steeve" age="25"/>
				<node id="n4" name="Ilyes" age="28"/>
				<node id="n5" name="Cyril" age="50"/>
				<edge id="e1" source="n5" target="n2"/>
				<edge id="e2" source="n2" target="n4"/>
				<edge id="e3" source="n2" target="n1"/>
				<edge id="e4" source="n5" target="n3"/>
			</graphml>
		</fx:XML>
	</fx:Declarations>
	
	<visualizer:Visualizer width="100%" height="100%"
						   layout="hierarchicalTree" 
						   dataProvider="{dp}" 
						   nodeRendererFunction="{nodeRendererFunction}"
						   nodeExpandButtonPlacement="midBottom"
						   />
</s:Application>