/* Copyright (c) 2009 Yahoo! Inc. All rights reserved. The copyrights embodied in the content of this file are licensed under the BSD (revised) open source license */ package com.yahoo.astra.fl.charts { import com.yahoo.astra.fl.charts.events.ChartEvent; import com.yahoo.astra.fl.charts.legend.ILegend; import com.yahoo.astra.fl.charts.legend.LegendItemData; import com.yahoo.astra.fl.charts.series.ICategorySeries; import com.yahoo.astra.fl.charts.series.ILegendItemSeries; import com.yahoo.astra.fl.charts.series.ISeries; import com.yahoo.astra.fl.charts.series.ISeriesItemRenderer; import com.yahoo.astra.fl.utils.UIComponentUtil; import fl.core.InvalidationType; import fl.core.UIComponent; import flash.accessibility.AccessibilityProperties; import flash.display.DisplayObject; import flash.display.Sprite; import flash.events.Event; import flash.events.MouseEvent; import flash.geom.Point; import flash.text.TextFormat; import flash.text.TextFormatAlign; import flash.utils.getDefinitionByName; //-------------------------------------- // Styles //-------------------------------------- /** * The padding that separates the border of the component from its contents, * in pixels. * * @default 10 */ [Style(name="contentPadding", type="Number")] /** * Name of the class to use as the skin for the background and border of the * component. * * @default ChartBackgroundSkin */ [Style(name="backgroundSkin", type="Class")] /** * The default colors for each series. These colors are used for markers, * in most cases, but they may apply to lines, fills, or other graphical * items. * *
An Array of values that correspond to series indices in the data * provider. If the number of values in the Array is less than the number * of series, then the next series will restart at index zero in the style * Array. If the value of this style is an empty Array, then each individual series * will use the default or modified value set on the series itself.
* *Example: If the seriesColors style is equal to [0xffffff, 0x000000] and there * are three series in the chart's data provider, then the series at index 0 * will have a color of 0xffffff, index 1 will have a color of 0x000000, and * index 2 will have a color of 0xffffff (starting over from the beginning).
* * @default [0x00b8bf, 0x8dd5e7, 0xedff9f, 0xffa928, 0xc0fff6, 0xd00050, 0xc6c6c6, 0xc3eafb, 0xfcffad, 0xcfff83, 0x444444, 0x4d95dd, 0xb8ebff, 0x60558f, 0x737d7e, 0xa64d9a, 0x8e9a9b, 0x803e77] */ [Style(name="seriesColors", type="Array")] /** * The default size of the markers in pixels. The actual drawn size of the * markers could end up being different in some cases. For example, bar charts * and column charts display markers side-by-side, and a chart may need to make * the bars or columns smaller to fit within the required region. * *An Array of values that correspond to series indices in the data * provider. If the number of values in the Array is less than the number * of series, then the next series will restart at index zero in the style * Array. If the value of this style is an empty Array, then each individual series * will use the default or modified value set on the series itself.
* *Example: If the seriesMarkerSizes style is equal to [10, 15] and there * are three series in the chart's data provider, then the series at index 0 * will have a marker size of 10, index 1 will have a marker size of 15, and * index 2 will have a marker size of 10 (starting over from the beginning).
* * @default [] */ [Style(name="seriesMarkerSizes", type="Array")] /** * An Array containing the default skin classes for each series. These classes * are used to instantiate the marker skins. The values may be fully-qualified * package and class strings or a reference to the classes themselves. * *An Array of values that correspond to series indices in the data * provider. If the number of values in the Array is less than the number * of series, then the next series will restart at index zero in the style * Array. If the value of this style is an empty Array, then each individual series * will use the default or modified value set on the series itself.
* *Example: If the seriesMarkerSkins style is equal to [CircleSkin, DiamondSkin] and there * are three series in the chart's data provider, then the series at index 0 * will have a marker skin of CircleSkin, index 1 will have a marker skin of DiamondSkin, and * index 2 will have a marker skin of CircleSkin (starting over from the beginning).
* * @default [] */ [Style(name="seriesMarkerSkins", type="Array")] /** * The TextFormat object to use to render data tips. * * @default TextFormat("_sans", 11, 0x000000, false, false, false, '', '', TextFormatAlign.LEFT, 0, 0, 0, 0) */ [Style(name="dataTipTextFormat", type="TextFormat")] /** * Name of the class to use as the skin for the background and border of the * chart's data tip. * * @default ChartDataTipBackground */ [Style(name="dataTipBackgroundSkin", type="Class")] /** * If the datatip's content padding is customizable, it will use this value. * The padding that separates the border of the component from its contents, * in pixels. * * @default 6 */ [Style(name="dataTipContentPadding", type="Number")] /** * Determines if data changes should be displayed with animation. * * @default true */ [Style(name="animationEnabled", type="Boolean")] /** * Indicates whether embedded font outlines are used to render the text * field. If this value is true, Flash Player renders the text field by * using embedded font outlines. If this value is false, Flash Player * renders the text field by using device fonts. * * If you set the embedFonts property to true for a text field, you must * specify a font for that text by using the font property of a TextFormat * object that is applied to the text field. If the specified font is not * embedded in the SWF file, the text is not displayed. * * @default false */ [Style(name="embedFonts", type="Boolean")] /** * Functionality common to most charts. Generally, aChart
object
* shouldn't be instantiated directly. Instead, a subclass with a concrete
* implementation should be used. That subclass generally should implement the
* IPlotArea
interface.
*
* @author Josh Tynjala
*/
public class Chart extends UIComponent
{
//--------------------------------------
// Class Variables
//--------------------------------------
/**
* @private
*/
private static var defaultStyles:Object =
{
seriesMarkerSizes: null,
seriesMarkerSkins: null,
seriesColors:
[
0x00b8bf, 0x8dd5e7, 0xedff9f, 0xffa928, 0xc0fff6, 0xd00050,
0xc6c6c6, 0xc3eafb, 0xfcffad, 0xcfff83, 0x444444, 0x4d95dd,
0xb8ebff, 0x60558f, 0x737d7e, 0xa64d9a, 0x8e9a9b, 0x803e77
],
seriesBorderColors:[],
seriesFillColors:[],
seriesLineColors:[],
seriesBorderAlphas:[1],
seriesFillAlphas:[1],
seriesLineAlphas:[1],
contentPadding: 10,
backgroundSkin: "ChartBackground",
backgroundColor: 0xffffff,
dataTipBackgroundSkin: "ChartDataTipBackground",
dataTipContentPadding: 6,
dataTipTextFormat: new TextFormat("_sans", 11, 0x000000, false, false, false, '', '', TextFormatAlign.LEFT, 0, 0, 0, 0),
animationEnabled: true,
embedFonts: false
};
/**
* @private
*/
private static const ALL_SERIES_STYLES:Object =
{
color: "seriesColors",
markerSize: "seriesMarkerSizes",
markerSkin: "seriesMarkerSkins",
borderColor: "seriesBorderColors",
fillColor: "seriesFillColors",
lineColor: "seriesLineColors",
borderAlpha: "seriesBorderAlphas",
fillAlpha: "seriesFillAlphas",
lineAlpha: "seriesLineAlphas"
};
/**
* @private
*/
private static const SHARED_SERIES_STYLES:Object =
{
animationEnabled: "animationEnabled"
};
private static const DATA_TIP_STYLES:Object =
{
backgroundSkin: "dataTipBackgroundSkin",
contentPadding: "dataTipContentPadding",
textFormat: "dataTipTextFormat",
embedFonts: "embedFonts"
};
//--------------------------------------
// Class Methods
//--------------------------------------
/**
* @private
* @copy fl.core.UIComponent#getStyleDefinition()
*/
public static function getStyleDefinition():Object
{
return mergeStyles(defaultStyles, UIComponent.getStyleDefinition());
}
//--------------------------------------
// Constructor
//--------------------------------------
/**
* Constructor.
*/
public function Chart()
{
super();
this.accessibilityProperties = new AccessibilityProperties();
this.accessibilityProperties.forceSimple = true;
this.accessibilityProperties.description = "Chart";
}
//--------------------------------------
// Variables and Properties
//--------------------------------------
/**
* @private
* The display object representing the chart background.
*/
protected var background:DisplayObject;
/**
* @private
* The area where series are drawn.
*/
protected var content:Sprite;
/**
* @private
* The mouse over data tip that displays information about an item on the chart.
*/
protected var dataTip:DisplayObject;
/**
* @private
* Storage for the data property. Saves a copy of the unmodified data.
*/
private var _dataProvider:Object;
/**
* @private
* Modified version of the stored data.
*/
protected var series:Array = [];
[Inspectable(type=Array)]
/**
* @copy com.yahoo.astra.fl.charts.IChart#dataProvider
*/
public function get dataProvider():Object
{
return this.series;
}
/**
* @private
*/
public function set dataProvider(value:Object):void
{
if(this._dataProvider != value)
{
this._dataProvider = value;
this.invalidate(InvalidationType.DATA);
}
}
/**
* @private
* Storage for the defaultSeriesType property.
*/
private var _defaultSeriesType:Class;
/**
* When raw data (like an Array of Numbers) is encountered where an
* ISeries instance is expected, it will be converted to this default
* type. Accepts either a Class instance or a String referencing a
* fully-qualified class name.
*/
public function get defaultSeriesType():Object
{
return this._defaultSeriesType;
}
/**
* @private
*/
public function set defaultSeriesType(value:Object):void
{
if(!value) return;
var classDefinition:Class = null;
if(value is Class)
{
classDefinition = value as Class;
}
else
{
// borrowed from fl.core.UIComponent#getDisplayObjectInstance()
try
{
classDefinition = getDefinitionByName(value.toString()) as Class;
}
catch(e:Error)
{
try
{
classDefinition = this.loaderInfo.applicationDomain.getDefinition(value.toString()) as Class;
}
catch (e:Error)
{
// Nothing
}
}
}
this._defaultSeriesType = classDefinition;
//no need to redraw.
//if the series have already been created, the user probably wanted it that way.
//we have no way to tell if the user chose a particular series' type or not anyway.
}
private var _lastDataTipRenderer:ISeriesItemRenderer;
/**
* @private
* Storage for the dataTipFunction property.
*/
private var _dataTipFunction:Function = defaultDataTipFunction;
/**
* If defined, the chart will call the input function to determine the
* text displayed in the chart's data tip. The function uses the following
* signature:
*
* function dataTipFunction(item:Object, index:int, series:ISeries):String