blob: 8e4c9c1528d6b02d2ec8532ab0d8999a47ba74b7 [file] [log] [blame]
////////////////////////////////////////////////////////////////////////////////
//
// Licensed to the Apache Software Foundation (ASF) under one or more
// contributor license agreements. See the NOTICE file distributed with
// this work for additional information regarding copyright ownership.
// The ASF licenses this file to You under the Apache License, Version 2.0
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////
package mx.charts.chartClasses
{
import flash.display.Graphics;
import flash.geom.Rectangle;
import mx.charts.DateTimeAxis;
import mx.charts.HitData;
import mx.charts.series.items.HLOCSeriesItem;
import mx.charts.series.renderData.HLOCSeriesRenderData;
import mx.collections.CursorBookmark;
import mx.core.IDataRenderer;
import mx.core.IFactory;
import mx.core.IFlexDisplayObject;
import mx.core.mx_internal;
import mx.graphics.IStroke;
import mx.styles.ISimpleStyleClient;
import mx.resources.IResourceManager;
import mx.charts.series.CandlestickSeries;
import flash.geom.Point;
import mx.charts.chartClasses.IAxis;
use namespace mx_internal;
//--------------------------------------
// Styles
//--------------------------------------
include "../styles/metadata/ItemRendererStyles.as"
[ResourceBundle("charts")]
/**
* HLOCSeriesBase is the base class for the two financial series types,
* HLOCSeries and CandlestickSeries.
* Most of the behavior related to charting open, close, high and low values
* resides in this class.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public class HLOCSeriesBase extends Series implements IColumn
{
include "../../core/Version.as";
//--------------------------------------------------------------------------
//
// Constructor
//
//--------------------------------------------------------------------------
/**
* Constructor.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function HLOCSeriesBase()
{
super();
_instanceCache = new InstanceCache(null, this);
_instanceCache.properties = { styleName: this };
dataTransform = new CartesianTransform();
}
//--------------------------------------------------------------------------
//
// Variables
//
//--------------------------------------------------------------------------
/**
* @private
*/
private var _instanceCache:InstanceCache;
/**
* @private
*/
mx_internal var _renderData:HLOCSeriesRenderData;
//--------------------------------------------------------------------------
//
// Properties
//
//--------------------------------------------------------------------------
//----------------------------------
// closeField
//----------------------------------
/**
* @private
* Storage for the closeField property.
*/
private var _closeField:String = "";
[Inspectable(category="General")]
/**
* Specifies the field of the data provider that determines
* the y-axis location of the closing value of the element.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get closeField():String
{
return _closeField;
}
/**
* @private
*/
public function set closeField(value:String):void
{
_closeField = value;
dataChanged();
}
//----------------------------------
// columnWidthRatio
//----------------------------------
/**
* @private
* Storage for the columnWidthRatio property.
*/
private var _columnWidthRatio:Number = 0.65;
[Inspectable(category="General", defaultValue="0.65")]
/**
* Specifies the width of elements relative to the category width.
* A value of <code>1</code> uses the entire space, while a value
* of <code>0.6</code> uses 60% of the element's available space.
* You typically do not set this property directly.
* The actual element width used is the smaller of the
* <code>columnWidthRatio</code> and <code>maxColumnWidth</code>
* properties.
*
* @default 0.65.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get columnWidthRatio():Number
{
return _columnWidthRatio;
}
/**
* @private
*/
public function set columnWidthRatio(value:Number):void
{
_columnWidthRatio = value;
invalidateTransform();
}
//----------------------------------
// highField
//----------------------------------
/**
* @private
* Storage for the highField property.
*/
private var _highField:String = "";
[Inspectable(category="General")]
/**
* Specifies the field of the data provider that determines
* the y-axis location of the high value of the element.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get highField():String
{
return _highField;
}
/**
* @private
*/
public function set highField(value:String):void
{
_highField = value;
dataChanged();
}
//----------------------------------
// horizontalAxis
//----------------------------------
/**
* @private
* Storage for the horizontalAxis property.
*/
private var _horizontalAxis:IAxis;
[Inspectable(category="Data")]
/**
* Defines the labels, tick marks, and data position
* for items on the x-axis.
* Use either the LinearAxis class or the CategoryAxis class
* to set the properties of the horizontalAxis as a child tag in MXML
* or create a LinearAxis or CategoryAxis object in ActionScript.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get horizontalAxis():IAxis
{
return _horizontalAxis;
}
/**
* @private
*/
public function set horizontalAxis(value:IAxis):void
{
_horizontalAxis = value;
_bAxesDirty = true;
invalidateData();
invalidateProperties();
}
//----------------------------------
// items
//----------------------------------
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function get items():Array /* of HLOCSeriesItem */
{
return _renderData ? _renderData.filteredCache : null;
}
//----------------------------------
// itemType
//----------------------------------
/**
* The subtype of ChartItem used by this series
* to represent individual items.
* Subclasses can override and return a more specialized class
* if they need to store additional information in the items.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get itemType():Class
{
return HLOCSeriesItem;
}
//----------------------------------
// lowField
//----------------------------------
/**
* @private
* Storage for the lowField property.
*/
private var _lowField:String = "";
[Inspectable(category="General")]
/**
* Specifies the field of the data provider that determines
* the y-axis location of the low value of the element.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get lowField():String
{
return _lowField;
}
/**
* @private
*/
public function set lowField(value:String):void
{
_lowField = value;
dataChanged();
}
//----------------------------------
// maxColumnWidth
//----------------------------------
/**
* @private
* Storage for the maxColumnWidth property.
*/
private var _maxColumnWidth:Number;
[Inspectable(category="General")]
/**
* Specifies the width of the elements, in pixels.
* The actual element width used is the smaller of this style
* and the <code>columnWidthRatio</code> property.
* You typically do not set this value directly;
* it is assigned by the enclosing chart.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get maxColumnWidth():Number
{
return _maxColumnWidth;
}
/**
* @private
*/
public function set maxColumnWidth(value:Number):void
{
_maxColumnWidth = value;
invalidateTransform();
}
//----------------------------------
// offset
//----------------------------------
/**
* @private
* Storage for the offset property.
*/
private var _offset:Number = 0;
[Inspectable(category="General", defaultValue="0")]
/**
* Specifies how far to offset the center of the elements
* from the center of the available space,
* relative to the category width.
* At the value of default <code>0</code>,
* the elements are centered on the space.
* Set to <code>-50</code> to center the element
* at the beginning of the available space.
* You typically do not set this property directly.
* The enclosing chart control manages this value based on
* the value of its <code>columnWidthRatio</code> property.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get offset():Number
{
return _offset;
}
/**
* @private
*/
public function set offset(value:Number):void
{
_offset = value;
invalidateTransform();
}
//----------------------------------
// openField
//----------------------------------
/**
* @private
* Storage for the openField property.
*/
mx_internal var _openField:String = "";
[Inspectable(category="General")]
/**
* Specifies the field of the data provider that determines
* the y-axis location of the opening value of the element.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get openField():String
{
return _openField;
}
/**
* @private
*/
public function set openField(value:String):void
{
_openField = value;
dataChanged();
}
//----------------------------------
// renderDataType
//----------------------------------
/**
* The subtype of ChartRenderData used by this series
* to store all data necessary to render.
* Subclasses can override and return a more specialized class
* if they need to store additional information for rendering.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function get renderDataType():Class
{
return HLOCSeriesRenderData;
}
private var _bAxesDirty:Boolean = false;
//----------------------------------
// verticalAxis
//----------------------------------
/**
* @private
* Storage for the verticalAxis property.
*/
private var _verticalAxis:IAxis;
[Inspectable(category="Data")]
/**
* Defines the labels, tick marks, and data position
* for items on the y-axis.
* Use either the LinearAxis class or the CategoryAxis class
* to set the properties of the horizontalAxis as a child tag in MXML
* or create a LinearAxis or CategoryAxis object in ActionScript.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get verticalAxis():IAxis
{
return _verticalAxis;
}
/**
* @private
*/
public function set verticalAxis(value:IAxis):void
{
_verticalAxis = value;
_bAxesDirty = true;
invalidateData();
//invalidateChildOrder();
invalidateProperties();
}
//----------------------------------
// xField
//----------------------------------
/**
* @private
* Storage for the xField property.
*/
private var _xField:String = "";
[Inspectable(category="General")]
/**
* Specifies the field of the data provider that determines
* the x-axis location of the element.
* If set to the empty string (<code>""</code>),
* Flex renders the columns in the order they appear in the dataProvider.
*
* @default ""
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
public function get xField():String
{
return _xField;
}
/**
* @private
*/
public function set xField(value:String):void
{
_xField = value;
dataChanged();
}
//--------------------------------------------------------------------------
//
// Overridden methods: Series
//
//--------------------------------------------------------------------------
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function updateData():void
{
var renderDataType:Class = this.renderDataType;
_renderData = new renderDataType();
_renderData.cache = [];
var i:int = 0;
var itemClass:Class = itemType;
if (cursor)
{
cursor.seek(CursorBookmark.FIRST);
while (!cursor.afterLast)
{
_renderData.cache[i] = new itemClass(this, cursor.current, i);
i++;
cursor.moveNext();
}
}
cacheIndexValues(_xField, _renderData.cache, "xValue");
cacheDefaultValues(_highField, _renderData.cache, "highValue");
cacheNamedValues(_lowField, _renderData.cache,
"lowValue");
if (_openField != "")
cacheNamedValues(_openField, _renderData.cache, "openValue");
cacheNamedValues(_closeField, _renderData.cache, "closeValue");
if(dataTransform && dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS) is NumericAxis &&
!(dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS) is DateTimeAxis) &&
(dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS) as NumericAxis).direction == "inverted")
_renderData.cache = reverseYValues(_renderData.cache);
if(dataTransform && dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS) is NumericAxis &&
!(dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS) is DateTimeAxis) &&
(dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS) as NumericAxis).direction == "inverted")
_renderData.cache = reverseXValues(_renderData.cache);
super.updateData();
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function updateMapping():void
{
dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).
mapCache(_renderData.cache, "xValue", "xNumber", _xField == "");
var yAxis:IAxis = dataTransform.getAxis(
CartesianTransform.VERTICAL_AXIS);
yAxis.mapCache(_renderData.cache, "lowValue", "lowNumber");
yAxis.mapCache(_renderData.cache, "highValue", "highNumber");
if (_openField != "")
yAxis.mapCache(_renderData.cache, "openValue", "openNumber");
yAxis.mapCache(_renderData.cache, "closeValue", "closeNumber");
super.updateMapping();
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function updateFilter():void
{
_renderData.filteredCache = filterFunction(_renderData.cache);
super.updateFilter();
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function updateTransform():void
{
dataTransform.transformCache(_renderData.filteredCache,
"xNumber", "x", "highNumber", "high");
dataTransform.transformCache(_renderData.filteredCache,
null, null, "highNumber", "high");
dataTransform.transformCache(_renderData.filteredCache,
null, null, "lowNumber", "low");
if (_openField != "")
{
dataTransform.transformCache(_renderData.filteredCache,
null, null, "openNumber", "open");
}
dataTransform.transformCache(_renderData.filteredCache,
null, null, "closeNumber", "close");
var unitSize:Number = dataTransform.getAxis(
CartesianTransform.HORIZONTAL_AXIS).unitSize
var params:Array /* of Object */ =
[
{ xNumber: 0 },
{ xNumber: _columnWidthRatio * unitSize / 2 },
{ xNumber: _offset * unitSize }
];
dataTransform.transformCache(params, "xNumber", "x", null, null);
_renderData.renderedHalfWidth = params[1].x - params[0].x;
if (_offset == 0)
_renderData.renderedXOffset = 0;
else
_renderData.renderedXOffset = params[2].x - params[0].x;
if (!isNaN(_maxColumnWidth) &&
_maxColumnWidth < _renderData.renderedHalfWidth)
{
_renderData.renderedXOffset *= _maxColumnWidth /
_renderData.renderedHalfWidth;
_renderData.renderedHalfWidth = _maxColumnWidth;
}
super.updateTransform();
allSeriesTransform = true;
if (chart && chart is CartesianChart)
{
var cChart:CartesianChart = CartesianChart(chart);
var n:int = cChart.series.length;
for (var i:int = 0; i < n; i++)
{
if (cChart.getSeriesTransformState(cChart.series[i]))
allSeriesTransform = false;
}
if (allSeriesTransform)
cChart.measureLabels();
}
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function commitProperties():void
{
super.commitProperties();
if (dataTransform)
{
if (_horizontalAxis)
{
_horizontalAxis.chartDataProvider = dataProvider;
CartesianTransform(dataTransform).setAxis(
CartesianTransform.HORIZONTAL_AXIS,_horizontalAxis);
}
if (_verticalAxis)
{
_verticalAxis.chartDataProvider = dataProvider;
CartesianTransform(dataTransform).setAxis(
CartesianTransform.VERTICAL_AXIS, _verticalAxis);
}
}
var c:CartesianChart = CartesianChart(chart);
if (c)
{
if (!_horizontalAxis)
{
if (dataTransform.axes[CartesianTransform.HORIZONTAL_AXIS] != c.horizontalAxis)
CartesianTransform(dataTransform).setAxis(
CartesianTransform.HORIZONTAL_AXIS,c.horizontalAxis);
}
if (!_verticalAxis)
{
if (dataTransform.axes[CartesianTransform.VERTICAL_AXIS] != c.verticalAxis)
CartesianTransform(dataTransform).setAxis(
CartesianTransform.VERTICAL_AXIS, c.verticalAxis);
}
}
dataTransform.elements = [this];
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function updateDisplayList(unscaledWidth:Number,
unscaledHeight:Number):void
{
super.updateDisplayList(unscaledWidth, unscaledHeight);
if (!dataTransform)
return;
var g:Graphics = graphics;
g.clear();
if (!isNaN(_maxColumnWidth) &&
(_maxColumnWidth <= 0 || _columnWidthRatio <= 0))
{
return;
}
var renderData:HLOCSeriesRenderData =
transitionRenderData == null ?
_renderData :
HLOCSeriesRenderData(transitionRenderData);
var renderCache:Array /* of HLOCSeriesItem */ = renderData.filteredCache;
var i:int;
var sampleCount:int = renderCache.length;
var rc:Rectangle;
var instances:Array /* of IFlexDisplayObject */;
var inst:IFlexDisplayObject;
var v:HLOCSeriesItem;
_instanceCache.factory = getStyle("itemRenderer");
_instanceCache.count = sampleCount;
instances = _instanceCache.instances;
var bSetData:Boolean = sampleCount > 0 &&
(instances[0] is IDataRenderer);
if (transitionRenderData &&
transitionRenderData.elementBounds)
{
var elementBounds:Array /* of Rectangle */ = transitionRenderData.elementBounds;
for (i = 0; i < sampleCount; i++)
{
inst = instances[i];
v = renderCache[i];
v.itemRenderer = inst;
if (this is CandlestickSeries)
{
v.fill = CandlestickSeries(this).fillFunction(v,i);
if (!(v.fill))
v.fill = CandlestickSeries(this).defaultFillFunction(v,i);
if ((v.itemRenderer as Object).hasOwnProperty('invalidateDisplayList'))
(v.itemRenderer as Object).invalidateDisplayList();
}
if (bSetData)
(inst as IDataRenderer).data = v;
rc = elementBounds[i];
inst.move(rc.left, rc.top);
inst.setActualSize(rc.width, rc.height);
}
}
else
{
var ro:Number = renderData.renderedHalfWidth +
renderData.renderedXOffset;
var lo:Number = -renderData.renderedHalfWidth +
renderData.renderedXOffset;
rc = new Rectangle();
var considerOpen:Boolean = _openField != "";
for (i = 0; i < sampleCount; i++)
{
v = renderCache[i];
rc.left = v.x + lo;
rc.right = v.x + ro;
rc.top = Math.min(v.high,Math.min(v.low,v.close));
if (considerOpen)
rc.top = Math.min(rc.top,v.open);
rc.bottom = Math.max(v.high,Math.max(v.low,v.close));
if (considerOpen)
rc.bottom = Math.max(rc.bottom,v.close);
inst = instances[i];
v.itemRenderer = inst;
if (this is CandlestickSeries)
{
v.fill = CandlestickSeries(this).fillFunction(v,i);
if (!(v.fill))
v.fill = CandlestickSeries(this).defaultFillFunction(v,i);
if ((v.itemRenderer as Object).hasOwnProperty('invalidateDisplayList'))
(v.itemRenderer as Object).invalidateDisplayList();
}
if (bSetData)
(inst as IDataRenderer).data = v
inst.move(rc.left,rc.top);
inst.setActualSize(rc.width,rc.height);
}
if (chart && allSeriesTransform && chart.chartState == 0)
chart.updateAllDataTips();
}
}
/**
* @private
*/
override public function dataToLocal(... dataValues):Point
{
var data:Object = {};
var da:Array /* of Object */ = [ data ];
var n:int = dataValues.length;
if (n > 0)
{
data["d0"] = dataValues[0];
dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).
mapCache(da, "d0", "v0");
}
if (n > 1)
{
data["d1"] = dataValues[1];
dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).
mapCache(da, "d1", "v1");
}
dataTransform.transformCache(da,"v0","s0","v1","s1");
return new Point(data.s0 + this.x,
data.s1 + this.y);
}
/**
* @private
*/
override public function localToData(v:Point):Array /* of Object */
{
var values:Array /* of Object */ = dataTransform.invertTransform(
v.x - this.x,
v.y - this.y);
return values;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function getItemsInRegion(r:Rectangle):Array /* of HLOCSeriesItem */
{
if (interactive == false || !_renderData)
return [];
var arrItems:Array /* of HLOCSeriesItem */ = [];
var rc:Rectangle = new Rectangle();
var localRectangle:Rectangle = new Rectangle();
var n:uint = _renderData.filteredCache.length;
var considerOpen:Boolean = _openField != "";
localRectangle.topLeft = globalToLocal(r.topLeft);
localRectangle.bottomRight = globalToLocal(r.bottomRight);
for (var i:int=0; i < n; i++)
{
var v:HLOCSeriesItem = _renderData.filteredCache[i];
var ro:Number = renderData.renderedHalfWidth + renderData.renderedXOffset;
var lo:Number = -renderData.renderedHalfWidth + renderData.renderedXOffset;
rc.left = v.x + lo;
rc.right = v.x + ro;
rc.top = Math.min(v.high,Math.min(v.low,v.close));
if (considerOpen)
rc.top = Math.min(rc.top,v.open);
rc.bottom = Math.max(v.high,Math.max(v.low,v.close));
if (considerOpen)
rc.bottom = Math.max(rc.bottom,v.close);
// Handle cases when width and height are -ve.
if (rc.right < rc.left || rc.bottom < rc.top)
{
var rcTemp:Rectangle = new Rectangle(rc.x,rc.y,rc.width,rc.height);
if (rc.right < rc.left)
{
rcTemp.left = rc.right;
rcTemp.right = rc.left;
}
if (rc.bottom < rc.top)
{
rcTemp.top = rc.bottom;
rcTemp.bottom = rc.top;
}
rc = rcTemp;
}
if (rc.intersects(localRectangle))
arrItems.push(v);
}
return arrItems;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function describeData(dimension:String,
requiredFields:uint):Array /* of DataDescription */
{
validateData();
if (_renderData.cache.length == 0)
return [];
var description:DataDescription = new DataDescription();
description.boundedValues = null;
if (dimension == CartesianTransform.VERTICAL_AXIS)
{
extractMinMax(_renderData.cache, "highNumber", description);
extractMinMax(_renderData.cache, "lowNumber", description);
}
else if (dimension == CartesianTransform.HORIZONTAL_AXIS)
{
if (_xField != "")
{
if ((requiredFields &
DataDescription.REQUIRED_MIN_INTERVAL) != 0)
{
// If we need to know the min interval,
// then we rely on the cache being in order.
// So we need to sort it if it hasn't already been sorted.
var sortedCache:Array /* of HLOCSeriesItem */ = _renderData.cache.concat();
sortedCache.sortOn("xNumber", Array.NUMERIC);
extractMinMax(sortedCache, "xNumber", description,
(requiredFields &
DataDescription.REQUIRED_MIN_INTERVAL) != 0);
}
else
{
extractMinMax(_renderData.cache, "xNumber", description,
(requiredFields &
DataDescription.REQUIRED_MIN_INTERVAL) != 0);
}
}
else
{
description.min = _renderData.cache[0].xNumber;
description.max =
_renderData.cache[_renderData.cache.length - 1].xNumber;
if ((requiredFields &
DataDescription.REQUIRED_MIN_INTERVAL) != 0)
{
extractMinInterval(_renderData.cache, "xNumber",
description);
}
}
description.padding = 0.5;
}
else
{
return [];
}
return [ description ];
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function get legendData():Array /* of LegendData */
{
var ld:LegendData = new LegendData();
var marker:IFlexDisplayObject;
ld.element = this;
var markerClass:IFactory = getStyle("legendMarkerRenderer");
if (!markerClass)
markerClass = getStyle("itemRenderer");
if (markerClass)
{
marker = markerClass.newInstance();
if (marker as ISimpleStyleClient)
(marker as ISimpleStyleClient).styleName = this;
}
ld.marker = marker;
ld.label = displayName;
return [ ld ];
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function styleChanged(styleProp:String):void
{
super.styleChanged(styleProp);
var styles:String = "stroke fill";
if (styleProp == null ||
styleProp == "" ||
styles.indexOf(styleProp) != -1)
{
invalidateDisplayList();
legendDataChanged();
}
if (styleProp == "itemRenderer")
{
_instanceCache.remove = true;
_instanceCache.discard = true;
_instanceCache.count = 0;
_instanceCache.discard = false;
_instanceCache.remove = false;
}
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function get renderData():Object
{
if (!_renderData)
{
var renderDataType:Class = this.renderDataType;
var rv:HLOCSeriesRenderData = new renderDataType();
rv.cache = rv.filteredCache = [];
rv.renderedHalfWidth = 0;
rv.renderedXOffset = 0;
return rv;
}
return _renderData;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function beginInterpolation(sourceRenderData:Object,
destRenderData:Object):Object
{
var interpFields:Object =
{ x: true, high: true, low: true, close: true };
if (_openField != "")
interpFields.open = true;
var idata:Object = initializeInterpolationData(
sourceRenderData.cache, destRenderData.cache,
interpFields, itemType,
{ sourceRenderData: sourceRenderData,
destRenderData: destRenderData });
var interpolationRenderData:HLOCSeriesRenderData =
HLOCSeriesRenderData(destRenderData.clone());
interpolationRenderData.cache = idata.cache;
interpolationRenderData.filteredCache = idata.cache;
transitionRenderData = interpolationRenderData;
return idata;
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override protected function getMissingInterpolationValues(
sourceProps:Object, srcCache:Array /* of HLOCSeriesItem */,
destProps:Object, destCache:Array /* of HLOCSeriesItem */,
index:Number, customData:Object):void
{
for (var p:String in sourceProps)
{
var src:Number = sourceProps[p];
var dst:Number = destProps[p];
if (p == "high" || p == "low" ||
p == "open" || p == "close")
{
if (isNaN(src))
src = unscaledHeight;
if (isNaN(dst))
dst = unscaledHeight;
}
else if (p == "x")
{
if (isNaN(src))
src = dst;
if (isNaN(dst))
dst = src;
}
sourceProps[p] = src;
destProps[p] = dst;
}
}
/**
* @inheritDoc
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
override public function getElementBounds(renderData:Object):void
{
var cache :Array /* of HLOCSeriesItem */ = renderData.filteredCache;
var rb :Array /* of Rectangle */ = [];
var sampleCount:int = cache.length;
if (sampleCount)
{
var ro:Number = renderData.renderedHalfWidth +
renderData.renderedXOffset;
var lo:Number = -renderData.renderedHalfWidth +
renderData.renderedXOffset;
var v:HLOCSeriesItem = cache[0];
var maxBounds:Rectangle = new Rectangle(v.x, v.low, 0, 0);
for (var i:int = 0; i < sampleCount; i++)
{
v = cache[i];
var top:Number = Math.min(v.high, v.low);
var b:Rectangle = new Rectangle(
v.x + lo, top, ro - lo, Math.max(v.high, v.low) - top);
maxBounds.left = Math.min(maxBounds.left, b.left);
maxBounds.top = Math.min(maxBounds.top, b.top);
maxBounds.right = Math.max(maxBounds.right, b.right);
maxBounds.bottom = Math.max(maxBounds.bottom, b.bottom);
rb[i] = b;
}
}
else
{
maxBounds = new Rectangle();
}
renderData.elementBounds = rb;
renderData.bounds = maxBounds;
}
/**
* @private
*/
override protected function defaultFilterFunction(cache:Array /*of HLOCSeriesItem */ ):Array /*of HLOCSeriesItem*/
{
var filteredCache:Array /*of HLOCSeriesItem*/ = [];
if (filterDataValues == "outsideRange")
{
filteredCache = cache.concat();
dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).
filterCache(filteredCache, "xNumber", "xFilter");
var yAxis:IAxis = dataTransform.getAxis(
CartesianTransform.VERTICAL_AXIS);
yAxis.filterCache(filteredCache,
"lowNumber", "lowFilter");
yAxis.filterCache(filteredCache,
"highNumber", "highFilter");
if (_openField != "")
{
yAxis.filterCache(filteredCache,
"openNumber", "openFilter");
}
yAxis.filterCache(filteredCache,
"closeNumber", "closeFilter");
stripNaNs(filteredCache, "xFilter");
stripNaNs(filteredCache, "lowFilter");
stripNaNs(filteredCache, "highFilter");
if (_openField != "")
stripNaNs(filteredCache, "openFilter");
stripNaNs(filteredCache, "closeFilter");
}
else if (filterDataValues == "nulls")
{
filteredCache = cache.concat();
stripNaNs(filteredCache, "xNumber");
stripNaNs(filteredCache, "lowNumber");
stripNaNs(filteredCache, "highNumber");
if (_openField != "")
stripNaNs(filteredCache, "openNumber");
stripNaNs(filteredCache, "closeNumber");
}
else if (filterDataValues == "none")
{
filteredCache = cache;
}
return filteredCache;
}
//-------------------------------------------------------------------------------
//
// Methods
//
//-------------------------------------------------------------------------------
/**
* Generates a text description of a ChartItem
* suitable for display as a DataTip.
*
* @param hd The HitData for the ChartItem.
*
* @return The item's DataTip.
*
* @langversion 3.0
* @playerversion Flash 9
* @playerversion AIR 1.1
* @productversion Flex 3
*/
protected function formatDataTip(hd:HitData):String
{
var openString:String = resourceManager.getString("charts", "open");
var closeString:String = resourceManager.getString("charts", "close");
var highString:String = resourceManager.getString("charts", "high");
var lowString:String = resourceManager.getString("charts", "low");
var dt:String = "";
var n:String = displayName;
if (n != null && n.length>0)
dt += "<B>" + n + "</B><BR/>";
var xName:String = dataTransform.getAxis(
CartesianTransform.HORIZONTAL_AXIS).displayName;
if (xName != "")
dt += "<I>" + xName + ":</I> ";
dt += dataTransform.getAxis(CartesianTransform.HORIZONTAL_AXIS).
formatForScreen(HLOCSeriesItem(hd.chartItem).xValue) + "\n";
var yName:String = dataTransform.getAxis(
CartesianTransform.VERTICAL_AXIS).displayName;
if (_openField != "")
{
if (yName != "")
dt += "<I>" + yName + " (" + openString + "):</I> ";
else
dt += "<I>" + openString + ":</I> ";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).
formatForScreen(HLOCSeriesItem(hd.chartItem).openValue) + "\n";
}
if (yName != "")
dt += "<I>" + yName + " (" + closeString + "):</I> ";
else
dt += "<I>" + closeString + ":</I> ";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).
formatForScreen(HLOCSeriesItem(hd.chartItem).closeValue) + "\n";
if (yName != "")
dt += "<I>" + yName + " (" + highString + "):</I> ";
else
dt += "<I>" + highString + ":</I> ";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).
formatForScreen(HLOCSeriesItem(hd.chartItem).highValue) + "\n";
if (yName != "")
dt += "<I>" + yName + " (" + lowString + "):</I> ";
else
dt += "<I>" + lowString + ":</I> ";
dt += dataTransform.getAxis(CartesianTransform.VERTICAL_AXIS).
formatForScreen(HLOCSeriesItem(hd.chartItem).lowValue) + "\n";
return dt;
}
private function reverseYValues(cache:Array):Array
{
var i:int = 0;
var n:int = cache.length;
for(i = 0; i < n ; i++)
{
cache[i]["highValue"] = -(cache[i]["highValue"]);
cache[i]["lowValue"] = -(cache[i]["lowValue"]);
if(_openField != "")
cache[i]["openValue"] = -(cache[i]["openValue"]);
cache[i]["closeValue"] = -(cache[i]["closeValue"]);
}
return cache;
}
private function reverseXValues(cache:Array):Array
{
var i:int = 0;
var n:int = cache.length;
for(i = 0; i < n ; i++)
{
cache[i]["xValue"] = -(cache[i]["xValue"]);
}
return cache;
}
}
}