Created
May 26, 2010 15:55
-
-
Save johnyanarella/414671 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.codecatalyst.charting.component | |
{ | |
import flash.geom.Point; | |
import flash.geom.Rectangle; | |
import mx.charts.DateTimeAxis; | |
import mx.charts.chartClasses.CartesianChart; | |
import mx.charts.chartClasses.CartesianDataCanvas; | |
import mx.charts.chartClasses.ChartState; | |
import mx.styles.CSSStyleDeclaration; | |
import mx.styles.StyleManager; | |
/** | |
* Day(s) to highlight. | |
* | |
* @see Date#days | |
*/ | |
[Style(name="days", type="Array", format="Number", inherit="no")] | |
/** | |
* Color(s) used when highlighting the specified day(s). | |
* | |
* NOTE: If fewer colors are specfied than days, the first specified color is used for when highlighting all days. | |
*/ | |
[Style(name="highlightColors", type="Array", format="Color", inherit="no")] | |
/** | |
* Alphas(s) used when highlighting the specified day(s). | |
* | |
* NOTE: If fewer alphas are specfied than days, the first specified alpha is used for when highlighting all days. | |
*/ | |
[Style(name="highlightAlphas", type="Array", format="Number", inherit="no")] | |
/** | |
* Custom chart background element that highlights the specified days on charts that use a DateTimeAxis. | |
*/ | |
public class DayHighlighter extends CartesianDataCanvas | |
{ | |
// ======================================== | |
// Default style initialization | |
// ======================================== | |
/** | |
* @private | |
*/ | |
protected static var stylesInitialized:Boolean = initializeStyles(); | |
/** | |
* @private | |
*/ | |
protected static function initializeStyles():Boolean | |
{ | |
if ( !StyleManager.getStyleDeclaration( "DayHighlighter" ) ) | |
{ | |
var defaultStyles:CSSStyleDeclaration = new CSSStyleDeclaration(); | |
defaultStyles.defaultFactory = | |
function():void | |
{ | |
this.days = [ 0, 6 ]; | |
this.highlightColors = [ 0xCCCCCC ]; | |
this.highlightAlphas = [ 0.5 ]; | |
}; | |
StyleManager.setStyleDeclaration( "DayHighlighter", defaultStyles, true ); | |
} | |
return true; | |
} | |
// ======================================== | |
// Protected constants | |
// ======================================== | |
/** | |
* Day defined in milliseconds. | |
*/ | |
protected static const DAY_IN_MS:Number = 24 * 60 * 60 * 1000; | |
/** | |
* Vertical direction. | |
*/ | |
protected static const VERTICAL:String = "vertical"; | |
/** | |
* Horizontal direction. | |
*/ | |
protected static const HORIZONTAL:String = "horizontal"; | |
// ======================================== | |
// Protected properties | |
// ======================================== | |
/** | |
* DateTimeAxis associated with the <code>chart</code>, if applicable. | |
*/ | |
protected var dateTimeAxis:DateTimeAxis; | |
/** | |
* Direction of the DateTimeAxis (<code>HORIZONTAL</code> or <code>VERTICAL</code>). | |
*/ | |
protected var dateTimeAxisDirection:String; | |
// ======================================== | |
// Constructor | |
// ======================================== | |
/** | |
* Constructor. | |
*/ | |
public function DayHighlighter() | |
{ | |
super(); | |
} | |
// ======================================== | |
// Protected methods | |
// ======================================== | |
/** | |
* @inheritDoc | |
*/ | |
override protected function commitProperties():void | |
{ | |
super.commitProperties(); | |
dateTimeAxis = getDateTimeAxis(); | |
dateTimeAxisDirection = getDateTimeAxisDirection(); | |
} | |
/** | |
* @inheritDoc | |
*/ | |
override protected function updateDisplayList( unscaledWidth:Number, unscaledHeight:Number ):void | |
{ | |
super.updateDisplayList( unscaledWidth, unscaledHeight ); | |
if ( ( chart == null ) || ( chart.chartState == ChartState.PREPARING_TO_HIDE_DATA ) || ( chart.chartState == ChartState.HIDING_DATA ) ) | |
return; | |
graphics.clear(); | |
if ( dateTimeAxis != null ) | |
{ | |
// get the days to highlight from the associated style | |
var days:Array = getStyle( "days" ) as Array; | |
if ( days != null ) | |
{ | |
// get the highlight colors and alphas from the associated styles | |
var colors:Array = getStyle( "highlightColors" ) as Array; | |
var alphas:Array = getStyle( "highlightAlphas" ) as Array; | |
// calculate the 'floored' starting and ending date (i.e. round down to the nearest day ) | |
var startDate:Date = new Date( dateTimeAxis.minimum.fullYear, dateTimeAxis.minimum.month, dateTimeAxis.minimum.date ); | |
var endDate:Date = new Date( dateTimeAxis.maximum.fullYear, dateTimeAxis.maximum.month, dateTimeAxis.maximum.date ); | |
// iterate through all the days between the starting and ending date | |
var date:Date = new Date( startDate.getTime() ); | |
while ( date.getTime() <= endDate.getTime() ) | |
{ | |
// determine if this date is one of the specified days | |
var index:int = days.indexOf( date.day ); | |
if ( index != -1 ) | |
{ | |
// determine the color and alpha to use | |
var color:Number = ( colors.length == days.length ) ? colors[ index ] : colors[ 0 ]; | |
var alpha:Number = ( alphas.length == days.length ) ? alphas[ index ] : alphas[ 0 ]; | |
// draw the day | |
drawDay( date, color, alpha ); | |
} | |
date.setTime( date.getTime() + DAY_IN_MS ); | |
} | |
} | |
} | |
} | |
/** | |
* Draws the rectangular bounds of the specified day with the specified color and alpha. | |
*/ | |
protected function drawDay( day:Date, color:Number, alpha:Number ):void | |
{ | |
var rectangle:Rectangle = calculateDayRectangle( day ); | |
if ( rectangle != null ) | |
{ | |
graphics.beginFill( color, alpha ); | |
graphics.drawRect( rectangle.x, rectangle.y, rectangle.width, rectangle.height ); | |
graphics.endFill(); | |
} | |
} | |
/** | |
* Calculate the rectangular bounds of the day within the chart, in component coordinates. | |
*/ | |
protected function calculateDayRectangle( day:Date ):Rectangle | |
{ | |
var rectangle:Rectangle = null; | |
var nextDay:Date = new Date( day.getTime() + DAY_IN_MS ); | |
var dayBegin:Point; | |
var dayEnd:Point; | |
if ( dateTimeAxisDirection == HORIZONTAL ) | |
{ | |
// convert from data coordinates to component coordinates | |
dayBegin = dataToLocal( day ); | |
dayEnd = dataToLocal( nextDay ); | |
// construct a rectangle that describes the bounds of the day, in component coordinates | |
rectangle = new Rectangle(); | |
rectangle.top = 0; | |
rectangle.left = dayBegin.x; | |
rectangle.bottom = height; | |
rectangle.right = dayEnd.x; | |
} | |
else if ( dateTimeAxisDirection == VERTICAL ) | |
{ | |
// convert from data coordinates to component coordinates | |
dayBegin = dataToLocal( null, day ); | |
dayEnd = dataToLocal( null, nextDay ); | |
// construct a rectangle that describes the bounds of the day, in component coordinates | |
rectangle = new Rectangle(); | |
rectangle.top = dayBegin.y; | |
rectangle.left = 0; | |
rectangle.bottom = dayEnd.y; | |
rectangle.right = width; | |
} | |
return rectangle; | |
} | |
/** | |
* Returns the DateTimeAxis, or <code>null</code> if the associated chart does not have a DateTimeAxis. | |
*/ | |
protected function getDateTimeAxis():DateTimeAxis | |
{ | |
if ( horizontalAxis is DateTimeAxis ) | |
return horizontalAxis as DateTimeAxis; | |
if ( verticalAxis is DateTimeAxis ) | |
return verticalAxis as DateTimeAxis; | |
if ( chart is CartesianChart ) | |
{ | |
var cartesianChart:CartesianChart = chart as CartesianChart; | |
if ( cartesianChart.horizontalAxis is DateTimeAxis ) | |
return cartesianChart.horizontalAxis as DateTimeAxis; | |
if ( cartesianChart.verticalAxis is DateTimeAxis ) | |
return cartesianChart.verticalAxis as DateTimeAxis; | |
} | |
return null; | |
} | |
/** | |
* Returns the DateTimeAxis direction (<code>HORIZONTAL</code> or <code>VERTICAL</code>), or <code>null</code> if the associated chart does not have a DateTimeAxis. | |
*/ | |
protected function getDateTimeAxisDirection():String | |
{ | |
if ( horizontalAxis is DateTimeAxis ) | |
return HORIZONTAL; | |
if ( verticalAxis is DateTimeAxis ) | |
return VERTICAL; | |
if ( chart is CartesianChart ) | |
{ | |
var cartesianChart:CartesianChart = chart as CartesianChart; | |
if ( cartesianChart.horizontalAxis is DateTimeAxis ) | |
return HORIZONTAL; | |
if ( cartesianChart.verticalAxis is DateTimeAxis ) | |
return VERTICAL; | |
} | |
return null; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment