[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/jquery/jqplot/plugins/ -> jqplot.mekkoRenderer.js (source)

   1  /**
   2   * jqPlot
   3   * Pure JavaScript plotting plugin using jQuery
   4   *
   5   * Version: 1.0.2
   6   * Revision: 1108
   7   *
   8   * Copyright (c) 2009-2011 Chris Leonello
   9   * jqPlot is currently available for use in all personal or commercial projects 
  10   * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL 
  11   * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can 
  12   * choose the license that best suits your project and use it accordingly. 
  13   *
  14   * Although not required, the author would appreciate an email letting him 
  15   * know of any substantial use of jqPlot.  You can reach the author at: 
  16   * chris at jqplot dot com or see http://www.jqplot.com/info.php .
  17   *
  18   * If you are feeling kind and generous, consider supporting the project by
  19   * making a donation at: http://www.jqplot.com/donate.php .
  20   *
  21   * sprintf functions contained in jqplot.sprintf.js by Ash Searle:
  22   *
  23   *     version 2007.04.27
  24   *     author Ash Searle
  25   *     http://hexmen.com/blog/2007/03/printf-sprintf/
  26   *     http://hexmen.com/js/sprintf.js
  27   *     The author (Ash Searle) has placed this code in the public domain:
  28   *     "This code is unrestricted: you are free to use it however you like."
  29   * 
  30   */
  31  (function($) {
  32      /**
  33       * Class: $.jqplot.MekkoRenderer
  34       * Draws a Mekko style chart which shows 3 dimensional data on a 2 dimensional graph.
  35       * the <$.jqplot.MekkoAxisRenderer> should be used with mekko charts.  The mekko renderer
  36       * overrides the default legend renderer with it's own $.jqplot.MekkoLegendRenderer
  37       * which allows more flexibility to specify number of rows and columns in the legend.
  38       * 
  39       * Data is specified per bar in the chart.  You can specify data as an array of y values, or as 
  40       * an array of [label, value] pairs.  Note that labels are used only on the first series.  
  41       * Labels on subsequent series are ignored:
  42       * 
  43       * > bar1 = [['shirts', 8],['hats', 14],['shoes', 6],['gloves', 16],['dolls', 12]];
  44       * > bar2 = [15,6,9,13,6];
  45       * > bar3 = [['grumpy',4],['sneezy',2],['happy',7],['sleepy',9],['doc',7]];
  46       * 
  47       * If you want to place labels for each bar under the axis, you use the barLabels option on 
  48       * the axes.  The bar labels can be styled with the ".jqplot-mekko-barLabel" css class.
  49       * 
  50       * > barLabels = ['Mickey Mouse', 'Donald Duck', 'Goofy'];
  51       * > axes:{xaxis:{barLabels:barLabels}}
  52       * 
  53       */
  54      
  55      
  56      $.jqplot.MekkoRenderer = function(){
  57          this.shapeRenderer = new $.jqplot.ShapeRenderer();
  58          // prop: borderColor
  59          // color of the borders between areas on the chart
  60          this.borderColor = null;
  61          // prop: showBorders
  62          // True to draw borders lines between areas on the chart.
  63          // False will draw borders lines with the same color as the area.
  64          this.showBorders = true;
  65      };
  66      
  67      // called with scope of series.
  68      $.jqplot.MekkoRenderer.prototype.init = function(options, plot) {
  69          this.fill = false;
  70          this.fillRect = true;
  71          this.strokeRect = true;
  72          this.shadow = false;
  73          // width of bar on x axis.
  74          this._xwidth = 0;
  75          this._xstart = 0;
  76          $.extend(true, this.renderer, options);
  77          // set the shape renderer options
  78          var opts = {lineJoin:'miter', lineCap:'butt', isarc:false, fillRect:this.fillRect, strokeRect:this.strokeRect};
  79          this.renderer.shapeRenderer.init(opts);
  80          plot.axes.x2axis._series.push(this);
  81          this._type = 'mekko';
  82      };
  83      
  84      // Method: setGridData
  85      // converts the user data values to grid coordinates and stores them
  86      // in the gridData array.  Will convert user data into appropriate
  87      // rectangles.
  88      // Called with scope of a series.
  89      $.jqplot.MekkoRenderer.prototype.setGridData = function(plot) {
  90          // recalculate the grid data
  91          var xp = this._xaxis.series_u2p;
  92          var yp = this._yaxis.series_u2p;
  93          var data = this._plotData;
  94          this.gridData = [];
  95          // figure out width on x axis.
  96          // this._xwidth = this._sumy / plot._sumy * this.canvas.getWidth();
  97          this._xwidth = xp(this._sumy) - xp(0);
  98          if (this.index>0) {
  99              this._xstart = plot.series[this.index-1]._xstart + plot.series[this.index-1]._xwidth;
 100          }
 101          var totheight = this.canvas.getHeight();
 102          var sumy = 0;
 103          var cury;
 104          var curheight;
 105          for (var i=0; i<data.length; i++) {
 106              if (data[i] != null) {
 107                  sumy += data[i][1];
 108                  cury = totheight - (sumy / this._sumy * totheight);
 109                  curheight = data[i][1] / this._sumy * totheight;
 110                  this.gridData.push([this._xstart, cury, this._xwidth, curheight]);
 111              }
 112          }
 113      };
 114      
 115      // Method: makeGridData
 116      // converts any arbitrary data values to grid coordinates and
 117      // returns them.  This method exists so that plugins can use a series'
 118      // linerenderer to generate grid data points without overwriting the
 119      // grid data associated with that series.
 120      // Called with scope of a series.
 121      $.jqplot.MekkoRenderer.prototype.makeGridData = function(data, plot) {
 122          // recalculate the grid data
 123          // figure out width on x axis.
 124          var xp = this._xaxis.series_u2p;
 125          var totheight = this.canvas.getHeight();
 126          var sumy = 0;
 127          var cury;
 128          var curheight;
 129          var gd = [];
 130          for (var i=0; i<data.length; i++) {
 131              if (data[i] != null) {
 132                  sumy += data[i][1];
 133                  cury = totheight - (sumy / this._sumy * totheight);
 134                  curheight = data[i][1] / this._sumy * totheight;
 135                  gd.push([this._xstart, cury, this._xwidth, curheight]);
 136              }
 137          }
 138          return gd;
 139      };
 140      
 141  
 142      // called within scope of series.
 143      $.jqplot.MekkoRenderer.prototype.draw = function(ctx, gd, options) {
 144          var i;
 145          var opts = (options != undefined) ? options : {};
 146          var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine;
 147          var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors);
 148          ctx.save();
 149          if (gd.length) {
 150              if (showLine) {
 151                  for (i=0; i<gd.length; i++){
 152                      opts.fillStyle = colorGenerator.next();
 153                      if (this.renderer.showBorders) {
 154                          opts.strokeStyle = this.renderer.borderColor;
 155                      }
 156                      else {
 157                          opts.strokeStyle = opts.fillStyle;
 158                      }
 159                      this.renderer.shapeRenderer.draw(ctx, gd[i], opts);
 160                  }
 161              }
 162          }
 163          
 164          ctx.restore();
 165      };  
 166      
 167      $.jqplot.MekkoRenderer.prototype.drawShadow = function(ctx, gd, options) {
 168          // This is a no-op, no shadows on mekko charts.
 169      };
 170      
 171      /**
 172       * Class: $.jqplot.MekkoLegendRenderer
 173       * Legend renderer used by mekko charts with options for 
 174       * controlling number or rows and columns as well as placement
 175       * outside of plot area.
 176       * 
 177       */
 178      $.jqplot.MekkoLegendRenderer = function(){
 179          //
 180      };
 181      
 182      $.jqplot.MekkoLegendRenderer.prototype.init = function(options) {
 183          // prop: numberRows
 184          // Maximum number of rows in the legend.  0 or null for unlimited.
 185          this.numberRows = null;
 186          // prop: numberColumns
 187          // Maximum number of columns in the legend.  0 or null for unlimited.
 188          this.numberColumns = null;
 189          // this will override the placement option on the Legend object
 190          this.placement = "outside";
 191          $.extend(true, this, options);
 192      };
 193      
 194      // called with scope of legend
 195      $.jqplot.MekkoLegendRenderer.prototype.draw = function() {
 196          var legend = this;
 197          if (this.show) {
 198              var series = this._series;
 199              var ss = 'position:absolute;';
 200              ss += (this.background) ? 'background:'+this.background+';' : '';
 201              ss += (this.border) ? 'border:'+this.border+';' : '';
 202              ss += (this.fontSize) ? 'font-size:'+this.fontSize+';' : '';
 203              ss += (this.fontFamily) ? 'font-family:'+this.fontFamily+';' : '';
 204              ss += (this.textColor) ? 'color:'+this.textColor+';' : '';
 205              this._elem = $('<table class="jqplot-table-legend" style="'+ss+'"></table>');
 206              // Mekko charts  legends don't go by number of series, but by number of data points
 207              // in the series.  Refactor things here for that.
 208              
 209              var pad = false, 
 210                  reverse = true,    // mekko charts are always stacked, so reverse
 211                  nr, nc;
 212              var s = series[0];
 213              var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors);
 214              
 215              if (s.show) {
 216                  var pd = s.data;
 217                  if (this.numberRows) {
 218                      nr = this.numberRows;
 219                      if (!this.numberColumns){
 220                          nc = Math.ceil(pd.length/nr);
 221                      }
 222                      else{
 223                          nc = this.numberColumns;
 224                      }
 225                  }
 226                  else if (this.numberColumns) {
 227                      nc = this.numberColumns;
 228                      nr = Math.ceil(pd.length/this.numberColumns);
 229                  }
 230                  else {
 231                      nr = pd.length;
 232                      nc = 1;
 233                  }
 234                  
 235                  var i, j, tr, td1, td2, lt, rs, color;
 236                  var idx = 0;    
 237                  
 238                  for (i=0; i<nr; i++) {
 239                      if (reverse){
 240                          tr = $('<tr class="jqplot-table-legend"></tr>').prependTo(this._elem);
 241                      }
 242                      else{
 243                          tr = $('<tr class="jqplot-table-legend"></tr>').appendTo(this._elem);
 244                      }
 245                      for (j=0; j<nc; j++) {
 246                          if (idx < pd.length) {
 247                              lt = this.labels[idx] || pd[idx][0].toString();
 248                              color = colorGenerator.next();
 249                              if (!reverse){
 250                                  if (i>0){
 251                                      pad = true;
 252                                  }
 253                                  else{
 254                                      pad = false;
 255                                  }
 256                              }
 257                              else{
 258                                  if (i == nr -1){
 259                                      pad = false;
 260                                  }
 261                                  else{
 262                                      pad = true;
 263                                  }
 264                              }
 265                              rs = (pad) ? this.rowSpacing : '0';
 266                  
 267                              td1 = $('<td class="jqplot-table-legend" style="text-align:center;padding-top:'+rs+';">'+
 268                                  '<div><div class="jqplot-table-legend-swatch" style="border-color:'+color+';"></div>'+
 269                                  '</div></td>');
 270                              td2 = $('<td class="jqplot-table-legend" style="padding-top:'+rs+';"></td>');
 271                              if (this.escapeHtml){
 272                                  td2.text(lt);
 273                              }
 274                              else {
 275                                  td2.html(lt);
 276                              }
 277                              if (reverse) {
 278                                  td2.prependTo(tr);
 279                                  td1.prependTo(tr);
 280                              }
 281                              else {
 282                                  td1.appendTo(tr);
 283                                  td2.appendTo(tr);
 284                              }
 285                              pad = true;
 286                          }
 287                          idx++;
 288                      }   
 289                  }
 290  
 291                  tr = null;
 292                  td1 = null;
 293                  td2 = null;
 294              }
 295          }
 296          return this._elem;
 297      };
 298      
 299      $.jqplot.MekkoLegendRenderer.prototype.pack = function(offsets) {
 300          if (this.show) {
 301              // fake a grid for positioning
 302              var grid = {_top:offsets.top, _left:offsets.left, _right:offsets.right, _bottom:this._plotDimensions.height - offsets.bottom};        
 303              if (this.placement == 'insideGrid') {
 304                  switch (this.location) {
 305                      case 'nw':
 306                          var a = grid._left + this.xoffset;
 307                          var b = grid._top + this.yoffset;
 308                          this._elem.css('left', a);
 309                          this._elem.css('top', b);
 310                          break;
 311                      case 'n':
 312                          var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
 313                          var b = grid._top + this.yoffset;
 314                          this._elem.css('left', a);
 315                          this._elem.css('top', b);
 316                          break;
 317                      case 'ne':
 318                          var a = offsets.right + this.xoffset;
 319                          var b = grid._top + this.yoffset;
 320                          this._elem.css({right:a, top:b});
 321                          break;
 322                      case 'e':
 323                          var a = offsets.right + this.xoffset;
 324                          var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
 325                          this._elem.css({right:a, top:b});
 326                          break;
 327                      case 'se':
 328                          var a = offsets.right + this.xoffset;
 329                          var b = offsets.bottom + this.yoffset;
 330                          this._elem.css({right:a, bottom:b});
 331                          break;
 332                      case 's':
 333                          var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
 334                          var b = offsets.bottom + this.yoffset;
 335                          this._elem.css({left:a, bottom:b});
 336                          break;
 337                      case 'sw':
 338                          var a = grid._left + this.xoffset;
 339                          var b = offsets.bottom + this.yoffset;
 340                          this._elem.css({left:a, bottom:b});
 341                          break;
 342                      case 'w':
 343                          var a = grid._left + this.xoffset;
 344                          var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
 345                          this._elem.css({left:a, top:b});
 346                          break;
 347                      default:  // same as 'se'
 348                          var a = grid._right - this.xoffset;
 349                          var b = grid._bottom + this.yoffset;
 350                          this._elem.css({right:a, bottom:b});
 351                          break;
 352                  }
 353                  
 354              }
 355              else {
 356                  switch (this.location) {
 357                      case 'nw':
 358                          var a = this._plotDimensions.width - grid._left + this.xoffset;
 359                          var b = grid._top + this.yoffset;
 360                          this._elem.css('right', a);
 361                          this._elem.css('top', b);
 362                          break;
 363                      case 'n':
 364                          var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
 365                          var b = this._plotDimensions.height - grid._top + this.yoffset;
 366                          this._elem.css('left', a);
 367                          this._elem.css('bottom', b);
 368                          break;
 369                      case 'ne':
 370                          var a = this._plotDimensions.width - offsets.right + this.xoffset;
 371                          var b = grid._top + this.yoffset;
 372                          this._elem.css({left:a, top:b});
 373                          break;
 374                      case 'e':
 375                          var a = this._plotDimensions.width - offsets.right + this.xoffset;
 376                          var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
 377                          this._elem.css({left:a, top:b});
 378                          break;
 379                      case 'se':
 380                          var a = this._plotDimensions.width - offsets.right + this.xoffset;
 381                          var b = offsets.bottom + this.yoffset;
 382                          this._elem.css({left:a, bottom:b});
 383                          break;
 384                      case 's':
 385                          var a = (offsets.left + (this._plotDimensions.width - offsets.right))/2 - this.getWidth()/2;
 386                          var b = this._plotDimensions.height - offsets.bottom + this.yoffset;
 387                          this._elem.css({left:a, top:b});
 388                          break;
 389                      case 'sw':
 390                          var a = this._plotDimensions.width - grid._left + this.xoffset;
 391                          var b = offsets.bottom + this.yoffset;
 392                          this._elem.css({right:a, bottom:b});
 393                          break;
 394                      case 'w':
 395                          var a = this._plotDimensions.width - grid._left + this.xoffset;
 396                          var b = (offsets.top + (this._plotDimensions.height - offsets.bottom))/2 - this.getHeight()/2;
 397                          this._elem.css({right:a, top:b});
 398                          break;
 399                      default:  // same as 'se'
 400                          var a = grid._right - this.xoffset;
 401                          var b = grid._bottom + this.yoffset;
 402                          this._elem.css({right:a, bottom:b});
 403                          break;
 404                  }
 405              }
 406          } 
 407      };
 408      
 409      // setup default renderers for axes and legend so user doesn't have to
 410      // called with scope of plot
 411      function preInit(target, data, options) {
 412          options = options || {};
 413          options.axesDefaults = options.axesDefaults || {};
 414          options.legend = options.legend || {};
 415          options.seriesDefaults = options.seriesDefaults || {};
 416          var setopts = false;
 417          if (options.seriesDefaults.renderer == $.jqplot.MekkoRenderer) {
 418              setopts = true;
 419          }
 420          else if (options.series) {
 421              for (var i=0; i < options.series.length; i++) {
 422                  if (options.series[i].renderer == $.jqplot.MekkoRenderer) {
 423                      setopts = true;
 424                  }
 425              }
 426          }
 427          
 428          if (setopts) {
 429              options.axesDefaults.renderer = $.jqplot.MekkoAxisRenderer;
 430              options.legend.renderer = $.jqplot.MekkoLegendRenderer;
 431              options.legend.preDraw = true;
 432          }
 433      }
 434      
 435      $.jqplot.preInitHooks.push(preInit);
 436      
 437  })(jQuery);    


Generated: Fri Nov 28 20:08:37 2014 Cross-referenced by PHPXref 0.7.1