In Part 8 of this series
I showed how nodes could be grouped together inside of a container node. This can provide a very effective way of organizing your diagram to allow progressive disclosure of large amounts of data and of course it is a very good way to plot hierarchical data sets. In some data sets though, you have large numbers of nodes at the same level from a hierarchical perspective, but would like to be able to selectively filter or otherwise distinguish between sets of nodes. This is where attribute groups come in.
Understanding Attribute Groups
Attribute groups are a way of varying the look of nodes of the same type based on some underlying property of the node contents. Effectively this allows you to group nodes with a shared property value in a visual manner without having to write complex expression language or define multiple node definitions.
As an example, I've made a slight change to the Node definition that this series has been using to add a status attribute to the nodes and this will have one of three values "Planned", "In Progress" or "Complete",
I can then use an attribute group to categorize the nodes on the diagram using that property as the grouping factor. (I've reverted to the flat node model with just 5 per nodes here)
And here's the modified diagramNode definition:
Notice the following about this version of the code:
- I've removed the fillColor from the marker, this is now provided by the attributeGroup
- The status attribute of the node is passed as the value of the attributeGroup, this is the grouping value. (I also set the label attribute as well which we'll discuss in a moment)
As well as varying by color you can also vary the fill pattern, x scaling and y scaling or even several attributes together using a space delimited list type="color pattern":
Controlling the Assignments
You'll notice that when I varied the color (and indeed the pattern), nowhere did I specify the "pool" of color options to be used or the order. The default behavior here is actually defined in the skin being used (see the tagdoc on <dvt:attributeGroups> for that ). You can, however, explicitly control things within a specific diagram, using the <dvt:attributeMatchRule> and <dvt:attributeExceptionRule> tags. Using the match rule I can assign specific colors to each different value for status:
height="80" width="80" shape="circle"
borderColor="#000000" borderStyle="solid" borderWidth="1.0">
<dvt:attributeMatchRule id="statPln" group="Pending">
<f:attribute name="color" value="red"/>
<dvt:attributeMatchRule id="statIn" group="In Progress">
<f:attribute name="color" value="yellow"/>
<dvt:attributeMatchRule id="statComp" group="Complete">
<f:attribute name="color" value="green"/>
This results in the control I need:
The <dvt:attributeExceptionRule> tag can be used in a similar way except rather than explicitly matching a value, it takes an expression in its condition property that can be evaluated using information from the current node to apply the property or not.
Using the Legend
One advantage of using attributeGroups for node formatting is that also integrates the diagram into the <dvt:legend> component. The legend appears in the top right of the diagram, optionally as a slide-out box, although it can be fixed as well shoudl you desire:
The legend is nested within the <dvt:diagram> tag thus:
<dvt:showLegendGroup label="Current Status">
The source attribute on the legendSection points to the relative id of the attributeGroups tag. When the legendSection is rendered the label used for each entry corresponds to the label property defined within the attributeGroups tag.
Functionality Added by the Legend
The legend not only provides a visual key for the diagram, but can also be used as a filter to control the display of whole groups of nodes at once. The user can click on the entry inside of the legend to toggle the display of that class or group of nodes. Here I've filtered the diagram to hide the nodes marked as "Completed":
As you hide or display groups of nodes using the Legend, the diagram will animate in an appropriate fashion.
Note that if you want to add this kind of filtering functionality to the diagram, then your layouts will need to be fairly forgiving and be able to cope with nodes being hidden and displayed.
A final feature of nodes that use attributeGroups is that you can use the grouping to "stack" all the nodes of the same type into a pile. Such a pile (from a different diagram) would look like this:
The number 16 overlaid on top of the node indicates how many nodes are in the "stack".
When you have a stack of nodes like this, you can either preview the contents of the stack using the preview icon that appears when you select the stack:
This will pop an overlay on top of the current diagram with a simple folder-style (you have no control of the layout) view of the nodes in the stack:
Or, you can also select the unstack option:
To un-stack the nodes into the diagram itself. Naturally you can re-stack in a similar way.
In order to use node stacking, you do of course need to be using attributeGroups, but in addition to this you need to reference the id of the attributeGroup that you want to use to stack by using the groupBy property on the <dvt:diagramNodes> tag. The diagram will initially display with the nodes stacked.
Design Considerations when using Stacking
Be aware of the following minor points:
- You have no control of the actual stacking order. Generally the first node within the nodes collection that represents a particular group will be the one displayed on the top of the stack, but you have no explicit control over this other than that ordering.
- When links are rendered between stacks on the diagram they essentially represent a union of all the defined links between individual nodes within those stacks. As a result your layout will be passed generated "summary" links which will not, for example, have any label information (as that would make no sense). Therefore any layout code that may be used in a stacked node scenario should be prepared for a null result from any call to getLabelBounds() on the link. Code defensively in your layout code for this scenario.
In the Next Article
Now that we have covered most of the visual and layout aspects of diagram it's time to look how your diagram can be decorated with a little interactivity. I'll start off in the next article which will talk about the definition of pop-ups on various artifacts within the diagram.