AS3 - 根据数据最小最大值计算轴的刻度
作者:hangge | 2015-02-26 11:22
如果要在Flex/Flash中自行开发图表。则不可避免的要进行值轴的绘制,而值轴中最重要的是要根据数据来确定轴的最小刻度和最大刻度,以及每个刻度的步长。下面提供了一个计算类,可以方便的计算出刻度相关的数据。
计算类:
先看使用方法:
var valueAxis:ValueAxis = new ValueAxis();
valueAxis.getMinMax(4,888);
trace("最小刻度值:"+valueAxis.min); //0
trace("最大刻度值:"+valueAxis.max); //900
trace("步长:"+valueAxis.step); //100
计算类:
package
{
public class ValueAxis
{
private var _min:Number;
private var _max:Number;
private var _gridCount:Number;
private var _minReal:Number;
private var _maxReal:Number;
private var _step:Number;
private var _maxDecCount:Number;
/**
* 计算最终的最大最小刻度
*/
public function getMinMax(min:Number,max:Number,gridCount:Number = 10):void{
this._max = max;
this._min = min;
this._gridCount = gridCount;
var difE:Number;
var maxT:Number;
if (_min > _max){
maxT = _max;
_max = _min;
_min = maxT;
};
_minReal = _min;
_maxReal = _max;
if ((((_min == 0)) && ((_max == 0)))){
_max = 9;
};
var initialMin:Number = _min;
var initialMax:Number = _max;
var dif:Number = (_max - _min);
if (dif == 0){
difE = (Math.pow(10, Math.floor((Math.log(Math.abs(_max)) * Math.LOG10E))) / 10);
} else {
difE = (Math.pow(10, Math.floor((Math.log(Math.abs(dif)) * Math.LOG10E))) / 10);
};
if ((((_min < 0)) && ((initialMin >= 0)))){
_min = 0;
};
if ((((_max > 0)) && ((initialMax <= 0)))){
_max = 0;
};
dif = (_max - _min);
difE = (Math.pow(10, Math.floor((Math.log(Math.abs(dif)) * Math.LOG10E))) / 10);
_step = (Math.ceil(((dif / _gridCount) / difE)) * difE);
var stepE:Number = Math.pow(10, Math.floor((Math.log(Math.abs(_step)) * Math.LOG10E)));
var stepExp:String = stepE.toExponential(0);
var stepExpArr:Array = stepExp.split("e");
var base:Number = stepExpArr[0];
var mant:Number = stepExpArr[1];
if (base == 9){
mant++;
};
stepE = generateNumber(1, mant);
var temp:Number = Math.ceil((_step / stepE));
if (temp > 5){
temp = 10;
};
if ((((temp <= 5)) && ((temp > 2)))){
temp = 5;
};
_step = ((Math.ceil((_step / (stepE * temp))) * stepE) * temp);
if (stepE < 1){
_maxDecCount = Math.abs((Math.log(Math.abs(stepE)) * Math.LOG10E));
_maxDecCount = Math.round(_maxDecCount);
_step = roundTo(_step, (_maxDecCount + 1));
} else {
_maxDecCount = 0;
};
_min = (_step * Math.floor((_min / _step)));
_max = (_step * Math.ceil((_max / _step)));
if ((((_min < 0)) && ((initialMin >= 0)))){
_min = 0;
};
if ((((_max > 0)) && ((initialMax <= 0)))){
_max = 0;
};
if ((((_minReal > 1)) && (((_max - _minReal) > 1)))){
_minReal = Math.floor(_minReal);
};
dif = Math.pow(10, Math.floor((Math.log(Math.abs(_minReal)) * Math.LOG10E)));
if (_min == 0){
_minReal = dif;
};
if ((((_min == 0)) && ((_minReal > 1)))){
_minReal = 1;
};
if ((((_min > 0)) && (((_minReal - _step) > 0)))){
if ((_min + _step) < _minReal){
_minReal = (_min + _step);
} else {
_minReal = _min;
};
};
}
/**
* 数字格式化
*/
private function generateNumber(num:Number, mant:Number):Number{
var n:Number;
var zeroes:String = "";
if (mant < 1){
n = (Math.abs(mant) - 1);
} else {
n = Math.abs(mant);
};
var i:Number = 0;
while (i < n) {
zeroes = (zeroes + "0");
i++;
};
if (mant < 1){
return (Number((("0." + zeroes) + String(num))));
};
return (Number((String(num) + zeroes)));
}
private function roundTo(num:Number, precision:Number):Number{
precision = Math.round(precision);
var p:Number = Math.pow(10, precision);
return ((Math.round((num * p)) / p));
}
public function get min():Number
{
return _min;
}
public function set min(value:Number):void
{
_min = value;
}
public function get max():Number
{
return _max;
}
public function set max(value:Number):void
{
_max = value;
}
public function get step():Number
{
return _step;
}
public function set step(value:Number):void
{
_step = value;
}
}
}
全部评论(0)