[ Index ] |
PHP Cross Reference of Unnamed Project |
[Summary view] [Print] [Text view]
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"]});
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Thu Aug 11 10:00:09 2016 | Cross-referenced by PHPXref 0.7.1 |