[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/axis-numeric-base/ -> axis-numeric-base-debug.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-numeric-base', function (Y, NAME) {
   9  
  10  /**
  11   * Provides functionality for the handling of numeric axis data for a chart.
  12   *
  13   * @module charts
  14   * @submodule axis-numeric-base
  15   */
  16  var Y_Lang = Y.Lang;
  17  
  18  /**
  19   * NumericImpl contains logic for numeric data. NumericImpl is used by the following classes:
  20   * <ul>
  21   *      <li>{{#crossLink "NumericAxisBase"}}{{/crossLink}}</li>
  22   *      <li>{{#crossLink "NumericAxis"}}{{/crossLink}}</li>
  23   *  </ul>
  24   *
  25   * @class NumericImpl
  26   * @constructor
  27   * @submodule axis-numeric-base
  28   */
  29  function NumericImpl()
  30  {
  31  }
  32  
  33  NumericImpl.NAME = "numericImpl";
  34  
  35  NumericImpl.ATTRS = {
  36      /**
  37       * Indicates whether 0 should always be displayed.
  38       *
  39       * @attribute alwaysShowZero
  40       * @type Boolean
  41       */
  42      alwaysShowZero: {
  43          value: true
  44      },
  45  
  46      /**
  47       * Method used for formatting a label. This attribute allows for the default label formatting method to overridden.
  48       * The method use would need to implement the arguments below and return a `String` or an `HTMLElement`. The default
  49       * implementation of the method returns a `String`. The output of this method will be rendered to the DOM using
  50       * `appendChild`. If you override the `labelFunction` method and return an html string, you will also need to override
  51       * the Data' `appendLabelFunction` to accept html as a `String`.
  52       * <dl>
  53       *      <dt>val</dt><dd>Label to be formatted. (`String`)</dd>
  54       *      <dt>format</dt><dd>Object containing properties used to format the label. (optional)</dd>
  55       * </dl>
  56       *
  57       * @attribute labelFunction
  58       * @type Function
  59       */
  60  
  61      /**
  62       * Object containing properties used by the `labelFunction` to format a
  63       * label.
  64       *
  65       * @attribute labelFormat
  66       * @type Object
  67       */
  68      labelFormat: {
  69          value: {
  70              prefix: "",
  71              thousandsSeparator: "",
  72              decimalSeparator: "",
  73              decimalPlaces: "0",
  74              suffix: ""
  75          }
  76      },
  77  
  78      /**
  79       *Indicates how to round unit values.
  80       *  <dl>
  81       *      <dt>niceNumber</dt><dd>Units will be smoothed based on the number of ticks and data range.</dd>
  82       *      <dt>auto</dt><dd>If the range is greater than 1, the units will be rounded.</dd>
  83       *      <dt>numeric value</dt><dd>Units will be equal to the numeric value.</dd>
  84       *      <dt>null</dt><dd>No rounding will occur.</dd>
  85       *  </dl>
  86       *
  87       * @attribute roundingMethod
  88       * @type String
  89       * @default niceNumber
  90       */
  91      roundingMethod: {
  92          value: "niceNumber"
  93      },
  94  
  95      /**
  96       * Indicates the scaling for the chart. The default value is `linear`. For a logarithmic axis, set the value
  97       * to `logarithmic`.
  98       *
  99       * @attribute
 100       * @type String
 101       * @default linear
 102       */
 103      scaleType: {
 104          value: "linear"
 105      }
 106  };
 107  
 108  NumericImpl.prototype = {
 109      /**
 110       * @method initializer
 111       * @private
 112       */
 113      initializer: function() {
 114          this.after("alwaysShowZeroChange", this._keyChangeHandler);
 115          this.after("roundingMethodChange", this._keyChangeHandler);
 116          this.after("scaleTypeChange", this._keyChangeHandler);
 117      },
 118  
 119      /**
 120       * Formats a label based on the axis type and optionally specified format.
 121       *
 122       * @method
 123       * @param {Object} value
 124       * @param {Object} format Pattern used to format the value.
 125       * @return String
 126       */
 127      formatLabel: function(val, format)
 128      {
 129          if(format)
 130          {
 131              return Y.DataType.Number.format(val, format);
 132          }
 133          return val;
 134      },
 135  
 136      /**
 137       * Returns the sum of all values per key.
 138       *
 139       * @method getTotalByKey
 140       * @param {String} key The identifier for the array whose values will be calculated.
 141       * @return Number
 142       */
 143      getTotalByKey: function(key)
 144      {
 145          var total = 0,
 146              values = this.getDataByKey(key),
 147              i = 0,
 148              val,
 149              len = values ? values.length : 0;
 150          for(; i < len; ++i)
 151          {
 152             val = parseFloat(values[i]);
 153             if(!isNaN(val))
 154             {
 155                  total += val;
 156             }
 157          }
 158          return total;
 159      },
 160  
 161      /**
 162       * Returns the value corresponding to the origin on the axis.
 163       *
 164       * @method getOrigin
 165       * @return Number
 166       */
 167      getOrigin: function() {
 168          var origin = 0,
 169              min = this.get("minimum"),
 170              max = this.get("maximum");
 171          origin = Math.max(origin, min);
 172          origin = Math.min(origin, max);
 173          return origin;
 174      },
 175  
 176      /**
 177       * Type of data used in `Data`.
 178       *
 179       * @property _type
 180       * @readOnly
 181       * @private
 182       */
 183      _type: "numeric",
 184  
 185      /**
 186       * Helper method for getting a `roundingUnit` when calculating the minimum and maximum values.
 187       *
 188       * @method _getMinimumUnit
 189       * @param {Number} max Maximum number
 190       * @param {Number} min Minimum number
 191       * @param {Number} units Number of units on the axis
 192       * @return Number
 193       * @private
 194       */
 195      _getMinimumUnit:function(max, min, units)
 196      {
 197          return this._getNiceNumber(Math.ceil((max - min)/units));
 198      },
 199  
 200      /**
 201       * Calculates a nice rounding unit based on the range.
 202       *
 203       * @method _getNiceNumber
 204       * @param {Number} roundingUnit The calculated rounding unit.
 205       * @return Number
 206       * @private
 207       */
 208      _getNiceNumber: function(roundingUnit)
 209      {
 210          var tempMajorUnit = roundingUnit,
 211              order = Math.ceil(Math.log(tempMajorUnit) * 0.4342944819032518),
 212              roundedMajorUnit = Math.pow(10, order),
 213              roundedDiff;
 214  
 215          if (roundedMajorUnit / 2 >= tempMajorUnit)
 216          {
 217              roundedDiff = Math.floor((roundedMajorUnit / 2 - tempMajorUnit) / (Math.pow(10,order-1)/2));
 218              tempMajorUnit = roundedMajorUnit/2 - roundedDiff*Math.pow(10,order-1)/2;
 219          }
 220          else
 221          {
 222              tempMajorUnit = roundedMajorUnit;
 223          }
 224          if(!isNaN(tempMajorUnit))
 225          {
 226              return tempMajorUnit;
 227          }
 228          return roundingUnit;
 229  
 230      },
 231  
 232      /**
 233       * Calculates the maximum and minimum values for the `Data`.
 234       *
 235       * @method _updateMinAndMax
 236       * @private
 237       */
 238      _updateMinAndMax: function()
 239      {
 240          var data = this.get("data"),
 241              max,
 242              min,
 243              len,
 244              num,
 245              i = 0,
 246              setMax = this.get("setMax"),
 247              setMin = this.get("setMin");
 248          if(!setMax || !setMin)
 249          {
 250              if(data && data.length && data.length > 0)
 251              {
 252                  len = data.length;
 253                  for(; i < len; i++)
 254                  {
 255                      num = data[i];
 256                      if(isNaN(num))
 257                      {
 258                          max = setMax ? this._setMaximum : max;
 259                          min = setMin ? this._setMinimum : min;
 260                          continue;
 261                      }
 262  
 263                      if(setMin)
 264                      {
 265                          min = this._setMinimum;
 266                      }
 267                      else if(min === undefined)
 268                      {
 269                          min = num;
 270                      }
 271                      else
 272                      {
 273                          min = Math.min(num, min);
 274                      }
 275                      if(setMax)
 276                      {
 277                          max = this._setMaximum;
 278                      }
 279                      else if(max === undefined)
 280                      {
 281                          max = num;
 282                      }
 283                      else
 284                      {
 285                          max = Math.max(num, max);
 286                      }
 287  
 288                      this._actualMaximum = max;
 289                      this._actualMinimum = min;
 290                  }
 291              }
 292              if(this.get("scaleType") !== "logarithmic")
 293              {
 294                  this._roundMinAndMax(min, max, setMin, setMax);
 295              }
 296              else
 297              {
 298                  this._dataMaximum = max;
 299                  this._dataMinimum = min;
 300              }
 301          }
 302      },
 303  
 304      /**
 305       * Rounds the mimimum and maximum values based on the `roundingUnit` attribute.
 306       *
 307       * @method _roundMinAndMax
 308       * @param {Number} min Minimum value
 309       * @param {Number} max Maximum value
 310       * @private
 311       */
 312      _roundMinAndMax: function(min, max, setMin, setMax)
 313      {
 314          var roundingUnit,
 315              minimumRange,
 316              minGreaterThanZero = min >= 0,
 317              maxGreaterThanZero = max > 0,
 318              dataRangeGreater,
 319              maxRound,
 320              minRound,
 321              topTicks,
 322              botTicks,
 323              tempMax,
 324              tempMin,
 325              units = this.getTotalMajorUnits() - 1,
 326              alwaysShowZero = this.get("alwaysShowZero"),
 327              roundingMethod = this.get("roundingMethod"),
 328              useIntegers = (max - min)/units >= 1;
 329          if(roundingMethod)
 330          {
 331              if(roundingMethod === "niceNumber")
 332              {
 333                  roundingUnit = this._getMinimumUnit(max, min, units);
 334                  if(minGreaterThanZero && maxGreaterThanZero)
 335                  {
 336                      if((alwaysShowZero || min < roundingUnit) && !setMin)
 337                      {
 338                          min = 0;
 339                          roundingUnit = this._getMinimumUnit(max, min, units);
 340                      }
 341                      else
 342                      {
 343                         min = this._roundDownToNearest(min, roundingUnit);
 344                      }
 345                      if(setMax)
 346                      {
 347                          if(!alwaysShowZero)
 348                          {
 349                              min = max - (roundingUnit * units);
 350                          }
 351                      }
 352                      else if(setMin)
 353                      {
 354                          max = min + (roundingUnit * units);
 355                      }
 356                      else
 357                      {
 358                          max = this._roundUpToNearest(max, roundingUnit);
 359                      }
 360                  }
 361                  else if(maxGreaterThanZero && !minGreaterThanZero)
 362                  {
 363                      if(alwaysShowZero)
 364                      {
 365                          topTicks = Math.round(units/((-1 * min)/max + 1));
 366                          topTicks = Math.max(Math.min(topTicks, units - 1), 1);
 367                          botTicks = units - topTicks;
 368                          tempMax = Math.ceil( max/topTicks );
 369                          tempMin = Math.floor( min/botTicks ) * -1;
 370  
 371                          if(setMin)
 372                          {
 373                              while(tempMin < tempMax && botTicks >= 0)
 374                              {
 375                                  botTicks--;
 376                                  topTicks++;
 377                                  tempMax = Math.ceil( max/topTicks );
 378                                  tempMin = Math.floor( min/botTicks ) * -1;
 379                              }
 380                              //if there are any bottom ticks left calcualate the maximum by multiplying by the tempMin value
 381                              //if not, it's impossible to ensure that a zero is shown. skip it
 382                              if(botTicks > 0)
 383                              {
 384                                  max = tempMin * topTicks;
 385                              }
 386                              else
 387                              {
 388                                  max = min + (roundingUnit * units);
 389                              }
 390                          }
 391                          else if(setMax)
 392                          {
 393                              while(tempMax < tempMin && topTicks >= 0)
 394                              {
 395                                  botTicks++;
 396                                  topTicks--;
 397                                  tempMin = Math.floor( min/botTicks ) * -1;
 398                                  tempMax = Math.ceil( max/topTicks );
 399                              }
 400                              //if there are any top ticks left calcualate the minimum by multiplying by the tempMax value
 401                              //if not, it's impossible to ensure that a zero is shown. skip it
 402                              if(topTicks > 0)
 403                              {
 404                                  min = tempMax * botTicks * -1;
 405                              }
 406                              else
 407                              {
 408                                  min = max - (roundingUnit * units);
 409                              }
 410                          }
 411                          else
 412                          {
 413                              roundingUnit = Math.max(tempMax, tempMin);
 414                              roundingUnit = this._getNiceNumber(roundingUnit);
 415                              max = roundingUnit * topTicks;
 416                              min = roundingUnit * botTicks * -1;
 417                          }
 418                      }
 419                      else
 420                      {
 421                          if(setMax)
 422                          {
 423                              min = max - (roundingUnit * units);
 424                          }
 425                          else if(setMin)
 426                          {
 427                              max = min + (roundingUnit * units);
 428                          }
 429                          else
 430                          {
 431                              min = this._roundDownToNearest(min, roundingUnit);
 432                              max = this._roundUpToNearest(max, roundingUnit);
 433                          }
 434                      }
 435                  }
 436                  else
 437                  {
 438                      if(setMin)
 439                      {
 440                          if(alwaysShowZero)
 441                          {
 442                              max = 0;
 443                          }
 444                          else
 445                          {
 446                              max = min + (roundingUnit * units);
 447                          }
 448                      }
 449                      else if(!setMax)
 450                      {
 451                          if(alwaysShowZero || max === 0 || max + roundingUnit > 0)
 452                          {
 453                              max = 0;
 454                              roundingUnit = this._getMinimumUnit(max, min, units);
 455                              min = max - (roundingUnit * units);
 456                          }
 457                          else
 458                          {
 459                              min = this._roundDownToNearest(min, roundingUnit);
 460                              max = this._roundUpToNearest(max, roundingUnit);
 461                          }
 462                      }
 463                      else
 464                      {
 465                          min = max - (roundingUnit * units);
 466                      }
 467                  }
 468              }
 469              else if(roundingMethod === "auto")
 470              {
 471                  if(minGreaterThanZero && maxGreaterThanZero)
 472                  {
 473                      if((alwaysShowZero || min < (max-min)/units) && !setMin)
 474                      {
 475                          min = 0;
 476                      }
 477  
 478                      roundingUnit = (max - min)/units;
 479                      if(useIntegers)
 480                      {
 481                          roundingUnit = Math.ceil(roundingUnit);
 482                          max = min + (roundingUnit * units);
 483                      }
 484                      else
 485                      {
 486                          max = min + Math.ceil(roundingUnit * units * 100000)/100000;
 487  
 488                      }
 489                  }
 490                  else if(maxGreaterThanZero && !minGreaterThanZero)
 491                  {
 492                      if(alwaysShowZero)
 493                      {
 494                          topTicks = Math.round( units / ( (-1 * min) /max + 1) );
 495                          topTicks = Math.max(Math.min(topTicks, units - 1), 1);
 496                          botTicks = units - topTicks;
 497  
 498                          if(useIntegers)
 499                          {
 500                              tempMax = Math.ceil( max/topTicks );
 501                              tempMin = Math.floor( min/botTicks ) * -1;
 502                              roundingUnit = Math.max(tempMax, tempMin);
 503                              max = roundingUnit * topTicks;
 504                              min = roundingUnit * botTicks * -1;
 505                          }
 506                          else
 507                          {
 508                              tempMax = max/topTicks;
 509                              tempMin = min/botTicks * -1;
 510                              roundingUnit = Math.max(tempMax, tempMin);
 511                              max = Math.ceil(roundingUnit * topTicks * 100000)/100000;
 512                              min = Math.ceil(roundingUnit * botTicks * 100000)/100000 * -1;
 513                          }
 514                      }
 515                      else
 516                      {
 517                          roundingUnit = (max - min)/units;
 518                          if(useIntegers)
 519                          {
 520                              roundingUnit = Math.ceil(roundingUnit);
 521                          }
 522                          min = Math.round(this._roundDownToNearest(min, roundingUnit) * 100000)/100000;
 523                          max = Math.round(this._roundUpToNearest(max, roundingUnit) * 100000)/100000;
 524                      }
 525                  }
 526                  else
 527                  {
 528                      roundingUnit = (max - min)/units;
 529                      if(useIntegers)
 530                      {
 531                          roundingUnit = Math.ceil(roundingUnit);
 532                      }
 533                      if(alwaysShowZero || max === 0 || max + roundingUnit > 0)
 534                      {
 535                          max = 0;
 536                          roundingUnit = (max - min)/units;
 537                          if(useIntegers)
 538                          {
 539                              Math.ceil(roundingUnit);
 540                              min = max - (roundingUnit * units);
 541                          }
 542                          else
 543                          {
 544                              min = max - Math.ceil(roundingUnit * units * 100000)/100000;
 545                          }
 546                      }
 547                      else
 548                      {
 549                          min = this._roundDownToNearest(min, roundingUnit);
 550                          max = this._roundUpToNearest(max, roundingUnit);
 551                      }
 552  
 553                  }
 554              }
 555              else if(!isNaN(roundingMethod) && isFinite(roundingMethod))
 556              {
 557                  roundingUnit = roundingMethod;
 558                  minimumRange = roundingUnit * units;
 559                  dataRangeGreater = (max - min) > minimumRange;
 560                  minRound = this._roundDownToNearest(min, roundingUnit);
 561                  maxRound = this._roundUpToNearest(max, roundingUnit);
 562                  if(setMax)
 563                  {
 564                      min = max - minimumRange;
 565                  }
 566                  else if(setMin)
 567                  {
 568                      max = min + minimumRange;
 569                  }
 570                  else if(minGreaterThanZero && maxGreaterThanZero)
 571                  {
 572                      if(alwaysShowZero || minRound <= 0)
 573                      {
 574                          min = 0;
 575                      }
 576                      else
 577                      {
 578                          min = minRound;
 579                      }
 580                      max = min + minimumRange;
 581                  }
 582                  else if(maxGreaterThanZero && !minGreaterThanZero)
 583                  {
 584                      min = minRound;
 585                      max = maxRound;
 586                  }
 587                  else
 588                  {
 589                      if(alwaysShowZero || maxRound >= 0)
 590                      {
 591                          max = 0;
 592                      }
 593                      else
 594                      {
 595                          max = maxRound;
 596                      }
 597                      min = max - minimumRange;
 598                  }
 599              }
 600          }
 601          this._dataMaximum = max;
 602          this._dataMinimum = min;
 603      },
 604  
 605      /**
 606       * Rounds a Number to the nearest multiple of an input. For example, by rounding
 607       * 16 to the nearest 10, you will receive 20. Similar to the built-in function Math.round().
 608       *
 609       * @method _roundToNearest
 610       * @param {Number} number Number to round
 611       * @param {Number} nearest Multiple to round towards.
 612       * @return Number
 613       * @private
 614       */
 615      _roundToNearest: function(number, nearest)
 616      {
 617          nearest = nearest || 1;
 618          var roundedNumber = Math.round(this._roundToPrecision(number / nearest, 10)) * nearest;
 619          return this._roundToPrecision(roundedNumber, 10);
 620      },
 621  
 622      /**
 623       * Rounds a Number up to the nearest multiple of an input. For example, by rounding
 624       * 16 up to the nearest 10, you will receive 20. Similar to the built-in function Math.ceil().
 625       *
 626       * @method _roundUpToNearest
 627       * @param {Number} number Number to round
 628       * @param {Number} nearest Multiple to round towards.
 629       * @return Number
 630       * @private
 631       */
 632      _roundUpToNearest: function(number, nearest)
 633      {
 634          nearest = nearest || 1;
 635          return Math.ceil(this._roundToPrecision(number / nearest, 10)) * nearest;
 636      },
 637  
 638      /**
 639       * Rounds a Number down to the nearest multiple of an input. For example, by rounding
 640       * 16 down to the nearest 10, you will receive 10. Similar to the built-in function Math.floor().
 641       *
 642       * @method _roundDownToNearest
 643       * @param {Number} number Number to round
 644       * @param {Number} nearest Multiple to round towards.
 645       * @return Number
 646       * @private
 647       */
 648      _roundDownToNearest: function(number, nearest)
 649      {
 650          nearest = nearest || 1;
 651          return Math.floor(this._roundToPrecision(number / nearest, 10)) * nearest;
 652      },
 653  
 654      /**
 655       * Returns a coordinate corresponding to a data values.
 656       *
 657       * @method _getCoordFromValue
 658       * @param {Number} min The minimum for the axis.
 659       * @param {Number} max The maximum for the axis.
 660       * @param {Number} length The distance that the axis spans.
 661       * @param {Number} dataValue A value used to ascertain the coordinate.
 662       * @param {Number} offset Value in which to offset the coordinates.
 663       * @param {Boolean} reverse Indicates whether the coordinates should start from
 664       * the end of an axis. Only used in the numeric implementation.
 665       * @return Number
 666       * @private
 667       */
 668      _getCoordFromValue: function(min, max, length, dataValue, offset, reverse)
 669      {
 670          var range,
 671              multiplier,
 672              valuecoord,
 673              isNumber = Y_Lang.isNumber;
 674          dataValue = parseFloat(dataValue);
 675          if(isNumber(dataValue))
 676          {
 677              if(this.get("scaleType") === "logarithmic" && min > 0)
 678              {
 679                  min = Math.log(min);
 680                  max = Math.log(max);
 681                  dataValue = Math.log(dataValue);
 682              }
 683              range = max - min;
 684              multiplier = length/range;
 685              valuecoord = (dataValue - min) * multiplier;
 686              valuecoord = reverse ? offset - valuecoord : offset + valuecoord;
 687          }
 688          else
 689          {
 690              valuecoord = NaN;
 691          }
 692          return valuecoord;
 693      },
 694  
 695      /**
 696       * Rounds a number to a certain level of precision. Useful for limiting the number of
 697       * decimal places on a fractional number.
 698       *
 699       * @method _roundToPrecision
 700       * @param {Number} number Number to round
 701       * @param {Number} precision Multiple to round towards.
 702       * @return Number
 703       * @private
 704       */
 705      _roundToPrecision: function(number, precision)
 706      {
 707          precision = precision || 0;
 708          var decimalPlaces = Math.pow(10, precision);
 709          return Math.round(decimalPlaces * number) / decimalPlaces;
 710      }
 711  };
 712  
 713  Y.NumericImpl = NumericImpl;
 714  
 715  /**
 716   * NumericAxisBase manages numeric data for an axis.
 717   *
 718   * @class NumericAxisBase
 719   * @constructor
 720   * @extends AxisBase
 721   * @uses NumericImpl
 722   * @param {Object} config (optional) Configuration parameters.
 723   * @submodule axis-numeric-base
 724   */
 725  Y.NumericAxisBase = Y.Base.create("numericAxisBase", Y.AxisBase, [Y.NumericImpl]);
 726  
 727  
 728  }, '3.17.2', {"requires": ["axis-base"]});


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