API Docs for: 3.10.3
Show:

File: charts/js/AxisBase.js

  1. /**
  2. * The axis-base submodule contains functionality for the handling of axis data in a chart.
  3. *
  4. * @module charts
  5. * @submodule axis-base
  6. */
  7. /**
  8. * An abstract class that provides the core functionality used by the following classes:
  9. * <ul>
  10. * <li>{{#crossLink "CategoryAxisBase"}}{{/crossLink}}</li>
  11. * <li>{{#crossLink "NumericAxisBase"}}{{/crossLink}}</li>
  12. * <li>{{#crossLink "StackedAxisBase"}}{{/crossLink}}</li>
  13. * <li>{{#crossLink "TimeAxisBase"}}{{/crossLink}}</li>
  14. * <li>{{#crossLink "CategoryAxis"}}{{/crossLink}}</li>
  15. * <li>{{#crossLink "NumericAxis"}}{{/crossLink}}</li>
  16. * <li>{{#crossLink "StackedAxis"}}{{/crossLink}}</li>
  17. * <li>{{#crossLink "TimeAxis"}}{{/crossLink}}</li>
  18. * </ul>
  19. *
  20. * @class AxisBase
  21. * @constructor
  22. * @extends Base
  23. * @uses Renderer
  24. * @param {Object} config (optional) Configuration parameters.
  25. * @submodule axis-base
  26. */
  27. Y.AxisBase = Y.Base.create("axisBase", Y.Base, [Y.Renderer], {
  28. /**
  29. * @method initializer
  30. * @private
  31. */
  32. initializer: function()
  33. {
  34. this.after("minimumChange", Y.bind(this._keyChangeHandler, this));
  35. this.after("maximumChange", Y.bind(this._keyChangeHandler, this));
  36. this.after("keysChange", this._keyChangeHandler);
  37. this.after("dataProviderChange", this._dataProviderChangeHandler);
  38. },
  39.  
  40. /**
  41. * Handles changes to `dataProvider`.
  42. *
  43. * @method _dataProviderChangeHandler
  44. * @param {Object} e Event object.
  45. * @private
  46. */
  47. _dataProviderChangeHandler: function()
  48. {
  49. var keyCollection = this.get("keyCollection").concat(),
  50. keys = this.get("keys"),
  51. i;
  52. if(keys)
  53. {
  54. for(i in keys)
  55. {
  56. if(keys.hasOwnProperty(i))
  57. {
  58. delete keys[i];
  59. }
  60. }
  61. }
  62. if(keyCollection && keyCollection.length)
  63. {
  64. this.set("keys", keyCollection);
  65. }
  66. },
  67.  
  68. /**
  69. * Calculates the maximum and minimum values for the `Data`.
  70. *
  71. * @method _updateMinAndMax
  72. * @private
  73. */
  74. _updateMinAndMax: function() {
  75. },
  76.  
  77. /**
  78. * Constant used to generate unique id.
  79. *
  80. * @property GUID
  81. * @type String
  82. * @private
  83. */
  84. GUID: "yuibaseaxis",
  85.  
  86. /**
  87. * Type of data used in `Axis`.
  88. *
  89. * @property _type
  90. * @type String
  91. * @readOnly
  92. * @private
  93. */
  94. _type: null,
  95.  
  96. /**
  97. * Storage for `setMaximum` attribute.
  98. *
  99. * @property _setMaximum
  100. * @type Object
  101. * @private
  102. */
  103. _setMaximum: null,
  104.  
  105. /**
  106. * Storage for `setMinimum` attribute.
  107. *
  108. * @property _setMinimum
  109. * @type Object
  110. * @private
  111. */
  112. _setMinimum: null,
  113.  
  114. /**
  115. * Reference to data array.
  116. *
  117. * @property _data
  118. * @type Array
  119. * @private
  120. */
  121. _data: null,
  122.  
  123. /**
  124. * Indicates whether the all data is up to date.
  125. *
  126. * @property _updateTotalDataFlag
  127. * @type Boolean
  128. * @private
  129. */
  130. _updateTotalDataFlag: true,
  131.  
  132. /**
  133. * Storage for `dataReady` attribute.
  134. *
  135. * @property _dataReady
  136. * @type Boolean
  137. * @readOnly
  138. * @private
  139. */
  140. _dataReady: false,
  141.  
  142. /**
  143. * Adds an array to the key hash.
  144. *
  145. * @method addKey
  146. * @param value Indicates what key to use in retrieving
  147. * the array.
  148. */
  149. addKey: function (value)
  150. {
  151. this.set("keys", value);
  152. },
  153.  
  154. /**
  155. * Gets an array of values based on a key.
  156. *
  157. * @method _getKeyArray
  158. * @param {String} key Value key associated with the data array.
  159. * @param {Array} data Array in which the data resides.
  160. * @return Array
  161. * @private
  162. */
  163. _getKeyArray: function(key, data)
  164. {
  165. var i = 0,
  166. obj,
  167. keyArray = [],
  168. len = data.length;
  169. for(; i < len; ++i)
  170. {
  171. obj = data[i];
  172. keyArray[i] = obj[key];
  173. }
  174. return keyArray;
  175. },
  176.  
  177. /**
  178. * Updates the total data array.
  179. *
  180. * @method _updateTotalData
  181. * @private
  182. */
  183. _updateTotalData: function()
  184. {
  185. var keys = this.get("keys"),
  186. i;
  187. this._data = [];
  188. for(i in keys)
  189. {
  190. if(keys.hasOwnProperty(i))
  191. {
  192. this._data = this._data.concat(keys[i]);
  193. }
  194. }
  195. this._updateTotalDataFlag = false;
  196. },
  197.  
  198. /**
  199. * Removes an array from the key hash.
  200. *
  201. * @method removeKey
  202. * @param {String} value Indicates what key to use in removing from
  203. * the hash.
  204. */
  205. removeKey: function(value)
  206. {
  207. var keys = this.get("keys");
  208. if(keys.hasOwnProperty(value))
  209. {
  210. delete keys[value];
  211. this._keyChangeHandler();
  212. }
  213. },
  214.  
  215. /**
  216. * Returns a value based of a key value and an index.
  217. *
  218. * @method getKeyValueAt
  219. * @param {String} key value used to look up the correct array
  220. * @param {Number} index within the array
  221. * @return Number
  222. */
  223. getKeyValueAt: function(key, index)
  224. {
  225. var value = NaN,
  226. keys = this.get("keys");
  227. if(keys[key] && Y_Lang.isNumber(parseFloat(keys[key][index])))
  228. {
  229. value = keys[key][index];
  230. }
  231. return parseFloat(value);
  232. },
  233.  
  234. /**
  235. * Returns values based on key identifiers. When a string is passed as an argument, an array of values is returned.
  236. * When an array of keys is passed as an argument, an object literal with an array of values mapped to each key is
  237. * returned.
  238. *
  239. * @method getDataByKey
  240. * @param {String|Array} value value used to identify the array
  241. * @return Array|Object
  242. */
  243. getDataByKey: function (value)
  244. {
  245. var obj,
  246. i,
  247. len,
  248. key,
  249. keys = this.get("keys");
  250. if(Y_Lang.isArray(value))
  251. {
  252. obj = {};
  253. len = value.length;
  254. for(i = 0; i < len; i = i + 1)
  255. {
  256. key = value[i];
  257. if(keys[key])
  258. {
  259. obj[key] = this.getDataByKey(key);
  260. }
  261. }
  262. }
  263. else if(keys[value])
  264. {
  265. obj = keys[value];
  266. }
  267. else
  268. {
  269. obj = null;
  270. }
  271. return obj;
  272. },
  273.  
  274. /**
  275. * Returns the total number of majorUnits that will appear on an axis.
  276. *
  277. * @method getTotalMajorUnits
  278. * @return Number
  279. */
  280. getTotalMajorUnits: function()
  281. {
  282. var units,
  283. majorUnit = this.get("styles").majorUnit;
  284. units = majorUnit.count;
  285. return units;
  286. },
  287.  
  288. /**
  289. * Gets the distance that the first and last ticks are offset from there respective
  290. * edges.
  291. *
  292. * @method getEdgeOffset
  293. * @param {Number} ct Number of ticks on the axis.
  294. * @param {Number} l Length (in pixels) of the axis.
  295. * @return Number
  296. */
  297. getEdgeOffset: function(ct, l)
  298. {
  299. var edgeOffset;
  300. if(this.get("calculateEdgeOffset")) {
  301. edgeOffset = (l/ct)/2;
  302. } else {
  303. edgeOffset = 0;
  304. }
  305. return edgeOffset;
  306. },
  307.  
  308. /**
  309. * Updates the `Axis` after a change in keys.
  310. *
  311. * @method _keyChangeHandler
  312. * @param {Object} e Event object.
  313. * @private
  314. */
  315. _keyChangeHandler: function()
  316. {
  317. this._updateMinAndMax();
  318. this._updateTotalDataFlag = true;
  319. this.fire("dataUpdate");
  320. },
  321.  
  322. /**
  323. * Gets the default value for the `styles` attribute. Overrides
  324. * base implementation.
  325. *
  326. * @method _getDefaultStyles
  327. * @return Object
  328. * @protected
  329. */
  330. _getDefaultStyles: function()
  331. {
  332. var axisstyles = {
  333. majorUnit: {
  334. determinant:"count",
  335. count:11,
  336. distance:75
  337. }
  338. };
  339. return axisstyles;
  340. },
  341.  
  342. /**
  343. * Getter method for maximum attribute.
  344. *
  345. * @method _maximumGetter
  346. * @return Number
  347. * @private
  348. */
  349. _maximumGetter: function ()
  350. {
  351. var max = this.get("dataMaximum"),
  352. min = this.get("minimum");
  353. //If all values are zero, force a range so that the Axis and related series
  354. //will still render.
  355. if(min === 0 && max === 0)
  356. {
  357. max = 10;
  358. }
  359. if(Y_Lang.isNumber(this._setMaximum))
  360. {
  361. max = this._setMaximum;
  362. }
  363. return parseFloat(max);
  364. },
  365.  
  366. /**
  367. * Setter method for maximum attribute.
  368. *
  369. * @method _maximumSetter
  370. * @param {Object} value
  371. * @private
  372. */
  373. _maximumSetter: function (value)
  374. {
  375. this._setMaximum = parseFloat(value);
  376. return value;
  377. },
  378.  
  379. /**
  380. * Getter method for minimum attribute.
  381. *
  382. * @method _minimumGetter
  383. * @return Number
  384. * @private
  385. */
  386. _minimumGetter: function ()
  387. {
  388. var min = this.get("dataMinimum");
  389. if(Y_Lang.isNumber(this._setMinimum))
  390. {
  391. min = this._setMinimum;
  392. }
  393. return parseFloat(min);
  394. },
  395.  
  396. /**
  397. * Setter method for minimum attribute.
  398. *
  399. * @method _minimumSetter
  400. * @param {Object} value
  401. * @private
  402. */
  403. _minimumSetter: function(val)
  404. {
  405. this._setMinimum = parseFloat(val);
  406. return val;
  407. },
  408.  
  409. /**
  410. * Indicates whether or not the maximum attribute has been explicitly set.
  411. *
  412. * @method _getSetMax
  413. * @return Boolean
  414. * @private
  415. */
  416. _getSetMax: function()
  417. {
  418. return Y_Lang.isNumber(this._setMaximum);
  419. },
  420.  
  421. /**
  422. * Indicates whether or not the minimum attribute has been explicitly set.
  423. *
  424. * @method _getSetMin
  425. * @return Boolean
  426. * @private
  427. */
  428. _getSetMin: function()
  429. {
  430. return Y_Lang.isNumber(this._setMinimum);
  431. }
  432. }, {
  433. ATTRS: {
  434. /**
  435. * Determines whether and offset is automatically calculated for the edges of the axis.
  436. *
  437. * @attribute calculateEdgeOffset
  438. * @type Boolean
  439. */
  440. calculateEdgeOffset: {
  441. value: false
  442. },
  443.  
  444. labelFunction: {
  445. valueFn: function() {
  446. return this.formatLabel;
  447. }
  448. },
  449.  
  450. /**
  451. * Hash of array identifed by a string value.
  452. *
  453. * @attribute keys
  454. * @type Object
  455. */
  456. keys: {
  457. value: {},
  458.  
  459. setter: function(val)
  460. {
  461. var keys = {},
  462. i,
  463. len,
  464. data = this.get("dataProvider");
  465. if(Y_Lang.isArray(val))
  466. {
  467. len = val.length;
  468. for(i = 0; i < len; ++i)
  469. {
  470. keys[val[i]] = this._getKeyArray(val[i], data);
  471. }
  472.  
  473. }
  474. else if(Y_Lang.isString(val))
  475. {
  476. keys = this.get("keys");
  477. keys[val] = this._getKeyArray(val, data);
  478. }
  479. else
  480. {
  481. for(i in val)
  482. {
  483. if(val.hasOwnProperty(i))
  484. {
  485. keys[i] = this._getKeyArray(i, data);
  486. }
  487. }
  488. }
  489. this._updateTotalDataFlag = true;
  490. return keys;
  491. }
  492. },
  493.  
  494. /**
  495. *Returns the type of axis data
  496. * <dl>
  497. * <dt>time</dt><dd>Manages time data</dd>
  498. * <dt>stacked</dt><dd>Manages stacked numeric data</dd>
  499. * <dt>numeric</dt><dd>Manages numeric data</dd>
  500. * <dt>category</dt><dd>Manages categorical data</dd>
  501. * </dl>
  502. *
  503. * @attribute type
  504. * @type String
  505. */
  506. type:
  507. {
  508. readOnly: true,
  509.  
  510. getter: function ()
  511. {
  512. return this._type;
  513. }
  514. },
  515.  
  516. /**
  517. * Instance of `ChartDataProvider` that the class uses
  518. * to build its own data.
  519. *
  520. * @attribute dataProvider
  521. * @type Array
  522. */
  523. dataProvider:{
  524. setter: function (value)
  525. {
  526. return value;
  527. }
  528. },
  529.  
  530. /**
  531. * The maximum value contained in the `data` array. Used for
  532. * `maximum` when `autoMax` is true.
  533. *
  534. * @attribute dataMaximum
  535. * @type Number
  536. */
  537. dataMaximum: {
  538. getter: function ()
  539. {
  540. if(!Y_Lang.isNumber(this._dataMaximum))
  541. {
  542. this._updateMinAndMax();
  543. }
  544. return this._dataMaximum;
  545. }
  546. },
  547.  
  548. /**
  549. * The maximum value that will appear on an axis.
  550. *
  551. * @attribute maximum
  552. * @type Number
  553. */
  554. maximum: {
  555. lazyAdd: false,
  556.  
  557. getter: "_maximumGetter",
  558.  
  559. setter: "_maximumSetter"
  560. },
  561.  
  562. /**
  563. * The minimum value contained in the `data` array. Used for
  564. * `minimum` when `autoMin` is true.
  565. *
  566. * @attribute dataMinimum
  567. * @type Number
  568. */
  569. dataMinimum: {
  570. getter: function ()
  571. {
  572. if(!Y_Lang.isNumber(this._dataMinimum))
  573. {
  574. this._updateMinAndMax();
  575. }
  576. return this._dataMinimum;
  577. }
  578. },
  579.  
  580. /**
  581. * The minimum value that will appear on an axis.
  582. *
  583. * @attribute minimum
  584. * @type Number
  585. */
  586. minimum: {
  587. lazyAdd: false,
  588.  
  589. getter: "_minimumGetter",
  590.  
  591. setter: "_minimumSetter"
  592. },
  593.  
  594. /**
  595. * Determines whether the maximum is calculated or explicitly
  596. * set by the user.
  597. *
  598. * @attribute setMax
  599. * @type Boolean
  600. */
  601. setMax: {
  602. readOnly: true,
  603.  
  604. getter: "_getSetMax"
  605. },
  606.  
  607. /**
  608. * Determines whether the minimum is calculated or explicitly
  609. * set by the user.
  610. *
  611. * @attribute setMin
  612. * @type Boolean
  613. */
  614. setMin: {
  615. readOnly: true,
  616.  
  617. getter: "_getSetMin"
  618. },
  619.  
  620. /**
  621. * Array of axis data
  622. *
  623. * @attribute data
  624. * @type Array
  625. */
  626. data: {
  627. getter: function ()
  628. {
  629. if(!this._data || this._updateTotalDataFlag)
  630. {
  631. this._updateTotalData();
  632. }
  633. return this._data;
  634. }
  635. },
  636.  
  637. /**
  638. * Array containing all the keys in the axis.
  639.  
  640. * @attribute keyCollection
  641. * @type Array
  642. */
  643. keyCollection: {
  644. getter: function()
  645. {
  646. var keys = this.get("keys"),
  647. i,
  648. col = [];
  649. for(i in keys)
  650. {
  651. if(keys.hasOwnProperty(i))
  652. {
  653. col.push(i);
  654. }
  655. }
  656. return col;
  657. },
  658. readOnly: true
  659. },
  660.  
  661. /**
  662. * Object which should have by the labelFunction
  663. *
  664. * @attribute labelFunctionScope
  665. * @type Object
  666. */
  667. labelFunctionScope: {}
  668. }
  669. });
  670.