⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 icicletreelayout.as

📁 用于flash/flex的 as3的 2D图形图像图表的动态生成
💻 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 + -