Create a custom item renderer for the OrgChart
The default item renderers are designed to answer most of the usual use cases. They can extended to add fields (see documentation).
But sometimes we want a completely different rendering or we may reach some limitations of default item renderers.
In this case, the solution is to create custom item renderer.
First of all let’s elaborate on how these item renderers are used by the OrgChart layout.
- An OrgChart item renderer has the constraint to have a fixed height for any data it represents.
- The OrgChart will measure the item renderer that represents the root data item and will affect its height to all the item renderers.
- The size of an item renderer is the same for every level of detail.
- The final width of an item renderer is the width of the widest item renderer of a branch level.
- The size of each item renderer is computed by the layout and can not be changed afterwards.
<p name="root">
<p name="p1"/>
<p name="p2"/>
<p name="p3"/>
</p>
If the item renderers that represent p1, p2 and p3 are respectively 100, 200, and 100 pixels wide, all the item renderers width will be set to 200px.
As you have understood, it’s very important to return a correct measured width and a constant height.
Now, let’s concentrate on the main subject.
Here are the main apects of an item renderer:
- Sub components : An item renderer is usually an aggregation of other components like Image, Label etc…
- Measure: The item renderer must have a correct natural size (
measuredWidth,measuredHeightproperties). - Layout: The item renderer has to layout its sub components. This could be either programmatically or using layout controls.
- Level of details (LOD): An item renderer should have different levels of details for readability and performance reasons.
- Style: An item renderer can expose styling properties to customize its rendering.
- Skin: An item renderer can delegate some rendering parts to skin components to allow deeper customization.
In this article, we will start from a base class that extends the Canvas class.
Let’s review the main aspects and describe what will be done in this custom item renderer:
- Sub components: We will use some labels and an image.
- Measure: the base class is a container and we will use layout controls for the sub components.
- Layout: As said in previous point, we will use layout containers.
- LOD: The base class provides API to specify which sub component is visible at a specific level.
- Style: For simplicity sake, we will not expose new style properties.
- Skin: As the base class is a Canvas, you can set the borderSkin property to specify a different background and/or border.
Our item renderer will be made of:
- At level 0: The background only.
- At level 1: The centered name of the person.
- At level 2: A picture at the left side and at the right side his/her name, position and location.
Let’s start by the MXML part of our renderer:
<?xml version="1.0" encoding="utf-8"?>
<OrgChartItemRendererBase xmlns="*" xmlns:mx="http://www.adobe.com/2006/mxml" >
<!-- the first layer with the name of the person centered -->
<mx:VBox id="layer1" width="100%" height="100%"
horizontalAlign="center" verticalAlign="middle"
paddingLeft="10" paddingRight="10" paddingTop="6"
paddingBottom="6">
<mx:Label id="nameLabel" truncateToFit="false" fontSize="20"
fontFamily="MyFont" fontGridFitType="none" fontAntiAliasType="advanced" />
</mx:VBox>
<!-- the second layer with the picture on the left and labels at the right.-->
<mx:HBox id="layer2" verticalAlign="middle" paddingLeft="10"
paddingRight="10" paddingTop="6" paddingBottom="6">
<mx:Image id="image" width="50" height="70"/>
<mx:VBox verticalAlign="middle">
<mx:Label id="nameLabel2" truncateToFit="false" fontFamily="MyFont"
fontGridFitType="none" fontAntiAliasType="advanced"/>
<mx:Label id="positionLabel" truncateToFit="false" fontFamily="MyFont"
fontGridFitType="none" fontAntiAliasType="advanced"/>
<mx:Label id="locationLabel" truncateToFit="false" fontFamily="MyFont"
fontGridFitType="none" fontAntiAliasType="advanced"/>
</mx:VBox>
</mx:HBox>
</OrgChartItemRendererBase>
Note the use of an embedded font named “MyFont” to have a better rendering and smooth zooming animation.
Then we add a script tag and override some methods.
Firstly, let’s override the configureLevelOfDetails method of the base class to define which sub component is visible at which level of detail.
override protected function configureLevelOfDetails():void {
setLevelsOfDetails(layer1, [1]);
setLevelsOfDetails(layer2, [2]);
}
Then let’s change the background color depending on the selection and highlight state of the data item.
override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void {
super.updateDisplayList(unscaledHeight, unscaledWidth);
var theData:OrgChartItem = data as OrgChartItem;
if (theData != null) {
var isHightlighted:Boolean = theData.orgChart.isItemHighlighted(theData);
var isSelected:Boolean = theData.orgChart.isItemSelected(theData);
var color:uint;
if (isHightlighted) {
color = isSelected ? 0x8695FF: 0xFEFBBA;
} else {
color = isSelected ? 0x637DFF: 0xEAF1F6;
}
setStyle("backgroundColor", color);
}
}
Here is the result:
The complete flex project can downloaded here.
Now that you know the secrets of item renderers, I let you do the following item renderer as exercise
Tags: item renderer








