BaseAxis.js revision 106cc795c2891f2d2d142772cadefbcb5975bcfa
/**
* BaseAxis is the base class for observable baseAxis classes.
*/
/**
* Creates the BaseAxis instance and contains initialization data
*
* @param {Object} config (optional) Configuration parameters for the Chart.
* @class SWFWidget
* @constructor
*/
function BaseAxis (config)
{
this._createId();
this._keys = {};
this._data = [];
BaseAxis.superclass.constructor.apply(this, arguments);
}
BaseAxis.NAME = "baseAxis";
/**
* Attribute config
* @private
*/
BaseAxis.ATTRS = {
/**
* Parent element for the BaseAxis instance.
*/
parent:{
lazyAdd:false,
value:null
},
/**
* @private
* Storage for rounding unit
*/
roundingUnit:{
getter: function ()
{
return this._roundingUnit;
},
setter: function (val)
{
this._roundingUnit = val;
if(this._roundMinAndMax)
{
this._updateMinAndMax();
}
return val;
}
},
/**
* Indicates whether or not to round values when calculating
* <code>maximum</code> and <code>minimum</code>.
*/
roundMinAndMax:{
getter: function ()
{
return this._roundMinAndMax;
},
setter: function (val)
{
if(this._roundMinAndMax == val)
{
return val;
}
this._roundMinAndMax = val;
this._updateMinAndMax();
}
},
/**
* Returns the type of axis data
* <ul>
* <li><code>time</code></li>
* <li><code>numeric</code></li>
* <li><code>category</code></li>
* </ul>
*/
dataType:
{
getter: function ()
{
return this._dataType;
}
},
/**
* Instance of <code>ChartDataProvider</code> that the class uses
* to build its own data.
*/
dataProvider:{
getter: function ()
{
return this._dataProvider;
},
setter: function (value)
{
if(value === this._dataProvider)
{
return;
}
if(this._dataProvider)
{
//remove listeners
}
value = Y.merge(value);
this._dataProvider = {data:value.data.concat()};
this._dataClone = this._dataProvider.data.concat();
return value;
},
lazyAdd: false
},
/**
* The maximum value contained in the <code>data</code> array. Used for
* <code>maximum</code> when <code>autoMax</code> is true.
*/
dataMaximum: {
getter: function ()
{
return this._dataMaximum;
}
},
/**
* The maximum value that will appear on an axis.
*/
maximum: {
getter: function ()
{
if(this._autoMax || !this._setMaximum)
{
return this._dataMaximum;
}
return this._setMaximum;
},
setter: function (value)
{
this._setMaximum = value;
}
},
/**
* The minimum value contained in the <code>data</code> array. Used for
* <code>minimum</code> when <code>autoMin</code> is true.
*/
dataMinimum: {
getter: function ()
{
return this._dataMinimum;
}
},
/**
* The minimum value that will appear on an axis.
*/
minimum: {
getter: function ()
{
if(this._autoMin || !this._setMinimum)
{
return this._dataMinimum;
}
return this._setMinimum;
},
setter: function(val)
{
this._setMinimum = val;
return val;
}
},
/**
* Determines whether the maximum is calculated or explicitly
* set by the user.
*/
autoMax: {
getter: function ()
{
return this._autoMax;
},
setter: function (value)
{
this._autoMax = value;
}
},
/**
* Determines whether the minimum is calculated or explicitly
* set by the user.
*/
autoMin: {
getter: function ()
{
return this._autoMin;
},
setter: function (value)
{
this._autoMin = value;
}
},
/**
* Array of axis data
*/
data: {
getter: function ()
{
return this._data;
}
},
/**
* Hash of array identifed by a string value.
*/
keys: {
getter: function ()
{
return this._keys;
}
}
};
Y.extend(BaseAxis, Y.Base,
{
/**
* Creates unique id for class instance.
*
* @private
*/
_createId: function()
{
this._id = Y.guid(this.GUID);
},
/**
* @private
* Storaga for roundingUnit
*/
_roundingUnit: NaN,
/**
* @private
* Storage for round min and max
*/
_roundMinAndMax: true,
/**
* @private
* Storage for dataType
*/
_dataType: null,
/**
* @private
* Storage for dataProvider
*/
_dataProvider: null,
/**
* @private
* Instance copy of the ChartDataProvider's data array.
*/
_dataClone: null,
/**
* @private
* Storage for maximum when autoMax is false.
*/
_setMaximum: null,
/**
* @private
* Storage for dataMaximum
* is true.
*/
_dataMaximum: null,
/**
* @private
* Storage for autoMax
*/
_autoMax: true,
/**
* @private
* Storage for minimum when autoMin is false.
*/
_setMinimum: null,
/**
* @private
* Storage for dataMinimum.
*/
_dataMinimum: null,
/**
* @private
* Storage for autoMin.
*/
_autoMin: true,
/**
* @private
* Storage for data
*/
_data: null,
/**
* @private
* Storage for keys
*/
_keys: null,
/**
* @private
* Indicates that the axis has a data source and at least one
* key.
*/
_axisReady: false,
/**
* Adds an array to the key hash.
*
* @param value Indicates what key to use in retrieving
* the array.
*/
addKey: function (value)
{
if(this._keys.hasOwnProperty(value))
{
return;
}
this._dataClone = this._dataProvider.data.concat();
var keys = this._keys,
eventKeys = {},
event = {axis:this};
this._setDataByKey(value);
eventKeys[value] = keys[value].concat();
this._updateMinAndMax();
event.keysAdded = eventKeys;
if(!this._dataReady)
{
this._dataReady = true;
this.publish("axisReady", {fireOnce:true});
this.fire("axisReady", event);
}
else
{
this.fire("axisUpdate", event);
}
},
/**
* @private
*
* Creates an array of data based on a key value.
*/
_setDataByKey: function(key)
{
var i,
obj,
arr = [],
dv = this._dataClone.concat(),
len = dv.length;
for(i = 0; i < len; ++i)
{
obj = dv[i];
arr[i] = obj[key];
}
this._keys[key] = arr;
this._data = this._data.concat(arr);
},
/**
* Removes an array from the key hash.
*
* @param value Indicates what key to use in removing from
* the hash.
* @return Boolean
*/
removeKey: function(value)
{
if(!this._keys.hasOwnProperty(value))
{
return;
}
var key,
oldKey,
newKeys = {},
newData = [],
removedKeys = {},
keys = this._keys,
event = {};
removedKeys[value] = keys[value].concat();
for(key in keys)
{
if(keys.hasOwnProperty(key))
{
if(key == value)
{
continue;
}
oldKey = keys[key];
newData = newData.concat(oldKey);
newKeys[key] = oldKey;
}
}
keys = newKeys;
this._data = newData;
this._updateMinAndMax();
event.keysRemoved = removedKeys;
this.fire("axisUpdate", event);
},
/**
* Returns a numeric value based of a key value and an index.
*/
getKeyValueAt: function(key, index)
{
var value = NaN,
keys = this.keys;
if(keys[key] && keys[key][index])
{
value = keys[key][index];
}
return value;
},
/**
* Returns an array of values based on an identifier key.
*/
getDataByKey: function (value)
{
var keys = this._keys;
if(keys[value])
{
return keys[value];
}
return null;
},
/**
* @private
* Updates the <code>dataMaximum</code> and <code>dataMinimum</code> values.
*/
_updateMinAndMax: function ()
{
var data = this.get("data"),
max = 0,
min = 0,
len,
num,
i;
if(data && data.length && data.length > 0)
{
len = data.length;
max = min = data[0];
if(len > 1)
{
for(i = 1; i < len; i++)
{
num = data[i];
if(isNaN(num))
{
continue;
}
max = Math.max(num, max);
min = Math.min(num, min);
}
}
}
this._dataMaximum = max;
this._dataMinimum = min;
},
/**
* @private
* Handles updates axis data properties based on the <code>DataEvent.NEW_DATA</code>
* event from the <code>dataProvider</code>.
*/
newDataUpdateHandler: function()
{
var i,
keys = this._keys,
event = {};
this._data = [];
this._dataClone = this._dataProvider.data.concat();
for(i in keys)
{
if(keys.hasOwnProperty(i))
{
keys[i] = this._setDataByKey(i);
this._data = this._data.concat(keys[i]);
}
}
this._updateMinAndMax();
event.keysAdded = keys;
this.fire("axisUpdate", event);
},
/**
* @private
* Updates axis data properties based on the <code>DataEvent.DATA_CHANGE</code>
* event from the <code>dataProvider</code>.
*/
_keyDataUpdateHandler: function ()
{
var hasKey = false,
event = {},
keysAdded = event.keysAdded,
keysRemoved = event.keysRemoved,
keys = this._keys;
for(var i in keys)
{
if(keys.hasOwnProperty(i))
{
if(keysAdded.hasOwnProperty(i))
{
hasKey = true;
keys[i] = keys[i];
}
if(keysRemoved.hasOwnProperty(i))
{
hasKey = true;
keys[i] = [];
}
}
}
if(!hasKey)
{
return;
}
this._data = [];
for(i in keys)
{
if(keys.hasOwnProperty(i))
{
this._data = this._data.concat(keys[i]);
}
}
this._updateMinAndMax();
event.keysAdded = keysAdded;
event.keysRemoved = keysRemoved;
this.fire("axisUpdate", event);
}
});
Y.BaseAxis = BaseAxis;