[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/lib/yuilib/3.17.2/series-pie/ -> series-pie-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('series-pie', function (Y, NAME) {
   9  
  10  /**
  11   * Provides functionality for creating a pie series.
  12   *
  13   * @module charts
  14   * @submodule series-pie
  15   */
  16  /**
  17   * PieSeries visualizes data as a circular chart divided into wedges which represent data as a
  18   * percentage of a whole.
  19   *
  20   * @class PieSeries
  21   * @constructor
  22   * @extends SeriesBase
  23   * @uses Plots
  24   * @param {Object} config (optional) Configuration parameters.
  25   * @submodule series-pie
  26   */
  27  var CONFIG = Y.config,
  28      DOCUMENT = CONFIG.doc,
  29      _getClassName = Y.ClassNameManager.getClassName,
  30      SERIES_MARKER = _getClassName("seriesmarker");
  31  Y.PieSeries = Y.Base.create("pieSeries", Y.SeriesBase, [Y.Plots], {
  32      /**
  33       * Image map used for interactivity when rendered with canvas.
  34       *
  35       * @property _map
  36       * @type HTMLElement
  37       * @private
  38       */
  39      _map: null,
  40  
  41      /**
  42       * Image used for image map when rendered with canvas.
  43       *
  44       * @property _image
  45       * @type HTMLElement
  46       * @private
  47       */
  48      _image: null,
  49  
  50      /**
  51       * Creates or updates the image map when rendered with canvas.
  52       *
  53       * @method _setMap
  54       * @private
  55       */
  56      _setMap: function()
  57      {
  58          var id = "pieHotSpotMapi_" + Math.round(100000 * Math.random()),
  59              graph = this.get("graph"),
  60              graphic,
  61              cb,
  62              areaNode;
  63          if(graph)
  64          {
  65              cb = graph.get("contentBox");
  66          }
  67          else
  68          {
  69              graphic = this.get("graphic");
  70              cb = graphic.get("node");
  71          }
  72          if(this._image)
  73          {
  74              cb.removeChild(this._image);
  75              while(this._areaNodes && this._areaNodes.length > 0)
  76              {
  77                  areaNode = this._areaNodes.shift();
  78                  this._map.removeChild(areaNode);
  79              }
  80              cb.removeChild(this._map);
  81          }
  82          this._image = DOCUMENT.createElement("img");
  83          this._image.src = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAYAAAABCAYAAAD9yd/wAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSB" +
  84                          "JbWFnZVJlYWR5ccllPAAAABJJREFUeNpiZGBgSGPAAgACDAAIkABoFyloZQAAAABJRU5ErkJggg==";
  85          cb.appendChild(this._image);
  86          this._image.style.position = "absolute";
  87          this._image.style.left = "0px";
  88          this._image.style.top = "0px";
  89          this._image.setAttribute("usemap", "#" + id);
  90          this._image.style.zIndex = 3;
  91          this._image.style.opacity = 0;
  92          this._image.setAttribute("alt", "imagemap");
  93          this._map = DOCUMENT.createElement("map");
  94          cb.appendChild(this._map);
  95          this._map.setAttribute("name", id);
  96          this._map.setAttribute("id", id);
  97          this._areaNodes = [];
  98      },
  99  
 100      /**
 101       * Storage for `categoryDisplayName` attribute.
 102       *
 103       * @property _categoryDisplayName
 104       * @private
 105       */
 106      _categoryDisplayName: null,
 107  
 108      /**
 109       * Storage for `valueDisplayName` attribute.
 110       *
 111       * @property _valueDisplayName
 112       * @private
 113       */
 114      _valueDisplayName: null,
 115  
 116      /**
 117       * Adds event listeners.
 118       *
 119       * @method addListeners
 120       * @private
 121       */
 122      addListeners: function()
 123      {
 124          var categoryAxis = this.get("categoryAxis"),
 125              valueAxis = this.get("valueAxis");
 126          if(categoryAxis)
 127          {
 128              categoryAxis.after("dataReady", Y.bind(this._categoryDataChangeHandler, this));
 129              categoryAxis.after("dataUpdate", Y.bind(this._categoryDataChangeHandler, this));
 130          }
 131          if(valueAxis)
 132          {
 133              valueAxis.after("dataReady", Y.bind(this._valueDataChangeHandler, this));
 134              valueAxis.after("dataUpdate", Y.bind(this._valueDataChangeHandler, this));
 135          }
 136          this.after("categoryAxisChange", this.categoryAxisChangeHandler);
 137          this.after("valueAxisChange", this.valueAxisChangeHandler);
 138          this._stylesChangeHandle = this.after("stylesChange", this._updateHandler);
 139          this._visibleChangeHandle = this.after("visibleChange", this._handleVisibleChange);
 140      },
 141  
 142      /**
 143       * Draws the series.
 144       *
 145       * @method validate
 146       * @private
 147       */
 148      validate: function()
 149      {
 150          this.draw();
 151          this._renderered = true;
 152      },
 153  
 154      /**
 155       * Event handler for the categoryAxisChange event.
 156       *
 157       * @method _categoryAxisChangeHandler
 158       * @param {Object} e Event object.
 159       * @private
 160       */
 161      _categoryAxisChangeHandler: function()
 162      {
 163          var categoryAxis = this.get("categoryAxis");
 164          categoryAxis.after("dataReady", Y.bind(this._categoryDataChangeHandler, this));
 165          categoryAxis.after("dataUpdate", Y.bind(this._categoryDataChangeHandler, this));
 166      },
 167  
 168      /**
 169       * Event handler for the valueAxisChange event.
 170       *
 171       * @method _valueAxisChangeHandler
 172       * @param {Object} e Event object.
 173       * @private
 174       */
 175      _valueAxisChangeHandler: function()
 176      {
 177          var valueAxis = this.get("valueAxis");
 178          valueAxis.after("dataReady", Y.bind(this._valueDataChangeHandler, this));
 179          valueAxis.after("dataUpdate", Y.bind(this._valueDataChangeHandler, this));
 180      },
 181  
 182      /**
 183       * Constant used to generate unique id.
 184       *
 185       * @property GUID
 186       * @type String
 187       * @private
 188       */
 189      GUID: "pieseries",
 190  
 191      /**
 192       * Event handler for categoryDataChange event.
 193       *
 194       * @method _categoryDataChangeHandler
 195       * @param {Object} event Event object.
 196       * @private
 197       */
 198      _categoryDataChangeHandler: function()
 199      {
 200         if(this._rendered && this.get("categoryKey") && this.get("valueKey"))
 201          {
 202              this.draw();
 203          }
 204      },
 205  
 206      /**
 207       * Event handler for valueDataChange event.
 208       *
 209       * @method _valueDataChangeHandler
 210       * @param {Object} event Event object.
 211       * @private
 212       */
 213      _valueDataChangeHandler: function()
 214      {
 215          if(this._rendered && this.get("categoryKey") && this.get("valueKey"))
 216          {
 217              this.draw();
 218          }
 219      },
 220  
 221      /**
 222       * Returns the sum of all values for the series.
 223       *
 224       * @method getTotalValues
 225       * @return Number
 226       */
 227      getTotalValues: function()
 228      {
 229          var total = this.get("valueAxis").getTotalByKey(this.get("valueKey"));
 230          return total;
 231      },
 232  
 233      /**
 234       * Draws the series. Overrides the base implementation.
 235       *
 236       * @method draw
 237       * @protected
 238       */
 239      draw: function()
 240      {
 241          var w = this.get("width"),
 242              h = this.get("height");
 243          if(isFinite(w) && isFinite(h) && w > 0 && h > 0)
 244          {
 245              this._rendered = true;
 246              if(this._drawing)
 247              {
 248                  this._callLater = true;
 249                  return;
 250              }
 251              this._drawing = true;
 252              this._callLater = false;
 253              this.drawSeries();
 254              this._drawing = false;
 255              if(this._callLater)
 256              {
 257                  this.draw();
 258              }
 259              else
 260              {
 261                  this.fire("drawingComplete");
 262              }
 263          }
 264      },
 265  
 266      /**
 267       * Draws the markers
 268       *
 269       * @method drawPlots
 270       * @protected
 271       */
 272      drawPlots: function()
 273      {
 274          var values = this.get("valueAxis").getDataByKey(this.get("valueKey")).concat(),
 275              totalValue = 0,
 276              itemCount = values.length,
 277              styles = this.get("styles").marker,
 278              fillColors = styles.fill.colors,
 279              fillAlphas = styles.fill.alphas || ["1"],
 280              borderColors = styles.border.colors,
 281              borderWeights = [styles.border.weight],
 282              borderAlphas = [styles.border.alpha],
 283              tbw = borderWeights.concat(),
 284              tbc = borderColors.concat(),
 285              tba = borderAlphas.concat(),
 286              tfc,
 287              tfa,
 288              padding = styles.padding,
 289              graphic = this.get("graphic"),
 290              minDimension = Math.min(graphic.get("width"), graphic.get("height")),
 291              w = minDimension - (padding.left + padding.right),
 292              h = minDimension - (padding.top + padding.bottom),
 293              startAngle = -90,
 294              halfWidth = w / 2,
 295              halfHeight = h / 2,
 296              radius = Math.min(halfWidth, halfHeight),
 297              i = 0,
 298              value,
 299              angle = 0,
 300              lc,
 301              la,
 302              lw,
 303              wedgeStyle,
 304              marker,
 305              graphOrder = this.get("graphOrder") || 0,
 306              isCanvas = Y.Graphic.NAME === "canvasGraphic";
 307          for(; i < itemCount; ++i)
 308          {
 309              value = parseFloat(values[i]);
 310  
 311              values.push(value);
 312              if(!isNaN(value))
 313              {
 314                  totalValue += value;
 315              }
 316          }
 317  
 318          tfc = fillColors ? fillColors.concat() : null;
 319          tfa = fillAlphas ? fillAlphas.concat() : null;
 320          this._createMarkerCache();
 321          if(isCanvas)
 322          {
 323              this._setMap();
 324              this._image.width = w;
 325              this._image.height = h;
 326          }
 327          for(i = 0; i < itemCount; i++)
 328          {
 329              value = values[i];
 330              if(totalValue === 0)
 331              {
 332                  angle = 360 / values.length;
 333              }
 334              else
 335              {
 336                  angle = 360 * (value / totalValue);
 337              }
 338              if(tfc && tfc.length < 1)
 339              {
 340                  tfc = fillColors.concat();
 341              }
 342              if(tfa && tfa.length < 1)
 343              {
 344                  tfa = fillAlphas.concat();
 345              }
 346              if(tbw && tbw.length < 1)
 347              {
 348                  tbw = borderWeights.concat();
 349              }
 350              if(tbw && tbc.length < 1)
 351              {
 352                  tbc = borderColors.concat();
 353              }
 354              if(tba && tba.length < 1)
 355              {
 356                  tba = borderAlphas.concat();
 357              }
 358              lw = tbw ? tbw.shift() : null;
 359              lc = tbc ? tbc.shift() : null;
 360              la = tba ? tba.shift() : null;
 361              startAngle += angle;
 362              wedgeStyle = {
 363                  border: {
 364                      color:lc,
 365                      weight:lw,
 366                      alpha:la
 367                  },
 368                  fill: {
 369                      color:tfc ? tfc.shift() : this._getDefaultColor(i, "slice"),
 370                      alpha:tfa ? tfa.shift() : null
 371                  },
 372                  type: "pieslice",
 373                  arc: angle,
 374                  radius: radius,
 375                  startAngle: startAngle,
 376                  cx: halfWidth,
 377                  cy: halfHeight,
 378                  width: w,
 379                  height: h
 380              };
 381              marker = this.getMarker(wedgeStyle, graphOrder, i);
 382              if(isCanvas)
 383              {
 384                  this._addHotspot(wedgeStyle, graphOrder, i);
 385              }
 386          }
 387          this._clearMarkerCache();
 388      },
 389  
 390      /**
 391       * @protected
 392       *
 393       * Method used by `styles` setter. Overrides base implementation.
 394       *
 395       * @method _setStyles
 396       * @param {Object} newStyles Hash of properties to update.
 397       * @return Object
 398       */
 399      _setStyles: function(val)
 400      {
 401          if(!val.marker)
 402          {
 403              val = {marker:val};
 404          }
 405          val = this._parseMarkerStyles(val);
 406          return Y.PieSeries.superclass._mergeStyles.apply(this, [val, this._getDefaultStyles()]);
 407      },
 408  
 409      /**
 410       *  Adds an interactive map when rendering in canvas.
 411       *
 412       *  @method _addHotspot
 413       *  @param {Object} cfg Object containing data used to draw the hotspot
 414       *  @param {Number} seriesIndex Index of series in the `seriesCollection`.
 415       *  @param {Number} index Index of the marker using the hotspot.
 416       *  @private
 417       */
 418      _addHotspot: function(cfg, seriesIndex, index)
 419      {
 420          var areaNode = DOCUMENT.createElement("area"),
 421              i = 1,
 422              x = cfg.cx,
 423              y = cfg.cy,
 424              arc = cfg.arc,
 425              startAngle = cfg.startAngle - arc,
 426              endAngle = cfg.startAngle,
 427              radius = cfg.radius,
 428              ax = x + Math.cos(startAngle / 180 * Math.PI) * radius,
 429              ay = y + Math.sin(startAngle / 180 * Math.PI) * radius,
 430              bx = x + Math.cos(endAngle / 180 * Math.PI) * radius,
 431              by = y + Math.sin(endAngle / 180 * Math.PI) * radius,
 432              numPoints = Math.floor(arc/10) - 1,
 433              divAngle = (arc/(Math.floor(arc/10)) / 180) * Math.PI,
 434              angleCoord = Math.atan((ay - y)/(ax - x)),
 435              pts = x + ", " + y + ", " + ax + ", " + ay,
 436              cosAng,
 437              sinAng,
 438              multDivAng;
 439          for(i = 1; i <= numPoints; ++i)
 440          {
 441              multDivAng = divAngle * i;
 442              cosAng = Math.cos(angleCoord + multDivAng);
 443              sinAng = Math.sin(angleCoord + multDivAng);
 444              if(startAngle <= 90)
 445              {
 446                  pts += ", " + (x + (radius * Math.cos(angleCoord + (divAngle * i))));
 447                  pts += ", " + (y + (radius * Math.sin(angleCoord + (divAngle * i))));
 448              }
 449              else
 450              {
 451                  pts += ", " + (x - (radius * Math.cos(angleCoord + (divAngle * i))));
 452                  pts += ", " + (y - (radius * Math.sin(angleCoord + (divAngle * i))));
 453              }
 454          }
 455          pts += ", " + bx + ", " + by;
 456          pts += ", " + x + ", " + y;
 457          this._map.appendChild(areaNode);
 458          areaNode.setAttribute("class", SERIES_MARKER);
 459          areaNode.setAttribute("id", "hotSpot_" + seriesIndex + "_" + index);
 460          areaNode.setAttribute("shape", "polygon");
 461          areaNode.setAttribute("coords", pts);
 462          this._areaNodes.push(areaNode);
 463  
 464      },
 465  
 466      /**
 467       * Resizes and positions markers based on a mouse interaction.
 468       *
 469       * @method updateMarkerState
 470       * @param {String} type state of the marker
 471       * @param {Number} i index of the marker
 472       * @protected
 473       */
 474      updateMarkerState: function(type, i)
 475      {
 476          if(this._markers[i])
 477          {
 478              var state = this._getState(type),
 479                  markerStyles,
 480                  indexStyles,
 481                  marker = this._markers[i],
 482                  styles = this.get("styles").marker;
 483              markerStyles = state === "off" || !styles[state] ? styles : styles[state];
 484              indexStyles = this._mergeStyles(markerStyles, {});
 485              indexStyles.fill.color = indexStyles.fill.colors[i % indexStyles.fill.colors.length];
 486              indexStyles.fill.alpha = indexStyles.fill.alphas[i % indexStyles.fill.alphas.length];
 487              marker.set(indexStyles);
 488          }
 489      },
 490  
 491      /**
 492       * Creates a shape to be used as a marker.
 493       *
 494       * @method _createMarker
 495       * @param {Object} styles Hash of style properties.
 496       * @return Shape
 497       * @private
 498       */
 499      _createMarker: function(styles)
 500      {
 501          var graphic = this.get("graphic"),
 502              marker,
 503              cfg = this._copyObject(styles);
 504          marker = graphic.addShape(cfg);
 505          marker.addClass(SERIES_MARKER);
 506          return marker;
 507      },
 508  
 509      /**
 510       * Creates a cache of markers for reuse.
 511       *
 512       * @method _createMarkerCache
 513       * @private
 514       */
 515      _clearMarkerCache: function()
 516      {
 517          var len = this._markerCache.length,
 518              i = 0,
 519              marker;
 520          for(; i < len; ++i)
 521          {
 522              marker = this._markerCache[i];
 523              if(marker)
 524              {
 525                  marker.destroy();
 526              }
 527          }
 528          this._markerCache = [];
 529      },
 530  
 531      /**
 532       * Gets the default style values for the markers.
 533       *
 534       * @method _getPlotDefaults
 535       * @return Object
 536       * @private
 537       */
 538      _getPlotDefaults: function()
 539      {
 540           var defs = {
 541              padding:{
 542                  top: 0,
 543                  left: 0,
 544                  right: 0,
 545                  bottom: 0
 546              },
 547              fill:{
 548                  alphas:["1"]
 549              },
 550              border: {
 551                  weight: 0,
 552                  alpha: 1
 553              }
 554          };
 555          defs.fill.colors = this._defaultSliceColors;
 556          defs.border.colors = this._defaultBorderColors;
 557          return defs;
 558      }
 559  }, {
 560      ATTRS: {
 561          /**
 562           * Read-only attribute indicating the type of series.
 563           *
 564           * @attribute type
 565           * @type String
 566           * @default pie
 567           */
 568          type: {
 569              value: "pie"
 570          },
 571  
 572          /**
 573           * Order of this instance of this `type`.
 574           *
 575           * @attribute order
 576           * @type Number
 577           */
 578          order: {},
 579  
 580          /**
 581           * Reference to the `Graph` in which the series is drawn into.
 582           *
 583           * @attribute graph
 584           * @type Graph
 585           */
 586          graph: {},
 587  
 588          /**
 589           * Reference to the `Axis` instance used for assigning
 590           * category values to the graph.
 591           *
 592           * @attribute categoryAxis
 593           * @type Axis
 594           */
 595          categoryAxis: {
 596              value: null,
 597  
 598              validator: function(value)
 599              {
 600                  return value !== this.get("categoryAxis");
 601              }
 602          },
 603  
 604          /**
 605           * Reference to the `Axis` instance used for assigning
 606           * series values to the graph.
 607           *
 608           * @attribute categoryAxis
 609           * @type Axis
 610           */
 611          valueAxis: {
 612              value: null,
 613  
 614              validator: function(value)
 615              {
 616                  return value !== this.get("valueAxis");
 617              }
 618          },
 619  
 620          /**
 621           * Indicates which array to from the hash of value arrays in
 622           * the category `Axis` instance.
 623           *
 624           * @attribute categoryKey
 625           * @type String
 626           */
 627          categoryKey: {
 628              value: null,
 629  
 630              validator: function(value)
 631              {
 632                  return value !== this.get("categoryKey");
 633              }
 634          },
 635          /**
 636           * Indicates which array to from the hash of value arrays in
 637           * the value `Axis` instance.
 638           *
 639           * @attribute valueKey
 640           * @type String
 641           */
 642          valueKey: {
 643              value: null,
 644  
 645              validator: function(value)
 646              {
 647                  return value !== this.get("valueKey");
 648              }
 649          },
 650  
 651          /**
 652           * Name used for for displaying category data
 653           *
 654           * @attribute categoryDisplayName
 655           * @type String
 656           */
 657          categoryDisplayName: {
 658              setter: function(val)
 659              {
 660                  this._categoryDisplayName = val;
 661                  return val;
 662              },
 663  
 664              getter: function()
 665              {
 666                  return this._categoryDisplayName || this.get("categoryKey");
 667              }
 668          },
 669  
 670          /**
 671           * Name used for for displaying value data
 672           *
 673           * @attribute valueDisplayName
 674           * @type String
 675           */
 676          valueDisplayName: {
 677              setter: function(val)
 678              {
 679                  this._valueDisplayName = val;
 680                  return val;
 681              },
 682  
 683              getter: function()
 684              {
 685                  return this._valueDisplayName || this.get("valueKey");
 686              }
 687          },
 688  
 689          /**
 690           * @attribute slices
 691           * @type Array
 692           * @private
 693           */
 694          slices: null
 695  
 696          /**
 697           * Style properties used for drawing markers. This attribute is inherited from `MarkerSeries`. Below are  the default
 698           * values:
 699           *  <dl>
 700           *      <dt>fill</dt><dd>A hash containing the following values:
 701           *          <dl>
 702           *              <dt>colors</dt><dd>An array of colors to be used for the marker fills. The color for each marker  is
 703           *              retrieved from the array below:<br/>
 704           *              `["#66007f", "#a86f41", "#295454", "#996ab2", "#e8cdb7", "#90bdbd","#000000","#c3b8ca", "#968373", "#678585"]`
 705           *              </dd>
 706           *              <dt>alphas</dt><dd>An array of alpha references (Number from 0 to 1) indicating the opacity of each marker
 707           *              fill. The default value is [1].</dd>
 708           *          </dl>
 709           *      </dd>
 710           *      <dt>border</dt><dd>A hash containing the following values:
 711           *          <dl>
 712           *              <dt>color</dt><dd>An array of colors to be used for the marker borders. The color for each marker is
 713           *              retrieved from the array below:<br/>
 714           *              `["#205096", "#b38206", "#000000", "#94001e", "#9d6fa0", "#e55b00", "#5e85c9", "#adab9e", "#6ac291", "#006457"]`
 715           *              <dt>alpha</dt><dd>Number from 0 to 1 indicating the opacity of the marker border. The default value is 1.</dd>
 716           *              <dt>weight</dt><dd>Number indicating the width of the border. The default value is 1.</dd>
 717           *          </dl>
 718           *      </dd>
 719           *      <dt>over</dt><dd>hash containing styles for markers when highlighted by a `mouseover` event. The default
 720           *      values for each style is null. When an over style is not set, the non-over value will be used. For example,
 721           *      the default value for `marker.over.fill.color` is equivalent to `marker.fill.color`.</dd>
 722           *  </dl>
 723           *
 724           * @attribute styles
 725           * @type Object
 726           */
 727      }
 728  });
 729  
 730  
 731  }, '3.17.2', {"requires": ["series-base", "series-plot-util"]});


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