April 21st, 2008 at 11:16 am
I’ve tried this example, but it seems that the configureLevelOfDetails() method does not exist in the OrgChartItemRenderer class. It’s not even present as a a protected member in your api documentation. Do you know if this is perhaps due to a change to the interface in recent versions, and if so, how should the lod be configured in custom renderers in the present version?
Thanks,
Shane
April 21st, 2008 at 1:04 pm
Hi Shane,
This is because the piece of code in the blog post does not inherit from OrgChartItemRender but from OrgChartItemRendererBase which is a class that is not provided with ILOG Elixir but that you can find in the project zip file that Damien attached to his blog post.
Hope this helps.
May 27th, 2008 at 1:02 pm
I believe the unscaledWidth and unscaledHeight parameters are transposed in the call to super in updateDisplayList(). This caused a very hard to find bug for me where the item renderers would flip from landscape to portrait orientation and back again every time I moused over or zoomed or anything else… Hopefully someone will update the original code to correct this.
May 28th, 2008 at 2:19 am
The project files have been fixed. Thanks for reporting back that information.
I’m very sorry for the inconvenience,
Damien
August 12th, 2008 at 5:52 pm
Hi,
Sorry for being such a beginner, but I’m just starting to use Flex and I need, of course, create custom item renderer like the one in this example. My question is (and this might be really basic stuff), where to save the files, e.g. ComplexItemRenderer.mxml? I’m basically using a chart in an application, and I get an error “Unable to locate specified base class ‘ComplexItemRenderer’ for component class …”.
August 18th, 2008 at 12:27 am
This example does not work with patch 1. What changes do I need to make in the code to make it compatible?
Thanks,
Jeff
August 19th, 2008 at 1:46 am
Hi Mike,
This file is a class like a standard class in an .as file but written in MXML.
To make it compile, you just have to put this file (and the super class) in the source directory of your Flex project.
Hope this helps…
August 19th, 2008 at 4:23 am
Hi Jeff,
I tried again and the code works fine with patch 1.
Maybe you could post on the ILOG Elixir forum (http://forums.ilog.com/elixir/) with some details on the problem you are facing.
Damien
August 23rd, 2008 at 7:22 pm
Is it possible that you could provide an example or tips to use Flip as above except extending OrgChartItemRenderer instead of OrgChartItemRendererBase.
Thanks in advance.
August 28th, 2008 at 2:32 am
Jeff,
I’m not sure to understand. Do you want to use this example custom item renderer with the flip sample ?
Damien
August 28th, 2008 at 4:58 am
Damien,
The heart of what I’m trying to achieve is to create a flip item renderer extending UIComponent instead Canvas which is extremely slow rendering more than 40 or 50. OrgChartItemRenderer extends UIComponent which accounts for its peppy performance.
I like the tidiness of OrgChartItemRendererBase and wanted something similar extending UIComponent.
Thanks,
Jeff