package flare.vis.operator.layout
{
import flare.util.Shapes;
import flare.util.Sort;
import flare.vis.data.Data;
import flare.vis.data.NodeSprite;
import flare.vis.data.render.ShapeRenderer;
import flash.geom.Rectangle;
/**
* Layout that places nodes as circles compacted into a larger circle.
*
* <p>Circle sizes are determined by a node's <code>size</code> property.
* It is assumed that the sizes are set <i>before</i> this operator is run,
* for example, by placing a <code>SizeEncoder</code> prior to this layout
* in an operator list.</p>
*
* <p>If the <code>treeLayout</code> property is <code>false</code>, all
* nodes will be treated the same and the result will be a "bubble" chart.
* If the <code>treeLayout<code> property is <code>true<code>, circles will
* be nested inside each other according to the tree structure of the data.
* </p>
*
* <p>The results of this layout can vary dramatically based on the sort
* order of the nodes. For example, sorting the nodes by the
* <code>size</code> property (in either ascending or descending order)
* can result in much cleaner layouts. Use the <code>sort</code> property
* of this class to set a preferred sorting routine. By default, this
* operator will not perform any sorting.</p>
*
* <p>NOTE: This operator will set a node's <code>renderer</code> and
* <code>shape</code> properties, overriding any previous values.</p>
*
* <p>The algorithm used to perform the circle packing is adapted from
* W. Wang, H. Wang, G. Dai, and H. Wang's <a
* href="http://portal.acm.org/citation.cfm?id=1124772.1124851">
* Visualization of large hierarchical data by circle packing</a>,
* ACM CHI 2006.</p>
*/
public class CirclePackingLayout extends Layout
{
private var _sort:Sort = null;
private var _order:int;
private var _b:Rectangle = new Rectangle();
/** The data group to process. This setting will be ignored if tree mode
* is set to true. */
public var group:String = Data.NODES;
/** The amount of spacing between neighboring circles.
* The default value is 4 pixels. */
public var spacing:Number = 4;
/** Indicates if the view should be scaled to fit within the
* display bounds. The default is true. */
public var fitInBounds:Boolean = true;
/** Indicates if a tree layout (circles nested within circles) should
* be computed. The default is false. Any data group settings will
* be ignored if this operator uses a tree layout. */
public var treeLayout:Boolean = false;
/** A sort criteria for ordering nodes in this layout.
* Ordered nodes are placed in a spiral starting at the center.
* The default is null, meaning no sorting is performed. */
public function get sort():Sort { return _sort; }
public function set sort(s:*):void {
_sort = s==null ? s : (s is Sort ? Sort(s) : new Sort(s));
}
/**
* Creates a new CirclePackingLayout.
* @param spacing the minimum spacing between neighboring circles
* @param treeLayout if true, a hierarchical circles-within-circles
* layout will be peformed; if false (the default) all nodes will be
* considered equally
* @param sort a sort criteria for ordering nodes in the layout.
* Ordered nodes are placed in a spiral starting at the center.
*/
public function CirclePackingLayout(spacing:Number=4,
treeLayout:Boolean=false, sort:*=n