Flex3D圖表——立方體柱狀圖(ColumnChart組件)

思路分爲以下:三步:

1:創建SolidChart組件,像製作二維圖表一樣正常顯示數據部分。

2:自定義ColumnChart的ItemRenderer項呈示器,並指定ColumnSeries的itemRenderer屬性爲剛自定義的項項呈示器。

3:創建MXML應用程序,將剛製作好的ColumnChart組件放入顯示。

這樣自定義組件,也是爲了以後可以複用的考慮。


項目目錄結構如下:前面點紅色部分是本例所能使用到的。

第一步:創建SolidChart.組件,代碼如下:commponent.chart/SolidChart.MXML

<?xml version="1.0" encoding="utf-8"?>  
<mx:Panel xmlns:mx="library://ns.adobe.com/flex/mx"
		  xmlns:s="library://ns.adobe.com/flex/spark"
		  xmlns:fx="http://ns.adobe.com/mxml/2009"
		  width="100%"
		  height="100%"
		  title="{Title}"
		  layout="absolute"
		  >  
	<fx:Script>  
		<![CDATA[  
			import itemRender.histogramSkin;			
			import mx.charts.chartClasses.CartesianCanvasValue;
			import mx.charts.events.ChartItemEvent;
			import mx.charts.events.LegendMouseEvent;
			import mx.charts.renderers.BoxItemRenderer;
			import mx.collections.ArrayCollection;
			import mx.events.FlexEvent;
			import mx.graphics.codec.JPEGEncoder;
			
		[Bindable]  
		public var expenses:ArrayCollection; //數據集合

		[Bindable]  
		private var Title:String;   //Panel頭部信息
		public function init(datas:ArrayCollection,title:String):void{  
			expenses = new ArrayCollection(); 
			Title = title;  //初始化Panel頭部信息
			expenses = datas;  //初始化表的數據集合		
		}  
			
		protected function legend1_itemMouseDownHandler(event:LegendMouseEvent):void
			{
				var index:int=-1;
				for(var i:int=0;i<myChart.series.length;i++){
					if(event.item.label==myChart.series[i].displayName){					
						index=i;
					}
					myChart.series[i].visible=false;					
				}	
				myChart.series[index].visible=true;
			}									
		]]>  
	</fx:Script>  
	<fx:Declarations>
		<fx:Array id="fillcolor">
			<s:SolidColor color="#EF7651" alpha="0.5"/>
			<s:SolidColor color="#E9C836" alpha="0.6" />
			<s:SolidColor color="#6FB35F" alpha="0.7" />
			<s:SolidColor color="#A1AECF" alpha="0.8" />
			<s:SolidColor color="green" alpha="0.9" />
		</fx:Array>
		<mx:SeriesSlide  id="SlideIn" direction="up" duration="3000"/>
		<mx:SeriesSlide  id="SlideOut" direction="down" duration="1000"/>
		</fx:Declarations>

	<mx:ColumnChart id="myChart"
		            horizontalCenter="true"
					fontSize="13.5"
                    dataProvider="{expenses}"   
					showDataTips="true"
					textAlign="center" 
					width="95%" 
					height="100%" 
					>  
		<mx:horizontalAxis>  
			<mx:CategoryAxis  categoryField="name" 
							  displayName="動畫名稱"
							  title="動畫名稱"/>  
		</mx:horizontalAxis>  
		
		<mx:verticalAxis>
			<mx:LinearAxis title="數量"
						   autoAdjust="true" 
						   alignLabelsToInterval="true"
						   computedMaximum="800"
						   displayName="數量"
						   interval="100"
						   maximum="800"
						   />
		</mx:verticalAxis>		
		<mx:series>  
			<mx:ColumnSeries displayName="人氣指數" yField="hot"     itemRenderer="itemRender.solidSkin" 
							 showDataEffect="{SlideIn}" showEffect="{SlideIn}"
							 />				
			<mx:ColumnSeries displayName="劇場版數" yField="theatre" itemRenderer="itemRender.solidSkin" 
							 showDataEffect="{SlideIn}" showEffect="{SlideIn}"
							/>
			<mx:ColumnSeries displayName="已出集數" yField="blues"   itemRenderer="itemRender.solidSkin" 
							 showDataEffect="{SlideIn}" showEffect="{SlideIn}" 
							/>
			<mx:ColumnSeries displayName="好評度"  yField="rating"  itemRenderer="itemRender.solidSkin" 
							 showDataEffect="{SlideIn}" showEffect="{SlideIn}" 
							/>
			<mx:ColumnSeries displayName="發展趨勢" yField="trends"  itemRenderer="itemRender.solidSkin"
							 showDataEffect="{SlideIn}" showEffect="{SlideIn}" 
							/>	    
		</mx:series>  
	</mx:ColumnChart>  
	<mx:Legend id="legend1"			   
		       right="40" top="30" height="151"
			   dataProvider="{myChart}"
			   toolTip="點擊圖例名稱可只顯示
一個相應欄目"
			   itemClick="legend1_itemMouseDownHandler(event)"
			   />
</mx:Panel>  
第二部,因爲柱狀圖ColumnChart組件的默認呈示器BoxItemRenderer是二維畫圖的,所以在此需要自定義項呈示器solidSkin。itemRender/solidSkin.MXML。代碼如下:

//自定義柱狀圖的外觀類——實現立方效果

package itemRender
{  
	import flash.display.Graphics;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import mx.charts.ChartItem;
	import mx.charts.chartClasses.GraphicsUtilities;
	import mx.charts.series.ColumnSeries;
	import mx.charts.series.items.ColumnSeriesItem;
	import mx.collections.ArrayCollection;
	import mx.controls.Text;
	import mx.core.IDataRenderer;
	import mx.graphics.IFill;
	import mx.graphics.IStroke;
	import mx.graphics.SolidColor;
	import mx.skins.ProgrammaticSkin;
	import mx.utils.ColorUtil;
	
	import spark.primitives.Graphic;
	
	
	//ProgrammaticSkin是外觀元素的基類,他們通過編程方式繪製自身。
	public class solidSkin extends ProgrammaticSkin implements IDataRenderer  
	{  
		//data屬性表示要呈示或編輯的數據,在這裏指chartItem,柱狀圖的一列
		private var _data:Object;
	

		//創建柱狀圖的一列
		private var _chartItem:ColumnSeriesItem;  
		//構造函數
		public function solidSkin()  
		{  
			super();  
		} 


		public function get data():Object  
		{  
			return Object(_chartItem);  
		}  
		public function set data(value:Object):void  
		{  		
			_chartItem = value as ColumnSeriesItem;  	
			//標記組件,以便在稍後屏幕更新期間調用該組件的 updateDisplayList() 方法。 
			invalidateDisplayList();  
		}  
		//從ProgramaticSkin繼承的方法,通過編程方式繪製自身
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void  
		{   
			super.updateDisplayList(unscaledWidth,unscaledHeight);
			//清除畫布
			this.graphics.clear();  
			//得到立方圖的8個點座標
			var points:Array = getPoints(unscaledWidth*0.65,unscaledHeight);
			//柱狀圖展示,只需要3面就可,畫3個矩形即可。
			drawFill(points[4],points[7],points[6],points[5]);  
			drawFill(points[6],points[2],points[3],points[7]);  
	        drawFill(points[7],points[4],points[0],points[3]); 	
			this.graphics.endFill();  
			
		}  
		
		//根據長寬計算8點座標信息
		protected function getPoints(w:Number,h:Number):Array  
		{  
			var points:Array = new Array(8);  
			points[0] = new Point(0,h);  
			points[1] = new Point(w,h);  
			points[2] = new Point(w,0);  
			points[3] = new Point(0,0);  
			points[4] = new Point(0+w/2.0,h+w/2.0);  
			points[5] = new Point(w+w/2.0,h+w/2.0);  
			points[6] = new Point(w+w/2.0,0+w/2.0);  
			points[7] = new Point(0+w/2.0,0+w/2.0);  
			return points;  
		}  
		//根據傳入的座標信息,繪製線條及填充繪製區域  
		protected function drawFill(...args):void  
		{  			
			var fill:IFill;//定義執行填充的類必須實現的接口。
			var state:String = "";//定義當前組件的視圖狀態
			//以下代碼爲默認項呈示器的內容,用來判斷每個系列的顏色,
			if (_data is ChartItem && _data.hasOwnProperty('fill'))
			{
				state = _data.currentState;
				fill = _data.fill;
			}	 	
			else{
				fill = GraphicsUtilities.fillFromStyle(getStyle('fill'));
			
			}			
			var color:uint;
			var adjustedRadius:Number = 0;
			
			switch (state)
			{
				case ChartItem.FOCUSED:
				case ChartItem.ROLLOVER:
					if (styleManager.isValidStyleValue(getStyle('itemRollOverColor')))
						color = getStyle('itemRollOverColor');
					else
						color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),-20);
					fill = new SolidColor(color);		
					adjustedRadius = getStyle('adjustedRadius');
					if (!adjustedRadius)
						adjustedRadius = 0;
					break;
				case ChartItem.DISABLED:
					if (styleManager.isValidStyleValue(getStyle('itemDisabledColor')))
						color = getStyle('itemDisabledColor');
					else
						color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),20);
					fill = new SolidColor(GraphicsUtilities.colorFromFill(color));
					break;
				case ChartItem.FOCUSEDSELECTED:
				case ChartItem.SELECTED:
					if (styleManager.isValidStyleValue(getStyle('itemSelectionColor')))
						color = getStyle('itemSelectionColor');
					else
						color = ColorUtil.adjustBrightness2(GraphicsUtilities.colorFromFill(fill),-30);
					fill = new SolidColor(color);				
					adjustedRadius = getStyle('adjustedRadius');
					if (!adjustedRadius)
						adjustedRadius = 0;
					break;
			}	
			var stroke:IStroke = getStyle("stroke");			
			var w:Number = stroke ? stroke.weight / 2 : 0;			
			var rc:Rectangle = new Rectangle(w - adjustedRadius, w - adjustedRadius, width - 2 * w + adjustedRadius * 2, height - 2 * w + adjustedRadius * 2);			
			var g:Graphics = graphics;	
			if (stroke)
				stroke.apply(g,null,null);
			if (fill)
				fill.begin(g,rc,null);			  
			g.moveTo(args[0].x,args[0].y);  
			for(var i:int=1;i<args.length;i++)  
				{  
					g.lineTo(args[i].x,args[i].y);  
				} 
		}  		
	}  
}  
第三步,創建應用程序,顯示第一步自定義的組件SolidChart.代碼如下:

<?xml version="1.0" encoding="utf-8"?>  
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
			   xmlns:s="library://ns.adobe.com/flex/spark"
			   xmlns:mx="library://ns.adobe.com/flex/mx"
			   xmlns:chart="component.chart.*"
			   creationComplete="init()">  
	<fx:Style source="css/Chart3D.css"/>
	<fx:Script>  
		<![CDATA[  
		import mx.collections.ArrayCollection;  
		[Bindable]
		public var funs:ArrayCollection=new ArrayCollection([//創建數據集合
				{name:"海賊王",hot:90,theatre:110,blues:482,rating:90,trends:100},
				{name:"死神",hot:60,theatre:120,blues:230,rating:460,trends:570},
				{name:"火影忍者",hot:80,theatre:413,blues:520,rating:80,trends:340},
				{name:"柯南",hot:250,theatre:340,blues:600,rating:370,trends:430}
		]);//傳入數據源,顯示柱狀圖		
		protected function init():void {  	
	 
			chart1.init(funs,"柱狀圖——立方圖");  
		}  
			
		
		]]>  
	</fx:Script>  
			<chart:SolidChart id="chart1" x="-4" y="3"/>
</s:Application> 

最終效果如圖:









發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章