2198 lines
66 KiB
ActionScript
Executable File
2198 lines
66 KiB
ActionScript
Executable File
/*
|
|
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.axes.AxisOrientation;
|
|
import com.yahoo.astra.fl.charts.axes.CategoryAxis;
|
|
import com.yahoo.astra.fl.charts.axes.DefaultAxisRenderer;
|
|
import com.yahoo.astra.fl.charts.axes.DefaultGridLinesRenderer;
|
|
import com.yahoo.astra.fl.charts.axes.IAxis;
|
|
import com.yahoo.astra.fl.charts.axes.ICartesianAxisRenderer;
|
|
import com.yahoo.astra.fl.charts.axes.IGridLinesRenderer;
|
|
import com.yahoo.astra.fl.charts.axes.IStackingAxis;
|
|
import com.yahoo.astra.fl.charts.axes.NumericAxis;
|
|
import com.yahoo.astra.fl.charts.axes.TimeAxis;
|
|
import com.yahoo.astra.fl.charts.series.CartesianSeries;
|
|
import com.yahoo.astra.fl.charts.series.ISeries;
|
|
import com.yahoo.astra.fl.charts.series.IStackedSeries;
|
|
import com.yahoo.astra.fl.utils.UIComponentUtil;
|
|
import com.yahoo.astra.utils.AxisLabelUtil;
|
|
import com.yahoo.astra.display.BitmapText;
|
|
|
|
import fl.core.InvalidationType;
|
|
import fl.core.UIComponent;
|
|
|
|
import flash.display.DisplayObject;
|
|
import flash.display.Sprite;
|
|
import flash.geom.Point;
|
|
import flash.geom.Rectangle;
|
|
import flash.text.TextFormat;
|
|
import flash.text.TextFormatAlign;
|
|
import flash.text.TextFieldAutoSize;
|
|
import flash.utils.Dictionary;
|
|
|
|
//--------------------------------------
|
|
// Styles
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* An object containing style values to be passed to the vertical axis
|
|
* renderer. The available styles are listed with the class that is used as the
|
|
* axis renderer.
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* {
|
|
* showTicks: true,
|
|
* tickWeight: 1,
|
|
* tickColor: 0x999999,
|
|
* showMinorTicks: true,
|
|
* minorTickWeight: 1,
|
|
* minorTickColor: 0xcccccc
|
|
* }
|
|
* </listing>
|
|
*
|
|
* <p><strong>Note:</strong> Previously, all styles for the axis renderers
|
|
* were listed as individual styles on the chart, but since it is possible
|
|
* to use a renderer class that has completely different styles than the
|
|
* default renderer, we need to deprecate the previous method to allow
|
|
* maximum flexibility when new or custom renderers are added.</p>
|
|
*
|
|
* <p>The old styles still exist, and legacy code will continue to work
|
|
* for the time being. However, it is recommended that you begin porting
|
|
* code to the new system as soon as possible.</p>
|
|
*
|
|
* <p>For the vertical axis, you should use the following method to set
|
|
* styles at runtime:</p>
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* chart.setVerticalAxisStyle("showTicks", false);
|
|
* </listing>
|
|
*
|
|
* @see setVerticalAxisStyle()
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultAxisRenderer
|
|
*/
|
|
[Style(name="verticalAxisStyles", type="Object")]
|
|
|
|
/**
|
|
* The class used to instantiate the visual representation of the vertical
|
|
* axis.
|
|
*
|
|
* @default DefaultAxisRenderer
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultAxisRenderer
|
|
*/
|
|
[Style(name="verticalAxisRenderer", type="Class")]
|
|
|
|
/**
|
|
* An object containing style values to be passed to the horizontal axis
|
|
* renderer. The available styles are listed with the class that is used as the
|
|
* axis renderer.
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* {
|
|
* showTicks: true,
|
|
* tickWeight: 1,
|
|
* tickColor: 0x999999,
|
|
* showMinorTicks: true,
|
|
* minorTickWeight: 1,
|
|
* minorTickColor: 0xcccccc
|
|
* }
|
|
* </listing>
|
|
*
|
|
* <p><strong>Note:</strong> Previously, all styles for the grid lines
|
|
* renderer were listed as individual styles on the chart, but since it is
|
|
* possible to use a renderer class that has completely different styles
|
|
* than the default renderer, we need to deprecate the previous
|
|
* method to allow maximum flexibility when new or custom renderers are
|
|
* added.</p>
|
|
*
|
|
* <p>The old styles still exist, and legacy code will continue to work
|
|
* for the time being. However, it is recommended that you begin porting
|
|
* code to the new system as soon as possible.</p>
|
|
*
|
|
* <p>For the horizontal axis, you should use the following method to set
|
|
* styles at runtime:</p>
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* chart.setHorizontalAxisStyle("showTicks", false);
|
|
* </listing>
|
|
*
|
|
* @see setHorizontalAxisStyle()
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultAxisRenderer
|
|
*/
|
|
[Style(name="horizontalAxisStyles", type="Object")]
|
|
|
|
/**
|
|
* The class used to instantiate the visual representation of the horizontal
|
|
* axis.
|
|
*
|
|
* @default DefaultAxisRenderer
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultAxisRenderer
|
|
*/
|
|
[Style(name="horizontalAxisRenderer", type="Class")]
|
|
|
|
/**
|
|
* An object containing style values to be passed to the vertical axis grid
|
|
* lines renderer. The available styles are listed with the class that is used as the
|
|
* grid lines renderer.
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* {
|
|
* showLines: true,
|
|
* lineWeight: 1,
|
|
* lineColor: 0x999999,
|
|
* showMinorLines: false
|
|
* }
|
|
* </listing>
|
|
*
|
|
* <p><strong>Note:</strong> Previously, all styles for the grid lines were listed as individual
|
|
* styles on the chart, but since it is possible to use a renderer class
|
|
* that has completely different styles, we need to deprecate the previous
|
|
* method to allow maximum flexibility when new or custom renderers are
|
|
* added.</p>
|
|
*
|
|
* <p>The old styles still exist, and legacy code will continue to work
|
|
* for the time being. However, it is recommended that you begin porting
|
|
* code to the new system as soon as possible.</p>
|
|
*
|
|
* <p>For the vertical axis grid lines, you should use the following method to set
|
|
* styles at runtime:</p>
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* chart.setVerticalAxisGridLinesStyle("lineColor", 0x999999);
|
|
* </listing>
|
|
*
|
|
* @see setVerticalAxisGridLinesStyle()
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultGridLinesRenderer
|
|
*/
|
|
[Style(name="verticalAxisGridLinesStyles", type="Object")]
|
|
|
|
/**
|
|
* The class used to instantiate the vertical axis grid lines.
|
|
*
|
|
* @default DefaultGridLinesRenderer
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultGridLinesRenderer
|
|
*/
|
|
[Style(name="verticalAxisGridLinesRenderer", type="Class")]
|
|
|
|
/**
|
|
* An object containing style values to be passed to the horizontal axis grid
|
|
* lines renderer. The available styles are listed with the class that is used as the
|
|
* grid lines renderer.
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* {
|
|
* showLines: true,
|
|
* lineWeight: 1,
|
|
* lineColor: 0x999999,
|
|
* showMinorLines: false
|
|
* }
|
|
* </listing>
|
|
*
|
|
* <p><strong>Note:</strong> Previously, all styles for the grid lines were listed as individual
|
|
* styles on the chart, but since it is possible to use a renderer class
|
|
* that has completely different styles, we need to deprecate the previous
|
|
* method to allow maximum flexibility when new or custom renderers are
|
|
* added.</p>
|
|
*
|
|
* <p>The old styles still exist, and legacy code will continue to work
|
|
* for the time being. However, it is recommended that you begin porting
|
|
* code to the new system as soon as possible.</p>
|
|
*
|
|
* <p>For the horizontal axis grid lines, you should use the following method to set
|
|
* styles at runtime:</p>
|
|
*
|
|
* @example
|
|
* <listing version="3.0">
|
|
* chart.setHorizontalAxisGridLinesStyle("lineColor", 0x999999);
|
|
* </listing>
|
|
*
|
|
* @see setHorizontalAxisGridLinesStyle()
|
|
* @see com.yahoo.astra.fl.charts.axes.DefaultGridLinesRenderer
|
|
*/
|
|
[Style(name="horizontalAxisGridLinesStyles", type="Object")]
|
|
|
|
/**
|
|
* The class used to instantiate the horizontal axis grid lines.
|
|
*
|
|
* @default DefaultGridLinesRenderer
|
|
*/
|
|
[Style(name="horizontalAxisGridLinesRenderer", type="Class")]
|
|
|
|
//-- DEPRECATED Vertical Axis styles
|
|
|
|
/**
|
|
* If false, the vertical axis is not drawn. Titles, labels, ticks, and grid
|
|
* lines may still be drawn, however, so you must specifically hide each
|
|
* item if nothing should be drawn.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxis", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the vertical axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the vertical axis.
|
|
*
|
|
* @default #888a85
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisColor", type="uint")]
|
|
|
|
//-- Labels - Vertical Axis
|
|
|
|
/**
|
|
* If true, labels will be displayed on the vertical axis.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxisLabels", type="Boolean")]
|
|
|
|
/**
|
|
* The distance, in pixels, between a label and the vertical axis.
|
|
*
|
|
* @default 2
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisLabelDistance", type="Number")]
|
|
|
|
/**
|
|
* Defines the TextFormat used by labels on the vertical axis. If null,
|
|
* the <code>textFormat</code> style will be used.
|
|
*
|
|
* @default null
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisTextFormat", type="TextFormat")]
|
|
|
|
/**
|
|
* If true, labels that overlap previously drawn labels on the axis will be
|
|
* hidden. The first and last labels on the axis will always be drawn.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisHideOverlappingLabels", type="Boolean")]
|
|
|
|
/**
|
|
* The angle, in degrees, of the labels on the vertical axis. May be a value
|
|
* between <code>-90</code> and <code>90</code>. The font must be embedded
|
|
* in the SWF and the <code>embedFonts</code> style on the chart must be set
|
|
* to <code>true</code> before labels may be rotated. If these conditions
|
|
* aren't met, the labels will not be rotated.
|
|
*
|
|
* @default 0
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisLabelRotation", type="Number")]
|
|
|
|
//-- Grid - Vertical Axis
|
|
|
|
/**
|
|
* An Array of <code>uint</code> color values that is used to draw
|
|
* alternating fills between the vertical axis' grid lines.
|
|
*
|
|
* @default []
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisGridFillColors", type="Array")]
|
|
|
|
/**
|
|
* An Array of alpha values (in the range of 0 to 1) that is used to draw
|
|
* alternating fills between the vertical axis' grid lines.
|
|
*
|
|
* @default []
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisGridFillAlphas", type="Array")]
|
|
|
|
//-- DEPRECATED Grid Lines styles - Vertical Axis
|
|
|
|
/**
|
|
* If true, grid lines will be displayed on the vertical axis.
|
|
*
|
|
* @default false
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxisGridLines", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the grid lines on the vertical axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisGridLineWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the grid lines on the vertical axis.
|
|
*
|
|
* @default #babdb6
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisGridLineColor", type="uint")]
|
|
|
|
//-- Minor Grid Lines - Vertical Axis
|
|
|
|
/**
|
|
* If true, minor grid lines will be displayed on the vertical axis.
|
|
*
|
|
* @default false
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxisMinorGridLines", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the minor grid lines on the vertical axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisMinorGridLineWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the minor grid lines on the vertical axis.
|
|
*
|
|
* @default #eeeeec
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisMinorGridLineColor", type="uint")]
|
|
|
|
//-- Ticks - Vertical Axis
|
|
|
|
/**
|
|
* If true, ticks will be displayed on the vertical axis.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxisTicks", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the ticks on the vertical axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisTickWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the ticks on the vertical axis.
|
|
*
|
|
* @default #888a85
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisTickColor", type="uint")]
|
|
|
|
/**
|
|
* The length, in pixels, of the ticks on the vertical axis.
|
|
*
|
|
* @default 4
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisTickLength", type="Number")]
|
|
|
|
/**
|
|
* The position of the ticks on the vertical axis.
|
|
*
|
|
* @default "cross"
|
|
* @see com.yahoo.astra.fl.charts.axes.TickPosition
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisTickPosition", type="String")]
|
|
|
|
//-- Minor ticks - Vertical Axis
|
|
|
|
/**
|
|
* If true, ticks will be displayed on the vertical axis at minor positions.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxisMinorTicks", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the minor ticks on the vertical axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisMinorTickWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the minor ticks on the vertical axis.
|
|
*
|
|
* @default #888a85
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisMinorTickColor", type="uint")]
|
|
|
|
/**
|
|
* The length of the minor ticks on the vertical axis.
|
|
*
|
|
* @default 3
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisMinorTickLength", type="Number")]
|
|
|
|
/**
|
|
* The position of the minor ticks on the vertical axis.
|
|
*
|
|
* @default "outside"
|
|
* @see com.yahoo.astra.fl.charts.axes.TickPosition
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisMinorTickPosition", type="String")]
|
|
|
|
//-- Title - Vertical Axis
|
|
|
|
/**
|
|
* If true, the vertical axis title will be displayed.
|
|
*
|
|
* @default 2
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showVerticalAxisTitle", type="Boolean")]
|
|
|
|
/**
|
|
* The TextFormat object to use to render the vertical axis title label.
|
|
*
|
|
* @default TextFormat("_sans", 11, 0x000000, false, false, false, '', '', TextFormatAlign.LEFT, 0, 0, 0, 0)
|
|
* @deprecated
|
|
*/
|
|
[Style(name="verticalAxisTitleTextFormat", type="TextFormat")]
|
|
|
|
//-- DEPRECATED Horizontal Axis styles
|
|
|
|
/**
|
|
* If false, the horizontal axis is not drawn. Titles, labels, ticks, and grid
|
|
* lines may still be drawn, however, so you must specifically hide each
|
|
* item if nothing should be drawn.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxis", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the horizontal axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the horizontal axis.
|
|
*
|
|
* @default #888a85
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisColor", type="uint")]
|
|
|
|
//-- Labels - Horizontal Axis
|
|
|
|
/**
|
|
* If true, labels will be displayed on the horizontal axis.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxisLabels", type="Boolean")]
|
|
|
|
/**
|
|
* The distance, in pixels, between a label and the horizontal axis.
|
|
*
|
|
* @default 2
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisLabelDistance", type="Number")]
|
|
|
|
/**
|
|
* Defines the TextFormat used by labels on the horizontal axis. If null,
|
|
* the <code>textFormat</code> style will be used.
|
|
*
|
|
* @default null
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisTextFormat", type="TextFormat")]
|
|
|
|
/**
|
|
* If true, labels that overlap previously drawn labels on the axis will be
|
|
* hidden. The first and last labels on the axis will always be drawn.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisHideOverlappingLabels", type="Boolean")]
|
|
|
|
/**
|
|
* The angle, in degrees, of the labels on the horizontal axis. May be a value
|
|
* between <code>-90</code> and <code>90</code>. The font must be embedded
|
|
* in the SWF and the <code>embedFonts</code> style on the chart must be set
|
|
* to <code>true</code> before labels may be rotated. If these conditions
|
|
* aren't met, the labels will not be rotated.
|
|
*
|
|
* @default 0
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisLabelRotation", type="Number")]
|
|
|
|
//-- Grid - Horizontal Axis
|
|
|
|
/**
|
|
* An Array of <code>uint</code> color values that is used to draw
|
|
* alternating fills between the horizontal axis' grid lines.
|
|
*
|
|
* @default []
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisGridFillColors", type="Array")]
|
|
|
|
/**
|
|
* An Array of alpha values (in the range of 0 to 1) that is used to draw
|
|
* alternating fills between the horizontal axis' grid lines.
|
|
*
|
|
* @default []
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisGridFillAlphas", type="Array")]
|
|
|
|
//-- DEPRECATED Grid Lines - Horizontal Axis
|
|
|
|
/**
|
|
* If true, grid lines will be displayed on the horizontal axis.
|
|
*
|
|
* @default false
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxisGridLines", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the grid lines on the horizontal axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisGridLineWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the grid lines on the horizontal axis.
|
|
*
|
|
* @default #babdb6
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisGridLineColor", type="uint")]
|
|
|
|
//-- Minor Grid Lines - Horizontal Axis
|
|
|
|
/**
|
|
* If true, minor grid lines will be displayed on the horizontal axis.
|
|
*
|
|
* @default false
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxisMinorGridLines", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the minor grid lines on the horizontal axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisMinorGridLineWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the minor grid lines on the horizontal axis.
|
|
*
|
|
* @default #eeeeec
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisMinorGridLineColor", type="uint")]
|
|
|
|
//-- Ticks - Horizontal Axis
|
|
|
|
/**
|
|
* If true, ticks will be displayed on the horizontal axis.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxisTicks", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the ticks on the horizontal axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisTickWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the ticks on the horizontal axis.
|
|
*
|
|
* @default #888a85
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisTickColor", type="uint")]
|
|
|
|
/**
|
|
* The length, in pixels, of the ticks on the horizontal axis.
|
|
*
|
|
* @default 4
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisTickLength", type="Number")]
|
|
|
|
/**
|
|
* The position of the ticks on the horizontal axis.
|
|
*
|
|
* @default "cross"
|
|
* @see com.yahoo.astra.fl.charts.axes.TickPosition
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisTickPosition", type="String")]
|
|
|
|
//-- Minor ticks - Horizontal Axis
|
|
|
|
/**
|
|
* If true, ticks will be displayed on the horizontal axis at minor positions.
|
|
*
|
|
* @default true
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxisMinorTicks", type="Boolean")]
|
|
|
|
/**
|
|
* The line weight, in pixels, for the minor ticks on the horizontal axis.
|
|
*
|
|
* @default 1
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisMinorTickWeight", type="int")]
|
|
|
|
/**
|
|
* The line color for the minor ticks on the horizontal axis.
|
|
*
|
|
* @default #888a85
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisMinorTickColor", type="uint")]
|
|
|
|
/**
|
|
* The length of the minor ticks on the horizontal axis.
|
|
*
|
|
* @default 3
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisMinorTickLength", type="Number")]
|
|
|
|
/**
|
|
* The position of the minor ticks on the horizontal axis.
|
|
*
|
|
* @default "outside"
|
|
* @see com.yahoo.astra.fl.charts.axes.TickPosition
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisMinorTickPosition", type="String")]
|
|
|
|
//-- Title - Horizontal Axis
|
|
|
|
/**
|
|
* If true, the horizontal axis title will be displayed.
|
|
*
|
|
* @default 2
|
|
* @deprecated
|
|
*/
|
|
[Style(name="showHorizontalAxisTitle", type="Boolean")]
|
|
|
|
/**
|
|
* The TextFormat object to use to render the horizontal axis title label.
|
|
*
|
|
* @default TextFormat("_sans", 11, 0x000000, false, false, false, '', '', TextFormatAlign.LEFT, 0, 0, 0, 0)
|
|
* @deprecated
|
|
*/
|
|
[Style(name="horizontalAxisTitleTextFormat", type="TextFormat")]
|
|
|
|
/**
|
|
* The border color of the markers in a series. When not specified, the border color
|
|
* is determined by the color style.
|
|
*
|
|
* @default []
|
|
*/
|
|
[Style(name="seriesBorderColors", type="Array")]
|
|
|
|
/**
|
|
* The border alpha of the markers in a series.
|
|
*
|
|
* @default [1]
|
|
*/
|
|
[Style(name="seriesBorderAlphas", type="Array")]
|
|
|
|
/**
|
|
* The fill color of the markers in a series. When not specified, the fill color
|
|
* is determined by the color style.
|
|
*
|
|
* @default []
|
|
*/
|
|
[Style(name="seriesFillColors", type="Array")]
|
|
|
|
/**
|
|
* The fill alpha of the markers in a series.
|
|
*
|
|
* @default [1]
|
|
*/
|
|
[Style(name="seriesFillAlphas", type="Array")]
|
|
|
|
/**
|
|
* A chart based on the cartesian coordinate system (x, y).
|
|
*
|
|
* @author Josh Tynjala
|
|
*/
|
|
public class CartesianChart extends Chart implements IChart, ICategoryChart
|
|
{
|
|
|
|
//--------------------------------------
|
|
// Class Variables
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @private
|
|
* Exists simply to reference dependencies that aren't used
|
|
* anywhere else by this component.
|
|
*/
|
|
private static const DEPENDENCIES:Array = [TimeAxis];
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
private static var defaultStyles:Object =
|
|
{
|
|
horizontalAxisStyles: {},
|
|
horizontalAxisGridLinesStyles: {},
|
|
horizontalAxisRenderer: DefaultAxisRenderer,
|
|
horizontalAxisGridLinesRenderer: DefaultGridLinesRenderer,
|
|
|
|
verticalAxisStyles: {},
|
|
verticalAxisGridLinesStyles: {},
|
|
verticalAxisRenderer: DefaultAxisRenderer,
|
|
verticalAxisGridLinesRenderer: DefaultGridLinesRenderer,
|
|
|
|
//DEPRECATED BELOW THIS POINT!
|
|
//(to be removed in a future version)
|
|
|
|
//axis
|
|
showHorizontalAxis: true,
|
|
horizontalAxisWeight: 1,
|
|
horizontalAxisColor: 0x888a85,
|
|
|
|
//title
|
|
showHorizontalAxisTitle: true,
|
|
horizontalAxisTitleTextFormat: new TextFormat("_sans", 11, 0x000000, false, false, false, "", "", TextFormatAlign.LEFT, 0, 0, 0, 0),
|
|
horizontalAxisTitleRotation: 0,
|
|
horizontalAxisTitleDistance: 2,
|
|
|
|
//labels
|
|
showHorizontalAxisLabels: true,
|
|
horizontalAxisTextFormat: null,
|
|
horizontalAxisLabelDistance: 2,
|
|
horizontalAxisHideOverlappingLabels: true,
|
|
horizontalAxisLabelRotation: 0,
|
|
horizontalAxisLabelSpacing: 2,
|
|
|
|
//grid lines
|
|
horizontalAxisGridLineWeight: 1,
|
|
horizontalAxisGridLineColor: 0xbabdb6,
|
|
showHorizontalAxisGridLines: false,
|
|
horizontalAxisMinorGridLineWeight: 1,
|
|
horizontalAxisMinorGridLineColor: 0xeeeeec,
|
|
showHorizontalAxisMinorGridLines: false,
|
|
horizontalAxisGridFillColors: [],
|
|
horizontalAxisGridFillAlphas: [],
|
|
showHorizontalZeroGridLine: false,
|
|
horizontalZeroGridLineWeight: 2,
|
|
horizontalZeroGridLineColor: 0xbabdb6,
|
|
|
|
//ticks
|
|
showHorizontalAxisTicks: false,
|
|
horizontalAxisTickWeight: 1,
|
|
horizontalAxisTickColor: 0x888a85,
|
|
horizontalAxisTickLength: 4,
|
|
horizontalAxisTickPosition: "cross",
|
|
showHorizontalAxisMinorTicks: false,
|
|
horizontalAxisMinorTickWeight: 1,
|
|
horizontalAxisMinorTickColor: 0x888a85,
|
|
horizontalAxisMinorTickLength: 3,
|
|
horizontalAxisMinorTickPosition: "outside",
|
|
|
|
//axis
|
|
showVerticalAxis: true,
|
|
verticalAxisWeight: 1,
|
|
verticalAxisColor: 0x888a85,
|
|
|
|
//title
|
|
showVerticalAxisTitle: true,
|
|
verticalAxisTitleTextFormat: new TextFormat("_sans", 11, 0x000000, false, false, false, "", "", TextFormatAlign.LEFT, 0, 0, 0, 0),
|
|
verticalAxisTitleRotation: 0,
|
|
verticalAxisTitleDistance: 2,
|
|
|
|
//labels
|
|
showVerticalAxisLabels: true,
|
|
verticalAxisTextFormat: null,
|
|
verticalAxisLabelDistance: 2,
|
|
verticalAxisHideOverlappingLabels: true,
|
|
verticalAxisLabelRotation: 0,
|
|
verticalAxisLabelSpacing: 2,
|
|
|
|
//grid lines
|
|
showVerticalAxisGridLines: true,
|
|
verticalAxisGridLineWeight: 1,
|
|
verticalAxisGridLineColor: 0xbabdb6,
|
|
verticalAxisMinorGridLineWeight: 1,
|
|
verticalAxisMinorGridLineColor: 0xeeeeec,
|
|
showVerticalAxisMinorGridLines: false,
|
|
verticalAxisGridFillColors: [],
|
|
verticalAxisGridFillAlphas: [],
|
|
showVerticalZeroGridLine: false,
|
|
verticalZeroGridLineWeight: 2,
|
|
verticalZeroGridLineColor: 0xbabdb6,
|
|
|
|
//ticks
|
|
showVerticalAxisTicks: true,
|
|
verticalAxisTickWeight: 1,
|
|
verticalAxisTickColor: 0x888a85,
|
|
verticalAxisTickLength: 4,
|
|
verticalAxisTickPosition: "cross",
|
|
showVerticalAxisMinorTicks: true,
|
|
verticalAxisMinorTickWeight: 1,
|
|
verticalAxisMinorTickColor: 0x888a85,
|
|
verticalAxisMinorTickLength: 3,
|
|
verticalAxisMinorTickPosition: "outside"
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* The chart styles that correspond to styles on the horizontal axis.
|
|
*/
|
|
private static const HORIZONTAL_AXIS_STYLES:Object =
|
|
{
|
|
showAxis: "showHorizontalAxis",
|
|
axisWeight: "horizontalAxisWeight",
|
|
axisColor: "horizontalAxisColor",
|
|
|
|
textFormat: "textFormat",
|
|
embedFonts: "embedFonts",
|
|
hideOverlappingLabels: "horizontalAxisHideOverlappingLabels",
|
|
labelRotation: "horizontalAxisLabelRotation",
|
|
labelDistance: "horizontalAxisLabelDistance",
|
|
showLabels: "showHorizontalAxisLabels",
|
|
labelSpacing: "horizontalAxisLabelSpacing",
|
|
titleRotation: "horizontalAxisTitleRotation",
|
|
titleDistance: "horizontalAxisTitleDistance",
|
|
|
|
showTitle: "showHorizontalAxisTitle",
|
|
titleTextFormat: "horizontalAxisTitleTextFormat",
|
|
|
|
tickWeight: "horizontalAxisTickWeight",
|
|
tickColor: "horizontalAxisTickColor",
|
|
tickLength: "horizontalAxisTickLength",
|
|
tickPosition: "horizontalAxisTickPosition",
|
|
showTicks: "showHorizontalAxisTicks",
|
|
|
|
minorTickWeight: "horizontalAxisMinorTickWeight",
|
|
minorTickColor: "horizontalAxisMinorTickColor",
|
|
minorTickLength: "horizontalAxisMinorTickLength",
|
|
minorTickPosition: "horizontalAxisMinorTickPosition",
|
|
showMinorTicks: "showHorizontalAxisMinorTicks"
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* The chart styles that correspond to styles on the horizontal axis
|
|
* grid lines.
|
|
*/
|
|
private static const HORIZONTAL_GRID_LINES_STYLES:Object =
|
|
{
|
|
lineWeight: "horizontalAxisGridLineWeight",
|
|
lineColor: "horizontalAxisGridLineColor",
|
|
showLines: "showHorizontalAxisGridLines",
|
|
|
|
minorLineWeight: "horizontalAxisMinorGridLineWeight",
|
|
minorLineColor: "horizontalAxisMinorGridLineColor",
|
|
showMinorLines: "showHorizontalAxisMinorGridLines",
|
|
|
|
showZeroGridLine: "showHorizontalZeroGridLine",
|
|
zeroGridLineWeight: "horizontalZeroGridLineWeight",
|
|
zeroGridLineColor: "horizontalZeroGridLineColor",
|
|
|
|
fillColors: "horizontalAxisGridFillColors",
|
|
fillAlphas: "horizontalAxisGridFillAlphas"
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* The chart styles that correspond to styles on the vertical axis.
|
|
*/
|
|
private static const VERTICAL_AXIS_STYLES:Object =
|
|
{
|
|
showAxis: "showVerticalAxis",
|
|
axisWeight: "verticalAxisWeight",
|
|
axisColor: "verticalAxisColor",
|
|
|
|
textFormat: "textFormat",
|
|
embedFonts: "embedFonts",
|
|
hideOverlappingLabels: "verticalAxisHideOverlappingLabels",
|
|
labelRotation: "verticalAxisLabelRotation",
|
|
labelDistance: "verticalAxisLabelDistance",
|
|
showLabels: "showVerticalAxisLabels",
|
|
labelSpacing: "verticalAxisLabelSpacing",
|
|
titleRotation: "verticalAxisTitleRotation",
|
|
titleDistance: "verticalAxisTitleDistance",
|
|
|
|
showTitle: "showVerticalAxisTitle",
|
|
titleTextFormat: "verticalAxisTitleTextFormat",
|
|
|
|
tickWeight: "verticalAxisTickWeight",
|
|
tickColor: "verticalAxisTickColor",
|
|
tickLength: "verticalAxisTickLength",
|
|
tickPosition: "verticalAxisTickPosition",
|
|
showTicks: "showVerticalAxisTicks",
|
|
|
|
minorTickWeight: "verticalAxisMinorTickWeight",
|
|
minorTickColor: "verticalAxisMinorTickColor",
|
|
minorTickLength: "verticalAxisMinorTickLength",
|
|
minorTickPosition: "verticalAxisMinorTickPosition",
|
|
showMinorTicks: "showVerticalAxisMinorTicks"
|
|
};
|
|
|
|
/**
|
|
* @private
|
|
* The chart styles that correspond to styles on the vertical axis
|
|
* grid lines.
|
|
*/
|
|
private static const VERTICAL_GRID_LINES_STYLES:Object =
|
|
{
|
|
lineWeight: "verticalAxisGridLineWeight",
|
|
lineColor: "verticalAxisGridLineColor",
|
|
showLines: "showVerticalAxisGridLines",
|
|
|
|
minorLineWeight: "verticalAxisMinorGridLineWeight",
|
|
minorLineColor: "verticalAxisMinorGridLineColor",
|
|
showMinorLines: "showVerticalAxisMinorGridLines",
|
|
|
|
showZeroGridLine: "showVerticalZeroGridLine",
|
|
zeroGridLineWeight: "verticalZeroGridLineWeight",
|
|
zeroGridLineColor: "verticalZeroGridLineColor",
|
|
|
|
fillColors: "verticalAxisGridFillColors",
|
|
fillAlphas: "verticalAxisGridFillAlphas"
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Class Methods
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @copy fl.core.UIComponent#getStyleDefinition()
|
|
*/
|
|
public static function getStyleDefinition():Object
|
|
{
|
|
return mergeStyles(defaultStyles, Chart.getStyleDefinition());
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Constructor
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* Constructor.
|
|
*/
|
|
public function CartesianChart()
|
|
{
|
|
super();
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Properties
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the contentBounds property.
|
|
*/
|
|
protected var _contentBounds:Rectangle = new Rectangle();
|
|
|
|
/**
|
|
* The rectangular bounds where the cartesian chart's data is drawn.
|
|
*/
|
|
public function get contentBounds():Rectangle
|
|
{
|
|
return this._contentBounds;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected var horizontalGridLines:IGridLinesRenderer;
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected var verticalGridLines:IGridLinesRenderer;
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected var verticalMinorGridLines:Sprite;
|
|
|
|
/**
|
|
* @private
|
|
* The visual representation of the horizontal axis.
|
|
*/
|
|
protected var horizontalAxisRenderer:ICartesianAxisRenderer;
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the horizontalAxis property.
|
|
*/
|
|
private var _horizontalAxis:IAxis;
|
|
|
|
/**
|
|
* The axis representing the horizontal range.
|
|
*/
|
|
public function get horizontalAxis():IAxis
|
|
{
|
|
return this._horizontalAxis;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set horizontalAxis(axis:IAxis):void
|
|
{
|
|
if(this._horizontalAxis != axis)
|
|
{
|
|
this._horizontalAxis = axis;
|
|
this._horizontalAxis.chart = this;
|
|
|
|
this.invalidate("axes");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* The visual representation of the horizontal axis.
|
|
*/
|
|
protected var verticalAxisRenderer:ICartesianAxisRenderer;
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the verticalAxis property.
|
|
*/
|
|
private var _verticalAxis:IAxis;
|
|
|
|
/**
|
|
* The axis representing the vertical range.
|
|
*/
|
|
public function get verticalAxis():IAxis
|
|
{
|
|
return this._verticalAxis;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set verticalAxis(axis:IAxis):void
|
|
{
|
|
if(this._verticalAxis != axis)
|
|
{
|
|
this._verticalAxis = axis;
|
|
this._verticalAxis.chart = this;
|
|
this.invalidate("axes");
|
|
}
|
|
}
|
|
|
|
//-- Data
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the horizontalField property.
|
|
*/
|
|
private var _horizontalField:String = "category";
|
|
|
|
[Inspectable(defaultValue="category",verbose=1)]
|
|
/**
|
|
* If the items displayed on the chart are complex objects, the horizontalField string
|
|
* defines the property to access when determining the x value.
|
|
*/
|
|
public function get horizontalField():String
|
|
{
|
|
return this._horizontalField;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set horizontalField(value:String):void
|
|
{
|
|
if(this._horizontalField != value)
|
|
{
|
|
this._horizontalField = value;
|
|
this.invalidate(InvalidationType.DATA);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the verticalField property.
|
|
*/
|
|
private var _verticalField:String = "value";
|
|
|
|
[Inspectable(defaultValue="value",verbose=1)]
|
|
/**
|
|
* If the items displayed on the chart are complex objects, the verticalField string
|
|
* defines the property to access when determining the y value.
|
|
*/
|
|
public function get verticalField():String
|
|
{
|
|
return this._verticalField;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set verticalField(value:String):void
|
|
{
|
|
if(this._verticalField != value)
|
|
{
|
|
this._verticalField = value;
|
|
this.invalidate(InvalidationType.DATA);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
private var _horizontalAxisLabelData:Object;
|
|
|
|
public function get horizontalAxisLabelData():Object
|
|
{
|
|
return _horizontalAxisLabelData;
|
|
}
|
|
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
private var _verticalAxisLabelData:Object;
|
|
|
|
public function get verticalAxisLabelData():Object
|
|
{
|
|
return _verticalAxisLabelData;
|
|
}
|
|
|
|
//-- Titles
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the horizontalAxisTitle property.
|
|
*/
|
|
private var _horizontalAxisTitle:String = "";
|
|
|
|
[Inspectable(defaultValue="")]
|
|
/**
|
|
* The title text displayed on the horizontal axis.
|
|
*/
|
|
public function get horizontalAxisTitle():String
|
|
{
|
|
return this._horizontalAxisTitle;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set horizontalAxisTitle(value:String):void
|
|
{
|
|
if(this._horizontalAxisTitle != value)
|
|
{
|
|
this._horizontalAxisTitle = value;
|
|
this.invalidate(InvalidationType.DATA);
|
|
this.invalidate("axes");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the verticalAxisTitle property.
|
|
*/
|
|
private var _verticalAxisTitle:String = "";
|
|
|
|
[Inspectable(defaultValue="")]
|
|
/**
|
|
* The title text displayed on the horizontal axis.
|
|
*/
|
|
public function get verticalAxisTitle():String
|
|
{
|
|
return this._verticalAxisTitle;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set verticalAxisTitle(value:String):void
|
|
{
|
|
if(this._verticalAxisTitle != value)
|
|
{
|
|
this._verticalAxisTitle = value;
|
|
this.invalidate(InvalidationType.DATA);
|
|
this.invalidate("axes");
|
|
}
|
|
}
|
|
|
|
//-- Category names
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the categoryNames property.
|
|
*/
|
|
private var _explicitCategoryNames:Array;
|
|
|
|
[Inspectable]
|
|
/**
|
|
* The names of the categories displayed on the category axis. If the
|
|
* chart does not have a category axis, this value will be ignored.
|
|
*/
|
|
public function get categoryNames():Array
|
|
{
|
|
if(this._explicitCategoryNames && this._explicitCategoryNames.length > 0)
|
|
{
|
|
return this._explicitCategoryNames;
|
|
}
|
|
else if(this.horizontalAxis is CategoryAxis)
|
|
{
|
|
return CategoryAxis(this.horizontalAxis).categoryNames;
|
|
}
|
|
else if(this.verticalAxis is CategoryAxis)
|
|
{
|
|
return CategoryAxis(this.verticalAxis).categoryNames;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set categoryNames(value:Array):void
|
|
{
|
|
if(this._explicitCategoryNames != value)
|
|
{
|
|
this._explicitCategoryNames = value;
|
|
this.invalidate(InvalidationType.DATA);
|
|
this.invalidate("axes");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Storage for the overflowEnabled property.
|
|
*/
|
|
private var _overflowEnabled:Boolean = false;
|
|
|
|
[Inspectable(defaultValue=false,verbose=1)]
|
|
/**
|
|
* If false, which is the default, the axes will be resized to fit within the defined
|
|
* bounds of the plot area. However, if set to true, the axes themselves will grow to
|
|
* fit the plot area bounds and the labels and other items that normally cause the
|
|
* resize will be drawn outside.
|
|
*/
|
|
public function get overflowEnabled():Boolean
|
|
{
|
|
return this._overflowEnabled;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function set overflowEnabled(value:Boolean):void
|
|
{
|
|
if(this._overflowEnabled != value)
|
|
{
|
|
this._overflowEnabled = value;
|
|
this.invalidate("axes");
|
|
}
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Public Methods
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @inheritDoc
|
|
*/
|
|
public function itemToPosition(series:ISeries, itemIndex:int):Point
|
|
{
|
|
var horizontalValue:Object = this.itemToAxisValue(series, itemIndex, this.horizontalAxis);
|
|
var xPosition:Number = this.horizontalAxis.valueToLocal(horizontalValue);
|
|
|
|
var verticalValue:Object = this.itemToAxisValue(series, itemIndex, this.verticalAxis);
|
|
var yPosition:Number = this.verticalAxis.valueToLocal(verticalValue);
|
|
|
|
return new Point(xPosition, yPosition);
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
public function itemToAxisValue(series:ISeries, itemIndex:int, axis:IAxis, stack:Boolean = true):Object
|
|
{
|
|
if(!stack || !ChartUtil.isStackingAllowed(axis, series))
|
|
{
|
|
var item:Object = series.dataProvider[itemIndex];
|
|
var valueField:String = this.axisAndSeriesToField(axis, series);
|
|
return item[valueField];
|
|
}
|
|
|
|
var type:Class = UIComponentUtil.getClassDefinition(series);
|
|
var stackAxis:IStackingAxis = IStackingAxis(axis);
|
|
var stackValue:Object;
|
|
var allSeriesOfType:Array = ChartUtil.findSeriesOfType(series, this);
|
|
var seriesIndex:int = allSeriesOfType.indexOf(series);
|
|
var values:Array = [];
|
|
for(var i:int = 0; i <= seriesIndex; i++)
|
|
{
|
|
var stackedSeries:IStackedSeries = IStackedSeries(allSeriesOfType[i]);
|
|
item = stackedSeries.dataProvider[itemIndex];
|
|
valueField = this.axisAndSeriesToField(stackAxis, stackedSeries);
|
|
values.unshift(item[valueField]);
|
|
}
|
|
|
|
if(values.length > 0) stackValue = stackAxis.stack.apply(stackAxis, values);
|
|
return stackValue;
|
|
}
|
|
|
|
/**
|
|
* Sets a style on the horizontal axis.
|
|
*/
|
|
public function setHorizontalAxisStyle(name:String, value:Object):void
|
|
{
|
|
this.setComplexStyle("horizontalAxisStyles", name, value);
|
|
}
|
|
|
|
public function getHorizontalAxisStyle(name:String):Object
|
|
{
|
|
var obj:Object = this.getStyleValue("horizontalAxisStyles");
|
|
var style:Object;
|
|
if(obj[name] != null)
|
|
{
|
|
style = obj[name];
|
|
}
|
|
else
|
|
{
|
|
style = this.getStyleValue(HORIZONTAL_AXIS_STYLES[name]);
|
|
}
|
|
return style;
|
|
}
|
|
|
|
public function getVerticalAxisStyle(name:String):Object
|
|
{
|
|
var obj:Object = this.getStyleValue("verticalAxisStyles");
|
|
var style:Object;
|
|
if(obj[name] != null)
|
|
{
|
|
style = obj[name];
|
|
}
|
|
else
|
|
{
|
|
style = this.getStyleValue(VERTICAL_AXIS_STYLES[name]);
|
|
}
|
|
return style;
|
|
}
|
|
|
|
/**
|
|
* Sets a style on the vertical axis.
|
|
*/
|
|
public function setVerticalAxisStyle(name:String, value:Object):void
|
|
{
|
|
this.setComplexStyle("verticalAxisStyles", name, value);
|
|
}
|
|
|
|
/**
|
|
* Sets a style on the horizontal axis grid lines.
|
|
*/
|
|
public function setHorizontalAxisGridLinesStyle(name:String, value:Object):void
|
|
{
|
|
this.setComplexStyle("horizontalAxisGridLinesStyles", name, value);
|
|
}
|
|
|
|
/**
|
|
* Sets a style on the vertical axis grid lines.
|
|
*/
|
|
public function setVerticalAxisGridLinesStyle(name:String, value:Object):void
|
|
{
|
|
this.setComplexStyle("verticalAxisGridLinesStyles", name, value);
|
|
}
|
|
|
|
//--------------------------------------
|
|
// Protected Methods
|
|
//--------------------------------------
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
override protected function draw():void
|
|
{
|
|
var dataInvalid:Boolean = this.isInvalid(InvalidationType.DATA);
|
|
var stylesInvalid:Boolean = this.isInvalid(InvalidationType.STYLES);
|
|
var sizeInvalid:Boolean = this.isInvalid(InvalidationType.SIZE);
|
|
var axesInvalid:Boolean = this.isInvalid("axes")
|
|
|
|
super.draw();
|
|
|
|
if(stylesInvalid)
|
|
{
|
|
this.updateRenderers();
|
|
}
|
|
|
|
if(sizeInvalid || dataInvalid || stylesInvalid || axesInvalid)
|
|
{
|
|
this.drawAxes();
|
|
|
|
//the series display objects are dependant on the axes, so all series redraws must
|
|
//happen after the axes have redrawn
|
|
this.drawSeries();
|
|
}
|
|
|
|
this.updateLegend();
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Make sure no numeric points exist. Convert to objects compatible with the axes.
|
|
*/
|
|
override protected function refreshSeries():void
|
|
{
|
|
super.refreshSeries();
|
|
var numericAxis:IAxis = this.horizontalAxis;
|
|
var otherAxis:IAxis = this.verticalAxis;
|
|
if(this.verticalAxis is NumericAxis)
|
|
{
|
|
numericAxis = this.verticalAxis;
|
|
otherAxis = this.horizontalAxis;
|
|
}
|
|
|
|
var seriesCount:int = this.series.length;
|
|
for(var i:int = 0; i < seriesCount; i++)
|
|
{
|
|
var currentSeries:ISeries = this.series[i] as ISeries;
|
|
|
|
var numericField:String = this.axisAndSeriesToField(numericAxis, currentSeries);
|
|
var otherField:String = this.axisAndSeriesToField(otherAxis, currentSeries);
|
|
|
|
var seriesLength:int = currentSeries.length;
|
|
for(var j:int = 0; j < seriesLength; j++)
|
|
{
|
|
var item:Object = currentSeries.dataProvider[j];
|
|
if(item is Number || !isNaN(Number(item)))
|
|
{
|
|
//if we only have a number, then it is safe to convert
|
|
//to a default type for a category chart.
|
|
//if it's not a number, then the user is expected to update
|
|
//the x and y fields so that the plot area knows how to handle it.
|
|
var point:Object = {};
|
|
point[numericField] = item;
|
|
|
|
//we assume it's a category axis
|
|
if(this._explicitCategoryNames && this._explicitCategoryNames.length > 0)
|
|
{
|
|
point[otherField] = this.categoryNames[j];
|
|
}
|
|
else point[otherField] = j;
|
|
currentSeries.dataProvider[j] = point;
|
|
}
|
|
}
|
|
combineDuplicateCategoryNames(otherAxis);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*
|
|
* Combines duplicate category labels
|
|
*/
|
|
private function combineDuplicateCategoryNames(categoryAxis:IAxis):void
|
|
{
|
|
if(!(categoryAxis is CategoryAxis)) return;
|
|
var seriesCount:int = this.series.length;
|
|
for(var i:int = 0; i < seriesCount; i++)
|
|
{
|
|
var currentSeries:ISeries = this.series[i] as ISeries;
|
|
var categoryField:String = this.axisAndSeriesToField(categoryAxis, currentSeries);
|
|
var dict:Dictionary = new Dictionary();
|
|
var seriesLength:int = currentSeries.length;
|
|
var newDataProvider:Array = [];
|
|
for(var j:int = 0; j < seriesLength; j++)
|
|
{
|
|
var item:Object = currentSeries.dataProvider[j];
|
|
|
|
if(item.hasOwnProperty(categoryField))
|
|
{
|
|
//Combine items that share the same "categoryField" property
|
|
if(!dict.hasOwnProperty(item[categoryField]))
|
|
{
|
|
dict[item[categoryField]] = item;
|
|
newDataProvider.push(dict[item[categoryField]]);
|
|
}
|
|
else
|
|
{
|
|
for(var z:String in item)
|
|
{
|
|
if(z != categoryField && item[z] != null)
|
|
{
|
|
dict[item[categoryField]][z] = item[z];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
dict[item] = item;
|
|
newDataProvider.push(dict[item]);
|
|
}
|
|
}
|
|
currentSeries.dataProvider = newDataProvider.concat();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Creates the default axes. Without user intervention, the x-axis is a category
|
|
* axis and the y-axis is a numeric axis.
|
|
*/
|
|
override protected function configUI():void
|
|
{
|
|
super.configUI();
|
|
|
|
//by default, the x axis is for categories. other types of charts will need
|
|
//to override this if they need a numeric or other type of axis
|
|
if(!this.horizontalAxis)
|
|
{
|
|
var categoryAxis:CategoryAxis = new CategoryAxis();
|
|
this.horizontalAxis = categoryAxis;
|
|
}
|
|
|
|
if(!this.horizontalAxisRenderer)
|
|
{
|
|
var RendererClass:Class = this.getStyleValue("horizontalAxisRenderer") as Class;
|
|
this.horizontalAxisRenderer = new RendererClass(AxisOrientation.HORIZONTAL);
|
|
this.addChild(DisplayObject(this.horizontalAxisRenderer));
|
|
this.horizontalAxis.renderer = this.horizontalAxisRenderer;
|
|
}
|
|
|
|
if(!this.verticalAxis)
|
|
{
|
|
var numericAxis:NumericAxis = new NumericAxis();
|
|
numericAxis.stackingEnabled = true;
|
|
this.verticalAxis = numericAxis;
|
|
}
|
|
|
|
if(!this.verticalAxisRenderer)
|
|
{
|
|
RendererClass = this.getStyleValue("verticalAxisRenderer") as Class;
|
|
this.verticalAxisRenderer = new RendererClass(AxisOrientation.VERTICAL);
|
|
this.addChild(DisplayObject(this.verticalAxisRenderer));
|
|
this.verticalAxis.renderer = this.verticalAxisRenderer;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Determines the text that will appear on the data tip.
|
|
*/
|
|
override protected function defaultDataTipFunction(item:Object, index:int, series:ISeries):String
|
|
{
|
|
var text:String = super.defaultDataTipFunction(item, index, series);
|
|
if(text.length > 0)
|
|
{
|
|
text += "\n";
|
|
}
|
|
|
|
var categoryAxis:CategoryAxis = this.verticalAxis as CategoryAxis;
|
|
var otherAxis:IAxis = this.horizontalAxis;
|
|
if(!categoryAxis)
|
|
{
|
|
categoryAxis = this.horizontalAxis as CategoryAxis;
|
|
otherAxis = this.verticalAxis;
|
|
}
|
|
|
|
//if we have a category axis, the category is always displayed first
|
|
if(categoryAxis)
|
|
{
|
|
var categoryValue:Object = this.itemToAxisValue(series, index, categoryAxis, false);
|
|
text += categoryAxis.valueToLabel(categoryValue) + "\n";
|
|
|
|
var otherValue:Object = this.itemToAxisValue(series, index, otherAxis, false);
|
|
text += otherAxis.valueToLabel(otherValue) + "\n";
|
|
}
|
|
//otherwise, display the horizontal axis value first
|
|
else
|
|
{
|
|
var horizontalValue:Object = this.itemToAxisValue(series, index, this.horizontalAxis, false);
|
|
text += horizontalAxis.valueToLabel(horizontalValue) + "\n";
|
|
|
|
var verticalValue:Object = this.itemToAxisValue(series, index, this.verticalAxis, false);
|
|
text += verticalAxis.valueToLabel(verticalValue) + "\n";
|
|
}
|
|
return text;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Positions and updates the series objects.
|
|
*/
|
|
protected function drawSeries():void
|
|
{
|
|
var contentPadding:Number = this.getStyleValue("contentPadding") as Number;
|
|
var seriesWidth:Number = this._contentBounds.width - (contentPadding * 2);
|
|
var seriesHeight:Number = this._contentBounds.height - (contentPadding *2);
|
|
|
|
var contentScrollRect:Rectangle = new Rectangle(0, 0, seriesWidth, seriesHeight);
|
|
this.content.x = contentPadding + this._contentBounds.x;
|
|
this.content.y = contentPadding + this._contentBounds.y;
|
|
|
|
this.content.scrollRect = contentScrollRect;
|
|
|
|
var seriesCount:int = this.series.length;
|
|
for(var i:int = 0; i < seriesCount; i++)
|
|
{
|
|
var series:UIComponent = this.series[i] as UIComponent;
|
|
series.width = seriesWidth;
|
|
series.height = seriesHeight;
|
|
series.drawNow();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Removes the old axis renderers and create new instances.
|
|
*/
|
|
protected function updateRenderers():void
|
|
{
|
|
//create axis renderers
|
|
|
|
if(this.horizontalAxisRenderer)
|
|
{
|
|
this.removeChild(DisplayObject(this.horizontalAxisRenderer));
|
|
this.horizontalAxisRenderer = null;
|
|
}
|
|
var RendererClass:Class = this.getStyleValue("horizontalAxisRenderer") as Class;
|
|
this.horizontalAxisRenderer = new RendererClass(AxisOrientation.HORIZONTAL);
|
|
this.addChild(DisplayObject(this.horizontalAxisRenderer));
|
|
this.copyStylesToChild(UIComponent(this.horizontalAxisRenderer), CartesianChart.HORIZONTAL_AXIS_STYLES);
|
|
this.copyStyleObjectToChild(UIComponent(this.horizontalAxisRenderer), this.getStyleValue("horizontalAxisStyles"));
|
|
var horizontalAxisTextFormat:TextFormat = this.getHorizontalAxisStyle("textFormat") as TextFormat;
|
|
if(horizontalAxisTextFormat)
|
|
{
|
|
UIComponent(this.horizontalAxisRenderer).setStyle("textFormat", horizontalAxisTextFormat);
|
|
}
|
|
|
|
if(this.verticalAxisRenderer)
|
|
{
|
|
this.removeChild(DisplayObject(this.verticalAxisRenderer));
|
|
this.verticalAxisRenderer = null;
|
|
}
|
|
RendererClass = this.getStyleValue("verticalAxisRenderer") as Class;
|
|
this.verticalAxisRenderer = new RendererClass(AxisOrientation.VERTICAL);
|
|
this.addChild(DisplayObject(this.verticalAxisRenderer));
|
|
this.copyStylesToChild(UIComponent(verticalAxisRenderer), CartesianChart.VERTICAL_AXIS_STYLES);
|
|
this.copyStyleObjectToChild(UIComponent(this.verticalAxisRenderer), this.getStyleValue("verticalAxisStyles"));
|
|
var verticalAxisTextFormat:TextFormat = this.getVerticalAxisStyle("textFormat") as TextFormat;
|
|
if(verticalAxisTextFormat)
|
|
{
|
|
UIComponent(this.verticalAxisRenderer).setStyle("textFormat", verticalAxisTextFormat);
|
|
}
|
|
|
|
//create grid lines renderers
|
|
|
|
if(this.horizontalGridLines)
|
|
{
|
|
this.removeChild(DisplayObject(this.horizontalGridLines));
|
|
}
|
|
RendererClass = this.getStyleValue("horizontalAxisGridLinesRenderer") as Class;
|
|
this.horizontalGridLines = new RendererClass();
|
|
this.horizontalGridLines.axisRenderer = this.horizontalAxisRenderer;
|
|
this.addChild(DisplayObject(this.horizontalGridLines));
|
|
this.copyStylesToChild(UIComponent(this.horizontalGridLines), CartesianChart.HORIZONTAL_GRID_LINES_STYLES);
|
|
this.copyStyleObjectToChild(UIComponent(this.horizontalGridLines), this.getStyleValue("horizontalAxisGridLinesStyles"));
|
|
|
|
if(this.verticalGridLines)
|
|
{
|
|
this.removeChild(DisplayObject(this.verticalGridLines));
|
|
}
|
|
RendererClass = this.getStyleValue("verticalAxisGridLinesRenderer") as Class;
|
|
this.verticalGridLines = new RendererClass();
|
|
this.verticalGridLines.axisRenderer = this.verticalAxisRenderer;
|
|
this.addChild(DisplayObject(this.verticalGridLines));
|
|
this.copyStylesToChild(UIComponent(this.verticalGridLines), CartesianChart.VERTICAL_GRID_LINES_STYLES);
|
|
this.copyStyleObjectToChild(UIComponent(this.verticalGridLines), this.getStyleValue("verticalAxisGridLinesStyles"));
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Positions and sizes the axes based on their edge metrics.
|
|
*/
|
|
protected function drawAxes():void
|
|
{
|
|
var contentPadding:Number = this.getStyleValue("contentPadding") as Number;
|
|
var axisWidth:Number = this.width - (2 * contentPadding);
|
|
var axisHeight:Number = this.height - (2 * contentPadding);
|
|
|
|
|
|
this.horizontalAxis.renderer = this.horizontalAxisRenderer;
|
|
if(horizontalAxis is CategoryAxis && this._explicitCategoryNames && this._explicitCategoryNames.length > 0)
|
|
{
|
|
CategoryAxis(this.horizontalAxis).categoryNames = this._explicitCategoryNames;
|
|
}
|
|
var horizontalAxisRenderer:UIComponent = UIComponent(this.horizontalAxisRenderer);
|
|
|
|
horizontalAxisRenderer.setSize(axisWidth, axisHeight);
|
|
this.setChildIndex(horizontalAxisRenderer, this.numChildren - 1);
|
|
|
|
this.verticalAxis.renderer = this.verticalAxisRenderer;
|
|
if(verticalAxis is CategoryAxis && this._explicitCategoryNames && this._explicitCategoryNames.length > 0)
|
|
{
|
|
CategoryAxis(this.verticalAxis).categoryNames = this._explicitCategoryNames;
|
|
}
|
|
var verticalAxisRenderer:UIComponent = UIComponent(this.verticalAxisRenderer);
|
|
|
|
verticalAxisRenderer.setSize(axisWidth, axisHeight);
|
|
this.setChildIndex(verticalAxisRenderer, this.numChildren - 1);
|
|
|
|
this.updateAxisScalesAndBounds();
|
|
this.horizontalAxisRenderer.updateAxis();
|
|
this.verticalAxisRenderer.updateAxis();
|
|
|
|
this.drawGridLines();
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Determines the axis scales, and positions the axes based on their
|
|
* <code>contentBounds</code> properties.
|
|
*/
|
|
protected function updateAxisScalesAndBounds():void
|
|
{
|
|
//reset the ticks and minor ticks (start with a clean axis)
|
|
this.horizontalAxisRenderer.ticks = [];
|
|
this.horizontalAxisRenderer.minorTicks = [];
|
|
this.verticalAxisRenderer.ticks = [];
|
|
this.verticalAxisRenderer.minorTicks = [];
|
|
|
|
//Pass series data to the axes
|
|
this._horizontalAxis.dataProvider = this.series;
|
|
this._verticalAxis.dataProvider = this.series;
|
|
|
|
var horizontalAxisTextFormat:TextFormat = this.getHorizontalAxisStyle("textFormat") != null ? this.getHorizontalAxisStyle("textFormat") as TextFormat : this.getStyleValue("textFormat") as TextFormat;
|
|
var verticalAxisTextFormat:TextFormat = this.getVerticalAxisStyle("textFormat") != null ? this.getVerticalAxisStyle("textFormat") as TextFormat : this.getStyleValue("textFormat") as TextFormat;
|
|
|
|
_horizontalAxisLabelData = getHorizontalAxisLabelData();
|
|
_verticalAxisLabelData = getVerticalAxisLabelData();
|
|
|
|
this.horizontalAxis.maxLabelWidth = _horizontalAxisLabelData.maxLabelWidth;
|
|
this.horizontalAxis.maxLabelHeight = _horizontalAxisLabelData.maxLabelHeight;
|
|
|
|
this.verticalAxis.maxLabelWidth = _verticalAxisLabelData.maxLabelWidth;
|
|
this.verticalAxis.maxLabelHeight = _verticalAxisLabelData.maxLabelHeight;
|
|
|
|
this.horizontalAxis.labelSpacing = this.getHorizontalAxisStyle("labelSpacing") as Number;
|
|
this.verticalAxis.labelSpacing = this.getVerticalAxisStyle("labelSpacing") as Number;
|
|
|
|
this.calculateContentBounds();
|
|
|
|
this._horizontalAxis.updateScale();
|
|
this._verticalAxis.updateScale();
|
|
|
|
//Set titles
|
|
this.horizontalAxisRenderer.title = this.horizontalAxis.title;
|
|
this.verticalAxisRenderer.title = this.verticalAxis.title;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Combine the content bounds to determine the series positioning.
|
|
*/
|
|
protected function calculateContentBounds():void
|
|
{
|
|
//calculate axis dimensions
|
|
var contentPadding:Number = this.getStyleValue("contentPadding") as Number;
|
|
var axisWidth:Number = this.width - (2 * contentPadding);
|
|
var axisHeight:Number = this.height - (2 * contentPadding);
|
|
|
|
var verticalTitleWidth:Number = 0;
|
|
var horizontalTitleHeight:Number = 0;
|
|
var verticalAxisTitleDistance:Number = 0;
|
|
var horizontalAxisTitleDistance:Number = 0;
|
|
|
|
//Calculate the dimensions of the title fields.
|
|
if(this.verticalAxis.title != null && this.verticalAxis.title != "")
|
|
{
|
|
verticalTitleWidth = AxisLabelUtil.getTextWidth(this.verticalAxis.title, this.getVerticalAxisStyle("titleTextFormat") as TextFormat, this.getVerticalAxisStyle("titleRotation") as Number);
|
|
verticalAxisTitleDistance = this.getVerticalAxisStyle("titleDistance") as Number;
|
|
}
|
|
|
|
if(this.horizontalAxis.title != null && this.horizontalAxis.title != "")
|
|
{
|
|
horizontalTitleHeight = AxisLabelUtil.getTextHeight(this.horizontalAxis.title, this.getHorizontalAxisStyle("titleTextFormat") as TextFormat, this.getHorizontalAxisStyle("titleRotation") as Number);
|
|
horizontalAxisTitleDistance = this.getHorizontalAxisStyle("titleDistance") as Number;
|
|
}
|
|
|
|
//Calculate the dimensions for the outerTickOffset
|
|
this.horizontalAxisRenderer.outerTickOffset = this.getAxisTickOffset(this.horizontalAxisRenderer) as Number;
|
|
this.verticalAxisRenderer.outerTickOffset = this.getAxisTickOffset(this.verticalAxisRenderer) as Number;
|
|
|
|
this._contentBounds = new Rectangle();
|
|
|
|
var contentBoundsLeftLabelOffset:Number = _horizontalAxisLabelData.leftLabelOffset;
|
|
var contentBoundsRightLabelOffset:Number = _horizontalAxisLabelData.rightLabelOffset;
|
|
|
|
var contentBoundsTopLabelOffset:Number = _verticalAxisLabelData.topLabelOffset;
|
|
var contentBoundsBottomLabelOffset:Number = _verticalAxisLabelData.bottomLabelOffset;
|
|
|
|
//Accomodate for the fact that the category axis is not and origin axis and labels are not plotted at the origin or end of the axis.
|
|
if(this.horizontalAxis is CategoryAxis)
|
|
{
|
|
contentBoundsLeftLabelOffset = contentBoundsLeftLabelOffset/2;
|
|
contentBoundsRightLabelOffset = contentBoundsRightLabelOffset/2;
|
|
}
|
|
|
|
//Accomodate for the fact that the category axis is not and origin axis and labels are not plotted at the origin or end of the axis.
|
|
if(this.verticalAxis is CategoryAxis)
|
|
{
|
|
contentBoundsTopLabelOffset = contentBoundsTopLabelOffset/2;
|
|
contentBoundsBottomLabelOffset = contentBoundsBottomLabelOffset/2;
|
|
}
|
|
|
|
var horizontalAxisLabelDistance:Number = this.getHorizontalAxisStyle("labelDistance") as Number;
|
|
var verticalAxisLabelDistance:Number = this.getVerticalAxisStyle("labelDistance") as Number;
|
|
|
|
this.contentBounds.x = Math.ceil(Math.max((this.verticalAxis.maxLabelWidth + verticalTitleWidth + this.verticalAxisRenderer.outerTickOffset + verticalAxisTitleDistance + verticalAxisLabelDistance), contentBoundsLeftLabelOffset));
|
|
this.contentBounds.y = Math.ceil(contentBoundsTopLabelOffset);
|
|
|
|
this.contentBounds.width = Math.floor(this.width - (this.contentBounds.x + (contentBoundsRightLabelOffset)));
|
|
this.contentBounds.height = Math.floor(this.height - (this.contentBounds.y + Math.max((this.horizontalAxis.maxLabelHeight + horizontalTitleHeight + this.horizontalAxisRenderer.outerTickOffset + horizontalAxisTitleDistance + horizontalAxisLabelDistance), contentBoundsBottomLabelOffset)));
|
|
|
|
this.horizontalAxisRenderer.contentBounds.width = this.contentBounds.width - (contentPadding * 2);
|
|
this.horizontalAxisRenderer.contentBounds.height = this.contentBounds.height - (contentPadding * 2);
|
|
this.verticalAxisRenderer.contentBounds.height = this.contentBounds.height - (contentPadding * 2);
|
|
this.verticalAxisRenderer.contentBounds.width = this.contentBounds.width - (contentPadding * 2);
|
|
|
|
this.horizontalAxisRenderer.contentBounds.x = contentPadding + this.contentBounds.x;
|
|
this.horizontalAxisRenderer.contentBounds.y = contentPadding + this.contentBounds.y;
|
|
this.verticalAxisRenderer.contentBounds.x = contentPadding + this.contentBounds.x;
|
|
this.verticalAxisRenderer.contentBounds.y = contentPadding + this.contentBounds.y;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Returns the amount of distance ticks extend over the edge of the content bounds
|
|
*/
|
|
protected function getAxisTickOffset(axis:ICartesianAxisRenderer):Number
|
|
{
|
|
var showTicks:Boolean = (axis as UIComponent).getStyle("showTicks") as Boolean;
|
|
var showMinorTicks:Boolean = (axis as UIComponent).getStyle("showMinorTicks") as Boolean;
|
|
var tickPosition:String = (axis as UIComponent).getStyle("tickPosition") as String;
|
|
var minorTickPosition:String = (axis as UIComponent).getStyle("minorTickPosition") as String;
|
|
var tickLength:Number = (axis as UIComponent).getStyle("tickLength") as Number;
|
|
var minorTickLength:Number = (axis as UIComponent).getStyle("minorTickLength") as Number;
|
|
var tickBuffer:Number = 0;
|
|
var minorTickBuffer:Number = 0;
|
|
|
|
if(showTicks)
|
|
{
|
|
if(tickPosition == "outside")
|
|
{
|
|
tickBuffer = tickLength;
|
|
}
|
|
else if(tickPosition == "cross")
|
|
{
|
|
tickBuffer = tickLength/2;
|
|
}
|
|
}
|
|
|
|
if(showMinorTicks)
|
|
{
|
|
if(minorTickPosition == "outside")
|
|
{
|
|
minorTickBuffer = minorTickLength;
|
|
}
|
|
else if(minorTickPosition == "cross")
|
|
{
|
|
minorTickBuffer = minorTickLength/2;
|
|
}
|
|
}
|
|
|
|
return Math.max(tickBuffer, minorTickBuffer);
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Draws the axis grid lines, if they exist.
|
|
*/
|
|
protected function drawGridLines():void
|
|
{
|
|
var contentPadding:Number = this.getStyleValue("contentPadding") as Number;
|
|
var horizontalAxisRenderer:UIComponent = this.horizontalAxisRenderer as UIComponent;
|
|
var verticalAxisRenderer:UIComponent = this.verticalAxisRenderer as UIComponent;
|
|
|
|
var index:int = 0;
|
|
if(this.background)
|
|
{
|
|
index++;
|
|
}
|
|
|
|
if(this.horizontalGridLines)
|
|
{
|
|
var horizontalGridLines:UIComponent = this.horizontalGridLines as UIComponent;
|
|
this.setChildIndex(horizontalGridLines, index++);
|
|
horizontalGridLines.x = contentPadding + this.contentBounds.x;
|
|
horizontalGridLines.y = contentPadding + this.contentBounds.y;
|
|
horizontalGridLines.drawNow();
|
|
}
|
|
|
|
if(this.verticalGridLines)
|
|
{
|
|
var verticalGridLines:UIComponent = this.verticalGridLines as UIComponent;
|
|
this.setChildIndex(verticalGridLines, index++);
|
|
verticalGridLines.x = contentPadding + this.contentBounds.x;
|
|
verticalGridLines.y = contentPadding + this.contentBounds.y;
|
|
verticalGridLines.drawNow();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected function setComplexStyle(complexName:String, subStyleName:String, subStyleValue:Object):void
|
|
{
|
|
var container:Object = this.getStyleValue(complexName);
|
|
var copy:Object = {};
|
|
for(var prop:String in container)
|
|
{
|
|
copy[prop] = container[prop];
|
|
}
|
|
copy[subStyleName] = subStyleValue;
|
|
this.setStyle(complexName, copy);
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected function copyStyleObjectToChild(child:UIComponent, styles:Object):void
|
|
{
|
|
if(!child)
|
|
{
|
|
return;
|
|
}
|
|
|
|
for(var prop:String in styles)
|
|
{
|
|
child.setStyle(prop, styles[prop]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected function axisAndSeriesToField(axis:IAxis, series:ISeries):String
|
|
{
|
|
var cartesianSeries:CartesianSeries = series as CartesianSeries;
|
|
var field:String = this.axisToField(axis);
|
|
var renderer:ICartesianAxisRenderer = this.axisToAxisRenderer(axis);
|
|
if(renderer.orientation == AxisOrientation.VERTICAL && cartesianSeries.verticalField)
|
|
{
|
|
field = cartesianSeries.verticalField;
|
|
}
|
|
else if(renderer.orientation == AxisOrientation.HORIZONTAL && cartesianSeries.horizontalField)
|
|
{
|
|
field = cartesianSeries.horizontalField;
|
|
}
|
|
|
|
return field;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected function axisToField(axis:IAxis):String
|
|
{
|
|
if(axis == this.horizontalAxis)
|
|
{
|
|
return this.horizontalField;
|
|
}
|
|
else if(axis == this.verticalAxis)
|
|
{
|
|
return this.verticalField;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
*/
|
|
protected function fieldToAxis(field:String):IAxis
|
|
{
|
|
if(field == this.horizontalField)
|
|
{
|
|
return this.horizontalAxis;
|
|
}
|
|
else if(field == this.verticalField)
|
|
{
|
|
return this.verticalAxis;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Finds the renderer for the specified axis.
|
|
*/
|
|
protected function axisToAxisRenderer(axis:IAxis):ICartesianAxisRenderer
|
|
{
|
|
if(axis == this.horizontalAxis)
|
|
{
|
|
return this.horizontalAxisRenderer;
|
|
}
|
|
else if(axis == this.verticalAxis)
|
|
{
|
|
return this.verticalAxisRenderer;
|
|
}
|
|
return null;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Returns an object containing values necessary for rendering labels on an axis based on the
|
|
* text, format and rotation of the labels.
|
|
*/
|
|
private function getHorizontalAxisLabelData():Object
|
|
{
|
|
var labelData:Object = {};
|
|
var label:BitmapText = new BitmapText();
|
|
label.embedFonts = this.getHorizontalAxisStyle("embedFonts") as Boolean;
|
|
var rotation:Number = this.getHorizontalAxisStyle("labelRotation") as Number;
|
|
var textFormat:TextFormat = this.getHorizontalAxisStyle("textFormat") != null ? this.getHorizontalAxisStyle("textFormat") as TextFormat : this.getStyleValue("textFormat") as TextFormat
|
|
rotation = Math.max(-90, Math.min(rotation, 90));
|
|
label.selectable = false;
|
|
label.autoSize = TextFieldAutoSize.LEFT;
|
|
if(textFormat != null) label.defaultTextFormat = textFormat;
|
|
label.text = (this.horizontalAxis as IAxis).getMaxLabel() as String;
|
|
label.rotation = rotation;
|
|
var adjustedWidth:Number;
|
|
var leftTextOverflow:Number;
|
|
var rightTextOverflow:Number;
|
|
var adjustedHeight:Number;
|
|
|
|
if(rotation == 0 || Math.abs(rotation) == 90)
|
|
{
|
|
adjustedWidth = label.width;
|
|
adjustedHeight = label.height;
|
|
leftTextOverflow = label.width/2;
|
|
rightTextOverflow = label.width/2;
|
|
}
|
|
else
|
|
{
|
|
var rad:Number = rotation * Math.PI/180;
|
|
adjustedHeight = (Math.sin(Math.abs(rad)) * label.contentWidth) + (Math.cos(Math.abs(rad)) * label.contentHeight);
|
|
|
|
if(rotation > 0)
|
|
{
|
|
leftTextOverflow = label.contentHeight * Math.sin(rotation * Math.PI/180)/2;
|
|
rightTextOverflow = (Math.cos(Math.abs(rad)) * label.contentWidth) + (label.contentHeight * Math.sin(Math.abs(rad)))/2;
|
|
}
|
|
else
|
|
{
|
|
leftTextOverflow = Math.cos(Math.abs(rad)) * label.contentWidth;
|
|
rightTextOverflow = label.contentHeight * Math.abs(Math.sin(rotation * Math.PI/180)/2);
|
|
}
|
|
}
|
|
|
|
labelData.maxLabelWidth = label.rotationWidth;
|
|
labelData.leftLabelOffset = leftTextOverflow;
|
|
labelData.rightLabelOffset = rightTextOverflow;
|
|
labelData.maxLabelHeight = adjustedHeight;
|
|
|
|
return labelData;
|
|
}
|
|
|
|
/**
|
|
* @private
|
|
* Returns an object containing values necessary for rendering labels on an axis based on the
|
|
* text, format and rotation of the labels.
|
|
*/
|
|
private function getVerticalAxisLabelData():Object
|
|
{
|
|
var labelData:Object = {};
|
|
var label:BitmapText = new BitmapText();
|
|
label.embedFonts = this.getVerticalAxisStyle("embedFonts") as Boolean;
|
|
var rotation:Number = this.getVerticalAxisStyle("labelRotation") as Number;
|
|
var textFormat:TextFormat = this.getVerticalAxisStyle("textFormat")!= null ? this.getVerticalAxisStyle("textFormat") as TextFormat : this.getStyleValue("textFormat") as TextFormat
|
|
rotation = Math.max(-90, Math.min(rotation, 90));
|
|
label.selectable = false;
|
|
label.autoSize = TextFieldAutoSize.LEFT;
|
|
if(textFormat != null) label.defaultTextFormat = textFormat;
|
|
label.text = (this.verticalAxis as IAxis).getMaxLabel() as String;
|
|
label.rotation = rotation;
|
|
|
|
var adjustedHeight:Number;
|
|
var adjustedWidth:Number;
|
|
var topTextOverflow:Number;
|
|
var bottomTextOverflow:Number;
|
|
|
|
if(rotation == 0 || Math.abs(rotation) == 90)
|
|
{
|
|
adjustedHeight = label.height;
|
|
adjustedWidth = label.width;
|
|
topTextOverflow = label.height/2;
|
|
bottomTextOverflow = label.height/2;
|
|
}
|
|
else
|
|
{
|
|
var rad:Number = rotation * Math.PI/180;
|
|
adjustedWidth = (Math.cos(Math.abs(rad)) * label.contentWidth) + (label.contentHeight * Math.sin(Math.abs(rad)))/2;
|
|
|
|
if(rotation > 0)
|
|
{
|
|
topTextOverflow = label.height - .5 * Math.abs(label.contentHeight*Math.cos(rotation*Math.PI/180));
|
|
bottomTextOverflow = label.contentHeight/2 * Math.cos((Math.abs(rotation)) * Math.PI/180);
|
|
}
|
|
else
|
|
{
|
|
topTextOverflow = label.contentHeight/2 * Math.cos((Math.abs(rotation)) * Math.PI/180);
|
|
bottomTextOverflow = label.height - .5 * Math.abs(label.contentHeight*Math.cos(rotation*Math.PI/180));
|
|
}
|
|
}
|
|
labelData.maxLabelWidth = adjustedWidth;
|
|
labelData.topLabelOffset = topTextOverflow;
|
|
labelData.bottomLabelOffset = bottomTextOverflow;
|
|
labelData.maxLabelHeight = label.rotationHeight;
|
|
return labelData;
|
|
}
|
|
}
|
|
}
|