horizontalregion.as

来自「QS我也没用过」· AS 代码 · 共 279 行

AS
279
字号
package qs.charts
{
	import mx.charts.chartClasses.ChartElement;
	import flash.events.MouseEvent;
	import mx.charts.chartClasses.CartesianTransform;
	import flash.display.Graphics;
	import flash.events.Event;
	import flash.filters.ColorMatrixFilter;
	import mx.charts.chartClasses.DataDescription;

	[Event("change")]
	public class HorizontalRegion extends ChartElement
	{
		[Bindable] public var min:Number;
		[Bindable] public var max:Number;
		
		
		private var mouseStart:Number;
		private var mouseMin:Number;
		private var mouseMax:Number;
		
		
		public var changeFunction:Function;
		/* the x/y coordinates of the start of the tracking region */
		private var tX:Number;


		/* whether or not a region is selected */
		private var bSet:Boolean = false;

		/* whether or not we're currently tracking */		
		private var bTracking:String = null;
		

		/* constructor */
		public function HorizontalRegion():void
		{
			/* mousedowns are where we start tracking the selection */
			addEventListener("mouseDown",startTracking);			
		}
		
		public function panBy(delta:Number):void
		{
			var hMin:Number = this.hMin;
			var hMax:Number = this.hMax;
			
			if(min + delta < hMin)
			{
				delta = hMin - min;
			}
			if(max + delta > hMax)
			{
				delta = hMax - max;
			}
				
			this.min = min + delta;
			this.max = max + delta;	
			invalidateProperties();
			invalidateDisplayList();
			changeFunction();
			
		}
		
		/* draw the overlay */
		override protected function updateDisplayList(unscaledWidth:Number,
												   unscaledHeight:Number):void
		{

			super.updateDisplayList(unscaledWidth, unscaledHeight);
			

			var g:Graphics = graphics;
			g.clear();
			
			// draw a big transparent square so the flash player sees us for mouse events */
			g.moveTo(0,0);
			g.lineStyle(0,0,0);
			g.beginFill(0,0);
			g.drawRect(0,0,unscaledWidth,unscaledHeight);
			g.endFill();
			
			/* draw the selected region, if there is one */
			if(bSet)
			{
				/* the selection is a data selection, so we want to make sure the region stays correct as the chart changes size and/or ranges.
				*  so we store it in data coordaintes. So before we draw it, we need to transform it back into screen coordaintes
				*/
				var c:Array = [{dx: min }, {dx:max }];
				dataTransform.transformCache(c,"dx","x",null,null);

				/* now draw the region on screen */
				g.moveTo(c[0].x,unscaledHeight);				
				g.lineStyle(1,0);
				g.lineTo(c[0].x,0);
				g.lineTo(c[1].x,0);
				g.lineTo(c[1].x,unscaledHeight);
				
				g.lineStyle(1,0x086DDE);
				g.moveTo(c[0].x-2,unscaledHeight/2-4);
				g.beginFill(0xF7FFFF);
				g.drawRoundRect(c[0].x-2,unscaledHeight/2-4,4,8,2,2);
				g.endFill();
				
				g.lineStyle(1,0x086DDE);
				g.moveTo(c[1].x-2,unscaledHeight/2-4);
				g.beginFill(0xF7FFFF);
				g.drawRoundRect(c[1].x-2,unscaledHeight/2-4,4,8,2,2);
				g.endFill();
								
				}
		}


		/* to make sure we end up in any ranges autogenerated by the axes, we need to describe our data to them
		*/
		override public function describeData(dimension:String,requiredFields:uint):Array
		{
			/* if no region is selected, we have no data */
			if(bSet == false)
				return [];
			
			
			
			if (dimension == CartesianTransform.HORIZONTAL_AXIS) {
				var dd:DataDescription = new DataDescription();
				/* describe the minimum and maximum values we need on screen */
				dd.min = min;
				dd.max = max;				
				return [dd];
			}
			
			return [];
		}

		override public function mappingChanged():void
		{
			/* since we store our selection in data coordinates, we need to redraw when the mapping between data coordinates and screen coordinates changes
			*/
			invalidateDisplayList();
		}

		private function startTracking(e:MouseEvent) :void
		{
			/* the user clicked the mouse down. First, we need to add listeners for the mouse dragging */
			systemManager.addEventListener("mouseUp",endTracking,true);
			systemManager.addEventListener("mouseMove",track,true);

			/* now store off the data values where the user clicked the mouse */
			var dataVals:Array = dataTransform.invertTransform(mouseX,mouseY);
			mouseStart = mouseX;
			tX = dataVals[0];

			var c:Array = [{dx: min }, {dx:max }];
			dataTransform.transformCache(c,"dx","x",null,null);
			
			mouseMin = c[0].x;
			mouseMax = c[1].x;
			
			if(bSet && Math.abs(mouseX - mouseMin) < 5)
			{
				tX = max;
				bTracking = "resize";
				bSet = false;
				updateTrackBounds(mouseX);								
			}
			else if (bSet && Math.abs(mouseX - mouseMax) < 5)
			{
				tX = min;
				bTracking = "resize";
				bSet = false;
				updateTrackBounds(mouseX);								
								
			}
			if(bSet && mouseX > mouseMin && mouseX < mouseMax)
			{
				bTracking = "move";							
				updateDragBounds(mouseX);
			}
			else
			{
				bTracking = "resize";
				bSet = false;
				updateTrackBounds(mouseX);								
			}
		}

		private function track(e:MouseEvent):void {
			if(bTracking == null)
				return;
			if (bTracking == "move")
			{
				updateDragBounds(mouseX);
			}
			else
			{
				bSet = true;
				updateTrackBounds(mouseX);
			}
			e.stopPropagation();
		}

		private function endTracking(e:MouseEvent):void
		{
			/* the selection is complete, so remove our listeners and update one last time to match the final position of the mouse */
			systemManager.removeEventListener("mouseUp",endTracking,true);
			systemManager.removeEventListener("mouseMove",track,true);
			e.stopPropagation();
			if (bTracking == "move")
			{
				updateDragBounds(mouseX);
			}
			else
			{
				updateTrackBounds(mouseX);
				changeFunction();
			}
			bTracking = null;
						
		}
		
		private function get hMin():Number
		{
			return dataTransform.invertTransform(0,0)[0];
		}
		private function get hMax():Number
		{
			return dataTransform.invertTransform(unscaledWidth,0)[0];
		}
		

		private function updateDragBounds(mouseX:Number):void
		{
			var newMouseMax:Number = mouseMax + (mouseX - mouseStart);
			var newMouseMin:Number = mouseMin + (mouseX - mouseStart);

			if(newMouseMax > unscaledWidth)
			{
				newMouseMin -= newMouseMax - unscaledWidth;
				newMouseMax = unscaledWidth;
			}
			if(newMouseMin < 0)
			{
				newMouseMax += -newMouseMin;
				newMouseMin = 0;
			}
			max = dataTransform.invertTransform(newMouseMax,0)[0];
			min = dataTransform.invertTransform(newMouseMin,0)[0];
						
			
			/* invalidate our data, and redraw */
			//modelChangedHandler();
			invalidateProperties();
			invalidateDisplayList();
			changeFunction();
																								
		}
		
		private function updateTrackBounds(mouseX:Number):void
		{
			if(mouseX > unscaledWidth)
				mouseX = unscaledWidth;
			if(mouseX < 0)
				mouseX = 0;
				
			var dataVals:Array = dataTransform.invertTransform(mouseX,0);
			
			/* store the bounding rectangle of the selection, in a normalized data-based rectangle */
			max = Math.max(tX,dataVals[0]);
			min = Math.min(tX,dataVals[0]);
			
			/* invalidate our data, and redraw */
			//modelChangedHandler();
			invalidateProperties();
			invalidateDisplayList();
			
		}
		
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?