Flex Chart DataTip Renderer

Here is a quick post with some code to create custom DataTip renderers for Flex charts using Spark components and containers. Below is a screen shot of the custom DataTip and the source code to create it follows.

Main.mxml

<?xml version="1.0" encoding="utf-8"?>
<s:WindowedApplication 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:charts="com.thanksmister.charts.*" 
					   width="480" height="340">
	
	<fx:Style source="assets/css/style.css"/>
	
	<fx:Script>
		<![CDATA[
			import mx.charts.CategoryAxis;
			
			private function categoryAxis_labelFunc(item:Object, prevValue:Object, axis:CategoryAxis, categoryItem:Object):String 
			{
				var datNum:Number = Date.parse(item);
				var tempDate:Date = new Date(datNum);
				
				return dateFormatter.format(tempDate).toUpperCase();
			}
		]]>
	</fx:Script>
	
	<fx:Declarations>
		<mx:DateFormatter id="dateFormatter" formatString="MMMM-DD-YYYY" />
	
		<s:XMLListCollection id="dp">
			<s:source>
				<fx:XMLList>
					<quote date="8/1/2007" open="40.29" close="39.58" />
					<quote date="8/2/2007" open="39.4" close="39.52" />
					<quote date="8/3/2007" open="39.47" close="38.75" />
					<quote date="8/6/2007" open="38.71" close="39.38" />
					<quote date="8/7/2007" open="39.08" close="39.42" />
					<quote date="8/8/2007" open="39.61" close="40.23" />
					<quote date="8/9/2007" open="39.9" close="40.75" />
					<quote date="8/10/2007" open="41.3" close="41.06" />
					<quote date="8/13/2007" open="41" close="40.83" />
					<quote date="8/14/2007" open="41.01" close="40.41" />
					<quote date="8/15/2007" open="40.22" close="40.18" />
					<quote date="8/16/2007" open="39.83" close="39.96" />
					<quote date="8/17/2007" open="40.18" close="40.32" />
					<quote date="8/20/2007" open="40.55" close="40.74" />
					<quote date="8/21/2007" open="40.41" close="40.13" />
					<quote date="8/22/2007" open="40.4" close="40.77" />
					<quote date="8/23/2007" open="40.82" close="40.6" />
					<quote date="8/24/2007" open="40.5" close="40.41" />
					<quote date="8/27/2007" open="40.38" close="40.81" />
				</fx:XMLList>
			</s:source>
		</s:XMLListCollection>

		<s:SolidColorStroke id="lineStroke" color="#CCCCCCC" alpha=".2" weight="1"/>
		
	</fx:Declarations>
	
	<s:VGroup width="100%" height="100%" paddingBottom="10" paddingTop="10" paddingLeft="10" paddingRight="10">
		
		<mx:LineChart id="lineChart"
					  showDataTips="true"
					  dataProvider="{dp}"
					  width="100%" gutterRight="10"
					  height="100%" 
					  dataTipRenderer="com.thanksmister.charts.DataTipSkin">
			
			<!-- vertical axis -->
			<mx:verticalAxis>
				<mx:LinearAxis baseAtZero="false" title="Price" />
			</mx:verticalAxis>
			
			<!-- horizontal axis -->
			<mx:horizontalAxis>
				<mx:CategoryAxis id="ca" categoryField="@date" title="Date" labelFunction="categoryAxis_labelFunc" />
			</mx:horizontalAxis>
			
			<!-- horizontal axis renderer -->
			<mx:horizontalAxisRenderers>
				<mx:AxisRenderer axis="{ca}" canDropLabels="true" />
			</mx:horizontalAxisRenderers>
			
			<!-- series -->
			<mx:series>
				<mx:LineSeries yField="@open" form="segment" displayName="Open" />
			</mx:series>
			
			<!-- series filters -->
			<mx:seriesFilters>
				<fx:Array/>
			</mx:seriesFilters>
			
			<!-- assign stroke to grid lines -->
			<mx:backgroundElements>
				<mx:GridLines gridDirection="both" horizontalChangeCount="2" verticalChangeCount="6">
					<mx:horizontalStroke>{lineStroke}</mx:horizontalStroke>
					<mx:verticalStroke>{lineStroke}</mx:verticalStroke>
				</mx:GridLines>
			</mx:backgroundElements>
			
			<mx:annotationElements>
				<fx:Array>
					<charts:RangeSelector id="selectedRange" />
				</fx:Array>
			</mx:annotationElements>
			
		</mx:LineChart>
		
	</s:VGroup>
	
</s:WindowedApplication>

DataTipSkin.mxml

'
<?xml version="1.0" encoding="utf-8"?>
<s:Group  xmlns:fx="http://ns.adobe.com/mxml/2009" 
		 xmlns:s="library://ns.adobe.com/flex/spark"  
		 implements="mx.core.IFlexDisplayObject, mx.core.IDataRenderer"
		 xmlns:mx="library://ns.adobe.com/flex/mx" width="120">
	
	<fx:Script>
		<![CDATA[
			import flashx.textLayout.conversion.TextConverter;
			import flashx.textLayout.elements.TextFlow;
			
			import mx.charts.HitData;
			import mx.charts.series.items.LineSeriesItem;
			
			private var _data:HitData;
			
			[Bindable]
			private var _xValue:String;
			
			[Bindable]
			private var _yValue:String;
			
			[Bindable]
			private var _displayText:TextFlow;
			
			public function get data():Object
			{
				// TODO Auto Generated method stub
				return null;
			}
			
			public function set data(value:Object):void
			{
				// HitData data from chart
				_data = value as HitData;
				
				// The display text used in datatip which comes in HTML format
				_displayText = TextConverter.importToFlow(_data.displayText, TextConverter.TEXT_FIELD_HTML_FORMAT);
				
				// HitData contains a reference to the ChartItem
				var item:LineSeriesItem = _data.chartItem as LineSeriesItem;
				
				// ChartItem xValue and yValue 
				_xValue = String(item.xValue);
				_yValue = String(item.yValue);
			}
		]]>
	</fx:Script>
	
	<fx:Declarations>
		
	</fx:Declarations>
	
	<s:Rect right="0" left="0" bottom="0" top="0">
		<s:filters>
			<s:DropShadowFilter blurX="20" blurY="20" alpha="0.22" distance="5" angle="90" knockout="false" />
		</s:filters>
		<s:fill>
			<s:SolidColor color="0x393939"/>
		</s:fill>    
		<s:stroke>
			<s:SolidColorStroke color="0x1a1a19"  weight="1" alpha=".2" />
		</s:stroke>
	</s:Rect>
	
	<s:VGroup width="100%" height="100%" paddingTop="10" paddingRight="10" paddingBottom="10" paddingLeft="10">
		
		<s:RichEditableText textFlow="{_displayText}" width="100%" textAlign="center" selectable="false" editable="false"/>
		
	</s:VGroup>

</s:Group>

-Mister