data tables are going to need some work yet, but the other stuff seems to be working 100%
1353 lines
40 KiB
ActionScript
1353 lines
40 KiB
ActionScript
package
|
|
{
|
|
import com.adobe.serialization.json.JSON;
|
|
import com.yahoo.astra.fl.charts.*;
|
|
import com.yahoo.astra.fl.charts.events.ChartEvent;
|
|
import com.yahoo.astra.fl.charts.legend.Legend;
|
|
import com.yahoo.astra.fl.charts.series.*;
|
|
import com.yahoo.astra.fl.charts.skins.*;
|
|
import com.yahoo.astra.fl.utils.UIComponentUtil;
|
|
import com.yahoo.astra.utils.InstanceFactory;
|
|
import com.yahoo.astra.utils.JavaScriptUtil;
|
|
import com.yahoo.yui.LoggerCategory;
|
|
import com.yahoo.yui.YUIAdapter;
|
|
import com.yahoo.yui.charts.*;
|
|
|
|
import fl.core.UIComponent;
|
|
|
|
import flash.display.DisplayObject;
|
|
import flash.display.Shape;
|
|
import flash.display.Sprite;
|
|
import flash.events.ErrorEvent;
|
|
import flash.events.MouseEvent;
|
|
import flash.external.ExternalInterface;
|
|
import flash.text.TextFormat;
|
|
import flash.utils.getDefinitionByName;
|
|
import flash.utils.getQualifiedClassName;
|
|
|
|
[SWF(backgroundColor=0xffffff)]
|
|
/**
|
|
* A wrapper for the Astra Charts components to allow them to be used by the YUI library.
|
|
*
|
|
* @author Josh Tynjala
|
|
*/
|
|
public class Charts extends YUIAdapter
|
|
{
|
|
|
|
//--------------------------------------
|
|
// Constructor
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function Charts()
|
|
{
|
|
super();
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Properties
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @private
|
|
* A reference to the chart instance.
|
|
*/
|
|
protected var chart:Chart;
|
|
|
|
/**
|
|
* @private
|
|
* The type of the chart specified by setType().
|
|
*/
|
|
protected var type:String;
|
|
|
|
/**
|
|
* @private
|
|
* A reference to the legend instance.
|
|
*/
|
|
protected var legend:Legend;
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the legendDisplay property.
|
|
*/
|
|
protected var _legendDisplay:String = "none";
|
|
|
|
/**
|
|
* @private
|
|
* Specifies the location of the legend, or "none" if the legend
|
|
* is not to be displayed.
|
|
*/
|
|
public function get legendDisplay():String
|
|
{
|
|
return this._legendDisplay;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set legendDisplay(value:String):void
|
|
{
|
|
this._legendDisplay = value;
|
|
this.refreshComponentSize();
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the spacing property.
|
|
*/
|
|
protected var _spacing:Number = 6;
|
|
|
|
/**
|
|
* @private
|
|
* The spacing between the chart and other objects, such as the legend.
|
|
*/
|
|
public function get spacing():Number
|
|
{
|
|
return this._spacing;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set spacing(value:Number):void
|
|
{
|
|
this._spacing = value;
|
|
this.refreshComponentSize();
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the padding property.
|
|
*/
|
|
protected var _padding:Number = 10;
|
|
|
|
/**
|
|
* @private
|
|
* The padding around the chart, in pixels.
|
|
*/
|
|
public function get padding():Number
|
|
{
|
|
return this._padding;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set padding(value:Number):void
|
|
{
|
|
this._padding = value;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected var backgroundAndBorder:BackgroundAndBorder;
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
override protected function get component():DisplayObject
|
|
{
|
|
//why do I have to do this? it's not ambiguous!
|
|
return super.component;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
override protected function set component(value:DisplayObject):void
|
|
{
|
|
this.chart = Chart(value);
|
|
super.component = value;
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Public Methods
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* Creates a chart instance based on the specified type.
|
|
*/
|
|
public function setType(value:String):void
|
|
{
|
|
if(this.chart)
|
|
{
|
|
this.removeChild(this.chart);
|
|
this.chart.removeEventListener(ChartEvent.ITEM_CLICK, chartItemEventHandler);
|
|
this.chart.removeEventListener(ChartEvent.ITEM_DOUBLE_CLICK, chartItemEventHandler);
|
|
this.chart.removeEventListener(ChartEvent.ITEM_ROLL_OUT, chartItemEventHandler);
|
|
this.chart.removeEventListener(ChartEvent.ITEM_ROLL_OVER, chartItemEventHandler);
|
|
this.chart.removeEventListener(MouseEvent.MOUSE_DOWN, chartItemExtraEventHandler);
|
|
}
|
|
|
|
this.type = value;
|
|
var ChartType:Class = ChartSerializer.getType(this.type);
|
|
var chart:Chart = new ChartType();
|
|
chart.setStyle("contentPadding", 0);
|
|
chart.setStyle("backgroundSkin", Sprite);
|
|
var backgroundFactory:InstanceFactory = this.createBorderBackgroundFactory();
|
|
backgroundFactory.properties.fillColor = 0xffffff;
|
|
backgroundFactory.properties.fillAlpha = 0.9;
|
|
backgroundFactory.properties.borderWeight = 1;
|
|
backgroundFactory.properties.borderColor = 0x000000;
|
|
chart.setStyle("dataTipBackgroundSkin", backgroundFactory);
|
|
chart.setStyle("seriesMarkerSkins", []);
|
|
this.addChildAt(chart, 1);
|
|
|
|
this.component = chart;
|
|
this.chart.addEventListener(ChartEvent.ITEM_CLICK, chartItemEventHandler, false, 0, true);
|
|
this.chart.addEventListener(ChartEvent.ITEM_DOUBLE_CLICK, chartItemEventHandler, false, 0, true);
|
|
this.chart.addEventListener(ChartEvent.ITEM_ROLL_OUT, chartItemEventHandler, false, 0, true);
|
|
this.chart.addEventListener(ChartEvent.ITEM_ROLL_OVER, chartItemEventHandler, false, 0, true);
|
|
this.chart.addEventListener(MouseEvent.MOUSE_DOWN, chartItemExtraEventHandler, false, 0, true);
|
|
|
|
this.chart.legend = this.legend;
|
|
|
|
this.log("Type set to \"" + this.type + "\"");
|
|
}
|
|
|
|
public function setDataProvider(value:Array):void
|
|
{
|
|
var dataProvider:Array = [];
|
|
var seriesCount:int = value.length;
|
|
var seriesStyles:Array = [];
|
|
for(var i:int = 0; i < seriesCount; i++)
|
|
{
|
|
var dataFromJavaScript:Object = value[i];
|
|
var currentData:ISeries = this.chart.dataProvider[i] as ISeries;
|
|
var seriesType:Class = SeriesSerializer.shortNameToSeriesType(dataFromJavaScript.type ? dataFromJavaScript.type : this.type);
|
|
|
|
var series:ISeries;
|
|
if(currentData && getDefinitionByName(getQualifiedClassName(currentData)) == seriesType)
|
|
{
|
|
//reuse the series if possible because we want animation
|
|
series = SeriesSerializer.readSeries(dataFromJavaScript, currentData);
|
|
}
|
|
else
|
|
{
|
|
series = SeriesSerializer.readSeries(dataFromJavaScript);
|
|
}
|
|
dataProvider[i] = series;
|
|
|
|
//this is where we parse the individual series styles, and we convert them
|
|
//to the format the chart actually expects.
|
|
//we fill in with defaults for styles that have not been specified
|
|
if(dataFromJavaScript.style)
|
|
{
|
|
seriesStyles.push(dataFromJavaScript.style);
|
|
}
|
|
else seriesStyles.push(null);
|
|
}
|
|
|
|
this.log("Displaying " + seriesCount + " series.");
|
|
|
|
//set data provider and new styles
|
|
this.chart.dataProvider = dataProvider;
|
|
|
|
//make sures the series are created!
|
|
this.chart.drawNow();
|
|
|
|
//set the styles for the series
|
|
this.setSeriesStyles(seriesStyles);
|
|
|
|
this.refreshComponentSize();
|
|
}
|
|
|
|
/**
|
|
* Returns the category names.
|
|
*/
|
|
public function getCategoryNames():Array
|
|
{
|
|
var categoryChart:ICategoryChart = this.chart as ICategoryChart;
|
|
if(categoryChart)
|
|
{
|
|
return categoryChart.categoryNames;
|
|
}
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Cannot find categoryNames on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the category names used if the data requires a category axis.
|
|
* This field should be used if the data does not define the category
|
|
* values directly.
|
|
*/
|
|
public function setCategoryNames(value:Array):void
|
|
{
|
|
var categoryChart:ICategoryChart = this.chart as ICategoryChart;
|
|
if(categoryChart)
|
|
{
|
|
categoryChart.categoryNames = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set categoryNames on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the field used in complex objects to access data to be
|
|
* displayed on the PieChart.
|
|
*/
|
|
public function getDataField():String
|
|
{
|
|
var pieChart:PieChart = this.chart as PieChart;
|
|
if(pieChart)
|
|
{
|
|
return pieChart.dataField;
|
|
}
|
|
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to find dataField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the field used in complex objects to access data to be displayed
|
|
* on the PieChart.
|
|
*/
|
|
public function setDataField(value:String):void
|
|
{
|
|
var pieChart:PieChart = this.chart as PieChart;
|
|
if(pieChart)
|
|
{
|
|
pieChart.dataField = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set dataField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the field used in complex objects to access categories to be
|
|
* displayed on the PieChart.
|
|
*/
|
|
public function getCategoryField():String
|
|
{
|
|
var pieChart:PieChart = this.chart as PieChart;
|
|
if(pieChart)
|
|
{
|
|
return pieChart.categoryField;
|
|
}
|
|
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to find categoryField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the field used in complex objects to access categories to be displayed
|
|
* on the PieChart.
|
|
*/
|
|
public function setCategoryField(value:String):void
|
|
{
|
|
var pieChart:PieChart = this.chart as PieChart;
|
|
if(pieChart)
|
|
{
|
|
pieChart.categoryField = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set categoryField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the field used in complex objects to access data to be
|
|
* displayed on the horizontal axis.
|
|
*/
|
|
public function getHorizontalField():String
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
return cartesianChart.horizontalField;
|
|
}
|
|
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to find horizontalField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the field used in complex objects to access data to be displayed
|
|
* on the horizontal axis. If the input data is XML, and the field is an
|
|
* attribute, be sure to include the "@" symbol at the beginning of the
|
|
* field name.
|
|
*/
|
|
public function setHorizontalField(value:String):void
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
cartesianChart.horizontalField = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set horizontalField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the field used in complex objects to access data to be
|
|
* displayed on the vertical axis.
|
|
*/
|
|
public function getVerticalField():String
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
return cartesianChart.verticalField;
|
|
}
|
|
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to find verticalField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the field used in complex objects to access data to be displayed
|
|
* on the vertical axis. If the input data is XML, and the field is an
|
|
* attribute, be sure to include the "@" symbol at the beginning of the
|
|
* field name.
|
|
*/
|
|
public function setVerticalField(value:String):void
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
cartesianChart.verticalField = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set verticalField on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the title displayed next to the vertical axis.
|
|
*/
|
|
public function getHorizontalAxisTitle():String
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
return cartesianChart.horizontalAxisTitle;
|
|
}
|
|
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to find horizontalAxisTitle on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the title displayed next to the horizontal axis.
|
|
*/
|
|
public function setHorizontalAxisTitle(value:String):void
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
cartesianChart.horizontalAxisTitle = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set horizontalAxisTitle on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the title displayed next to the vertical axis.
|
|
*/
|
|
public function getVerticalAxisTitle():String
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
return cartesianChart.verticalAxisTitle;
|
|
}
|
|
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to find verticalAxisTitle on a chart of type " + shortName, LoggerCategory.WARN);
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* Sets the title displayed next to the vertical axis.
|
|
*/
|
|
public function setVerticalAxisTitle(value:String):void
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
cartesianChart.verticalAxisTitle = value;
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set verticalAxisTitle on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the horizontal axis with a new type.
|
|
*/
|
|
public function setHorizontalAxis(value:Object):void
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
cartesianChart.horizontalAxis = AxisSerializer.readAxis(value);
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set horizontalAxis on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Updates the vertical axis with a new type.
|
|
*/
|
|
public function setVerticalAxis(value:Object):void
|
|
{
|
|
var cartesianChart:CartesianChart = this.chart as CartesianChart;
|
|
if(cartesianChart)
|
|
{
|
|
cartesianChart.verticalAxis = AxisSerializer.readAxis(value);
|
|
}
|
|
else
|
|
{
|
|
var shortName:String = ChartSerializer.getShortName(getQualifiedClassName(this.chart));
|
|
this.log("Unable to set verticalAxis on a chart of type " + shortName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Sets the JavaScript function to call to generate the chart's data tip.
|
|
*/
|
|
public function setDataTipFunction(value:String):void
|
|
{
|
|
var delegate:Object = {dataTipFunction: JavaScriptUtil.createCallbackFunction(value).callback};
|
|
delegate.callback = function(item:Object, index:int, series:ISeries):String
|
|
{
|
|
return delegate.dataTipFunction(item, index, SeriesSerializer.writeSeries(series));
|
|
}
|
|
|
|
this.chart.dataTipFunction = delegate.callback;
|
|
}
|
|
|
|
/**
|
|
* Accepts a JSON-encoded set of styles for the chart itself.
|
|
* Flash Player versions below 9.0.60 don't encode ExternalInterface
|
|
* calls correctly!
|
|
*/
|
|
public function setStyles(styles:String):void
|
|
{
|
|
if(!styles) return;
|
|
var parsedStyles:Object = JSON.decode(styles);
|
|
for(var styleName:String in parsedStyles)
|
|
{
|
|
this.setStyle(styleName, parsedStyles[styleName], false);
|
|
}
|
|
}
|
|
|
|
public function setStyle(name:String, value:Object, json:Boolean = true):void
|
|
{
|
|
if(json && value)
|
|
{
|
|
//by default, we assume it's json data, only setStyles will send false
|
|
value = JSON.decode(value as String);
|
|
}
|
|
|
|
var needsSizingRefresh:Boolean = false;
|
|
|
|
switch(name)
|
|
{
|
|
case "padding":
|
|
this.padding = value as Number;
|
|
needsSizingRefresh = true;
|
|
break;
|
|
case "spacing":
|
|
this.spacing = value as Number;
|
|
needsSizingRefresh = true;
|
|
break;
|
|
case "animationEnabled":
|
|
this.chart.setStyle("animationEnabled", value);
|
|
break;
|
|
case "border":
|
|
if(value.color != null)
|
|
{
|
|
this.backgroundAndBorder.borderColor = this.parseColor(value.color);
|
|
}
|
|
|
|
if(value.size != null)
|
|
{
|
|
this.backgroundAndBorder.borderWeight = value.size;
|
|
needsSizingRefresh = true;
|
|
}
|
|
break;
|
|
case "background":
|
|
if(value.color != null)
|
|
{
|
|
this.backgroundAndBorder.fillColor = this.parseColor(value.color);
|
|
}
|
|
|
|
if(value.image)
|
|
{
|
|
this.backgroundAndBorder.image = value.image;
|
|
}
|
|
|
|
if(value.alpha != null)
|
|
{
|
|
this.backgroundAndBorder.fillAlpha = value.alpha;
|
|
}
|
|
if(value.mode)
|
|
{
|
|
this.backgroundAndBorder.imageMode = value.mode;
|
|
}
|
|
break;
|
|
case "font":
|
|
var textFormat:TextFormat = TextFormatSerializer.readTextFormat(value);
|
|
this.chart.setStyle("textFormat", textFormat);
|
|
break;
|
|
case "dataTip":
|
|
this.setDataTipStyles(value);
|
|
break;
|
|
case "xAxis":
|
|
this.setAxisStyles(value, "horizontal");
|
|
break;
|
|
case "yAxis":
|
|
this.setAxisStyles(value, "vertical");
|
|
break;
|
|
case "legend":
|
|
this.setLegendStyles(value);
|
|
break;
|
|
default:
|
|
this.log("Unknown style: " + name, LoggerCategory.WARN);
|
|
}
|
|
|
|
if(needsSizingRefresh)
|
|
{
|
|
this.refreshComponentSize();
|
|
}
|
|
}
|
|
|
|
public function setSeriesStyles(styles:Array):void
|
|
{
|
|
var defaultSeriesColors:Array =
|
|
[0x00b8bf, 0x8dd5e7, 0xedff9f, 0xffa928, 0xc0fff6, 0xd00050,
|
|
0xc6c6c6, 0xc3eafb, 0xfcffad, 0xcfff83, 0x444444, 0x4d95dd,
|
|
0xb8ebff, 0x60558f, 0x737d7e, 0xa64d9a, 0x8e9a9b, 0x803e77];
|
|
|
|
//will be filled based on the defaults or the series style definition, if present.
|
|
var seriesColors:Array = [];
|
|
var seriesCount:int = Math.min(this.chart.dataProvider.length, styles.length);
|
|
for(var i:int = 0; i < seriesCount; i++)
|
|
{
|
|
var series:ISeries = ISeries(this.chart.dataProvider[i]);
|
|
var style:Object = styles[i];
|
|
if(style)
|
|
{
|
|
style = JSON.decode(style as String);
|
|
}
|
|
|
|
//defaults
|
|
var defaultColors:Array = defaultSeriesColors.concat();
|
|
if(series is PieSeries)
|
|
{
|
|
defaultColors = [defaultColors];
|
|
}
|
|
|
|
var defaultSize:Number = 10;
|
|
if(series is ColumnSeries || series is BarSeries)
|
|
{
|
|
defaultSize = 20;
|
|
}
|
|
|
|
var defaultSkin:Object = RectangleSkin;
|
|
if(series is LineSeries)
|
|
{
|
|
defaultSkin = CircleSkin;
|
|
}
|
|
else if(series is PieSeries)
|
|
{
|
|
defaultSkin = [defaultSkin];
|
|
}
|
|
|
|
//initialize styles with defaults
|
|
var color:Object = defaultColors[i % defaultColors.length];
|
|
var skin:Object = defaultSkin;
|
|
var mode:Object = "repeat";
|
|
if(style)
|
|
{
|
|
for(var styleName:String in style)
|
|
{
|
|
switch(styleName)
|
|
{
|
|
case "images":
|
|
if(!(series is PieSeries))
|
|
{
|
|
this.log(styleName + " style is only supported by series of type 'pie'.", LoggerCategory.WARN);
|
|
break;
|
|
}
|
|
var images:Array = style.images as Array;
|
|
var imageCount:int = images.length;
|
|
for(var j:int = 0; j < imageCount; j++)
|
|
{
|
|
images[j] = this.createMarkerSkin(String(images[j]), series);
|
|
}
|
|
skin = images;
|
|
break;
|
|
case "image":
|
|
skin = this.createMarkerSkin(style.image, series);
|
|
if(!(series is LineSeries))
|
|
{
|
|
skin.properties.fillColor = color;
|
|
skin.properties.fillAlpha = 1;
|
|
}
|
|
break;
|
|
case "mode":
|
|
mode = style.mode;
|
|
break;
|
|
case "colors":
|
|
if(!(series is PieSeries))
|
|
{
|
|
this.log(styleName + " style is only supported by series of type 'pie'.", LoggerCategory.WARN);
|
|
break;
|
|
}
|
|
var colors:Array = style.colors;
|
|
var colorCount:int = colors.length;
|
|
for(j = 0; j < colorCount; j++)
|
|
{
|
|
colors[j] = this.parseColor(colors[j]);
|
|
}
|
|
color = colors;
|
|
break;
|
|
case "color":
|
|
color = this.parseColor(style.color);
|
|
if(skin is InstanceFactory && !(series is LineSeries))
|
|
{
|
|
skin.properties.fillColor = color;
|
|
skin.properties.fillAlpha = 1;
|
|
}
|
|
break;
|
|
case "size":
|
|
UIComponent(series).setStyle("markerSize", style.size);
|
|
break;
|
|
case "alpha":
|
|
UIComponent(series).setStyle("markerAlpha", style.alpha);
|
|
break;
|
|
case "showAreaFill": //LineSeries only
|
|
if(!(series is LineSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'line'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("showAreaFill", style.showAreaFill);
|
|
break;
|
|
case "areaFillAlpha": //LineSeries only
|
|
if(!(series is LineSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'line'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("areaFillAlpha", style.areaFillAlpha);
|
|
break;
|
|
case "lineSize": //LineSeries only
|
|
if(!(series is LineSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'line'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("lineWeight", style.lineSize);
|
|
break;
|
|
case "connectPoints": //LineSeries only
|
|
if(!(series is LineSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'line'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("connectPoints", style.connectPoints);
|
|
break;
|
|
case "connectDiscontinuousPoints": //LineSeries only
|
|
if(!(series is LineSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'line'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("connectDiscontinuousPoints", style.connectDiscontinuousPoints);
|
|
break;
|
|
case "discontinuousDashLength": //LineSeries only
|
|
if(!(series is LineSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'line'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("discontinuousDashLength", style.discontinuousDashLength);
|
|
break;
|
|
case "showLabels": //PieSeries only
|
|
if(!(series is PieSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'pie'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("showLabels", style.showLabels);
|
|
break;
|
|
case "hideOverlappingLabels": //PieSeries only
|
|
if(!(series is PieSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'pie'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("hideOverlappingLabels", style.showLabels);
|
|
break;
|
|
case "font": //PieSeries only
|
|
if(!(series is PieSeries))
|
|
{
|
|
this.log("The style " + styleName + " is only supported by series of type 'pie'.", LoggerCategory.WARN);
|
|
}
|
|
UIComponent(series).setStyle("textFormat", TextFormatSerializer.readTextFormat(style.font))
|
|
break;
|
|
default:
|
|
this.log("Unknown series style: " + styleName, LoggerCategory.WARN);
|
|
}
|
|
}
|
|
}
|
|
if(mode)
|
|
{
|
|
if(skin is InstanceFactory)
|
|
{
|
|
skin.properties.imageMode = mode;
|
|
}
|
|
else if(skin is Array)
|
|
{
|
|
var skinCount:int = (skin as Array).length;
|
|
for(j = 0; j < skinCount; j++)
|
|
{
|
|
var subSkin:InstanceFactory = skin[j] as InstanceFactory;
|
|
if(subSkin)
|
|
{
|
|
subSkin.properties.imageMode = mode;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if(series is PieSeries)
|
|
{
|
|
PieSeries(series).setStyle("markerSkins", skin);
|
|
}
|
|
else UIComponent(series).setStyle("markerSkin", skin);
|
|
|
|
seriesColors[i] = color;
|
|
}
|
|
this.chart.setStyle("seriesColors", seriesColors);
|
|
|
|
this.chart.drawNow();
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Protected Methods
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @private (protected)
|
|
* Initialize the functions that may be called by JavaScript through ExternalInterface.
|
|
*/
|
|
override protected function initializeComponent():void
|
|
{
|
|
super.initializeComponent();
|
|
|
|
try
|
|
{
|
|
ExternalInterface.addCallback("setType", setType);
|
|
ExternalInterface.addCallback("setStyle", setStyle);
|
|
ExternalInterface.addCallback("setStyles", setStyles);
|
|
ExternalInterface.addCallback("setSeriesStyles", setSeriesStyles);
|
|
ExternalInterface.addCallback("setDataProvider", setDataProvider);
|
|
ExternalInterface.addCallback("getCategoryNames", getCategoryNames);
|
|
ExternalInterface.addCallback("setCategoryNames", setCategoryNames);
|
|
ExternalInterface.addCallback("setDataTipFunction", setDataTipFunction);
|
|
ExternalInterface.addCallback("getCategoryNames", getCategoryNames);
|
|
ExternalInterface.addCallback("setCategoryNames", setCategoryNames);
|
|
|
|
//CartesianChart
|
|
ExternalInterface.addCallback("getHorizontalField", getHorizontalField);
|
|
ExternalInterface.addCallback("setHorizontalField", setHorizontalField);
|
|
ExternalInterface.addCallback("getVerticalField", getVerticalField);
|
|
ExternalInterface.addCallback("setVerticalField", setVerticalField);
|
|
ExternalInterface.addCallback("setHorizontalAxis", setHorizontalAxis);
|
|
ExternalInterface.addCallback("setVerticalAxis", setVerticalAxis);
|
|
|
|
//PieChart
|
|
ExternalInterface.addCallback("getDataField", getDataField);
|
|
ExternalInterface.addCallback("setDataField", setDataField);
|
|
ExternalInterface.addCallback("getCategoryField", getCategoryField);
|
|
ExternalInterface.addCallback("setCategoryField", setCategoryField);
|
|
}
|
|
catch(error:SecurityError)
|
|
{
|
|
//do nothing. it will be caught by the YUIAdapter.
|
|
}
|
|
|
|
this.backgroundAndBorder = new BackgroundAndBorder();
|
|
this.backgroundAndBorder.width = this.stage.stageWidth;
|
|
this.backgroundAndBorder.height = this.stage.stageHeight;
|
|
this.backgroundAndBorder.addEventListener(ErrorEvent.ERROR, backgroundErrorHandler);
|
|
this.addChild(this.backgroundAndBorder);
|
|
|
|
this.legend = new Legend();
|
|
this.legend.setStyle("backgroundSkin", Shape);
|
|
this.addChild(this.legend);
|
|
}
|
|
|
|
/**
|
|
* @private (protected)
|
|
* Since Chart is a Flash CS3 component, we should call drawNow() to be sure it updates properly.
|
|
*/
|
|
override protected function refreshComponentSize():void
|
|
{
|
|
super.refreshComponentSize();
|
|
|
|
if(this.backgroundAndBorder)
|
|
{
|
|
this.backgroundAndBorder.width = this.stage.stageWidth;
|
|
this.backgroundAndBorder.height = this.stage.stageHeight;
|
|
this.backgroundAndBorder.drawNow();
|
|
}
|
|
|
|
if(this.chart)
|
|
{
|
|
this.chart.x = this.chart.y = this.backgroundAndBorder.borderWeight + this.padding;
|
|
this.chart.width -= 2 * (this.backgroundAndBorder.borderWeight + this.padding);
|
|
this.chart.height -= 2 * (this.backgroundAndBorder.borderWeight + this.padding);
|
|
if(this.legend && this.legendDisplay != "none")
|
|
{
|
|
this.legend.visible = true;
|
|
//we need to draw because the legend resizes itself
|
|
this.legend.drawNow();
|
|
|
|
if(this.legendDisplay == "left" || this.legendDisplay == "right")
|
|
{
|
|
if(this.legendDisplay == "left")
|
|
{
|
|
this.legend.x = this.backgroundAndBorder.borderWeight + this.padding;
|
|
this.chart.x = this.legend.x + this.legend.width + this.spacing;
|
|
}
|
|
else //right
|
|
{
|
|
this.legend.x = this.stage.stageWidth - this.backgroundAndBorder.borderWeight - this.legend.width - padding;
|
|
}
|
|
//center vertically
|
|
this.legend.y = Math.max(0, (this.stage.stageHeight - this.legend.height) / 2);
|
|
this.chart.width -= (this.legend.width + this.spacing);
|
|
}
|
|
else //top or bottom
|
|
{
|
|
if(this.legendDisplay == "top")
|
|
{
|
|
this.legend.y = this.backgroundAndBorder.borderWeight + this.padding;
|
|
this.chart.y = this.legend.y + this.legend.height + this.spacing;
|
|
}
|
|
else //bottom
|
|
{
|
|
this.legend.y = this.stage.stageHeight - this.backgroundAndBorder.borderWeight - this.legend.height - padding;
|
|
}
|
|
//center horizontally
|
|
this.legend.x = Math.max(0, (this.stage.stageWidth - this.legend.width) / 2);
|
|
this.chart.height -= (this.legend.height + this.spacing);
|
|
}
|
|
|
|
//we disable animation temporarily because we don't want the markers
|
|
//sliding around because the legend resized
|
|
if(this.legend && this.legendDisplay != "none")
|
|
{
|
|
var oldAnimationEnabled:Boolean = UIComponentUtil.getStyleValue(this.chart, "animationEnabled");
|
|
this.chart.setStyle("animationEnabled", false);
|
|
this.chart.drawNow();
|
|
this.chart.setStyle("animationEnabled", oldAnimationEnabled);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
this.legend.visible = false;
|
|
}
|
|
this.chart.drawNow();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private (protected)
|
|
* Logs errors for the background image loading.
|
|
*/
|
|
protected function backgroundErrorHandler(event:ErrorEvent):void
|
|
{
|
|
this.log(event.text, LoggerCategory.ERROR);
|
|
}
|
|
|
|
/**
|
|
* @private (protected)
|
|
*
|
|
* Receives chart item mouse events and passes them out to JavaScript.
|
|
*/
|
|
protected function chartItemEventHandler(event:ChartEvent):void
|
|
{
|
|
var type:String = event.type.replace("Roll", "Mouse");
|
|
type += "Event";
|
|
var seriesIndex:int = (this.chart.dataProvider as Array).indexOf(event.series);
|
|
var itemEvent:Object = {type: type, seriesIndex: seriesIndex, index: event.index, item: event.item, x: this.mouseX, y: this.mouseY};
|
|
this.dispatchEventToJavaScript(itemEvent);
|
|
}
|
|
|
|
private var _lastMouseItem:ISeriesItemRenderer;
|
|
|
|
protected function chartItemExtraEventHandler(event:MouseEvent):void
|
|
{
|
|
var dragEventType:String = "itemDragEvent";
|
|
var renderer:ISeriesItemRenderer = this._lastMouseItem;
|
|
this._lastMouseItem = null;
|
|
if(event.type == MouseEvent.MOUSE_DOWN)
|
|
{
|
|
//crawl up until we get to the chart or an item renderer
|
|
var displayObject:DisplayObject = event.target as DisplayObject;
|
|
while(!(displayObject is ISeriesItemRenderer) && !(displayObject is Chart))
|
|
{
|
|
displayObject = displayObject.parent;
|
|
}
|
|
|
|
if(displayObject is ISeriesItemRenderer)
|
|
{
|
|
renderer = ISeriesItemRenderer(displayObject);
|
|
|
|
this.stage.addEventListener(MouseEvent.MOUSE_MOVE, chartItemExtraEventHandler);
|
|
this.stage.addEventListener(MouseEvent.MOUSE_UP, chartItemExtraEventHandler);
|
|
}
|
|
else
|
|
{
|
|
renderer = null;
|
|
}
|
|
dragEventType = "itemDragStartEvent";
|
|
}
|
|
else if(event.type == MouseEvent.MOUSE_UP)
|
|
{
|
|
dragEventType = "itemDragEndEvent";
|
|
this.stage.removeEventListener(MouseEvent.MOUSE_MOVE, chartItemExtraEventHandler);
|
|
this.stage.removeEventListener(MouseEvent.MOUSE_UP, chartItemExtraEventHandler);
|
|
}
|
|
|
|
//if we've found an item renderer, dispatch the event
|
|
if(renderer is ISeriesItemRenderer)
|
|
{
|
|
var seriesIndex:int = (this.chart.dataProvider as Array).indexOf(renderer.series);
|
|
var itemIndex:int = renderer.series.dataProvider.indexOf(renderer.data)
|
|
var itemEvent:Object = {type: dragEventType, seriesIndex: seriesIndex, index: itemIndex, item: renderer.data, x: this.mouseX, y: this.mouseY};
|
|
this.dispatchEventToJavaScript(itemEvent);
|
|
this._lastMouseItem = renderer;
|
|
}
|
|
}
|
|
|
|
protected function setDataTipStyles(styles:Object):void
|
|
{
|
|
var contentPadding:Number = 6;
|
|
if(styles.padding >= 0)
|
|
{
|
|
contentPadding = styles.padding;
|
|
}
|
|
|
|
if(styles.border || styles.background)
|
|
{
|
|
//defaults
|
|
var backgroundFactory:InstanceFactory = this.createBorderBackgroundFactory();
|
|
backgroundFactory.properties.fillColor = 0xffffff;
|
|
backgroundFactory.properties.fillAlpha = 0.9;
|
|
backgroundFactory.properties.borderWeight = 1;
|
|
backgroundFactory.properties.borderColor = 0x000000;
|
|
var border:Object = styles.border;
|
|
if(border)
|
|
{
|
|
if(border.color != null)
|
|
{
|
|
backgroundFactory.properties.borderColor = this.parseColor(border.color)
|
|
}
|
|
if(border.size != null)
|
|
{
|
|
backgroundFactory.properties.borderWeight = border.size;
|
|
contentPadding += border.size;
|
|
}
|
|
}
|
|
var background:Object = styles.background;
|
|
if(background)
|
|
{
|
|
if(background.color != null)
|
|
{
|
|
backgroundFactory.properties.fillColor = this.parseColor(background.color);
|
|
}
|
|
if(background.image)
|
|
{
|
|
backgroundFactory.properties.image = background.image;
|
|
}
|
|
if(background.alpha != null)
|
|
{
|
|
backgroundFactory.properties.fillAlpha = background.alpha;
|
|
}
|
|
if(background.mode)
|
|
{
|
|
backgroundFactory.properties.imageMode = background.mode;
|
|
}
|
|
}
|
|
this.chart.setStyle("dataTipBackgroundSkin", backgroundFactory);
|
|
}
|
|
|
|
this.chart.setStyle("dataTipContentPadding", contentPadding);
|
|
|
|
if(styles.font)
|
|
{
|
|
var textFormat:TextFormat = TextFormatSerializer.readTextFormat(styles.font);
|
|
this.chart.setStyle("dataTipTextFormat", textFormat);
|
|
}
|
|
}
|
|
|
|
protected function setAxisStyles(styles:Object, axisName:String):void
|
|
{
|
|
if(styles.color != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisColor", this.parseColor(styles.color));
|
|
}
|
|
|
|
if(styles.size != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisWeight", styles.size);
|
|
}
|
|
|
|
if(styles.showLabels != null)
|
|
{
|
|
this.chart.setStyle("show" + axisName.substr(0, 1).toUpperCase() + axisName.substr(1) + "AxisLabels", styles.showLabels);
|
|
}
|
|
|
|
if(styles.hideOverlappingLabels != null)
|
|
{
|
|
this.chart.setStyle(axisName.substr(0, 1).toUpperCase() + axisName.substr(1) + "AxisHideOverlappingLabels", styles.hideOverlappingLabels);
|
|
}
|
|
|
|
if(styles.majorGridLines)
|
|
{
|
|
var majorGridLines:Object = styles.majorGridLines;
|
|
if(majorGridLines.color != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisGridLineColor", this.parseColor(majorGridLines.color));
|
|
}
|
|
if(majorGridLines.size != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisGridLineWeight", majorGridLines.size);
|
|
this.chart.setStyle("show" + axisName.substr(0, 1).toUpperCase() + axisName.substr(1) + "AxisGridLines", majorGridLines.size > 0);
|
|
}
|
|
}
|
|
|
|
if(styles.minorGridLines)
|
|
{
|
|
var minorGridLines:Object = styles.minorGridLines;
|
|
if(minorGridLines.color != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisMinorGridLineColor", this.parseColor(minorGridLines.color));
|
|
}
|
|
if(minorGridLines.size != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisMinorGridLineWeight", minorGridLines.size);
|
|
this.chart.setStyle("show" + axisName.substr(0, 1).toUpperCase() + axisName.substr(1) + "AxisMinorGridLines", minorGridLines.size > 0);
|
|
}
|
|
}
|
|
|
|
if(styles.majorTicks)
|
|
{
|
|
var majorTicks:Object = styles.majorTicks;
|
|
if(majorTicks.color != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisTickColor", this.parseColor(majorTicks.color));
|
|
}
|
|
if(majorTicks.size != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisTickWeight", majorTicks.size);
|
|
}
|
|
if(majorTicks.length != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisTickLength", majorTicks.length);
|
|
}
|
|
if(majorTicks.display)
|
|
{
|
|
this.chart.setStyle("show" + axisName.substr(0, 1).toUpperCase() + axisName.substr(1) + "AxisTicks", majorTicks.display != "none");
|
|
if(majorTicks.display != "none")
|
|
{
|
|
this.chart.setStyle(axisName + "AxisTickPosition", majorTicks.display);
|
|
}
|
|
}
|
|
}
|
|
|
|
if(styles.minorTicks)
|
|
{
|
|
var minorTicks:Object = styles.minorTicks;
|
|
if(minorTicks.color != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisMinorTickColor", this.parseColor(minorTicks.color));
|
|
}
|
|
if(minorTicks.size != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisMinorTickWeight", minorTicks.size);
|
|
}
|
|
if(minorTicks.length != null)
|
|
{
|
|
this.chart.setStyle(axisName + "AxisMinorTickLength", minorTicks.length);
|
|
}
|
|
if(minorTicks.display)
|
|
{
|
|
this.chart.setStyle("show" + axisName.substr(0, 1).toUpperCase() + axisName.substr(1) + "AxisMinorTicks", minorTicks.display != "none");
|
|
if(minorTicks.display != "none")
|
|
{
|
|
this.chart.setStyle(axisName + "AxisMinorTickPosition", minorTicks.display);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
protected function setLegendStyles(styles:Object):void
|
|
{
|
|
if(styles.font)
|
|
{
|
|
var textFormat:TextFormat = TextFormatSerializer.readTextFormat(styles.font);
|
|
this.legend.setStyle("textFormat", textFormat);
|
|
}
|
|
|
|
if(styles.spacing != null)
|
|
{
|
|
this.legend.setStyle("gap", styles.spacing);
|
|
}
|
|
|
|
if(styles.display)
|
|
{
|
|
switch(styles.display)
|
|
{
|
|
case "left":
|
|
case "right":
|
|
this.legend.setStyle("direction", "vertical");
|
|
break;
|
|
default: //top, bottom
|
|
this.legend.setStyle("direction", "horizontal");
|
|
}
|
|
this.legendDisplay = styles.display;
|
|
}
|
|
|
|
var contentPadding:Number = 6;
|
|
if(styles.padding != null)
|
|
{
|
|
contentPadding = styles.padding;
|
|
}
|
|
|
|
if(styles.border || styles.background)
|
|
{
|
|
var backgroundFactory:InstanceFactory = this.createBorderBackgroundFactory();
|
|
var border:Object = styles.border;
|
|
if(border)
|
|
{
|
|
if(border.color != null)
|
|
{
|
|
backgroundFactory.properties.borderColor = this.parseColor(border.color)
|
|
}
|
|
if(border.size != null)
|
|
{
|
|
backgroundFactory.properties.borderWeight = border.size;
|
|
contentPadding += border.size;
|
|
}
|
|
}
|
|
var background:Object = styles.background;
|
|
if(background)
|
|
{
|
|
if(background.color != null)
|
|
{
|
|
backgroundFactory.properties.fillColor = this.parseColor(background.color);
|
|
}
|
|
if(background.image)
|
|
{
|
|
backgroundFactory.properties.image = background.image;
|
|
}
|
|
if(background.alpha != null)
|
|
{
|
|
backgroundFactory.properties.fillAlpha = background.alpha;
|
|
}
|
|
if(background.mode)
|
|
{
|
|
backgroundFactory.properties.imageMode = background.mode;
|
|
}
|
|
}
|
|
this.legend.setStyle("backgroundSkin", backgroundFactory);
|
|
}
|
|
|
|
this.legend.setStyle("contentPadding", contentPadding);
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Private Methods
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @private
|
|
* Creates a pseudo-class to instantiate a BackgroundAndBorder object.
|
|
*/
|
|
private function createBorderBackgroundFactory():InstanceFactory
|
|
{
|
|
var factory:InstanceFactory = new InstanceFactory(BackgroundAndBorder);
|
|
factory.properties =
|
|
{
|
|
fillColor: 0xffffff,
|
|
fillAlpha: 1,
|
|
borderColor: 0x000000,
|
|
borderWeight: 0,
|
|
image: null,
|
|
imageMode: BackgroundImageMode.REPEAT
|
|
};
|
|
factory.methods =
|
|
{
|
|
addEventListener: [ErrorEvent.ERROR, backgroundLoadErrorHandler, false, 0, true]
|
|
};
|
|
return factory;
|
|
}
|
|
|
|
private function backgroundLoadErrorHandler(event:ErrorEvent):void
|
|
{
|
|
this.log(event.text, LoggerCategory.ERROR);
|
|
}
|
|
|
|
private function createMarkerSkin(imagePath:String, series:ISeries):InstanceFactory
|
|
{
|
|
//a simple UILoader would be enough, but we want tiling
|
|
var skin:InstanceFactory = this.createBorderBackgroundFactory();
|
|
//turn off the border
|
|
skin.properties.borderWeight = 0;
|
|
//turn off the fill
|
|
skin.properties.fillAlpha = 0;
|
|
skin.properties.image = imagePath;
|
|
skin.properties.imageMode = BackgroundImageMode.REPEAT;
|
|
if(series is LineSeries)
|
|
{
|
|
//make points fit to size and maintain their aspect ratio
|
|
skin.properties.imageMode = BackgroundImageMode.STRETCH_AND_MAINTAIN_ASPECT_RATIO;
|
|
}
|
|
return skin;
|
|
}
|
|
|
|
private function parseColor(value:Object):uint
|
|
{
|
|
if(!(value is Number))
|
|
{
|
|
var valueAsString:String = value.toString().replace("#", "");
|
|
if(valueAsString.indexOf("0x") != 0)
|
|
{
|
|
valueAsString = "0x" + valueAsString;
|
|
}
|
|
return parseInt(String(valueAsString), 16);
|
|
}
|
|
return uint(value);
|
|
}
|
|
}
|
|
}
|