📄 icicletreelayout.as
字号:
package flare.vis.operator.layout
{
import flare.util.Orientation;
import flare.vis.data.NodeSprite;
import flash.geom.Rectangle;
/**
* Layout that places nodes in an icicle layout, distributing nodes
* evenly within the display bounds. To get a standard icicle view, set
* the nodes <code>shape</code> property to <code>Shapes.BLOCK</code> and
* hide all edges. By default, this operator will attempt to scale the
* layout to fit within the display bounds. By setting
* <code>fitToBounds</code> false, the current <code>depthSpacing<code>
* will be preserved, allowing the layout to exceed the bounds along
* the depth dimension.
*/
public class IcicleTreeLayout extends Layout
{
private var _orient:String = Orientation.TOP_TO_BOTTOM; // orientation
private var _dspace:Number = 50; // the spacing between depth levels
private var _maxDepth:int = 0;
private var _vertical:Boolean = true;
/** Indicates if the layout should be scaled to fit in the bounds. */
public var fitToBounds:Boolean = true;
/** The orientation of the layout. */
public function get orientation():String { return _orient; }
public function set orientation(o:String):void { _orient = o; }
/** The space between successive depth levels of the tree. */
public function get depthSpacing():Number { return _dspace; }
public function set depthSpacing(s:Number):void { _dspace = s; }
// --------------------------------------------------------------------
/**
* Creates a new IcicleTreeLayout.
* @param orientation the orientation of the layout
*/
public function IcicleTreeLayout(orientation:String=null)
{
if (orientation) this.orientation = orientation;
}
/** @inheritDoc */
protected override function layout():void
{
// get bounds parameters
var root:NodeSprite = layoutRoot as NodeSprite;
var b:Rectangle = layoutBounds;
var bMin:Number, bMax:Number, dMax:Number, d:Number, dInc:Number;
switch (_orient) {
case Orientation.LEFT_TO_RIGHT:
case Orientation.RIGHT_TO_LEFT:
bMin = b.bottom;
bMax = b.top;
dMax = b.width;
_vertical = false;
break;
case Orientation.TOP_TO_BOTTOM:
case Orientation.BOTTOM_TO_TOP:
bMin = b.left;
bMax = b.right;
dMax = b.height;
_vertical = true;
break;
default:
throw new Error("Unrecognized orientation value");
}
switch (_orient) {
case Orientation.LEFT_TO_RIGHT:
d = b.left; dInc = _dspace; break;
case Orientation.TOP_TO_BOTTOM:
d = b.top; dInc = _dspace; break;
case Orientation.RIGHT_TO_LEFT:
d = b.right; dInc = -_dspace; break;
case Orientation.BOTTOM_TO_TOP:
d = b.bottom; dInc = -_dspace; break;
default:
throw new Error("Unrecognized orientation value");
}
// calculate depth and width
_maxDepth = 0;
firstPass(root, 0);
// scale the depth to fit as needed
if (fitToBounds && _maxDepth * _dspace > dMax) {
dInc *= dMax / (_maxDepth * _dspace);
}
// perform the layout
doLayout(root, bMin, bMax, d, dInc);
updateEdgePoints(_t);
}
private function firstPass(n:NodeSprite, d:int):Number
{
if (d > _maxDepth) _maxDepth = d;
var extent:Number = 0;
if (n.childDegree == 0 || !n.expanded) {
extent = 1;
} else {
for (var i:int=0; i<n.childDegree; ++i) {
extent += firstPass(n.getChildNode(i), d+1)
}
}
n.props.icicleWidth = extent;
return extent;
}
private function doLayout(n:NodeSprite, b1:Number, b2:Number,
d:Number, dInc:Number):void
{
var pw:Number = n.props.icicleWidth;
var x:Number = b1, w:Number = b2 - b1;
if (n.childDegree > 0 && !n.expanded) {
n.visitTreeDepthFirst(function(c:NodeSprite):void {
update(c, b1 + w/2, b1 + w/2, d+dInc, dInc, false);
});
} else {
for (var i:int=0; i<n.childDegree; ++i) {
var c:NodeSprite = n.getChildNode(i);
var cw:Number = w * c.props.icicleWidth / pw;
doLayout(c, x, x+cw, d+dInc, dInc);
x += cw;
}
}
update(n, b1, b2, d, dInc, true);
}
private function update(n:NodeSprite, b1:Number, b2:Number,
d:Number, dInc:Number, visible:Boolean):void
{
var o:Object = _t.$(n);
if (_vertical) {
o.x = (b1 + b2) / 2;
o.y = d + dInc / 2;
o.u = b1;
o.v = d;
o.w = b2 - b1;
o.h = dInc;
} else {
o.x = d + dInc / 2;
o.y = (b1 + b2) / 2;
o.u = d;
o.v = b1;
o.w = dInc;
o.h = b2 - b1;
}
var alpha:Number = visible ? 1 : 0;
o.alpha = alpha;
o.mouseEnabled = visible;
if (n.parentEdge != null)
_t.$(n.parentEdge).alpha = alpha;
}
} // end of class IcicleTreeLayout
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -