欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Flex chart 改变图表元素的颜色 博客分类: Flex flexchartlengend颜色自定义 

程序员文章站 2024-03-20 11:42:04
...

Flex 有许许多多的chart组件,他们的父类都是ChartBase。ChartBase下面有两个直接子类:CartesianChart 和 PolarChart。除了PieChart 继承自PolarChart外,其他的chart图形都继承自CartesianChart。因此如果像改变图表元素的颜色的话,就需要对这两种类型的chart做不同的处理。

在下面的例子里,我们在lengend 做一下定制来得到我们想要的结果。

主程序:

 

<?xml version="1.0"?>
<!-- Simple example to demonstrate the PieChart control. -->
<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">
	<fx:Script>
		<![CDATA[          
			import mx.charts.HitData;
			import mx.charts.series.PieSeries;
			import mx.charts.series.items.PieSeriesItem;
			import mx.collections.ArrayCollection;
			
			[Bindable]
			private var medalsAC:ArrayCollection = new ArrayCollection( [
				{ Country: "USA", Gold: 35, Silver:39, Bronze: 29 },
				{ Country: "China", Gold: 32, Silver:17, Bronze: 14 },
				{ Country: "Russia", Gold: 27, Silver:27, Bronze: 38 } ]);
			
			private function dataTipFunction(hitData:HitData):String
			{
				 var temp:String= (" " + (hitData.chartItem as PieSeriesItem).percentValue).substr(0,6);
				 //对于PieChart来说,PieSeriesItem有一个percentValue的值来标记百分比
				return hitData.item[(hitData.element as PieSeries).nameField] + "(" + temp + "%)"; 
			}
		]]>
	</fx:Script>
	<s:layout>
		<s:VerticalLayout/>
	</s:layout>
	<mx:VDividedBox width="100%" height="100%">
		<mx:Panel title="Pie Chart" height="100%" width="100%">
			<mx:PieChart id="chart" 
						 height="100%" 
						 width="100%"
						 paddingRight="5" 
						 paddingLeft="5" 
						 showDataTips="true" 
						 dataTipFunction="dataTipFunction"
						 dataProvider="{medalsAC}">          
				<mx:series>
					<mx:PieSeries 
						nameField="Country"
						labelPosition="callout" 
						field="Silver">
						<mx:filters>
							<fx:Array/>
						</mx:filters>
					</mx:PieSeries>
				</mx:series>
			</mx:PieChart>  
			<mx:Legend dataProvider="{chart}" legendItemClass="com.skin.PolarLegendItem"/>
		</mx:Panel>
		<mx:Panel title="Column Chart" height="100%" width="100%">
			<mx:ColumnChart id="column" 
							height="100%" 
							width="45%" 
							paddingLeft="5" 
							paddingRight="5" 
							showDataTips="true" 
							dataProvider="{medalsAC}"
							>                
				<mx:horizontalAxis>
					<mx:CategoryAxis categoryField="Country"/>
				</mx:horizontalAxis>
				<mx:series>
					<mx:ColumnSeries 
						xField="Country" 
						yField="Gold" 
						displayName="Gold"
						/>
					<mx:ColumnSeries 
						xField="Country" 
						yField="Silver" 
						displayName="Silver"
						/>
					<mx:ColumnSeries 
						xField="Country" 
						yField="Bronze" 
						displayName="Bronze"
						/>
				</mx:series>
			</mx:ColumnChart>
			<mx:Legend dataProvider="{column}" legendItemClass="com.skin.CartesianLegendItem"/>
		</mx:Panel>
	</mx:VDividedBox>
</s:Application>
 CartesianLegendItem:
package com.skin
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import mx.charts.LegendItem;
	import mx.charts.chartClasses.ChartElement;
	import mx.charts.chartClasses.GraphicsUtilities;
	import mx.charts.chartClasses.StackedSeries;
	import mx.charts.renderers.BoxItemRenderer;
	import mx.charts.series.ColumnSeries;
	import mx.charts.series.LineSeries;
	import mx.charts.series.PieSeries;
	import mx.controls.ColorPicker;
	import mx.core.IDataRenderer;
	import mx.core.IFlexDisplayObject;
	import mx.core.IInvalidating;
	import mx.core.UIComponent;
	import mx.events.DropdownEvent;
	import mx.graphics.IFill;
	import mx.graphics.SolidColor;
	import mx.graphics.SolidColorStroke;
	import mx.graphics.Stroke;
	import mx.skins.ProgrammaticSkin;
	import mx.utils.ColorUtil;
	
	public class CartesianLegendItem extends LegendItem {
		public function CartesianLegendItem() {
			super();
			this.buttonMode = true;
			this.mouseChildren = false;
			this.addEventListener(MouseEvent.CLICK,selecteLegend,false,0,true);

		}
		
		private function selecteLegend(e:MouseEvent):void
		{
			if(e.target is LegendItem)
			{
				var cp:ColorPicker = new ColorPicker();
				this.addChild(cp);
				cp.selectedColor = (element as UIComponent).getStyle("fill").color;//element 负责生成此图例项目的图表元素。
				cp.addEventListener(DropdownEvent.CLOSE, changeItemColor,false,0,true);
				cp.x = e.localX;
				cp.y = e.localY;
				cp.width = 0;
				cp.height = 0;
				cp.open();
			}
		}
		
		private function changeItemColor(e:DropdownEvent):void 
		{
			var solidColor:SolidColor = (element as UIComponent).getStyle("fill") as SolidColor;				
			if (solidColor != null)
			{
				solidColor.color = e.target.selectedColor;
			}
			(element as UIComponent).setStyle("fill",solidColor);
			var stroke:SolidColorStroke = (element as UIComponent).getStyle("stroke");
			if (stroke != null)
			{
				stroke.color = e.target.selectedColor;					
			}
			(element as UIComponent).setStyle("stroke",stroke);
			e.target.removeEventListener(DropdownEvent.CLOSE, changeItemColor,false);
			this.removeChild(e.target as DisplayObject);
			(this.marker as IInvalidating).invalidateDisplayList();
			(element as UIComponent).invalidateDisplayList();
			this.invalidateDisplayList();
		}
	}
}
 PolarLegendItem:
package com.skin
{
	import flash.display.DisplayObject;
	import flash.events.Event;
	import flash.events.MouseEvent;
	
	import mx.charts.LegendItem;
	import mx.charts.chartClasses.ChartElement;
	import mx.charts.chartClasses.GraphicsUtilities;
	import mx.charts.chartClasses.StackedSeries;
	import mx.charts.renderers.BoxItemRenderer;
	import mx.charts.series.ColumnSeries;
	import mx.charts.series.LineSeries;
	import mx.charts.series.PieSeries;
	import mx.controls.ColorPicker;
	import mx.core.IDataRenderer;
	import mx.core.IFlexDisplayObject;
	import mx.core.IInvalidating;
	import mx.core.UIComponent;
	import mx.events.DropdownEvent;
	import mx.graphics.IFill;
	import mx.graphics.SolidColor;
	import mx.graphics.SolidColorStroke;
	import mx.graphics.Stroke;
	import mx.skins.ProgrammaticSkin;
	import mx.utils.ColorUtil;
	
	public class PolarLegendItem extends LegendItem {
		public function PolarLegendItem() {
			super();
			this.buttonMode = true;
			this.mouseChildren = false;
			this.addEventListener(MouseEvent.CLICK,selecteLegend,false,0,true);
		}

		private function selecteLegend(e:MouseEvent):void
		{
			if(e.target is LegendItem)
			{
				var cp:ColorPicker = new ColorPicker();
				this.addChild(cp);
				cp.selectedColor =  (marker as IDataRenderer).data.fill.color;
				/*marker 此图例项目所显示的标记。因为对于PieChart来说,chart中每一块其实是一个PieSeries生产的,所以如果你
				用element来取值的话,你会发现每次element都是同样的。
				*/
				cp.addEventListener(DropdownEvent.CLOSE, changeItemColor,false,0,true);
				cp.x = e.localX;
				cp.y = e.localY;
				cp.width = 0;
				cp.height = 0;
				cp.open();
			}
		}
		
		private function changeItemColor(e:DropdownEvent):void 
		{		
				var solidColor:SolidColor = (marker as IDataRenderer).data.fill as SolidColor;				
				if (solidColor != null)
				{
					solidColor.color = e.target.selectedColor;
				}
				e.target.removeEventListener(DropdownEvent.CLOSE, changeItemColor,false);
				this.removeChild(e.target as DisplayObject);
				(marker as IInvalidating).invalidateDisplayList();
				(element as IInvalidating).invalidateDisplayList();
				this.invalidateDisplayList();
			}
	}
}