src/cm/media/js/lib/yui/yui_3.10.3/build/series-cartesian/series-cartesian.js
changeset 525 89ef5ed3c48b
equal deleted inserted replaced
524:322d0feea350 525:89ef5ed3c48b
       
     1 /*
       
     2 YUI 3.10.3 (build 2fb5187)
       
     3 Copyright 2013 Yahoo! Inc. All rights reserved.
       
     4 Licensed under the BSD License.
       
     5 http://yuilibrary.com/license/
       
     6 */
       
     7 
       
     8 YUI.add('series-cartesian', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11  * Provides functionality for creating a cartesian chart series.
       
    12  *
       
    13  * @module charts
       
    14  * @submodule series-cartesian
       
    15  */
       
    16 var Y_Lang = Y.Lang;
       
    17 
       
    18 /**
       
    19  * An abstract class for creating series instances with horizontal and vertical axes.
       
    20  * CartesianSeries provides the core functionality used by the following classes:
       
    21  * <ul>
       
    22  *      <li>{{#crossLink "LineSeries"}}{{/crossLink}}</li>
       
    23  *      <li>{{#crossLink "MarkerSeries"}}{{/crossLink}}</li>
       
    24  *      <li>{{#crossLink "AreaSeries"}}{{/crossLink}}</li>
       
    25  *      <li>{{#crossLink "SplineSeries"}}{{/crossLink}}</li>
       
    26  *      <li>{{#crossLink "AreaSplineSeries"}}{{/crossLink}}</li>
       
    27  *      <li>{{#crossLink "ComboSeries"}}{{/crossLink}}</li>
       
    28  *      <li>{{#crossLink "ComboSplineSeries"}}{{/crossLink}}</li>
       
    29  *      <li>{{#crossLink "Histogram"}}{{/crossLink}}</li>
       
    30  *  </ul>
       
    31  *
       
    32  * @class CartesianSeries
       
    33  * @extends SeriesBase
       
    34  * @constructor
       
    35  * @param {Object} config (optional) Configuration parameters.
       
    36  * @submodule series-base
       
    37  */
       
    38 Y.CartesianSeries = Y.Base.create("cartesianSeries", Y.SeriesBase, [], {
       
    39     /**
       
    40      * Storage for `xDisplayName` attribute.
       
    41      *
       
    42      * @property _xDisplayName
       
    43      * @type String
       
    44      * @private
       
    45      */
       
    46     _xDisplayName: null,
       
    47 
       
    48     /**
       
    49      * Storage for `yDisplayName` attribute.
       
    50      *
       
    51      * @property _yDisplayName
       
    52      * @type String
       
    53      * @private
       
    54      */
       
    55     _yDisplayName: null,
       
    56 
       
    57     /**
       
    58      * Th x-coordinate for the left edge of the series.
       
    59      *
       
    60      * @property _leftOrigin
       
    61      * @type String
       
    62      * @private
       
    63      */
       
    64     _leftOrigin: null,
       
    65 
       
    66     /**
       
    67      * The y-coordinate for the bottom edge of the series.
       
    68      *
       
    69      * @property _bottomOrigin
       
    70      * @type String
       
    71      * @private
       
    72      */
       
    73     _bottomOrigin: null,
       
    74 
       
    75     /**
       
    76      * Adds event listeners.
       
    77      *
       
    78      * @method addListeners
       
    79      * @private
       
    80      */
       
    81     addListeners: function()
       
    82     {
       
    83         var xAxis = this.get("xAxis"),
       
    84             yAxis = this.get("yAxis");
       
    85         if(xAxis)
       
    86         {
       
    87             this._xDataReadyHandle = xAxis.after("dataReady", Y.bind(this._xDataChangeHandler, this));
       
    88             this._xDataUpdateHandle = xAxis.after("dataUpdate", Y.bind(this._xDataChangeHandler, this));
       
    89         }
       
    90         if(yAxis)
       
    91         {
       
    92             this._yDataReadyHandle = yAxis.after("dataReady", Y.bind(this._yDataChangeHandler, this));
       
    93             this._yDataUpdateHandle = yAxis.after("dataUpdate", Y.bind(this._yDataChangeHandler, this));
       
    94         }
       
    95         this._xAxisChangeHandle = this.after("xAxisChange", this._xAxisChangeHandler);
       
    96         this._yAxisChangeHandle = this.after("yAxisChange", this._yAxisChangeHandler);
       
    97         this._stylesChangeHandle = this.after("stylesChange", function() {
       
    98             var axesReady = this._updateAxisBase();
       
    99             if(axesReady)
       
   100             {
       
   101                 this.draw();
       
   102             }
       
   103         });
       
   104         this._widthChangeHandle = this.after("widthChange", function() {
       
   105             var axesReady = this._updateAxisBase();
       
   106             if(axesReady)
       
   107             {
       
   108                 this.draw();
       
   109             }
       
   110         });
       
   111         this._heightChangeHandle = this.after("heightChange", function() {
       
   112             var axesReady = this._updateAxisBase();
       
   113             if(axesReady)
       
   114             {
       
   115                 this.draw();
       
   116             }
       
   117         });
       
   118         this._visibleChangeHandle = this.after("visibleChange", this._handleVisibleChange);
       
   119     },
       
   120 
       
   121     /**
       
   122      * Event handler for the xAxisChange event.
       
   123      *
       
   124      * @method _xAxisChangeHandler
       
   125      * @param {Object} e Event object.
       
   126      * @private
       
   127      */
       
   128     _xAxisChangeHandler: function()
       
   129     {
       
   130         var xAxis = this.get("xAxis");
       
   131         xAxis.after("dataReady", Y.bind(this._xDataChangeHandler, this));
       
   132         xAxis.after("dataUpdate", Y.bind(this._xDataChangeHandler, this));
       
   133     },
       
   134 
       
   135     /**
       
   136      * Event handler the yAxisChange event.
       
   137      *
       
   138      * @method _yAxisChangeHandler
       
   139      * @param {Object} e Event object.
       
   140      * @private
       
   141      */
       
   142     _yAxisChangeHandler: function()
       
   143     {
       
   144         var yAxis = this.get("yAxis");
       
   145         yAxis.after("dataReady", Y.bind(this._yDataChangeHandler, this));
       
   146         yAxis.after("dataUpdate", Y.bind(this._yDataChangeHandler, this));
       
   147     },
       
   148 
       
   149     /**
       
   150      * Constant used to generate unique id.
       
   151      *
       
   152      * @property GUID
       
   153      * @type String
       
   154      * @private
       
   155      */
       
   156     GUID: "yuicartesianseries",
       
   157 
       
   158     /**
       
   159      * Event handler for xDataChange event.
       
   160      *
       
   161      * @method _xDataChangeHandler
       
   162      * @param {Object} event Event object.
       
   163      * @private
       
   164      */
       
   165     _xDataChangeHandler: function()
       
   166     {
       
   167         var axesReady = this._updateAxisBase();
       
   168         if(axesReady)
       
   169         {
       
   170             this.draw();
       
   171         }
       
   172     },
       
   173 
       
   174     /**
       
   175      * Event handler for yDataChange event.
       
   176      *
       
   177      * @method _yDataChangeHandler
       
   178      * @param {Object} event Event object.
       
   179      * @private
       
   180      */
       
   181     _yDataChangeHandler: function()
       
   182     {
       
   183         var axesReady = this._updateAxisBase();
       
   184         if(axesReady)
       
   185         {
       
   186             this.draw();
       
   187         }
       
   188     },
       
   189 
       
   190     /**
       
   191      * Checks to ensure that both xAxis and yAxis data are available. If so, set the `xData` and `yData` attributes
       
   192      * and return `true`. Otherwise, return `false`.
       
   193      *
       
   194      * @method _updateAxisBase
       
   195      * @return Boolean
       
   196      * @private
       
   197      */
       
   198     _updateAxisBase: function()
       
   199     {
       
   200         var xAxis = this.get("xAxis"),
       
   201             yAxis = this.get("yAxis"),
       
   202             xKey = this.get("xKey"),
       
   203             yKey = this.get("yKey"),
       
   204             yData,
       
   205             xData,
       
   206             xReady,
       
   207             yReady,
       
   208             ready;
       
   209         if(!xAxis || !yAxis || !xKey || !yKey)
       
   210         {
       
   211             ready = false;
       
   212         }
       
   213         else
       
   214         {
       
   215             xData = xAxis.getDataByKey(xKey);
       
   216             yData = yAxis.getDataByKey(yKey);
       
   217             if(Y_Lang.isArray(xKey))
       
   218             {
       
   219                 xReady = (xData && Y.Object.size(xData) > 0) ? this._checkForDataByKey(xData, xKey) : false;
       
   220             }
       
   221             else
       
   222             {
       
   223                 xReady = xData ? true : false;
       
   224             }
       
   225             if(Y_Lang.isArray(yKey))
       
   226             {
       
   227                 yReady = (yData && Y.Object.size(yData) > 0) ? this._checkForDataByKey(yData, yKey) : false;
       
   228             }
       
   229             else
       
   230             {
       
   231                 yReady = yData ? true : false;
       
   232             }
       
   233             ready = xReady && yReady;
       
   234             if(ready)
       
   235             {
       
   236                 this.set("xData", xData);
       
   237                 this.set("yData", yData);
       
   238             }
       
   239         }
       
   240         return ready;
       
   241     },
       
   242 
       
   243     /**
       
   244      * Checks to see if all keys of a data object exist and contain data.
       
   245      *
       
   246      * @method _checkForDataByKey
       
   247      * @param {Object} obj The object to check
       
   248      * @param {Array} keys The keys to check
       
   249      * @return Boolean
       
   250      * @private
       
   251      */
       
   252     _checkForDataByKey: function(obj, keys)
       
   253     {
       
   254         var i,
       
   255             len = keys.length,
       
   256             hasData = false;
       
   257         for(i = 0; i < len; i = i + 1)
       
   258         {
       
   259             if(obj[keys[i]])
       
   260             {
       
   261                 hasData = true;
       
   262                 break;
       
   263             }
       
   264         }
       
   265         return hasData;
       
   266     },
       
   267 
       
   268     /**
       
   269      * Draws the series is the xAxis and yAxis data are both available.
       
   270      *
       
   271      * @method validate
       
   272      * @private
       
   273      */
       
   274     validate: function()
       
   275     {
       
   276         if((this.get("xData") && this.get("yData")) || this._updateAxisBase())
       
   277         {
       
   278             this.draw();
       
   279         }
       
   280         else
       
   281         {
       
   282             this.fire("drawingComplete");
       
   283         }
       
   284     },
       
   285 
       
   286     /**
       
   287      * Calculates the coordinates for the series.
       
   288      *
       
   289      * @method setAreaData
       
   290      * @protected
       
   291      */
       
   292     setAreaData: function()
       
   293     {
       
   294         var w = this.get("width"),
       
   295             h = this.get("height"),
       
   296             xAxis = this.get("xAxis"),
       
   297             yAxis = this.get("yAxis"),
       
   298             xData = this._copyData(this.get("xData")),
       
   299             yData = this._copyData(this.get("yData")),
       
   300             direction = this.get("direction"),
       
   301             dataLength = direction === "vertical" ? yData.length : xData.length,
       
   302             xOffset = xAxis.getEdgeOffset(xAxis.getTotalMajorUnits(), w),
       
   303             yOffset = yAxis.getEdgeOffset(yAxis.getTotalMajorUnits(), h),
       
   304             padding = this.get("styles").padding,
       
   305 			leftPadding = padding.left,
       
   306 			topPadding = padding.top,
       
   307 			dataWidth = w - (leftPadding + padding.right + xOffset * 2),
       
   308 			dataHeight = h - (topPadding + padding.bottom + yOffset * 2),
       
   309 			xMax = xAxis.get("maximum"),
       
   310 			xMin = xAxis.get("minimum"),
       
   311 			yMax = yAxis.get("maximum"),
       
   312 			yMin = yAxis.get("minimum"),
       
   313             xScaleFactor = dataWidth / (xMax - xMin),
       
   314 			yScaleFactor = dataHeight / (yMax - yMin),
       
   315             graphic = this.get("graphic"),
       
   316             xcoords,
       
   317             ycoords;
       
   318         graphic.set("width", w);
       
   319         graphic.set("height", h);
       
   320         //Assuming a vertical graph has a range/category for its vertical axis.
       
   321         if(direction === "vertical")
       
   322         {
       
   323             yData = yData.reverse();
       
   324         }
       
   325         this._leftOrigin = Math.round(((0 - xMin) * xScaleFactor) + leftPadding + xOffset);
       
   326         this._bottomOrigin = Math.round((dataHeight + topPadding + yOffset));
       
   327         if(yMin < 0)
       
   328         {
       
   329             this._bottomOrigin = this._bottomOrigin - ((0 - yMin) * yScaleFactor);
       
   330         }
       
   331         xcoords = this._getXCoords(xData, xMin, dataWidth, xScaleFactor, xOffset, dataLength, leftPadding);
       
   332         ycoords = this._getYCoords(yData, yMin, dataHeight, yScaleFactor, yOffset, dataLength, topPadding);
       
   333         this.set("xcoords", xcoords);
       
   334 		this.set("ycoords", ycoords);
       
   335         this._dataLength = dataLength;
       
   336         this._setXMarkerPlane(xcoords, dataLength);
       
   337         this._setYMarkerPlane(ycoords, dataLength);
       
   338     },
       
   339 
       
   340     /**
       
   341      * Used to cache xData and yData in the setAreaData method. Returns a copy of an
       
   342      * array if an array is received as the param and returns an object literal of
       
   343      * array copies if an object literal is received as the param.
       
   344      *
       
   345      * @method _copyData
       
   346      * @param {Array|Object} val The object or array to be copied.
       
   347      * @return Array|Object
       
   348      * @private
       
   349      */
       
   350     _copyData: function(val)
       
   351     {
       
   352         var copy,
       
   353             key;
       
   354         if(Y_Lang.isArray(val))
       
   355         {
       
   356             copy = val.concat();
       
   357         }
       
   358         else
       
   359         {
       
   360             copy = {};
       
   361             for(key in val)
       
   362             {
       
   363                 if(val.hasOwnProperty(key))
       
   364                 {
       
   365                     copy[key] = val[key].concat();
       
   366                 }
       
   367             }
       
   368         }
       
   369         return copy;
       
   370     },
       
   371 
       
   372     /**
       
   373      * Sets the marker plane for the series when the coords argument is an array.
       
   374      * If the coords argument is an object literal no marker plane is set.
       
   375      *
       
   376      * @method _setXMarkerPlane
       
   377      * @param {Array|Object} coords An array of x coordinates or an object literal
       
   378      * containing key value pairs mapped to an array of coordinates.
       
   379      * @param {Number} dataLength The length of data for the series.
       
   380      * @private
       
   381      */
       
   382     _setXMarkerPlane: function(coords, dataLength)
       
   383     {
       
   384         var i = 0,
       
   385             xMarkerPlane = [],
       
   386             xMarkerPlaneOffset = this.get("xMarkerPlaneOffset"),
       
   387             nextX;
       
   388         if(Y_Lang.isArray(coords))
       
   389         {
       
   390             for(i = 0; i < dataLength; i = i + 1)
       
   391             {
       
   392                 nextX = coords[i];
       
   393                 xMarkerPlane.push({start:nextX - xMarkerPlaneOffset, end: nextX + xMarkerPlaneOffset});
       
   394             }
       
   395             this.set("xMarkerPlane", xMarkerPlane);
       
   396         }
       
   397     },
       
   398 
       
   399     /**
       
   400      * Sets the marker plane for the series when the coords argument is an array.
       
   401      * If the coords argument is an object literal no marker plane is set.
       
   402      *
       
   403      * @method _setYMarkerPlane
       
   404      * @param {Array|Object} coords An array of y coordinates or an object literal
       
   405      * containing key value pairs mapped to an array of coordinates.
       
   406      * @param {Number} dataLength The length of data for the series.
       
   407      * @private
       
   408      */
       
   409     _setYMarkerPlane: function(coords, dataLength)
       
   410     {
       
   411         var i = 0,
       
   412             yMarkerPlane = [],
       
   413             yMarkerPlaneOffset = this.get("yMarkerPlaneOffset"),
       
   414             nextY;
       
   415         if(Y_Lang.isArray(coords))
       
   416         {
       
   417             for(i = 0; i < dataLength; i = i + 1)
       
   418             {
       
   419                 nextY = coords[i];
       
   420                 yMarkerPlane.push({start:nextY - yMarkerPlaneOffset, end: nextY + yMarkerPlaneOffset});
       
   421             }
       
   422             this.set("yMarkerPlane", yMarkerPlane);
       
   423         }
       
   424     },
       
   425 
       
   426     /**
       
   427      * Gets the x-coordinates for a series. Used by the setAreaData method.
       
   428      * Returns an array when an array is received as the first argument.
       
   429      * Returns an object literal when an object literal is received as the first argument.
       
   430      *
       
   431      * @method _getXCoords
       
   432      * @param {Array|Object} xData An array of data values mapped to the x axis or an
       
   433      * object literal containing key values pairs of data values mapped to the x axis.
       
   434      * @param {Number} xMin The minimum value of the x axis.
       
   435      * @param {Number} dataWidth The width used to calculate the x-coordinates.
       
   436      * @param {Number} xScaleFactor The ratio used to calculate x-coordinates.
       
   437      * @param {Number} xOffset The distance of the first and last x-coordinate from the
       
   438      * beginning and end of the x-axis.
       
   439      * @param {Number} dataLength The number of data points in the arrays.
       
   440      * @param {Number} leftPadding The left padding of the series.
       
   441      * @return Array|Object
       
   442      * @private
       
   443      */
       
   444     _getXCoords: function(xData, xMin, dataWidth, xScaleFactor, xOffset, dataLength, leftPadding)
       
   445     {
       
   446         var isNumber = Y_Lang.isNumber,
       
   447 			xcoords,
       
   448             xValue,
       
   449             nextX,
       
   450             key,
       
   451             i;
       
   452         if(Y_Lang.isArray(xData))
       
   453         {
       
   454             xcoords = [];
       
   455             for (i = 0; i < dataLength; ++i)
       
   456             {
       
   457                 xValue = parseFloat(xData[i]);
       
   458                 if(isNumber(xValue))
       
   459                 {
       
   460                     nextX = (((xValue - xMin) * xScaleFactor) + leftPadding + xOffset);
       
   461                 }
       
   462                 else
       
   463                 {
       
   464                     nextX = NaN;
       
   465                 }
       
   466                 xcoords.push(nextX);
       
   467             }
       
   468         }
       
   469         else
       
   470         {
       
   471             xcoords = {};
       
   472             for(key in xData)
       
   473             {
       
   474                 if(xData.hasOwnProperty(key))
       
   475                 {
       
   476                     xcoords[key] = this._getXCoords.apply(
       
   477                         this,
       
   478                         [xData[key], xMin, dataWidth, xScaleFactor, xOffset, dataLength, leftPadding]
       
   479                     );
       
   480                 }
       
   481             }
       
   482         }
       
   483         return xcoords;
       
   484     },
       
   485 
       
   486     /**
       
   487      * Gets the y-coordinates for a series. Used by the setAreaData method.
       
   488      * Returns an array when an array is received as the first argument.
       
   489      * Returns an object literal when an object literal is received as the first argument.
       
   490      *
       
   491      * @method _getYCoords
       
   492      * @param {Array|Object} yData An array of data values mapped to the y axis or an
       
   493      * object literal containing key values pairs of data values mapped to the y axis.
       
   494      * @param {Number} yMin The minimum value of the y axis.
       
   495      * @param {Number} dataHeight The height used to calculate the y-coordinates.
       
   496      * @param {Number} yScaleFactor The ratio used to calculate y-coordinates.
       
   497      * @param {Number} yOffset The distance of the first and last y-coordinate from the beginning and end of the y-axis.
       
   498      * @param {Number} dataLength The number of data points in the arrays.
       
   499      * @param {Number} topPadding The top padding of the series.
       
   500      * @return Array|Object
       
   501      * @private
       
   502      */
       
   503     _getYCoords: function(yData, yMin, dataHeight, yScaleFactor, yOffset, dataLength, topPadding)
       
   504     {
       
   505         var isNumber = Y_Lang.isNumber,
       
   506 			ycoords,
       
   507             yValue,
       
   508             nextY,
       
   509             key,
       
   510             i;
       
   511         if(Y_Lang.isArray(yData))
       
   512         {
       
   513             ycoords = [];
       
   514             for (i = 0; i < dataLength; ++i)
       
   515             {
       
   516                 yValue = parseFloat(yData[i]);
       
   517                 if(isNumber(yValue))
       
   518                 {
       
   519                     nextY = ((dataHeight + topPadding + yOffset) - (yValue - yMin) * yScaleFactor);
       
   520                 }
       
   521                 else
       
   522                 {
       
   523                     nextY = NaN;
       
   524                 }
       
   525                 ycoords.push(nextY);
       
   526             }
       
   527         }
       
   528         else
       
   529         {
       
   530             ycoords = {};
       
   531             for(key in yData)
       
   532             {
       
   533                 if(yData.hasOwnProperty(key))
       
   534                 {
       
   535                     ycoords[key] = this._getYCoords.apply(
       
   536                         this,
       
   537                         [yData[key], yMin, dataHeight, yScaleFactor, yOffset, dataLength, topPadding]
       
   538                     );
       
   539                 }
       
   540             }
       
   541         }
       
   542         return ycoords;
       
   543     },
       
   544 
       
   545     /**
       
   546      * Finds the first valid index of an array coordinates.
       
   547      *
       
   548      * @method _getFirstValidIndex
       
   549      * @param {Array} coords An array of x or y coordinates.
       
   550      * @return Number
       
   551      * @private
       
   552      */
       
   553     _getFirstValidIndex: function(coords)
       
   554     {
       
   555         var coord,
       
   556             i = -1,
       
   557             limit = coords.length;
       
   558         while(!Y_Lang.isNumber(coord) && i < limit)
       
   559         {
       
   560             i += 1;
       
   561             coord = coords[i];
       
   562         }
       
   563         return i;
       
   564     },
       
   565 
       
   566     /**
       
   567      * Finds the last valid index of an array coordinates.
       
   568      *
       
   569      * @method _getLastValidIndex
       
   570      * @param {Array} coords An array of x or y coordinates.
       
   571      * @return Number
       
   572      * @private
       
   573      */
       
   574     _getLastValidIndex: function(coords)
       
   575     {
       
   576         var coord,
       
   577             i = coords.length,
       
   578             limit = -1;
       
   579         while(!Y_Lang.isNumber(coord) && i > limit)
       
   580         {
       
   581             i -= 1;
       
   582             coord = coords[i];
       
   583         }
       
   584         return i;
       
   585     },
       
   586 
       
   587     /**
       
   588      * Draws the series.
       
   589      *
       
   590      * @method draw
       
   591      * @protected
       
   592      */
       
   593     draw: function()
       
   594     {
       
   595         var w = this.get("width"),
       
   596             h = this.get("height"),
       
   597             xcoords,
       
   598             ycoords;
       
   599         if(this.get("rendered"))
       
   600         {
       
   601             if((isFinite(w) && isFinite(h) && w > 0 && h > 0) &&
       
   602                 ((this.get("xData") && this.get("yData")) ||
       
   603                 this._updateAxisBase()))
       
   604             {
       
   605                 if(this._drawing)
       
   606                 {
       
   607                     this._callLater = true;
       
   608                     return;
       
   609                 }
       
   610                 this._drawing = true;
       
   611                 this._callLater = false;
       
   612                 this.setAreaData();
       
   613                 xcoords = this.get("xcoords");
       
   614                 ycoords = this.get("ycoords");
       
   615                 if(xcoords && ycoords && xcoords.length > 0)
       
   616                 {
       
   617                     this.drawSeries();
       
   618                 }
       
   619                 this._drawing = false;
       
   620                 if(this._callLater)
       
   621                 {
       
   622                     this.draw();
       
   623                 }
       
   624                 else
       
   625                 {
       
   626                     this._toggleVisible(this.get("visible"));
       
   627                     this.fire("drawingComplete");
       
   628                 }
       
   629             }
       
   630         }
       
   631     },
       
   632 
       
   633     /**
       
   634      * Default value for plane offsets when the parent chart's `interactiveType` is `planar`.
       
   635      *
       
   636      * @property _defaultPlaneOffset
       
   637      * @type Number
       
   638      * @private
       
   639      */
       
   640     _defaultPlaneOffset: 4,
       
   641 
       
   642     /**
       
   643      * Destructor implementation for the CartesianSeries class.
       
   644      * Calls destroy on all Graphic instances.
       
   645      *
       
   646      * @method destructor
       
   647      * @protected
       
   648      */
       
   649     destructor: function()
       
   650     {
       
   651         if(this.get("rendered"))
       
   652         {
       
   653             if(this._xDataReadyHandle)
       
   654             {
       
   655                 this._xDataReadyHandle.detach();
       
   656             }
       
   657             if(this._xDataUpdateHandle)
       
   658             {
       
   659                 this._xDataUpdateHandle.detach();
       
   660             }
       
   661             if(this._yDataReadyHandle)
       
   662             {
       
   663                 this._yDataReadyHandle.detach();
       
   664             }
       
   665             if(this._yDataUpdateHandle)
       
   666             {
       
   667                 this._yDataUpdateHandle.detach();
       
   668             }
       
   669             this._xAxisChangeHandle.detach();
       
   670             this._yAxisChangeHandle.detach();
       
   671         }
       
   672     }
       
   673         /**
       
   674          * Event handle for the x-axis' dataReady event.
       
   675          *
       
   676          * @property _xDataReadyHandle
       
   677          * @type {EventHandle}
       
   678          * @private
       
   679          */
       
   680 
       
   681         /**
       
   682          * Event handle for the x-axis dataUpdate event.
       
   683          *
       
   684          * @property _xDataUpdateHandle
       
   685          * @type {EventHandle}
       
   686          * @private
       
   687          */
       
   688 
       
   689         /**
       
   690          * Event handle for the y-axis dataReady event.
       
   691          *
       
   692          * @property _yDataReadyHandle
       
   693          * @type {EventHandle}
       
   694          * @private
       
   695          */
       
   696 
       
   697         /**
       
   698          * Event handle for the y-axis dataUpdate event.
       
   699          * @property _yDataUpdateHandle
       
   700          * @type {EventHandle}
       
   701          * @private
       
   702          */
       
   703 
       
   704         /**
       
   705          * Event handle for the xAxisChange event.
       
   706          * @property _xAxisChangeHandle
       
   707          * @type {EventHandle}
       
   708          * @private
       
   709          */
       
   710 
       
   711         /**
       
   712          * Event handle for the yAxisChange event.
       
   713          * @property _yAxisChangeHandle
       
   714          * @type {EventHandle}
       
   715          * @private
       
   716          */
       
   717 
       
   718         /**
       
   719          * Event handle for the stylesChange event.
       
   720          * @property _stylesChangeHandle
       
   721          * @type {EventHandle}
       
   722          * @private
       
   723          */
       
   724 
       
   725         /**
       
   726          * Event handle for the widthChange event.
       
   727          * @property _widthChangeHandle
       
   728          * @type {EventHandle}
       
   729          * @private
       
   730          */
       
   731 
       
   732         /**
       
   733          * Event handle for the heightChange event.
       
   734          * @property _heightChangeHandle
       
   735          * @type {EventHandle}
       
   736          * @private
       
   737          */
       
   738 
       
   739         /**
       
   740          * Event handle for the visibleChange event.
       
   741          * @property _visibleChangeHandle
       
   742          * @type {EventHandle}
       
   743          * @private
       
   744          */
       
   745 }, {
       
   746     ATTRS: {
       
   747         /**
       
   748          * An array of all series of the same type used within a chart application.
       
   749          *
       
   750          * @attribute seriesTypeCollection
       
   751          * @type Array
       
   752          */
       
   753         seriesTypeCollection: {},
       
   754 
       
   755         /**
       
   756          * Name used for for displaying data related to the x-coordinate.
       
   757          *
       
   758          * @attribute xDisplayName
       
   759          * @type String
       
   760          */
       
   761         xDisplayName: {
       
   762             getter: function()
       
   763             {
       
   764                 return this._xDisplayName || this.get("xKey");
       
   765             },
       
   766 
       
   767             setter: function(val)
       
   768             {
       
   769                 this._xDisplayName = val.toString();
       
   770                 return val;
       
   771             }
       
   772         },
       
   773 
       
   774         /**
       
   775          * Name used for for displaying data related to the y-coordinate.
       
   776          *
       
   777          * @attribute yDisplayName
       
   778          * @type String
       
   779          */
       
   780         yDisplayName: {
       
   781             getter: function()
       
   782             {
       
   783                 return this._yDisplayName || this.get("yKey");
       
   784             },
       
   785 
       
   786             setter: function(val)
       
   787             {
       
   788                 this._yDisplayName = val.toString();
       
   789                 return val;
       
   790             }
       
   791         },
       
   792 
       
   793         /**
       
   794          * Name used for for displaying category data
       
   795          *
       
   796          * @attribute categoryDisplayName
       
   797          * @type String
       
   798          * @readOnly
       
   799          */
       
   800         categoryDisplayName: {
       
   801             lazyAdd: false,
       
   802 
       
   803             getter: function()
       
   804             {
       
   805                 return this.get("direction") === "vertical" ? this.get("yDisplayName") : this.get("xDisplayName");
       
   806             },
       
   807 
       
   808             setter: function(val)
       
   809             {
       
   810                 if(this.get("direction") === "vertical")
       
   811                 {
       
   812                     this._yDisplayName = val;
       
   813                 }
       
   814                 else
       
   815                 {
       
   816                     this._xDisplayName = val;
       
   817                 }
       
   818                 return val;
       
   819             }
       
   820         },
       
   821 
       
   822         /**
       
   823          * Name used for for displaying value data
       
   824          *
       
   825          * @attribute valueDisplayName
       
   826          * @type String
       
   827          * @readOnly
       
   828          */
       
   829         valueDisplayName: {
       
   830             lazyAdd: false,
       
   831 
       
   832             getter: function()
       
   833             {
       
   834                 return this.get("direction") === "vertical" ? this.get("xDisplayName") : this.get("yDisplayName");
       
   835             },
       
   836 
       
   837             setter: function(val)
       
   838             {
       
   839                 if(this.get("direction") === "vertical")
       
   840                 {
       
   841                     this._xDisplayName = val;
       
   842                 }
       
   843                 else
       
   844                 {
       
   845                     this._yDisplayName = val;
       
   846                 }
       
   847                 return val;
       
   848             }
       
   849         },
       
   850 
       
   851         /**
       
   852          * Read-only attribute indicating the type of series.
       
   853          *
       
   854          * @attribute type
       
   855          * @type String
       
   856          * @default cartesian
       
   857          */
       
   858         type: {
       
   859             value: "cartesian"
       
   860         },
       
   861 
       
   862         /**
       
   863          * Order of this instance of this `type`.
       
   864          *
       
   865          * @attribute order
       
   866          * @type Number
       
   867          */
       
   868         order: {},
       
   869 
       
   870         /**
       
   871          * Order of the instance
       
   872          *
       
   873          * @attribute graphOrder
       
   874          * @type Number
       
   875          */
       
   876         graphOrder: {},
       
   877 
       
   878         /**
       
   879          * x coordinates for the series.
       
   880          *
       
   881          * @attribute xcoords
       
   882          * @type Array
       
   883          */
       
   884         xcoords: {},
       
   885 
       
   886         /**
       
   887          * y coordinates for the series
       
   888          *
       
   889          * @attribute ycoords
       
   890          * @type Array
       
   891          */
       
   892         ycoords: {},
       
   893 
       
   894         /**
       
   895          * Reference to the `Axis` instance used for assigning
       
   896          * x-values to the graph.
       
   897          *
       
   898          * @attribute xAxis
       
   899          * @type Axis
       
   900          */
       
   901         xAxis: {},
       
   902 
       
   903         /**
       
   904          * Reference to the `Axis` instance used for assigning
       
   905          * y-values to the graph.
       
   906          *
       
   907          * @attribute yAxis
       
   908          * @type Axis
       
   909          */
       
   910         yAxis: {},
       
   911 
       
   912         /**
       
   913          * Indicates which array to from the hash of value arrays in
       
   914          * the x-axis `Axis` instance.
       
   915          *
       
   916          * @attribute xKey
       
   917          * @type String
       
   918          */
       
   919         xKey: {
       
   920             setter: function(val)
       
   921             {
       
   922                 if(Y_Lang.isArray(val))
       
   923                 {
       
   924                     return val;
       
   925                 }
       
   926                 else
       
   927                 {
       
   928                     return val.toString();
       
   929                 }
       
   930             }
       
   931         },
       
   932 
       
   933         /**
       
   934          * Indicates which array to from the hash of value arrays in
       
   935          * the y-axis `Axis` instance.
       
   936          *
       
   937          * @attribute yKey
       
   938          * @type String
       
   939          */
       
   940         yKey: {
       
   941             setter: function(val)
       
   942             {
       
   943                 if(Y_Lang.isArray(val))
       
   944                 {
       
   945                     return val;
       
   946                 }
       
   947                 else
       
   948                 {
       
   949                     return val.toString();
       
   950                 }
       
   951             }
       
   952         },
       
   953 
       
   954         /**
       
   955          * Array of x values for the series.
       
   956          *
       
   957          * @attribute xData
       
   958          * @type Array
       
   959          */
       
   960         xData: {},
       
   961 
       
   962         /**
       
   963          * Array of y values for the series.
       
   964          *
       
   965          * @attribute yData
       
   966          * @type Array
       
   967          */
       
   968         yData: {},
       
   969 
       
   970         /**
       
   971          * Collection of area maps along the xAxis. Used to determine mouseover for multiple
       
   972          * series.
       
   973          *
       
   974          * @attribute xMarkerPlane
       
   975          * @type Array
       
   976          */
       
   977         xMarkerPlane: {},
       
   978 
       
   979         /**
       
   980          * Collection of area maps along the yAxis. Used to determine mouseover for multiple
       
   981          * series.
       
   982          *
       
   983          * @attribute yMarkerPlane
       
   984          * @type Array
       
   985          */
       
   986         yMarkerPlane: {},
       
   987 
       
   988         /**
       
   989          * Distance from a data coordinate to the left/right for setting a hotspot.
       
   990          *
       
   991          * @attribute xMarkerPlaneOffset
       
   992          * @type Number
       
   993          */
       
   994         xMarkerPlaneOffset: {
       
   995             getter: function() {
       
   996                 var marker = this.get("styles").marker;
       
   997                 if(marker && marker.width && isFinite(marker.width))
       
   998                 {
       
   999                     return marker.width * 0.5;
       
  1000                 }
       
  1001                 return this._defaultPlaneOffset;
       
  1002             }
       
  1003         },
       
  1004 
       
  1005         /**
       
  1006          * Distance from a data coordinate to the top/bottom for setting a hotspot.
       
  1007          *
       
  1008          * @attribute yMarkerPlaneOffset
       
  1009          * @type Number
       
  1010          */
       
  1011         yMarkerPlaneOffset: {
       
  1012             getter: function() {
       
  1013                 var marker = this.get("styles").marker;
       
  1014                 if(marker && marker.height && isFinite(marker.height))
       
  1015                 {
       
  1016                     return marker.height * 0.5;
       
  1017                 }
       
  1018                 return this._defaultPlaneOffset;
       
  1019             }
       
  1020         },
       
  1021 
       
  1022         /**
       
  1023          * Direction of the series
       
  1024          *
       
  1025          * @attribute direction
       
  1026          * @type String
       
  1027          */
       
  1028         direction: {
       
  1029             value: "horizontal"
       
  1030         }
       
  1031     }
       
  1032 });
       
  1033 
       
  1034 
       
  1035 }, '3.10.3', {"requires": ["series-base"]});