- /**
- * The axis-base submodule contains functionality for the handling of axis data in a chart.
- *
- * @module charts
- * @submodule axis-base
- */
- /**
- * An abstract class that provides the core functionality used by the following classes:
- * <ul>
- * <li>{{#crossLink "CategoryAxisBase"}}{{/crossLink}}</li>
- * <li>{{#crossLink "NumericAxisBase"}}{{/crossLink}}</li>
- * <li>{{#crossLink "StackedAxisBase"}}{{/crossLink}}</li>
- * <li>{{#crossLink "TimeAxisBase"}}{{/crossLink}}</li>
- * <li>{{#crossLink "CategoryAxis"}}{{/crossLink}}</li>
- * <li>{{#crossLink "NumericAxis"}}{{/crossLink}}</li>
- * <li>{{#crossLink "StackedAxis"}}{{/crossLink}}</li>
- * <li>{{#crossLink "TimeAxis"}}{{/crossLink}}</li>
- * </ul>
- *
- * @class AxisBase
- * @constructor
- * @extends Base
- * @uses Renderer
- * @param {Object} config (optional) Configuration parameters.
- * @submodule axis-base
- */
- Y.AxisBase = Y.Base.create("axisBase", Y.Base, [Y.Renderer], {
- /**
- * @method initializer
- * @private
- */
- initializer: function()
- {
- this.after("minimumChange", Y.bind(this._keyChangeHandler, this));
- this.after("maximumChange", Y.bind(this._keyChangeHandler, this));
- this.after("keysChange", this._keyChangeHandler);
- this.after("dataProviderChange", this._dataProviderChangeHandler);
- },
-
- /**
- * Returns the value corresponding to the origin on the axis.
- *
- * @method getOrigin
- * @return Number
- */
- getOrigin: function() {
- return this.get("minimum");
- },
-
- /**
- * Handles changes to `dataProvider`.
- *
- * @method _dataProviderChangeHandler
- * @param {Object} e Event object.
- * @private
- */
- _dataProviderChangeHandler: function()
- {
- var keyCollection = this.get("keyCollection").concat(),
- keys = this.get("keys"),
- i;
- if(keys)
- {
- for(i in keys)
- {
- if(keys.hasOwnProperty(i))
- {
- delete keys[i];
- }
- }
- }
- if(keyCollection && keyCollection.length)
- {
- this.set("keys", keyCollection);
- }
- },
-
- /**
- * Calculates the maximum and minimum values for the `Data`.
- *
- * @method _updateMinAndMax
- * @private
- */
- _updateMinAndMax: function() {
- },
-
- /**
- * Constant used to generate unique id.
- *
- * @property GUID
- * @type String
- * @private
- */
- GUID: "yuibaseaxis",
-
- /**
- * Type of data used in `Axis`.
- *
- * @property _type
- * @type String
- * @readOnly
- * @private
- */
- _type: null,
-
- /**
- * Storage for `setMaximum` attribute.
- *
- * @property _setMaximum
- * @type Object
- * @private
- */
- _setMaximum: null,
-
- /**
- * Storage for `setMinimum` attribute.
- *
- * @property _setMinimum
- * @type Object
- * @private
- */
- _setMinimum: null,
-
- /**
- * Reference to data array.
- *
- * @property _data
- * @type Array
- * @private
- */
- _data: null,
-
- /**
- * Indicates whether the all data is up to date.
- *
- * @property _updateTotalDataFlag
- * @type Boolean
- * @private
- */
- _updateTotalDataFlag: true,
-
- /**
- * Storage for `dataReady` attribute.
- *
- * @property _dataReady
- * @type Boolean
- * @readOnly
- * @private
- */
- _dataReady: false,
-
- /**
- * Adds an array to the key hash.
- *
- * @method addKey
- * @param value Indicates what key to use in retrieving
- * the array.
- */
- addKey: function (value)
- {
- this.set("keys", value);
- },
-
- /**
- * Gets an array of values based on a key.
- *
- * @method _getKeyArray
- * @param {String} key Value key associated with the data array.
- * @param {Array} data Array in which the data resides.
- * @return Array
- * @private
- */
- _getKeyArray: function(key, data)
- {
- var i = 0,
- obj,
- keyArray = [],
- len = data.length;
- for(; i < len; ++i)
- {
- obj = data[i];
- keyArray[i] = obj[key];
- }
- return keyArray;
- },
-
- /**
- * Updates the total data array.
- *
- * @method _updateTotalData
- * @private
- */
- _updateTotalData: function()
- {
- var keys = this.get("keys"),
- i;
- this._data = [];
- for(i in keys)
- {
- if(keys.hasOwnProperty(i))
- {
- this._data = this._data.concat(keys[i]);
- }
- }
- this._updateTotalDataFlag = false;
- },
-
- /**
- * Removes an array from the key hash.
- *
- * @method removeKey
- * @param {String} value Indicates what key to use in removing from
- * the hash.
- */
- removeKey: function(value)
- {
- var keys = this.get("keys");
- if(keys.hasOwnProperty(value))
- {
- delete keys[value];
- this._keyChangeHandler();
- }
- },
-
- /**
- * Returns a value based of a key value and an index.
- *
- * @method getKeyValueAt
- * @param {String} key value used to look up the correct array
- * @param {Number} index within the array
- * @return Number
- */
- getKeyValueAt: function(key, index)
- {
- var value = NaN,
- keys = this.get("keys");
- if(keys[key] && Y_Lang.isNumber(parseFloat(keys[key][index])))
- {
- value = keys[key][index];
- }
- return parseFloat(value);
- },
-
- /**
- * Returns values based on key identifiers. When a string is passed as an argument, an array of values is returned.
- * When an array of keys is passed as an argument, an object literal with an array of values mapped to each key is
- * returned.
- *
- * @method getDataByKey
- * @param {String|Array} value value used to identify the array
- * @return Array|Object
- */
- getDataByKey: function (value)
- {
- var obj,
- i,
- len,
- key,
- keys = this.get("keys");
- if(Y_Lang.isArray(value))
- {
- obj = {};
- len = value.length;
- for(i = 0; i < len; i = i + 1)
- {
- key = value[i];
- if(keys[key])
- {
- obj[key] = this.getDataByKey(key);
- }
- }
- }
- else if(keys[value])
- {
- obj = keys[value];
- }
- else
- {
- obj = null;
- }
- return obj;
- },
-
- /**
- * Returns the total number of majorUnits that will appear on an axis.
- *
- * @method getTotalMajorUnits
- * @return Number
- */
- getTotalMajorUnits: function()
- {
- var units,
- majorUnit = this.get("styles").majorUnit;
- units = majorUnit.count;
- return units;
- },
-
- /**
- * Gets the distance that the first and last ticks are offset from there respective
- * edges.
- *
- * @method getEdgeOffset
- * @param {Number} ct Number of ticks on the axis.
- * @param {Number} l Length (in pixels) of the axis.
- * @return Number
- */
- getEdgeOffset: function(ct, l)
- {
- var edgeOffset;
- if(this.get("calculateEdgeOffset")) {
- edgeOffset = (l/ct)/2;
- } else {
- edgeOffset = 0;
- }
- return edgeOffset;
- },
-
- /**
- * Updates the `Axis` after a change in keys.
- *
- * @method _keyChangeHandler
- * @param {Object} e Event object.
- * @private
- */
- _keyChangeHandler: function()
- {
- this._updateMinAndMax();
- this._updateTotalDataFlag = true;
- this.fire("dataUpdate");
- },
-
- /**
- * Gets the default value for the `styles` attribute. Overrides
- * base implementation.
- *
- * @method _getDefaultStyles
- * @return Object
- * @protected
- */
- _getDefaultStyles: function()
- {
- var axisstyles = {
- majorUnit: {
- determinant:"count",
- count:11,
- distance:75
- }
- };
- return axisstyles;
- },
-
- /**
- * Getter method for maximum attribute.
- *
- * @method _maximumGetter
- * @return Number
- * @private
- */
- _maximumGetter: function ()
- {
- var max = this.get("dataMaximum"),
- min = this.get("minimum");
- //If all values are zero, force a range so that the Axis and related series
- //will still render.
- if(min === 0 && max === 0)
- {
- max = 10;
- }
- if(Y_Lang.isNumber(this._setMaximum))
- {
- max = this._setMaximum;
- }
- return parseFloat(max);
- },
-
- /**
- * Setter method for maximum attribute.
- *
- * @method _maximumSetter
- * @param {Object} value
- * @private
- */
- _maximumSetter: function (value)
- {
- this._setMaximum = parseFloat(value);
- return value;
- },
-
- /**
- * Getter method for minimum attribute.
- *
- * @method _minimumGetter
- * @return Number
- * @private
- */
- _minimumGetter: function ()
- {
- var min = this.get("dataMinimum");
- if(Y_Lang.isNumber(this._setMinimum))
- {
- min = this._setMinimum;
- }
- return parseFloat(min);
- },
-
- /**
- * Setter method for minimum attribute.
- *
- * @method _minimumSetter
- * @param {Object} value
- * @private
- */
- _minimumSetter: function(val)
- {
- this._setMinimum = parseFloat(val);
- return val;
- },
-
- /**
- * Indicates whether or not the maximum attribute has been explicitly set.
- *
- * @method _getSetMax
- * @return Boolean
- * @private
- */
- _getSetMax: function()
- {
- return Y_Lang.isNumber(this._setMaximum);
- },
-
-
- /**
- * Returns and array of coordinates corresponding to an array of data values.
- *
- * @method _getCoordsFromValues
- * @param {Number} min The minimum for the axis.
- * @param {Number} max The maximum for the axis.
- * @param {Number} length The distance that the axis spans.
- * @param {Array} dataValues An array of values.
- * @param {Number} offset Value in which to offset the coordinates.
- * @param {Boolean} reverse Indicates whether the coordinates should start from
- * the end of an axis. Only used in the numeric implementation.
- * @return Array
- * @private
- */
- _getCoordsFromValues: function(min, max, length, dataValues, offset, reverse)
- {
- var i,
- valuecoords = [],
- len = dataValues.length;
- for(i = 0; i < len; i = i + 1)
- {
- valuecoords.push(this._getCoordFromValue.apply(this, [min, max, length, dataValues[i], offset, reverse]));
- }
- return valuecoords;
- },
-
- /**
- * Returns and array of data values based on the axis' range and number of values.
- *
- * @method _getDataValuesByCount
- * @param {Number} count The number of values to be used.
- * @param {Number} min The minimum value of the axis.
- * @param {Number} max The maximum value of the axis.
- * @return Array
- * @private
- */
- _getDataValuesByCount: function(count, min, max)
- {
- var dataValues = [],
- dataValue = min,
- len = count - 1,
- range = max - min,
- increm = range/len,
- i;
- for(i = 0; i < len; i = i + 1)
- {
- dataValues.push(dataValue);
- dataValue = dataValue + increm;
- }
- dataValues.push(max);
- return dataValues;
- },
-
- /**
- * Indicates whether or not the minimum attribute has been explicitly set.
- *
- * @method _getSetMin
- * @return Boolean
- * @private
- */
- _getSetMin: function()
- {
- return Y_Lang.isNumber(this._setMinimum);
- }
- }, {
- ATTRS: {
- /**
- * Determines whether and offset is automatically calculated for the edges of the axis.
- *
- * @attribute calculateEdgeOffset
- * @type Boolean
- */
- calculateEdgeOffset: {
- value: false
- },
-
- labelFunction: {
- valueFn: function() {
- return this.formatLabel;
- }
- },
-
- /**
- * Hash of array identifed by a string value.
- *
- * @attribute keys
- * @type Object
- */
- keys: {
- value: {},
-
- setter: function(val)
- {
- var keys = {},
- i,
- len,
- data = this.get("dataProvider");
- if(Y_Lang.isArray(val))
- {
- len = val.length;
- for(i = 0; i < len; ++i)
- {
- keys[val[i]] = this._getKeyArray(val[i], data);
- }
-
- }
- else if(Y_Lang.isString(val))
- {
- keys = this.get("keys");
- keys[val] = this._getKeyArray(val, data);
- }
- else
- {
- for(i in val)
- {
- if(val.hasOwnProperty(i))
- {
- keys[i] = this._getKeyArray(i, data);
- }
- }
- }
- this._updateTotalDataFlag = true;
- return keys;
- }
- },
-
- /**
- *Returns the type of axis data
- * <dl>
- * <dt>time</dt><dd>Manages time data</dd>
- * <dt>stacked</dt><dd>Manages stacked numeric data</dd>
- * <dt>numeric</dt><dd>Manages numeric data</dd>
- * <dt>category</dt><dd>Manages categorical data</dd>
- * </dl>
- *
- * @attribute type
- * @type String
- */
- type:
- {
- readOnly: true,
-
- getter: function ()
- {
- return this._type;
- }
- },
-
- /**
- * Instance of `ChartDataProvider` that the class uses
- * to build its own data.
- *
- * @attribute dataProvider
- * @type Array
- */
- dataProvider:{
- setter: function (value)
- {
- return value;
- }
- },
-
- /**
- * The maximum value contained in the `data` array. Used for
- * `maximum` when `autoMax` is true.
- *
- * @attribute dataMaximum
- * @type Number
- */
- dataMaximum: {
- getter: function ()
- {
- if(!Y_Lang.isNumber(this._dataMaximum))
- {
- this._updateMinAndMax();
- }
- return this._dataMaximum;
- }
- },
-
- /**
- * The maximum value that will appear on an axis.
- *
- * @attribute maximum
- * @type Number
- */
- maximum: {
- lazyAdd: false,
-
- getter: "_maximumGetter",
-
- setter: "_maximumSetter"
- },
-
- /**
- * The minimum value contained in the `data` array. Used for
- * `minimum` when `autoMin` is true.
- *
- * @attribute dataMinimum
- * @type Number
- */
- dataMinimum: {
- getter: function ()
- {
- if(!Y_Lang.isNumber(this._dataMinimum))
- {
- this._updateMinAndMax();
- }
- return this._dataMinimum;
- }
- },
-
- /**
- * The minimum value that will appear on an axis.
- *
- * @attribute minimum
- * @type Number
- */
- minimum: {
- lazyAdd: false,
-
- getter: "_minimumGetter",
-
- setter: "_minimumSetter"
- },
-
- /**
- * Determines whether the maximum is calculated or explicitly
- * set by the user.
- *
- * @attribute setMax
- * @type Boolean
- */
- setMax: {
- readOnly: true,
-
- getter: "_getSetMax"
- },
-
- /**
- * Determines whether the minimum is calculated or explicitly
- * set by the user.
- *
- * @attribute setMin
- * @type Boolean
- */
- setMin: {
- readOnly: true,
-
- getter: "_getSetMin"
- },
-
- /**
- * Array of axis data
- *
- * @attribute data
- * @type Array
- */
- data: {
- getter: function ()
- {
- if(!this._data || this._updateTotalDataFlag)
- {
- this._updateTotalData();
- }
- return this._data;
- }
- },
-
- /**
- * Array containing all the keys in the axis.
-
- * @attribute keyCollection
- * @type Array
- */
- keyCollection: {
- getter: function()
- {
- var keys = this.get("keys"),
- i,
- col = [];
- for(i in keys)
- {
- if(keys.hasOwnProperty(i))
- {
- col.push(i);
- }
- }
- return col;
- },
- readOnly: true
- },
-
- /**
- * Object which should have by the labelFunction
- *
- * @attribute labelFunctionScope
- * @type Object
- */
- labelFunctionScope: {}
- }
- });
-
-