package flare.analytics.cluster { import flare.util.Arrays; import flare.util.Property; import flare.util.Sort; import flare.vis.data.Data; import flare.vis.data.DataList; import flare.vis.data.EdgeSprite; import flare.vis.data.NodeSprite; import flare.vis.data.Tree; import flare.vis.operator.Operator; /** * Base class for clustering operators that construct a hierarchical * clustering tree. Provides methods for taking a sequence of * merge operations by a clustering algorithm and constructing a * resulting cluster tree. * *
Once a clustering has been computed, each node included in the
* analysis will be annotated with both its cluster membership
* using the name indicated by the clusterField
property.
* By default, this class will attempt to pick an optimal level of the
* cluster tree at which to break up items into discrete clusters.
* However, clients can invoke the labelNodes
method with
* a specific merge number which indicates the point at which to "cut"
* the cluster tree into discrete sub-clusters. This class also annotates
* nodes with a sequence number using the name indicated by the
* sequenceField
property. The sequence number allows items
* to be sorted in a way that attempts to preserve the clustered structure.
* Additionally, the clusterTree
property will return a
* flare.vis.data.Tree
instance that can be used to
* visualize the structure of the cluster tree.
data
property. Non-leaf nodes indicate merges
* made by the clustering algorithm, and have data
* properties that include the merge
number (1 for the
* first merger, 2 for the second, etc), the criterion
* value computed for that merge, and the size
of the
* cluster rooted at that node (the number of descendants in the
* cluster tree).
*/
public function get clusterTree():Tree { return _tree; }
// --------------------------------------------------------------------
/**
* Creates a new HierarchicalCluster instance.
*/
public function HierarchicalCluster()
{
super();
}
/**
* Labels nodes with their cluster membership, determined by
* the given merge number. If the merge number is less than
* zero or unprovided, the merge number that maximizes the
* clustering criteria will be assumed.
* @param merge the merge number at which to compute the clusters
*/
public function labelNodes(merge:int=-1):void
{
if (merge < 0) merge = Arrays.maxIndex(_qvals);
var com:int, idx:int;
var helper:Function = function(n:NodeSprite):void
{
var nn:NodeSprite;
if (n.childDegree && n.data.merge > merge)
{
for (var i:int=0; i