src/cm/media/js/lib/yui/yui_3.10.3/build/series-plot-util/series-plot-util.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-plot-util', function (Y, NAME) {
       
     9 
       
    10 /**
       
    11  * Provides functionality for drawing plots in a series.
       
    12  *
       
    13  * @module charts
       
    14  * @submodule series-plot-util
       
    15  */
       
    16 var Y_Lang = Y.Lang,
       
    17     _getClassName = Y.ClassNameManager.getClassName,
       
    18     SERIES_MARKER = _getClassName("seriesmarker");
       
    19 
       
    20 /**
       
    21  * Utility class used for drawing markers.
       
    22  *
       
    23  * @class Plots
       
    24  * @constructor
       
    25  * @submodule series-plot-util
       
    26  */
       
    27 function Plots(cfg)
       
    28 {
       
    29     var attrs = {
       
    30         markers: {
       
    31             getter: function()
       
    32             {
       
    33                 return this._markers;
       
    34             }
       
    35         }
       
    36     };
       
    37     this.addAttrs(attrs, cfg);
       
    38 }
       
    39 
       
    40 Plots.prototype = {
       
    41     /**
       
    42      * Storage for default marker styles.
       
    43      *
       
    44      * @property _plotDefaults
       
    45      * @type Object
       
    46      * @private
       
    47      */
       
    48     _plotDefaults: null,
       
    49 
       
    50     /**
       
    51      * Draws the markers
       
    52      *
       
    53      * @method drawPlots
       
    54      * @protected
       
    55      */
       
    56     drawPlots: function()
       
    57     {
       
    58         if(!this.get("xcoords") || this.get("xcoords").length < 1)
       
    59 		{
       
    60 			return;
       
    61 		}
       
    62         var isNumber = Y_Lang.isNumber,
       
    63             style = Y.clone(this.get("styles").marker),
       
    64             w = style.width,
       
    65             h = style.height,
       
    66             xcoords = this.get("xcoords"),
       
    67             ycoords = this.get("ycoords"),
       
    68             i = 0,
       
    69             len = xcoords.length,
       
    70             top = ycoords[0],
       
    71             left,
       
    72             marker,
       
    73             offsetWidth = w/2,
       
    74             offsetHeight = h/2,
       
    75             xvalues,
       
    76             yvalues,
       
    77             fillColors = null,
       
    78             borderColors = null,
       
    79             graphOrder = this.get("graphOrder"),
       
    80             groupMarkers = this.get("groupMarkers");
       
    81         if(groupMarkers)
       
    82         {
       
    83             xvalues = [];
       
    84             yvalues = [];
       
    85             for(; i < len; ++i)
       
    86             {
       
    87                 xvalues.push(parseFloat(xcoords[i] - offsetWidth));
       
    88                 yvalues.push(parseFloat(ycoords[i] - offsetHeight));
       
    89             }
       
    90             this._createGroupMarker({
       
    91                 xvalues: xvalues,
       
    92                 yvalues: yvalues,
       
    93                 fill: style.fill,
       
    94                 border: style.border,
       
    95                 dimensions: {
       
    96                     width: w,
       
    97                     height: h
       
    98                 },
       
    99                 graphOrder: graphOrder,
       
   100                 shape: style.shape
       
   101             });
       
   102             return;
       
   103         }
       
   104         if(Y_Lang.isArray(style.fill.color))
       
   105         {
       
   106             fillColors = style.fill.color.concat();
       
   107         }
       
   108         if(Y_Lang.isArray(style.border.color))
       
   109         {
       
   110             borderColors = style.border.color.concat();
       
   111         }
       
   112         this._createMarkerCache();
       
   113         for(; i < len; ++i)
       
   114         {
       
   115             top = parseFloat(ycoords[i] - offsetHeight);
       
   116             left = parseFloat(xcoords[i] - offsetWidth);
       
   117             if(!isNumber(left) || !isNumber(top))
       
   118             {
       
   119                 this._markers.push(null);
       
   120                 continue;
       
   121             }
       
   122             if(fillColors)
       
   123             {
       
   124                 style.fill.color = fillColors[i % fillColors.length];
       
   125             }
       
   126             if(borderColors)
       
   127             {
       
   128                 style.border.color = borderColors[i % borderColors.length];
       
   129             }
       
   130 
       
   131             style.x = left;
       
   132             style.y = top;
       
   133             marker = this.getMarker(style, graphOrder, i);
       
   134         }
       
   135         this._clearMarkerCache();
       
   136     },
       
   137 
       
   138     /**
       
   139      * Pre-defined group shapes.
       
   140      *
       
   141      * @property _groupShapes
       
   142      * @private
       
   143      */
       
   144     _groupShapes: {
       
   145         circle: Y.CircleGroup,
       
   146         rect: Y.RectGroup,
       
   147         ellipse: Y.EllipseGroup,
       
   148         diamond: Y.DiamondGroup
       
   149     },
       
   150 
       
   151     /**
       
   152      * Returns the correct group shape class.
       
   153      *
       
   154      * @method _getGroupShape
       
   155      * @param {Shape | String} shape Indicates which shape class.
       
   156      * @return Function
       
   157      * @protected
       
   158      */
       
   159     _getGroupShape: function(shape)
       
   160     {
       
   161         if(Y_Lang.isString(shape))
       
   162         {
       
   163             shape = this._groupShapes[shape];
       
   164         }
       
   165         return shape;
       
   166     },
       
   167 
       
   168     /**
       
   169      * Gets the default values for series that use the utility. This method is used by
       
   170      * the class' `styles` attribute's getter to get build default values.
       
   171      *
       
   172      * @method _getPlotDefaults
       
   173      * @return Object
       
   174      * @protected
       
   175      */
       
   176     _getPlotDefaults: function()
       
   177     {
       
   178         var defs = {
       
   179             fill:{
       
   180                 type: "solid",
       
   181                 alpha: 1,
       
   182                 colors:null,
       
   183                 alphas: null,
       
   184                 ratios: null
       
   185             },
       
   186             border:{
       
   187                 weight: 1,
       
   188                 alpha: 1
       
   189             },
       
   190             width: 10,
       
   191             height: 10,
       
   192             shape: "circle"
       
   193         };
       
   194         defs.fill.color = this._getDefaultColor(this.get("graphOrder"), "fill");
       
   195         defs.border.color = this._getDefaultColor(this.get("graphOrder"), "border");
       
   196         return defs;
       
   197     },
       
   198 
       
   199     /**
       
   200      * Collection of markers to be used in the series.
       
   201      *
       
   202      * @property _markers
       
   203      * @type Array
       
   204      * @private
       
   205      */
       
   206     _markers: null,
       
   207 
       
   208     /**
       
   209      * Collection of markers to be re-used on a series redraw.
       
   210      *
       
   211      * @property _markerCache
       
   212      * @type Array
       
   213      * @private
       
   214      */
       
   215     _markerCache: null,
       
   216 
       
   217     /**
       
   218      * Gets and styles a marker. If there is a marker in cache, it will use it. Otherwise
       
   219      * it will create one.
       
   220      *
       
   221      * @method getMarker
       
   222      * @param {Object} styles Hash of style properties.
       
   223      * @param {Number} order Order of the series.
       
   224      * @param {Number} index Index within the series associated with the marker.
       
   225      * @return Shape
       
   226      * @protected
       
   227      */
       
   228     getMarker: function(styles, order, index)
       
   229     {
       
   230         var marker,
       
   231             border = styles.border;
       
   232         styles.id = this._getChart().get("id") + "_" + order + "_" + index;
       
   233         //fix name differences between graphic layer
       
   234         border.opacity = border.alpha;
       
   235         styles.stroke = border;
       
   236         styles.fill.opacity = styles.fill.alpha;
       
   237         if(this._markerCache.length > 0)
       
   238         {
       
   239             while(!marker)
       
   240             {
       
   241                 if(this._markerCache.length < 1)
       
   242                 {
       
   243                     marker = this._createMarker(styles);
       
   244                     break;
       
   245                 }
       
   246                 marker = this._markerCache.shift();
       
   247 
       
   248             }
       
   249             marker.set(styles);
       
   250         }
       
   251         else
       
   252         {
       
   253             marker = this._createMarker(styles);
       
   254         }
       
   255         this._markers.push(marker);
       
   256         return marker;
       
   257     },
       
   258 
       
   259     /**
       
   260      * Creates a shape to be used as a marker.
       
   261      *
       
   262      * @method _createMarker
       
   263      * @param {Object} styles Hash of style properties.
       
   264      * @return Shape
       
   265      * @private
       
   266      */
       
   267     _createMarker: function(styles)
       
   268     {
       
   269         var graphic = this.get("graphic"),
       
   270             marker,
       
   271             cfg = Y.clone(styles);
       
   272         cfg.type = cfg.shape;
       
   273         marker = graphic.addShape(cfg);
       
   274         marker.addClass(SERIES_MARKER);
       
   275         return marker;
       
   276     },
       
   277 
       
   278     /**
       
   279      * Creates a cache of markers for reuse.
       
   280      *
       
   281      * @method _createMarkerCache
       
   282      * @private
       
   283      */
       
   284     _createMarkerCache: function()
       
   285     {
       
   286         if(this._groupMarker)
       
   287         {
       
   288             this._groupMarker.destroy();
       
   289             this._groupMarker = null;
       
   290         }
       
   291         if(this._markers && this._markers.length > 0)
       
   292         {
       
   293             this._markerCache = this._markers.concat();
       
   294         }
       
   295         else
       
   296         {
       
   297             this._markerCache = [];
       
   298         }
       
   299         this._markers = [];
       
   300     },
       
   301 
       
   302     /**
       
   303      * Draws a series of markers in a single shape instance.
       
   304      *
       
   305      * @method _createGroupMarkers
       
   306      * @param {Object} styles Set of configuration properties used to create the markers.
       
   307      * @protected
       
   308      */
       
   309     _createGroupMarker: function(styles)
       
   310     {
       
   311         var marker,
       
   312             markers = this.get("markers"),
       
   313             border = styles.border,
       
   314             graphic,
       
   315             cfg,
       
   316             shape;
       
   317         if(markers && markers.length > 0)
       
   318         {
       
   319             while(markers.length > 0)
       
   320             {
       
   321                 marker = markers.shift();
       
   322                 marker.destroy();
       
   323             }
       
   324             this.set("markers", []);
       
   325         }
       
   326         //fix name differences between graphic layer
       
   327         border.opacity = border.alpha;
       
   328         cfg = {
       
   329             id: this._getChart().get("id") + "_" + styles.graphOrder,
       
   330             stroke: border,
       
   331             fill: styles.fill,
       
   332             dimensions: styles.dimensions,
       
   333             xvalues: styles.xvalues,
       
   334             yvalues: styles.yvalues
       
   335         };
       
   336         cfg.fill.opacity = styles.fill.alpha;
       
   337         shape = this._getGroupShape(styles.shape);
       
   338         if(shape)
       
   339         {
       
   340             cfg.type = shape;
       
   341         }
       
   342         if(styles.hasOwnProperty("radius") && !isNaN(styles.radius))
       
   343         {
       
   344             cfg.dimensions.radius = styles.radius;
       
   345         }
       
   346         if(this._groupMarker)
       
   347         {
       
   348             this._groupMarker.destroy();
       
   349         }
       
   350         graphic = this.get("graphic");
       
   351         this._groupMarker = graphic.addShape(cfg);
       
   352         graphic._redraw();
       
   353     },
       
   354 
       
   355     /**
       
   356      * Toggles visibility
       
   357      *
       
   358      * @method _toggleVisible
       
   359      * @param {Boolean} visible indicates visibilitye
       
   360      * @private
       
   361      */
       
   362     _toggleVisible: function(visible)
       
   363     {
       
   364         var marker,
       
   365             markers = this.get("markers"),
       
   366             i = 0,
       
   367             len;
       
   368         if(markers)
       
   369         {
       
   370             len = markers.length;
       
   371             for(; i < len; ++i)
       
   372             {
       
   373                 marker = markers[i];
       
   374                 if(marker)
       
   375                 {
       
   376                     marker.set("visible", visible);
       
   377                 }
       
   378             }
       
   379         }
       
   380     },
       
   381 
       
   382     /**
       
   383      * Removes unused markers from the marker cache
       
   384      *
       
   385      * @method _clearMarkerCache
       
   386      * @private
       
   387      */
       
   388     _clearMarkerCache: function()
       
   389     {
       
   390         var marker;
       
   391         while(this._markerCache.length > 0)
       
   392         {
       
   393             marker = this._markerCache.shift();
       
   394             if(marker)
       
   395             {
       
   396                 marker.destroy();
       
   397             }
       
   398         }
       
   399     },
       
   400 
       
   401     /**
       
   402      * Resizes and positions markers based on a mouse interaction.
       
   403      *
       
   404      * @method updateMarkerState
       
   405      * @param {String} type state of the marker
       
   406      * @param {Number} i index of the marker
       
   407      * @protected
       
   408      */
       
   409     updateMarkerState: function(type, i)
       
   410     {
       
   411         if(this._markers && this._markers[i])
       
   412         {
       
   413             var w,
       
   414                 h,
       
   415                 styles = Y.clone(this.get("styles").marker),
       
   416                 state = this._getState(type),
       
   417                 xcoords = this.get("xcoords"),
       
   418                 ycoords = this.get("ycoords"),
       
   419                 marker = this._markers[i],
       
   420                 markerStyles = state === "off" || !styles[state] ? styles : styles[state];
       
   421                 markerStyles.fill.color = this._getItemColor(markerStyles.fill.color, i);
       
   422                 markerStyles.border.color = this._getItemColor(markerStyles.border.color, i);
       
   423                 markerStyles.stroke = markerStyles.border;
       
   424                 marker.set(markerStyles);
       
   425                 w = markerStyles.width;
       
   426                 h = markerStyles.height;
       
   427                 marker.set("x", (xcoords[i] - w/2));
       
   428                 marker.set("y",  (ycoords[i] - h/2));
       
   429                 marker.set("visible", this.get("visible"));
       
   430         }
       
   431     },
       
   432 
       
   433     /**
       
   434      * Parses a color from an array.
       
   435      *
       
   436      * @method _getItemColor
       
   437      * @param {Array} val collection of colors
       
   438      * @param {Number} i index of the item
       
   439      * @return String
       
   440      * @protected
       
   441      */
       
   442     _getItemColor: function(val, i)
       
   443     {
       
   444         if(Y_Lang.isArray(val))
       
   445         {
       
   446             return val[i % val.length];
       
   447         }
       
   448         return val;
       
   449     },
       
   450 
       
   451     /**
       
   452      * Method used by `styles` setter. Overrides base implementation.
       
   453      *
       
   454      * @method _setStyles
       
   455      * @param {Object} newStyles Hash of properties to update.
       
   456      * @return Object
       
   457      * @protected
       
   458      */
       
   459     _setStyles: function(val)
       
   460     {
       
   461         val = this._parseMarkerStyles(val);
       
   462         return Y.Renderer.prototype._setStyles.apply(this, [val]);
       
   463     },
       
   464 
       
   465     /**
       
   466      * Combines new styles with existing styles.
       
   467      *
       
   468      * @method _parseMarkerStyles
       
   469      * @param {Object} Object containing style properties for the marker.
       
   470      * @return Object
       
   471      * @private
       
   472      */
       
   473     _parseMarkerStyles: function(val)
       
   474     {
       
   475         if(val.marker)
       
   476         {
       
   477             var defs = this._getPlotDefaults();
       
   478             val.marker = this._mergeStyles(val.marker, defs);
       
   479             if(val.marker.over)
       
   480             {
       
   481                 val.marker.over = this._mergeStyles(val.marker.over, val.marker);
       
   482             }
       
   483             if(val.marker.down)
       
   484             {
       
   485                 val.marker.down = this._mergeStyles(val.marker.down, val.marker);
       
   486             }
       
   487         }
       
   488         return val;
       
   489     },
       
   490 
       
   491     /**
       
   492      * Returns marker state based on event type
       
   493      *
       
   494      * @method _getState
       
   495      * @param {String} type event type
       
   496      * @return String
       
   497      * @protected
       
   498      */
       
   499     _getState: function(type)
       
   500     {
       
   501         var state;
       
   502         switch(type)
       
   503         {
       
   504             case "mouseout" :
       
   505                 state = "off";
       
   506             break;
       
   507             case "mouseover" :
       
   508                 state = "over";
       
   509             break;
       
   510             case "mouseup" :
       
   511                 state = "over";
       
   512             break;
       
   513             case "mousedown" :
       
   514                 state = "down";
       
   515             break;
       
   516         }
       
   517         return state;
       
   518     },
       
   519 
       
   520     /**
       
   521      * @property _statSyles
       
   522      * @type Object
       
   523      * @private
       
   524      */
       
   525     _stateSyles: null,
       
   526 
       
   527     /**
       
   528      * @protected
       
   529      *
       
   530      * Draws the series.
       
   531      *
       
   532      * @method drawSeries
       
   533      */
       
   534     drawSeries: function()
       
   535     {
       
   536         this.drawPlots();
       
   537     },
       
   538 
       
   539     /**
       
   540      * @protected
       
   541      *
       
   542      * Gets the default value for the `styles` attribute. Overrides
       
   543      * base implementation.
       
   544      *
       
   545      * @method _getDefaultStyles
       
   546      * @return Object
       
   547      */
       
   548     _getDefaultStyles: function()
       
   549     {
       
   550         var styles = this._mergeStyles({marker:this._getPlotDefaults()}, this.constructor.superclass._getDefaultStyles());
       
   551         return styles;
       
   552     }
       
   553 };
       
   554 
       
   555 Y.augment(Plots, Y.Attribute);
       
   556 Y.Plots = Plots;
       
   557 
       
   558 
       
   559 }, '3.10.3');