WindTheBusiness/com/yahoo/astra/fl/charts/axes/RadialAxisRenderer.as
2020-10-20 00:58:15 +02:00

273 lines
7.3 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.axes
{
import com.yahoo.astra.utils.GeomUtil;
import com.yahoo.astra.utils.NumberUtil;
import fl.core.UIComponent;
import flash.geom.Point;
//TODO: Add support for labels.
/**
* The default axis renderer for radial axes.
*
* @author Josh Tynjala
*/
public class RadialAxisRenderer extends UIComponent implements IRadialAxisRenderer
{
//--------------------------------------
// Class Variables
//--------------------------------------
/**
* @private
*/
private static var defaultStyles:Object =
{
//axis
showAxis: true,
axisWeight: 1,
axisColor: 0x888a85,
//ticks
showTicks: true,
tickWeight: 1,
tickColor: 0x888a85,
tickLength: 4,
tickPosition: TickPosition.INSIDE,
//minor ticks
showMinorTicks: true,
minorTickWeight: 1,
minorTickColor: 0x888a85,
minorTickLength: 3,
minorTickPosition: TickPosition.INSIDE
};
//--------------------------------------
// Class Methods
//--------------------------------------
/**
* @copy fl.core.UIComponent#getStyleDefinition()
*/
public static function getStyleDefinition():Object
{
return mergeStyles(defaultStyles, UIComponent.getStyleDefinition());
}
//--------------------------------------
// Constructor
//--------------------------------------
/**
* Constructor.
*/
public function RadialAxisRenderer()
{
super();
}
//--------------------------------------
// Properties
//--------------------------------------
/**
* @inheritDoc
*/
public function get length():Number
{
return Math.min(this.width, this.height) * Math.PI;
}
/**
* @private
* Storage for the ticks property.
*/
private var _ticks:Array = [];
/**
* @inheritDoc
*/
public function get ticks():Array
{
return this._ticks;
}
/**
* @private
*/
public function set ticks(value:Array):void
{
this._ticks = value;
this.invalidate();
}
/**
* @private
* Storage for the minorTicks property.
*/
private var _minorTicks:Array = [];
/**
* @inheritDoc
*/
public function get minorTicks():Array
{
return this._minorTicks;
}
/**
* @private
*/
public function set minorTicks(value:Array):void
{
this._minorTicks = value;
this.invalidate();
}
//--------------------------------------
// Public Methods
//--------------------------------------
/**
* @inheritDoc
*/
public function updateBounds():void
{
//no labels are created at this time, so this function is pretty useless
}
//--------------------------------------
// Protected Methods
//--------------------------------------
/**
* @private
*/
override protected function draw():void
{
var showTicks:Boolean = this.getStyleValue("showTicks") as Boolean;
var showMinorTicks:Boolean = this.getStyleValue("showMinorTicks") as Boolean;
var ticks:Array = this.ticks.concat();
var minorTicks:Array = this.minorTicks.concat();
if(showMinorTicks && showTicks)
{
//filter out minor ticks that appear at the same position
//as major ticks.
minorTicks = minorTicks.filter(function(item:AxisData, index:int, source:Array):Boolean
{
return !ticks.some(function(item2:AxisData, index2:int, source2:Array):Boolean
{
//using fuzzyEquals because we may encounter rounding errors
return NumberUtil.fuzzyEquals(item.position, item2.position, 10);
});
});
}
this.graphics.clear();
this.drawAxis();
var tickPosition:String = this.getStyleValue("tickPosition") as String;
var tickLength:Number = this.getStyleValue("tickLength") as Number;
var tickWeight:int = this.getStyleValue("tickWeight") as int;
var tickColor:uint = this.getStyleValue("tickColor") as uint;
this.drawTicks(ticks, showTicks, tickPosition, tickLength, tickWeight, tickColor);
var minorTickPosition:String = this.getStyleValue("minorTickPosition") as String;
var minorTickLength:Number = this.getStyleValue("minorTickLength") as Number;
var minorTickWeight:int = this.getStyleValue("minorTickWeight") as int;
var minorTickColor:uint = this.getStyleValue("minorTickColor") as uint;
this.drawTicks(minorTicks, showMinorTicks, minorTickPosition, minorTickLength, minorTickWeight, minorTickColor);
super.draw();
}
/**
* @private
* Draws the main axis line.
*/
protected function drawAxis():void
{
var showAxis:Boolean = this.getStyleValue("showAxis") as Boolean;
if(!showAxis)
{
return;
}
var axisWeight:int = this.getStyleValue("axisWeight") as int;
var axisColor:uint = this.getStyleValue("axisColor") as uint;
this.graphics.lineStyle(axisWeight, axisColor);
var center:Point = new Point(this.width / 2, this.height / 2);
var radius:Number = Math.min(center.x, center.y);
this.graphics.drawCircle(center.x, center.y, radius);
}
/**
* @private
* Draws a set of ticks along the main axis line. This function is shared
* by major and minor ticks.
*/
protected function drawTicks(data:Array, showTicks:Boolean, tickPosition:String,
tickLength:Number, tickWeight:Number, tickColor:uint):void
{
if(!showTicks)
{
return;
}
this.graphics.lineStyle(tickWeight, tickColor);
var center:Point = new Point(this.width / 2, this.height / 2);
var radius:Number = Math.min(center.x, center.y);
var dataCount:int = data.length;
for(var i:int = 0; i < dataCount; i++)
{
var axisData:AxisData = AxisData(data[i]);
if(isNaN(axisData.position))
{
//skip bad positions
continue;
}
var position:Number = axisData.position;
var angle:Number = GeomUtil.degreesToRadians(position * 360 / this.length);
var tickCenter:Point = Point.polar(radius, angle);
tickCenter = tickCenter.add(center);
switch(tickPosition)
{
case TickPosition.OUTSIDE:
var outsideEnd:Point = Point.polar(tickLength, angle);
outsideEnd = outsideEnd.add(tickCenter);
this.graphics.moveTo(tickCenter.x, tickCenter.y);
this.graphics.lineTo(outsideEnd.x, outsideEnd.y);
break;
case TickPosition.INSIDE:
var insideEnd:Point = Point.polar(tickLength, GeomUtil.degreesToRadians(180 + GeomUtil.radiansToDegrees(angle)));
insideEnd = insideEnd.add(tickCenter);
this.graphics.moveTo(tickCenter.x, tickCenter.y);
this.graphics.lineTo(insideEnd.x, insideEnd.y);
break;
default: //CROSS
outsideEnd = Point.polar(tickLength / 2, angle);
outsideEnd = outsideEnd.add(tickCenter);
insideEnd = Point.polar(tickLength / 2, GeomUtil.degreesToRadians(180 + GeomUtil.radiansToDegrees(angle)));
insideEnd = insideEnd.add(tickCenter);
this.graphics.moveTo(outsideEnd.x, outsideEnd.y);
this.graphics.lineTo(insideEnd.x, insideEnd.y);
break;
}
}
}
}
}