`
sherrysky
  • 浏览: 86866 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

flex+degrafa自定义曲线ployline绘制

阅读更多
应用程序
<?xml version="1.0" encoding="utf-8"?>
<mx:Application	xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
				xmlns:degrafa="com.degrafa.*"
				xmlns:paint="com.degrafa.paint.*"
				xmlns:geometry="com.degrafa.geometry.*" viewSourceURL="srcview/index.html" 
				 backgroundColor="#ffffff" xmlns:local="*"
				 creationComplete="inipolyline()" xmlns:text="flash.text.*">
				
	<degrafa:Surface id="asur">
	
		<!-- Creating fills. -->
		<degrafa:fills>
			<paint:SolidFill	id="blue"
								color="#62ABCD"/>
		</degrafa:fills>
		
		<!-- Creating Strokes. -->
		<degrafa:strokes>
			<paint:SolidStroke	id="black"
								color="#000000"
								alpha="1"
								weight="3"/>
			<paint:SolidStroke	id="red"
								color="#FF0000"
								alpha="1"
								weight="3"/>
		</degrafa:strokes>
		<!-- Creating Polyline-->
		<!-- Creating a Geometry Group. -->
		<degrafa:GeometryGroup x="0" y="0">
		
			<!-- Creating a Polygon. -->
			<geometry:Polyline stroke="{black}">
				<geometry:data>0,0 0,20 20,20 20,40 40,40 40,60</geometry:data>
			</geometry:Polyline>
			
		</degrafa:GeometryGroup> 
		<!--自定义曲线-->
		<degrafa:GeometryGroup x="0" y="100" id="geopolytl"/>
	</degrafa:Surface>
	<mx:Button  click="deletepolyline()"  label="deletepolyline" x="100" y="0"/>
	<mx:Script>
		<![CDATA[
			import com.degrafa.GraphicText;
			import com.degrafa.IGeometry;
		public function deletepolyline():void
		{
			    for each(var g:GeometryGroup in asur.graphicsCollection.items)
	        {
	            g.target = null;
	            g.visible = false;
	            for each(var o:IGeometry in g.geometryCollection.items)
	            {
	                o.data = "";
	                g.geometryCollection.removeItem(o);
	            }
	            g.geometry.length = 0;
	            g = null;
	        }
	        asur.graphicsCollection.items.length = 0;
		}
		public function inipolyline():void
		{
		    var polytl: DashedPolylinetl= new DashedPolylinetl();
	        polytl.dash=10;
	        polytl.gap=4;
	        polytl.style=2;
	        var datastl:String="0,0 0,20 20,20 20,40 40,40 40,60 60,60 60,0 ";
	        polytl.data=datastl;
	        polytl.colour=0x1f1fd5;
	        geopolytl.geometryCollection.addItem(polytl);         
		}
			
		]]>
	</mx:Script>
</mx:Application>

自定义的类dashpolylinet1
package  
{   
	import com.degrafa.core.collections.GraphicPointCollection;
	import com.degrafa.geometry.Polyline;
	
	import flash.display.Graphics;
	import flash.geom.Rectangle;
	
	import mx.events.PropertyChangeEvent;
public class DashedPolylinetl extends Polyline
{   
	/**
	 * 构造函数,其中定义了style属性的change事件
	 * */
	public function DashedPolylinetl(points:Array=null)
	{
		super(points);
		addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,redraw);
	}
   /**
   * commandstack用于存储直线绘制信息,主要是moveto和lineto命令 
   **/
    public var	commandstack:Array = new Array();
    private var _points:GraphicPointCollection;
    public var _bounds:Rectangle=new Rectangle();
   
   	override	public function get points():Array{
			if(!_points){_points = new GraphicPointCollection();}
			return _points.items;
		}
	override	public function set points(value:Array):void{			
			if(!_points){_points = new GraphicPointCollection();}
			_points.items = value;
						
			//add a listener to the collection
			if(_points && enableEvents){
				_points.addEventListener(PropertyChangeEvent.PROPERTY_CHANGE,propertyChangeHandler);
			}
			
			invalidated = true;
		
		}
        
        /**
        * 计算dashpolyline的外接矩形
		**/
		  private function calcBounds():void{
		
			var boundsMaxX:Number =0;
			var boundsMaxY:Number =0;
			var boundsMinX:Number =Number.MAX_VALUE;
			var boundsMinY:Number =Number.MAX_VALUE;
						
			for (var i:int = 0;i< _points.items.length; i++) 
			{
				boundsMaxX = Math.max(boundsMaxX, _points.items[i].x);
				boundsMaxY = Math.max(boundsMaxY, _points.items[i].y);
				
				boundsMinX= Math.min(boundsMinX, _points.items[i].x);
				boundsMinY= Math.min(boundsMinY, _points.items[i].y);
				
			}

			_bounds = new Rectangle(boundsMinX,boundsMinY,boundsMaxX-boundsMinX,boundsMaxY-boundsMinY);

		}	
   
   public var length:Number;

   private var _dash:Number;
    /**
     * 每段直线的长度,默认值为0
     **/
    public function get dash():Number
    {
    	if (!_dash)
    		return 0;
		return _dash;
    }
    public function set dash(value:Number):void
    {
		if (_dash != value)
		{
			_dash = value;
			if (gap == 0)
				gap = value;			
			invalidated = true;
        }
    }
    
    private var _style:int;
    
    public function get style():int
    {   if(!_style)
            return 0;
    	return _style;
    }
    
    /**
    * 在style属性change之后分发PropertyChangeEvent事件
    **/
    public function set style(value:int):void
    { 
    	
     if(_style != value)
     {
     	_style=value;
     	invalidated= true;
     }	
     dispatchEvent(new PropertyChangeEvent(PropertyChangeEvent.PROPERTY_CHANGE,false,false, null,int,null,null,this.style));
    }
    
    private var _gap:Number;
  
    /**
     *每段直线之间的距离,默认值为0
     **/
    public function get gap():Number
    {
    	if (!_gap)
    		return 0;
		return _gap;
    }
    public function set gap(value:Number):void
    {
		if (_gap != value)
		{
			_gap = value;
			invalidated = true;
        }
    }
    private var _colour:uint;
  
    /**
     *线的颜色
     **/
    public function get colour():uint
    {
    	if (!_colour)
    		return 0;
		return _colour;
    }
    public function set colour(value:uint):void
    {
		if (_colour != value)
		{
			_colour = value;
			invalidated = true;
        }
    }

	/**
     * 用于绘制之前的指令算法存储至commandstack数组中
     * 根据style值,重组绘制线的数据;
     * style=4,线形为直线,无论如何设置dash,gap,都按照原始data两点一连画直线;
     * style=0,线形为虚线,dash为虚线线段长,gap为虚线间隔,根据二者对原始data进行重组,新的data数据点数大于原始data点个数;
     *         要保证虚线效果,dash+gap必须小于线任意两点间隔或最小距离两点间的距离
     * style=2,线形为虚线并且间隔中有两点,dash为虚线线段长,gap为虚线间隔,根据二者对原始data进行重组,新的data数据点数大于原始data点个数;
     *         要保证效果,该线形适用于数据点任意两点距离大于20的data,线中dash+gap必须小于线任意两点间隔或最小距离两点间的距离,
     *         gap中画了两个点,其位置和gap,dash都有关系,两点距离为20时,dash=10,gap=10,能看到两点效果;算法需要继续改进
     * style=3,线形为虚线并且间隔中有一点,dash为虚线线段长,gap为虚线间隔,根据二者对原始data进行重组,新的data数据点数大于原始data点个数;
     *         要保证效果,该线形适用于数据点任意两点距离大于20的data,线中dash+gap必须小于线任意两点间隔或最小距离两点间的距离,
     *         gap中画了一个点,其位置和gap,dash都有关系,两点距离为20时,dash=5,gap=5,能看到效果;算法需要继续改进
     * style=1,线形为铁路线,算法有问题,无法画出来效果图
      **/
    override public function preDraw():void
    {
		if(invalidated)
		{  
	    	super.preDraw();
          if(points.length==0){ return;}
            commandstack.length=0;                                            
			commandstack.push({type:"m",x:points[0].x+x,y:points[0].y+y});
			//如果style=4,即使设置了dash,gap,它们也不起作用
			if (style==4)
			{    
				for (var i:int = 0;i < points.length; i++)
				{
					commandstack.push({type:"l",x:points[i].x+x,y:points[i].y+y});
				}  
			}
			else
			{   
			   for (var j:int = 0;j < points.length-1; j++)
				switch(style)
				{
				case 0:
					addDashCommands0(commandstack, points[j].x+x, points[j].y+y,points[j+1].x+x, points[j+1].y+y);
				    break;
				case 1:
					  addDashCommands1(commandstack, points[j].x+x, points[j].y+y,points[j+1].x+x, points[j+1].y+y);
                      break;
				case 2:
				case 3:
					addDashCommands2(commandstack, points[j].x+x, points[j].y+y,points[j+1].x+x, points[j+1].y+y);
				      	break;
				default: break;      
				}
			}
                        
			/**
			 * 用于封闭的polyline
			 * */
			if(autoClose)
			{
				commandstack.push({type:"l",x:points[0].x+x,y:points[0].y+y});
			}
	    	calcBounds();
			invalidated = false;
	    }
            
    }
    
    protected var leftOver:int = 0;
    protected var leftOverCount:int = 0;
    
    /**
    *绘制虚线的commandstack命令
    **/
    protected function addDashCommands0(commandstack:Array, x1:int, y1:int, x2:int, y2:int):void
    {
		var length:Number = Math.abs(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)));  //线段长度
		var count:int = leftOverCount;
		var currentLength:int = 0;  //当前长度
		var ratio:Number = 1;       //比例
		while (currentLength < length)
		{
			
			// 绘制直线
			if (count % 2 == 0)
			{
				currentLength += dash - leftOver;
				ratio = Math.min(1,(currentLength / length));
				commandstack.push({type:"l",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			else
			{
				currentLength += gap - leftOver;
				ratio = Math.min(1,(currentLength / length));
				
				commandstack.push({type:"m",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			if (currentLength > length)
			{
				leftOver = ((count % 2 == 0) ? dash : gap) - (currentLength - length);
				leftOverCount = count;
			}
			else
			{
				leftOver = 0;
				leftOverCount = 0;
			}
			count++;
		}     	
    }
    
        /**
        * 绘制铁路线的commandstack命令
        **/ 
         protected function addDashCommands1(commandStack:Array, x1:int, y1:int, x2:int, y2:int):void
    {
		var length:Number = Math.abs(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)));  //线段长度
		var count:int = leftOverCount;
		var currentLength:int = 0;  //当前长度
		var ratio:Number = 1;       //比例
		while (currentLength < length)
		{
			
			// dash
			if (count % 2 == 0)
			{
				currentLength += dash - leftOver;
				ratio = Math.min(1,(currentLength / length));
				commandStack.push({type:"l",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			else
			{
				currentLength += gap - leftOver;
				ratio = Math.min(1,(currentLength / length));
				
				commandStack.push({type:"mm",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio)});
			}
			if (currentLength > length)
			{
				leftOver = ((count % 2 == 0) ? dash : gap) - (currentLength - length);
				leftOverCount = count;
			}
			else
			{
				leftOver = 0;
				leftOverCount = 0;
			}
			count++;
		}    	
    }
    
    /**
    * 绘制单点线或者双点线的commandstack命令
    **/  
            protected function addDashCommands2(commandstack:Array, x1:int, y1:int, x2:int, y2:int):void
    {
		length= Math.abs(Math.sqrt(Math.pow(x1-x2, 2) + Math.pow(y1-y2, 2)));  //线段长度
		var count:int = leftOverCount;
		var currentLength:int = 0;  //当前长度
		var ratio:Number = 1;       //比例
		while (currentLength < length)
		{
			
			// dash
			if (count % 2 == 0)
			{
				currentLength += dash - leftOver;
				ratio = Math.min(1,(currentLength / length));
				commandstack.push({type:"l",x:x1 + ((x2-x1)*ratio),y:y1 + ((y2-y1)*ratio),x0:x2-x1,y0:y2-y1,xd:((x2-x1)*ratio),yd:((y2-y1)*ratio)});
			}
			else
			{
				currentLength += gap - leftOver;
				ratio = Math.min(1,(currentLength / length));
				
				commandstack.push({type:"m",x:x1 + ((x2-x1)*ratio),y:y1 + (y2-y1)*ratio});
			}
			if (currentLength > length)
			{
				leftOver = ((count % 2 == 0) ? dash : gap) - (currentLength - length);
				leftOverCount = count;
			}
			else
			{
				leftOver = 0;
				leftOverCount = 0;
			}
			count++;
		}     	
    }
           /**
           * 根据style参数来绘制不同的线型
           **/
           
           	private var item:Object;
			private var lengths:Number;
			private var sin:Number;
			private var cos:Number;
			private var xx0:Number;
			private var yy0:Number;
			private var xx:Number;
			private var yy:Number;
			private var dx:Number;
			private var dy:Number;

	   		override public function draw(graphics:Graphics,rc:Rectangle):void{
					
		 	preDraw();
		 							
			if(!rc)				
				super.draw(graphics,_bounds);	
			else
				super.draw(graphics,rc);
			
			for each (item in commandstack)
			{
			graphics.lineStyle(0.1,colour,1);	
			lengths=Math.abs(Math.sqrt(Math.pow(item.x0, 2) + Math.pow(item.y0, 2))) 	
        	sin=item.x0/lengths;//直线的sin值
        	cos=item.y0/lengths;  //直线的cos值 	
        	xx0=item.x+dash*sin/4;               //单点直线的x-coordinate起始位置
        	yy0=item.y+dash*cos/4;               //单点直线的y-coordinate结束位置
        	xx=item.x+dash*sin/2;                //双点直线的x-coordinate起始位置
        	yy=item.y+dash*cos/2;                //双点直线的y-coordinate结束位置
        	dx=(item.x0==0?0:(item.x0)/Math.abs(item.x0));//中间变量,即点的x-coordinate移动距离(取值为0,1,-1)
        	dy=(item.y0==0?0:(item.y0)/Math.abs(item.y0));//中间变量,即点的y-coordinate移动距离(取值为0,1,-1)
        	if(item.type=="m")
        	graphics.moveTo(item.x,item.y);
			else 
			switch(style)
			{
			//绘制虚线的算法	
			case 0:
			//绘制实线的算法
			case 4:
			  {
        		
        		graphics.lineTo(item.x,item.y);
        	    break;
			  }
			case 1:  //绘制铁路线(或者变色线的算法)
			  {
        		  	//graphics.moveTo(item.x,item.y);
        		    if(item.type=="mm")
        		    {
        	         graphics.lineStyle(1,0xff0000,1,true);
        	         graphics.lineTo(item.x,item.y);
        	        }
        		   else 
        		  {
        		    graphics.lineStyle(1,0x000000,1,true);	
        			graphics.lineTo(item.x,item.y);
        		  }
        	    break;
			  }
			  
			case 2:   //绘制双点线型的算法
			  { 
        		graphics.lineTo(item.x,item.y);      
        		 if((Math.abs(xx+dx)<=Math.max(Math.abs(item.x),Math.abs(item.x+item.x0-item.xd)))&&(Math.abs(yy+dy)<=Math.max(Math.abs(item.y),Math.abs(item.y+item.y0-item.yd))))
        		 {        		
        		graphics.moveTo(xx0,yy0);
        		graphics.lineTo(xx0+dx,yy0+dy);//绘制单点,即利用lineto来绘制直线
        		graphics.moveTo(xx,yy);
        		graphics.lineTo(xx+dx,yy+dy);  //绘制双点,即利用lineto来绘制直线
                 }
			  	break;
			  }
			case 3:  //绘制单点线型的算法
			   {
        		graphics.lineTo(item.x,item.y);              //设置线条样式,绘制直线
        		//判断点的绘制是否执行,当点直线x-coordinate和y-coordinate的起始位置在直线之内则绘制单点
        		if((Math.abs(xx)<=Math.max(Math.abs(item.x),Math.abs(item.x+item.x0-item.xd)))&&(Math.abs(yy)<=Math.max(Math.abs(item.y),Math.abs(item.y+item.y0-item.yd))))
        		{        		
        		graphics.moveTo(xx,yy);
        		graphics.lineTo(xx+dx,yy+dy); //绘制单点,即利用lineto来绘制直线
                }
			   	 break;
			   }
			}
			}
			super.endDraw(graphics);
			
			
		}
		  /**
		  * 当style属性发生change则调用重绘函数,能够及时的响应线型改变进行重绘(由于会产生bug导致暂时屏蔽重绘功能,因为会报ss引用为Null)
		  * */
		    public  function redraw(e:PropertyChangeEvent):void
    {
    	    
//    	    draw(ss.graphics,null);
    }
    public function commandstackclear():void
    {
      
    }
	
}

}

分享到:
评论

相关推荐

    Degrafa3.1源码

    Degrafa3.1源码 配合 FLEX绘制行政区域地图源码使用 两个工程依赖关系

    Degrafa画矢量曲线

    NULL 博文链接:https://angrycoder.iteye.com/blog/1436586

    Degrafa帮助文档

    好用的Degrafa.CHM,方便用flex绘制矢量图

    flex图形报表控件源代码

    主要是branch中的birdeye。 这里是源代码,但需要借助另外的开源框架Degrafa。我用的是Degrafaflex4.swf。 这里我直接将degrafaflex4.swf和birdeye本身自己写的vis打成一个swf文件。...我的IDE是eclipse3.5+flex4插件。

    SvgToDegrafa.rar_SvgToDegrafa_degrafa_flex

    用flex解析SVG,使用degrafa框架显示出来

    degrafa 的帮助文档

    flex开发的画图框架Degrafa 近来需在flex画些简单的图形,根据朋友推荐使用了Degrafa,但是官方没有提供离线的文档下载,于是自己制作了一下。 文档的所有版权均属http://www.degrafa.com 详细情况请查看degrafa的...

    Degrafa.CHM

    flex开发的画图框架Degrafa 近来需在flex画些简单的图形,根据朋友推荐使用了Degrafa,但是官方没有提供离线的文档下载,于是自己制作了一下。 文档的所有版权均属http://www.degrafa.com 详细情况请查看degrafa的...

    关于DEGRAFA的简介

    NULL 博文链接:https://smartblack.iteye.com/blog/385683

    flex3做的流程图

    flex3的Degrafa 做的流程图,适合初学者探讨

    degrafa源代码

    Degrafa扩展就是在FLEX中增加了对矢量数据的动态处理,包括动态添加,删除和修改,并支持SVG的路径格式数据, 因此只需要对现有的SVG数据进行一些必要的转换(以后会有工具支持,但现在只能手工完成),就可以将SVG...

    关于Degrafa's Fills简介

    只有一个sign05.mxml,需要加入其它FLEX工程使用 博文链接:https://smartblack.iteye.com/blog/388933

    Flex on Java MEAP Jul 2010

    Flex on Java Bernerd Allmon and Jeremy Anderson MEAP Began: May 2008 Softbound print: July 2010 (est.) | 375 pages ISBN: 1933988797 Part 1: Getting started 1. Some Flex with your Java 2. Beginning...

    degrafa绘图工具 svg操作

    一个开源的degrafa绘图工具,里面自带自动生成svg,flex实现,简单易懂,供大家学习

    Flex.on.Java.rar

    Part 1: Getting started 1. Some Flex with your Java 2. Beginning with Java ...8. Charting with DeGrafa 9. Desktop 2.0 with Adobe AIR 10. Testing your Flex app with FlexUnit 11. Flex on Grails

    Degrafa学习一,(含SDK4.0兼容版本及源码,略微有所修改)

    NULL 博文链接:https://madfroghe.iteye.com/blog/1020454

    Degrafa(Beta3)

    NULL 博文链接:https://cwfmaker.iteye.com/blog/544190

    一个隐藏式的登录窗口

    界面非常好看的一个登录窗口 采用隐藏式的登录界面 应用最新的shade 和 degrafa

    degrafaFlex4.SWC

    基于Actionscript3.0,强大的矢量图形绘制类库

Global site tag (gtag.js) - Google Analytics