[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/axis-base/ -> axis-base.js (source)

   1  /*
   2  YUI 3.17.2 (build 9c3c78e)
   3  Copyright 2014 Yahoo! Inc. All rights reserved.
   4  Licensed under the BSD License.
   5  http://yuilibrary.com/license/
   6  */
   7  
   8  YUI.add('axis-base', function (Y, NAME) {
   9  
  10  /**
  11   * The Charts widget provides an api for displaying data
  12   * graphically.
  13   *
  14   * @module charts
  15   * @main charts
  16   */
  17  
  18  /**
  19   * Provides functionality for the handling of axis data in a chart.
  20   *
  21   * @module charts
  22   * @submodule axis-base
  23   */
  24  var Y_Lang = Y.Lang;
  25  
  26  /**
  27   * The Renderer class is a base class for chart components that use the `styles`
  28   * attribute.
  29   *
  30   * @module charts
  31   * @class Renderer
  32   * @constructor
  33   */
  34  function Renderer(){}
  35  
  36  Renderer.ATTRS = {
  37          /**
  38           * Style properties for class
  39           *
  40           * @attribute styles
  41           * @type Object
  42           */
  43          styles:
  44          {
  45              getter: function()
  46              {
  47                  this._styles = this._styles || this._getDefaultStyles();
  48                  return this._styles;
  49              },
  50  
  51              setter: function(val)
  52              {
  53                  this._styles = this._setStyles(val);
  54              }
  55          },
  56  
  57          /**
  58           * The graphic in which drawings will be rendered.
  59           *
  60           * @attribute graphic
  61           * @type Graphic
  62           */
  63          graphic: {}
  64  };
  65  Renderer.NAME = "renderer";
  66  
  67  Renderer.prototype = {
  68      /**
  69       * Storage for `styles` attribute.
  70       *
  71       * @property _styles
  72       * @type Object
  73       * @private
  74       */
  75      _styles: null,
  76  
  77      /**
  78       * Method used by `styles` setter.
  79       *
  80       * @method _setStyles
  81       * @param {Object} newStyles Hash of properties to update.
  82       * @return Object
  83       * @protected
  84       */
  85      _setStyles: function(newstyles)
  86      {
  87          var styles = this.get("styles");
  88          return this._mergeStyles(newstyles, styles);
  89      },
  90  
  91      /**
  92       * Merges to object literals so that only specified properties are
  93       * overwritten.
  94       *
  95       * @method _mergeStyles
  96       * @param {Object} a Hash of new styles
  97       * @param {Object} b Hash of original styles
  98       * @return Object
  99       * @protected
 100       */
 101      _mergeStyles: function(a, b)
 102      {
 103          if(!b)
 104          {
 105              b = {};
 106          }
 107          var newstyles = Y.merge(b, {});
 108          Y.Object.each(a, function(value, key)
 109          {
 110              if(b.hasOwnProperty(key) && Y_Lang.isObject(value) && !Y_Lang.isFunction(value) && !Y_Lang.isArray(value))
 111              {
 112                  newstyles[key] = this._mergeStyles(value, b[key]);
 113              }
 114              else
 115              {
 116                  newstyles[key] = value;
 117              }
 118          }, this);
 119          return newstyles;
 120      },
 121  
 122      /**
 123       * Copies an object literal.
 124       *
 125       * @method _copyObject
 126       * @param {Object} obj Object literal to be copied.
 127       * @return Object
 128       * @private
 129       */
 130      _copyObject: function(obj) {
 131          var newObj = {},
 132              key,
 133              val;
 134          for(key in obj)
 135          {
 136              if(obj.hasOwnProperty(key))
 137              {
 138                  val = obj[key];
 139                  if(typeof val === "object" && !Y_Lang.isArray(val))
 140                  {
 141                      newObj[key] = this._copyObject(val);
 142                  }
 143                  else
 144                  {
 145                      newObj[key] = val;
 146                  }
 147              }
 148          }
 149          return newObj;
 150      },
 151  
 152      /**
 153       * Gets the default value for the `styles` attribute.
 154       *
 155       * @method _getDefaultStyles
 156       * @return Object
 157       * @protected
 158       */
 159      _getDefaultStyles: function()
 160      {
 161          return {padding:{
 162              top:0,
 163              right: 0,
 164              bottom: 0,
 165              left: 0
 166          }};
 167      }
 168  };
 169  
 170  Y.augment(Renderer, Y.Attribute);
 171  Y.Renderer = Renderer;
 172  
 173  /**
 174   * The axis-base submodule contains functionality for the handling of axis data in a chart.
 175   *
 176   * @module charts
 177   * @submodule axis-base
 178   */
 179  /**
 180   * An abstract class that provides the core functionality used by the following classes:
 181   * <ul>
 182   *      <li>{{#crossLink "CategoryAxisBase"}}{{/crossLink}}</li>
 183   *      <li>{{#crossLink "NumericAxisBase"}}{{/crossLink}}</li>
 184   *      <li>{{#crossLink "StackedAxisBase"}}{{/crossLink}}</li>
 185   *      <li>{{#crossLink "TimeAxisBase"}}{{/crossLink}}</li>
 186   *      <li>{{#crossLink "CategoryAxis"}}{{/crossLink}}</li>
 187   *      <li>{{#crossLink "NumericAxis"}}{{/crossLink}}</li>
 188   *      <li>{{#crossLink "StackedAxis"}}{{/crossLink}}</li>
 189   *      <li>{{#crossLink "TimeAxis"}}{{/crossLink}}</li>
 190   *  </ul>
 191   *
 192   * @class AxisBase
 193   * @constructor
 194   * @extends Base
 195   * @uses Renderer
 196   * @param {Object} config (optional) Configuration parameters.
 197   * @submodule axis-base
 198   */
 199  Y.AxisBase = Y.Base.create("axisBase", Y.Base, [Y.Renderer], {
 200      /**
 201       * @method initializer
 202       * @private
 203       */
 204      initializer: function()
 205      {
 206          this.after("minimumChange", Y.bind(this._keyChangeHandler, this));
 207          this.after("maximumChange", Y.bind(this._keyChangeHandler, this));
 208          this.after("keysChange", this._keyChangeHandler);
 209          this.after("dataProviderChange", this._dataProviderChangeHandler);
 210      },
 211  
 212      /**
 213       * Returns the value corresponding to the origin on the axis.
 214       *
 215       * @method getOrigin
 216       * @return Number
 217       */
 218      getOrigin: function() {
 219          return this.get("minimum");
 220      },
 221  
 222      /**
 223       * Handles changes to `dataProvider`.
 224       *
 225       * @method _dataProviderChangeHandler
 226       * @param {Object} e Event object.
 227       * @private
 228       */
 229      _dataProviderChangeHandler: function()
 230      {
 231          var keyCollection = this.get("keyCollection").concat(),
 232              keys = this.get("keys"),
 233              i;
 234          if(keys)
 235          {
 236              for(i in keys)
 237              {
 238                  if(keys.hasOwnProperty(i))
 239                  {
 240                      delete keys[i];
 241                  }
 242              }
 243          }
 244          if(keyCollection && keyCollection.length)
 245          {
 246              this.set("keys", keyCollection);
 247          }
 248      },
 249  
 250      /**
 251       * Calculates the maximum and minimum values for the `Data`.
 252       *
 253       * @method _updateMinAndMax
 254       * @private
 255       */
 256      _updateMinAndMax: function() {
 257      },
 258  
 259      /**
 260       * Constant used to generate unique id.
 261       *
 262       * @property GUID
 263       * @type String
 264       * @private
 265       */
 266      GUID: "yuibaseaxis",
 267  
 268      /**
 269       * Type of data used in `Axis`.
 270       *
 271       * @property _type
 272       * @type String
 273       * @readOnly
 274       * @private
 275       */
 276      _type: null,
 277  
 278      /**
 279       * Storage for `setMaximum` attribute.
 280       *
 281       * @property _setMaximum
 282       * @type Object
 283       * @private
 284       */
 285      _setMaximum: null,
 286  
 287      /**
 288       * Storage for `setMinimum` attribute.
 289       *
 290       * @property _setMinimum
 291       * @type Object
 292       * @private
 293       */
 294      _setMinimum: null,
 295  
 296      /**
 297       * Reference to data array.
 298       *
 299       * @property _data
 300       * @type Array
 301       * @private
 302       */
 303      _data: null,
 304  
 305      /**
 306       * Indicates whether the all data is up to date.
 307       *
 308       * @property _updateTotalDataFlag
 309       * @type Boolean
 310       * @private
 311       */
 312      _updateTotalDataFlag: true,
 313  
 314      /**
 315       * Storage for `dataReady` attribute.
 316       *
 317       * @property _dataReady
 318       * @type Boolean
 319       * @readOnly
 320       * @private
 321       */
 322      _dataReady: false,
 323  
 324      /**
 325       * Adds an array to the key hash.
 326       *
 327       * @method addKey
 328       * @param value Indicates what key to use in retrieving
 329       * the array.
 330       */
 331      addKey: function (value)
 332      {
 333          this.set("keys", value);
 334      },
 335  
 336      /**
 337       * Gets an array of values based on a key.
 338       *
 339       * @method _getKeyArray
 340       * @param {String} key Value key associated with the data array.
 341       * @param {Array} data Array in which the data resides.
 342       * @return Array
 343       * @private
 344       */
 345      _getKeyArray: function(key, data)
 346      {
 347          var i = 0,
 348              obj,
 349              keyArray = [],
 350              len = data.length;
 351          for(; i < len; ++i)
 352          {
 353              obj = data[i];
 354              keyArray[i] = obj[key];
 355          }
 356          return keyArray;
 357      },
 358  
 359      /**
 360       * Updates the total data array.
 361       *
 362       * @method _updateTotalData
 363       * @private
 364       */
 365      _updateTotalData: function()
 366      {
 367          var keys = this.get("keys"),
 368              i;
 369          this._data = [];
 370          for(i in keys)
 371          {
 372              if(keys.hasOwnProperty(i))
 373              {
 374                  this._data = this._data.concat(keys[i]);
 375              }
 376          }
 377          this._updateTotalDataFlag = false;
 378      },
 379  
 380      /**
 381       * Removes an array from the key hash.
 382       *
 383       * @method removeKey
 384       * @param {String} value Indicates what key to use in removing from
 385       * the hash.
 386       */
 387      removeKey: function(value)
 388      {
 389          var keys = this.get("keys");
 390          if(keys.hasOwnProperty(value))
 391          {
 392              delete keys[value];
 393              this._keyChangeHandler();
 394          }
 395      },
 396  
 397      /**
 398       * Returns a value based of a key value and an index.
 399       *
 400       * @method getKeyValueAt
 401       * @param {String} key value used to look up the correct array
 402       * @param {Number} index within the array
 403       * @return Number
 404       */
 405      getKeyValueAt: function(key, index)
 406      {
 407          var value = NaN,
 408              keys = this.get("keys");
 409          if(keys[key] && Y_Lang.isNumber(parseFloat(keys[key][index])))
 410          {
 411              value = keys[key][index];
 412          }
 413          return parseFloat(value);
 414      },
 415  
 416      /**
 417       * Returns values based on key identifiers. When a string is passed as an argument, an array of values is returned.
 418       * When an array of keys is passed as an argument, an object literal with an array of values mapped to each key is
 419       * returned.
 420       *
 421       * @method getDataByKey
 422       * @param {String|Array} value value used to identify the array
 423       * @return Array|Object
 424       */
 425      getDataByKey: function (value)
 426      {
 427          var obj,
 428              i,
 429              len,
 430              key,
 431              keys = this.get("keys");
 432          if(Y_Lang.isArray(value))
 433          {
 434              obj = {};
 435              len = value.length;
 436              for(i = 0; i < len; i = i + 1)
 437              {
 438                  key = value[i];
 439                  if(keys[key])
 440                  {
 441                      obj[key] = this.getDataByKey(key);
 442                  }
 443              }
 444          }
 445          else if(keys[value])
 446          {
 447              obj = keys[value];
 448          }
 449          else
 450          {
 451              obj = null;
 452          }
 453          return obj;
 454      },
 455  
 456      /**
 457       * Returns the total number of majorUnits that will appear on an axis.
 458       *
 459       * @method getTotalMajorUnits
 460       * @return Number
 461       */
 462      getTotalMajorUnits: function()
 463      {
 464          var units,
 465              majorUnit = this.get("styles").majorUnit;
 466          units = majorUnit.count;
 467          return units;
 468      },
 469  
 470      /**
 471       * Gets the distance that the first and last ticks are offset from there respective
 472       * edges.
 473       *
 474       * @method getEdgeOffset
 475       * @param {Number} ct Number of ticks on the axis.
 476       * @param {Number} l Length (in pixels) of the axis.
 477       * @return Number
 478       */
 479      getEdgeOffset: function(ct, l)
 480      {
 481          var edgeOffset;
 482          if(this.get("calculateEdgeOffset")) {
 483              edgeOffset = (l/ct)/2;
 484          } else {
 485              edgeOffset = 0;
 486          }
 487          return edgeOffset;
 488      },
 489  
 490      /**
 491       * Updates the `Axis` after a change in keys.
 492       *
 493       * @method _keyChangeHandler
 494       * @param {Object} e Event object.
 495       * @private
 496       */
 497      _keyChangeHandler: function()
 498      {
 499          this._updateMinAndMax();
 500          this._updateTotalDataFlag = true;
 501          this.fire("dataUpdate");
 502      },
 503  
 504      /**
 505       * Gets the default value for the `styles` attribute. Overrides
 506       * base implementation.
 507       *
 508       * @method _getDefaultStyles
 509       * @return Object
 510       * @protected
 511       */
 512      _getDefaultStyles: function()
 513      {
 514          var axisstyles = {
 515              majorUnit: {
 516                  determinant:"count",
 517                  count:11,
 518                  distance:75
 519              }
 520          };
 521          return axisstyles;
 522      },
 523  
 524      /**
 525       * Getter method for maximum attribute.
 526       *
 527       * @method _maximumGetter
 528       * @return Number
 529       * @private
 530       */
 531      _maximumGetter: function ()
 532      {
 533          var max = this.get("dataMaximum"),
 534              min = this.get("minimum");
 535          //If all values are zero, force a range so that the Axis and related series
 536          //will still render.
 537          if(min === 0 && max === 0)
 538          {
 539              max = 10;
 540          }
 541          if(Y_Lang.isNumber(this._setMaximum))
 542          {
 543              max = this._setMaximum;
 544          }
 545          return parseFloat(max);
 546      },
 547  
 548      /**
 549       * Setter method for maximum attribute.
 550       *
 551       * @method _maximumSetter
 552       * @param {Object} value
 553       * @private
 554       */
 555      _maximumSetter: function (value)
 556      {
 557          this._setMaximum = parseFloat(value);
 558          return value;
 559      },
 560  
 561      /**
 562       * Getter method for minimum attribute.
 563       *
 564       * @method _minimumGetter
 565       * @return Number
 566       * @private
 567       */
 568      _minimumGetter: function ()
 569      {
 570          var min = this.get("dataMinimum");
 571          if(Y_Lang.isNumber(this._setMinimum))
 572          {
 573              min = this._setMinimum;
 574          }
 575          return parseFloat(min);
 576      },
 577  
 578      /**
 579       * Setter method for minimum attribute.
 580       *
 581       * @method _minimumSetter
 582       * @param {Object} value
 583       * @private
 584       */
 585      _minimumSetter: function(val)
 586      {
 587          this._setMinimum = parseFloat(val);
 588          return val;
 589      },
 590  
 591      /**
 592       * Indicates whether or not the maximum attribute has been explicitly set.
 593       *
 594       * @method _getSetMax
 595       * @return Boolean
 596       * @private
 597       */
 598      _getSetMax: function()
 599      {
 600          return Y_Lang.isNumber(this._setMaximum);
 601      },
 602  
 603  
 604      /**
 605       * Returns and array of coordinates corresponding to an array of data values.
 606       *
 607       * @method _getCoordsFromValues
 608       * @param {Number} min The minimum for the axis.
 609       * @param {Number} max The maximum for the axis.
 610       * @param {Number} length The distance that the axis spans.
 611       * @param {Array} dataValues An array of values.
 612       * @param {Number} offset Value in which to offset the coordinates.
 613       * @param {Boolean} reverse Indicates whether the coordinates should start from
 614       * the end of an axis. Only used in the numeric implementation.
 615       * @return Array
 616       * @private
 617       */
 618      _getCoordsFromValues: function(min, max, length, dataValues, offset, reverse)
 619      {
 620          var i,
 621              valuecoords = [],
 622              len = dataValues.length;
 623          for(i = 0; i < len; i = i + 1)
 624          {
 625              valuecoords.push(this._getCoordFromValue.apply(this, [min, max, length, dataValues[i], offset, reverse]));
 626          }
 627          return valuecoords;
 628      },
 629  
 630      /**
 631       * Returns and array of data values based on the axis' range and number of values.
 632       *
 633       * @method _getDataValuesByCount
 634       * @param {Number} count The number of values to be used.
 635       * @param {Number} min The minimum value of the axis.
 636       * @param {Number} max The maximum value of the axis.
 637       * @return Array
 638       * @private
 639       */
 640      _getDataValuesByCount: function(count, min, max)
 641      {
 642          var dataValues = [],
 643              dataValue = min,
 644              len = count - 1,
 645              range = max - min,
 646              increm = range/len,
 647              i;
 648          for(i = 0; i < len; i = i + 1)
 649          {
 650              dataValues.push(dataValue);
 651              dataValue = dataValue + increm;
 652          }
 653          dataValues.push(max);
 654          return dataValues;
 655      },
 656  
 657      /**
 658       * Indicates whether or not the minimum attribute has been explicitly set.
 659       *
 660       * @method _getSetMin
 661       * @return Boolean
 662       * @private
 663       */
 664      _getSetMin: function()
 665      {
 666          return Y_Lang.isNumber(this._setMinimum);
 667      }
 668  }, {
 669      ATTRS: {
 670          /**
 671           * Determines whether and offset is automatically calculated for the edges of the axis.
 672           *
 673           * @attribute calculateEdgeOffset
 674           * @type Boolean
 675           */
 676          calculateEdgeOffset: {
 677              value: false
 678          },
 679  
 680          labelFunction: {
 681              valueFn: function() {
 682                  return this.formatLabel;
 683              }
 684          },
 685  
 686          /**
 687           * Hash of array identifed by a string value.
 688           *
 689           * @attribute keys
 690           * @type Object
 691           */
 692          keys: {
 693              value: {},
 694  
 695              setter: function(val)
 696              {
 697                  var keys = {},
 698                      i,
 699                      len,
 700                      data = this.get("dataProvider");
 701                  if(Y_Lang.isArray(val))
 702                  {
 703                      len = val.length;
 704                      for(i = 0; i < len; ++i)
 705                      {
 706                          keys[val[i]] = this._getKeyArray(val[i], data);
 707                      }
 708  
 709                  }
 710                  else if(Y_Lang.isString(val))
 711                  {
 712                      keys = this.get("keys");
 713                      keys[val] = this._getKeyArray(val, data);
 714                  }
 715                  else
 716                  {
 717                      for(i in val)
 718                      {
 719                          if(val.hasOwnProperty(i))
 720                          {
 721                              keys[i] = this._getKeyArray(i, data);
 722                          }
 723                      }
 724                  }
 725                  this._updateTotalDataFlag = true;
 726                  return keys;
 727              }
 728          },
 729  
 730          /**
 731           *Returns the type of axis data
 732           *  <dl>
 733           *      <dt>time</dt><dd>Manages time data</dd>
 734           *      <dt>stacked</dt><dd>Manages stacked numeric data</dd>
 735           *      <dt>numeric</dt><dd>Manages numeric data</dd>
 736           *      <dt>category</dt><dd>Manages categorical data</dd>
 737           *  </dl>
 738           *
 739           * @attribute type
 740           * @type String
 741           */
 742          type:
 743          {
 744              readOnly: true,
 745  
 746              getter: function ()
 747              {
 748                  return this._type;
 749              }
 750          },
 751  
 752          /**
 753           * Instance of `ChartDataProvider` that the class uses
 754           * to build its own data.
 755           *
 756           * @attribute dataProvider
 757           * @type Array
 758           */
 759          dataProvider:{
 760              setter: function (value)
 761              {
 762                  return value;
 763              }
 764          },
 765  
 766          /**
 767           * The maximum value contained in the `data` array. Used for
 768           * `maximum` when `autoMax` is true.
 769           *
 770           * @attribute dataMaximum
 771           * @type Number
 772           */
 773          dataMaximum: {
 774              getter: function ()
 775              {
 776                  if(!Y_Lang.isNumber(this._dataMaximum))
 777                  {
 778                      this._updateMinAndMax();
 779                  }
 780                  return this._dataMaximum;
 781              }
 782          },
 783  
 784          /**
 785           * The maximum value that will appear on an axis.
 786           *
 787           * @attribute maximum
 788           * @type Number
 789           */
 790          maximum: {
 791              lazyAdd: false,
 792  
 793              getter: "_maximumGetter",
 794  
 795              setter: "_maximumSetter"
 796          },
 797  
 798          /**
 799           * The minimum value contained in the `data` array. Used for
 800           * `minimum` when `autoMin` is true.
 801           *
 802           * @attribute dataMinimum
 803           * @type Number
 804           */
 805          dataMinimum: {
 806              getter: function ()
 807              {
 808                  if(!Y_Lang.isNumber(this._dataMinimum))
 809                  {
 810                      this._updateMinAndMax();
 811                  }
 812                  return this._dataMinimum;
 813              }
 814          },
 815  
 816          /**
 817           * The minimum value that will appear on an axis.
 818           *
 819           * @attribute minimum
 820           * @type Number
 821           */
 822          minimum: {
 823              lazyAdd: false,
 824  
 825              getter: "_minimumGetter",
 826  
 827              setter: "_minimumSetter"
 828          },
 829  
 830          /**
 831           * Determines whether the maximum is calculated or explicitly
 832           * set by the user.
 833           *
 834           * @attribute setMax
 835           * @type Boolean
 836           */
 837          setMax: {
 838              readOnly: true,
 839  
 840              getter: "_getSetMax"
 841          },
 842  
 843          /**
 844           * Determines whether the minimum is calculated or explicitly
 845           * set by the user.
 846           *
 847           * @attribute setMin
 848           * @type Boolean
 849           */
 850          setMin: {
 851              readOnly: true,
 852  
 853              getter: "_getSetMin"
 854          },
 855  
 856          /**
 857           * Array of axis data
 858           *
 859           * @attribute data
 860           * @type Array
 861           */
 862          data: {
 863              getter: function ()
 864              {
 865                  if(!this._data || this._updateTotalDataFlag)
 866                  {
 867                      this._updateTotalData();
 868                  }
 869                  return this._data;
 870              }
 871          },
 872  
 873          /**
 874           * Array containing all the keys in the axis.
 875  
 876           * @attribute keyCollection
 877           * @type Array
 878           */
 879          keyCollection: {
 880              getter: function()
 881              {
 882                  var keys = this.get("keys"),
 883                      i,
 884                      col = [];
 885                  for(i in keys)
 886                  {
 887                      if(keys.hasOwnProperty(i))
 888                      {
 889                          col.push(i);
 890                      }
 891                  }
 892                  return col;
 893              },
 894              readOnly: true
 895          },
 896  
 897          /**
 898           * Object which should have by the labelFunction
 899           *
 900           * @attribute labelFunctionScope
 901           * @type Object
 902           */
 903          labelFunctionScope: {}
 904      }
 905  });
 906  
 907  
 908  }, '3.17.2', {"requires": ["classnamemanager", "datatype-number", "datatype-date", "base", "event-custom"]});


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1