[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/jquery/jqplot/plugins/ -> jqplot.mekkoAxisRenderer.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      // class: $.jqplot.MekkoAxisRenderer
  33      // An axis renderer for a Mekko chart.
  34      // Should be used with a Mekko chart where the mekkoRenderer is used on the series.
  35      // Displays the Y axis as a range from 0 to 1 (0 to 100%) and the x axis with a tick
  36      // for each series scaled to the sum of all the y values.
  37      $.jqplot.MekkoAxisRenderer = function() {
  38      };
  39      
  40      // called with scope of axis object.
  41      $.jqplot.MekkoAxisRenderer.prototype.init = function(options){
  42          // prop: tickMode
  43          // How to space the ticks on the axis.
  44          // 'bar' will place a tick at the width of each bar.  
  45          // This is the default for the x axis.
  46          // 'even' will place ticks at even intervals.  This is
  47          // the default for x2 axis and y axis.  y axis cannot be changed.
  48          this.tickMode;
  49          // prop: barLabelRenderer
  50          // renderer to use to draw labels under each bar.
  51          this.barLabelRenderer = $.jqplot.AxisLabelRenderer;
  52          // prop: barLabels
  53          // array of labels to put under each bar.
  54          this.barLabels = this.barLabels || [];
  55          // prop: barLabelOptions
  56          // options object to pass to the bar label renderer.
  57          this.barLabelOptions = {};
  58          this.tickOptions = $.extend(true, {showGridline:false}, this.tickOptions);
  59          this._barLabels = [];
  60          $.extend(true, this, options);
  61          if (this.name == 'yaxis') {
  62              this.tickOptions.formatString = this.tickOptions.formatString || "%d\%";
  63          }
  64          var db = this._dataBounds;
  65          db.min = 0;
  66          // for y axes, scale always go from 0 to 1 (0 to 100%)
  67          if (this.name == 'yaxis' || this.name == 'y2axis') {
  68              db.max = 100;
  69              this.tickMode = 'even';
  70          }
  71          // For x axes, scale goes from 0 to sum of all y values.
  72          else if (this.name == 'xaxis'){
  73              this.tickMode = (this.tickMode == null) ? 'bar' : this.tickMode;
  74              for (var i=0; i<this._series.length; i++) {
  75                  db.max += this._series[i]._sumy;
  76              }
  77          }
  78          else if (this.name == 'x2axis'){
  79              this.tickMode = (this.tickMode == null) ? 'even' : this.tickMode;
  80              for (var i=0; i<this._series.length; i++) {
  81                  db.max += this._series[i]._sumy;
  82              }
  83          }
  84      };
  85      
  86      // called with scope of axis
  87      $.jqplot.MekkoAxisRenderer.prototype.draw = function(ctx, plot) {
  88          if (this.show) {
  89              // populate the axis label and value properties.
  90              // createTicks is a method on the renderer, but
  91              // call it within the scope of the axis.
  92              this.renderer.createTicks.call(this);
  93              // fill a div with axes labels in the right direction.
  94              // Need to pregenerate each axis to get it's bounds and
  95              // position it and the labels correctly on the plot.
  96              var dim=0;
  97              var temp;
  98              
  99              var elem = document.createElement('div');
 100              this._elem = $(elem);
 101              this._elem.addClass('jqplot-axis jqplot-'+this.name);
 102              this._elem.css('position', 'absolute');
 103              elem = null;
 104              
 105              if (this.name == 'xaxis' || this.name == 'x2axis') {
 106                  this._elem.width(this._plotDimensions.width);
 107              }
 108              else {
 109                  this._elem.height(this._plotDimensions.height);
 110              }
 111              
 112              // draw the axis label
 113              // create a _label object.
 114              this.labelOptions.axis = this.name;
 115              this._label = new this.labelRenderer(this.labelOptions);
 116              if (this._label.show) {
 117                  this._elem.append(this._label.draw(ctx));
 118              }
 119              
 120              var t, tick, elem;
 121              if (this.showTicks) {
 122                  t = this._ticks;
 123                  for (var i=0; i<t.length; i++) {
 124                      tick = t[i];
 125                      if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
 126                          this._elem.append(tick.draw(ctx));
 127                      }
 128                  }
 129              }
 130              
 131              // draw the series labels
 132              for (i=0; i<this.barLabels.length; i++) {
 133                  this.barLabelOptions.axis = this.name;
 134                  this.barLabelOptions.label = this.barLabels[i];
 135                  this._barLabels.push(new this.barLabelRenderer(this.barLabelOptions));
 136                  if (this.tickMode != 'bar') {
 137                      this._barLabels[i].show = false;
 138                  }
 139                  if (this._barLabels[i].show) {
 140                      var elem = this._barLabels[i].draw(ctx, plot);
 141                      elem.removeClass('jqplot-'+this.name+'-label');
 142                      elem.addClass('jqplot-'+this.name+'-tick');
 143                      elem.addClass('jqplot-mekko-barLabel');
 144                      elem.appendTo(this._elem);
 145                      elem = null;
 146                  }   
 147              }
 148              
 149          }
 150          return this._elem;
 151      };
 152      
 153      // called with scope of an axis
 154      $.jqplot.MekkoAxisRenderer.prototype.reset = function() {
 155          this.min = this._min;
 156          this.max = this._max;
 157          this.tickInterval = this._tickInterval;
 158          this.numberTicks = this._numberTicks;
 159          // this._ticks = this.__ticks;
 160      };
 161      
 162      // called with scope of axis
 163      $.jqplot.MekkoAxisRenderer.prototype.set = function() { 
 164          var dim = 0;
 165          var temp;
 166          var w = 0;
 167          var h = 0;
 168          var lshow = (this._label == null) ? false : this._label.show;
 169          if (this.show && this.showTicks) {
 170              var t = this._ticks;
 171              for (var i=0; i<t.length; i++) {
 172                  var tick = t[i];
 173                  if (tick.showLabel && (!tick.isMinorTick || this.showMinorTicks)) {
 174                      if (this.name == 'xaxis' || this.name == 'x2axis') {
 175                          temp = tick._elem.outerHeight(true);
 176                      }
 177                      else {
 178                          temp = tick._elem.outerWidth(true);
 179                      }
 180                      if (temp > dim) {
 181                          dim = temp;
 182                      }
 183                  }
 184              }
 185              
 186              if (lshow) {
 187                  w = this._label._elem.outerWidth(true);
 188                  h = this._label._elem.outerHeight(true); 
 189              }
 190              if (this.name == 'xaxis') {
 191                  dim = dim + h;
 192                  this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'});
 193              }
 194              else if (this.name == 'x2axis') {
 195                  dim = dim + h;
 196                  this._elem.css({'height':dim+'px', left:'0px', top:'0px'});
 197              }
 198              else if (this.name == 'yaxis') {
 199                  dim = dim + w;
 200                  this._elem.css({'width':dim+'px', left:'0px', top:'0px'});
 201                  if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
 202                      this._label._elem.css('width', w+'px');
 203                  }
 204              }
 205              else {
 206                  dim = dim + w;
 207                  this._elem.css({'width':dim+'px', right:'0px', top:'0px'});
 208                  if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) {
 209                      this._label._elem.css('width', w+'px');
 210                  }
 211              }
 212          }  
 213      };    
 214      
 215      // called with scope of axis
 216      $.jqplot.MekkoAxisRenderer.prototype.createTicks = function() {
 217          // we're are operating on an axis here
 218          var ticks = this._ticks;
 219          var userTicks = this.ticks;
 220          var name = this.name;
 221          // databounds were set on axis initialization.
 222          var db = this._dataBounds;
 223          var dim, interval;
 224          var min, max;
 225          var pos1, pos2;
 226          var t, tt, i, j;
 227          
 228          // if we already have ticks, use them.
 229          // ticks must be in order of increasing value.
 230          
 231          if (userTicks.length) {
 232              // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed
 233              for (i=0; i<userTicks.length; i++){
 234                  var ut = userTicks[i];
 235                  var t = new this.tickRenderer(this.tickOptions);
 236                  if (ut.constructor == Array) {
 237                      t.value = ut[0];
 238                      t.label = ut[1];
 239                      if (!this.showTicks) {
 240                          t.showLabel = false;
 241                          t.showMark = false;
 242                      }
 243                      else if (!this.showTickMarks) {
 244                          t.showMark = false;
 245                      }
 246                      t.setTick(ut[0], this.name);
 247                      this._ticks.push(t);
 248                  }
 249                  
 250                  else {
 251                      t.value = ut;
 252                      if (!this.showTicks) {
 253                          t.showLabel = false;
 254                          t.showMark = false;
 255                      }
 256                      else if (!this.showTickMarks) {
 257                          t.showMark = false;
 258                      }
 259                      t.setTick(ut, this.name);
 260                      this._ticks.push(t);
 261                  }
 262              }
 263              this.numberTicks = userTicks.length;
 264              this.min = this._ticks[0].value;
 265              this.max = this._ticks[this.numberTicks-1].value;
 266              this.tickInterval = (this.max - this.min) / (this.numberTicks - 1);
 267          }
 268          
 269          // we don't have any ticks yet, let's make some!
 270          else {
 271              if (name == 'xaxis' || name == 'x2axis') {
 272                  dim = this._plotDimensions.width;
 273              }
 274              else {
 275                  dim = this._plotDimensions.height;
 276              }
 277              
 278              // if min, max and number of ticks specified, user can't specify interval.
 279              if (this.min != null && this.max != null && this.numberTicks != null) {
 280                  this.tickInterval = null;
 281              }
 282          
 283              min = (this.min != null) ? this.min : db.min;
 284              max = (this.max != null) ? this.max : db.max;
 285              
 286              // if min and max are same, space them out a bit.+
 287              if (min == max) {
 288                  var adj = 0.05;
 289                  if (min > 0) {
 290                      adj = Math.max(Math.log(min)/Math.LN10, 0.05);
 291                  }
 292                  min -= adj;
 293                  max += adj;
 294              }
 295  
 296              var range = max - min;
 297              var rmin, rmax;
 298              var temp, prev, curr;
 299              var ynumticks = [3,5,6,11,21];
 300              
 301              // yaxis divide ticks in nice intervals from 0 to 1.
 302              if (this.name == 'yaxis' || this.name == 'y2axis') { 
 303                  this.min = 0;
 304                  this.max = 100; 
 305                  // user didn't specify number of ticks.
 306                  if (!this.numberTicks){
 307                      if (this.tickInterval) {
 308                          this.numberTicks = 3 + Math.ceil(range / this.tickInterval);
 309                      }
 310                      else {
 311                          temp = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
 312                          for (i=0; i<ynumticks.length; i++) {
 313                              curr = temp/ynumticks[i];
 314                              if (curr == 1) {
 315                                  this.numberTicks = ynumticks[i];
 316                                  break;
 317                              }
 318                              else if (curr > 1) {
 319                                  prev = curr;
 320                                  continue;
 321                              }
 322                              else if (curr < 1) {
 323                                  // was prev or is curr closer to one?
 324                                  if (Math.abs(prev - 1) < Math.abs(curr - 1)) {
 325                                      this.numberTicks = ynumticks[i-1];
 326                                      break;
 327                                  }
 328                                  else {
 329                                      this.numberTicks = ynumticks[i];
 330                                      break;
 331                                  }
 332                              }
 333                              else if (i == ynumticks.length -1) {
 334                                  this.numberTicks = ynumticks[i];
 335                              }
 336                          }
 337                          this.tickInterval = range / (this.numberTicks - 1);
 338                      }
 339                  }
 340                  
 341                  // user did specify number of ticks.
 342                  else {
 343                      this.tickInterval = range / (this.numberTicks - 1);
 344                  }
 345  
 346                  for (var i=0; i<this.numberTicks; i++){
 347                      tt = this.min + i * this.tickInterval;
 348                      t = new this.tickRenderer(this.tickOptions);
 349                      // var t = new $.jqplot.AxisTickRenderer(this.tickOptions);
 350                      if (!this.showTicks) {
 351                          t.showLabel = false;
 352                          t.showMark = false;
 353                      }
 354                      else if (!this.showTickMarks) {
 355                          t.showMark = false;
 356                      }
 357                      t.setTick(tt, this.name);
 358                      this._ticks.push(t);
 359                  }
 360              }
 361              
 362              // for x axes, have number ot ticks equal to number of series and ticks placed
 363              // at sum of y values for each series.
 364              else if (this.tickMode == 'bar') {
 365                  this.min = 0;
 366                  this.numberTicks = this._series.length + 1;
 367                  t = new this.tickRenderer(this.tickOptions);
 368                  if (!this.showTicks) {
 369                      t.showLabel = false;
 370                      t.showMark = false;
 371                  }
 372                  else if (!this.showTickMarks) {
 373                      t.showMark = false;
 374                  }
 375                  t.setTick(0, this.name);
 376                  this._ticks.push(t);
 377                  
 378                  temp = 0;
 379  
 380                  for (i=1; i<this.numberTicks; i++){
 381                      temp += this._series[i-1]._sumy;
 382                      t = new this.tickRenderer(this.tickOptions);
 383                      if (!this.showTicks) {
 384                          t.showLabel = false;
 385                          t.showMark = false;
 386                      }
 387                      else if (!this.showTickMarks) {
 388                          t.showMark = false;
 389                      }
 390                      t.setTick(temp, this.name);
 391                      this._ticks.push(t);
 392                  }
 393                  this.max = this.max || temp;
 394                  
 395                  // if user specified a max and it is greater than sum, add a tick
 396                  if (this.max > temp) {
 397                       t = new this.tickRenderer(this.tickOptions);
 398                      if (!this.showTicks) {
 399                          t.showLabel = false;
 400                          t.showMark = false;
 401                      }
 402                      else if (!this.showTickMarks) {
 403                          t.showMark = false;
 404                      }
 405                      t.setTick(this.max, this.name);
 406                      this._ticks.push(t);
 407                      
 408                  }
 409              }
 410              
 411              else if (this.tickMode == 'even') {
 412                  this.min = 0;
 413                  this.max = this.max || db.max;
 414                  // get a desired number of ticks
 415                  var nt = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing);
 416                  range = this.max - this.min;
 417                  this.numberTicks = nt;
 418                  this.tickInterval = range / (this.numberTicks - 1);
 419  
 420                  for (i=0; i<this.numberTicks; i++){
 421                      tt = this.min + i * this.tickInterval;
 422                      t = new this.tickRenderer(this.tickOptions);
 423                      // var t = new $.jqplot.AxisTickRenderer(this.tickOptions);
 424                      if (!this.showTicks) {
 425                          t.showLabel = false;
 426                          t.showMark = false;
 427                      }
 428                      else if (!this.showTickMarks) {
 429                          t.showMark = false;
 430                      }
 431                      t.setTick(tt, this.name);
 432                      this._ticks.push(t);
 433                  }
 434                  
 435              }
 436          }
 437      };
 438      
 439      // called with scope of axis
 440      $.jqplot.MekkoAxisRenderer.prototype.pack = function(pos, offsets) {
 441          var ticks = this._ticks;
 442          var max = this.max;
 443          var min = this.min;
 444          var offmax = offsets.max;
 445          var offmin = offsets.min;
 446          var lshow = (this._label == null) ? false : this._label.show;
 447          
 448          for (var p in pos) {
 449              this._elem.css(p, pos[p]);
 450          }
 451          
 452          this._offsets = offsets;
 453          // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left.
 454          var pixellength = offmax - offmin;
 455          var unitlength = max - min;
 456          
 457          // point to unit and unit to point conversions references to Plot DOM element top left corner.
 458          this.p2u = function(p){
 459              return (p - offmin) * unitlength / pixellength + min;
 460          };
 461          
 462          this.u2p = function(u){
 463              return (u - min) * pixellength / unitlength + offmin;
 464          };
 465                  
 466          if (this.name == 'xaxis' || this.name == 'x2axis'){
 467              this.series_u2p = function(u){
 468                  return (u - min) * pixellength / unitlength;
 469              };
 470              this.series_p2u = function(p){
 471                  return p * unitlength / pixellength + min;
 472              };
 473          }
 474          
 475          else {
 476              this.series_u2p = function(u){
 477                  return (u - max) * pixellength / unitlength;
 478              };
 479              this.series_p2u = function(p){
 480                  return p * unitlength / pixellength + max;
 481              };
 482          }
 483          
 484          if (this.show) {
 485              if (this.name == 'xaxis' || this.name == 'x2axis') {
 486                  for (var i=0; i<ticks.length; i++) {
 487                      var t = ticks[i];
 488                      if (t.show && t.showLabel) {
 489                          var shim;
 490                          
 491                          if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
 492                              // will need to adjust auto positioning based on which axis this is.
 493                              var temp = (this.name == 'xaxis') ? 1 : -1;
 494                              switch (t.labelPosition) {
 495                                  case 'auto':
 496                                      // position at end
 497                                      if (temp * t.angle < 0) {
 498                                          shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
 499                                      }
 500                                      // position at start
 501                                      else {
 502                                          shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
 503                                      }
 504                                      break;
 505                                  case 'end':
 506                                      shim = -t.getWidth() + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
 507                                      break;
 508                                  case 'start':
 509                                      shim = -t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2;
 510                                      break;
 511                                  case 'middle':
 512                                      shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
 513                                      break;
 514                                  default:
 515                                      shim = -t.getWidth()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2;
 516                                      break;
 517                              }
 518                          }
 519                          else {
 520                              shim = -t.getWidth()/2;
 521                          }
 522                          var val = this.u2p(t.value) + shim + 'px';
 523                          t._elem.css('left', val);
 524                          t.pack();
 525                      }
 526                  }
 527                  var w;
 528                  if (lshow) {
 529                      w = this._label._elem.outerWidth(true);
 530                      this._label._elem.css('left', offmin + pixellength/2 - w/2 + 'px');
 531                      if (this.name == 'xaxis') {
 532                          this._label._elem.css('bottom', '0px');
 533                      }
 534                      else {
 535                          this._label._elem.css('top', '0px');
 536                      }
 537                      this._label.pack();
 538                  }
 539                  // now show the labels under the bars.
 540                  var b, l, r;
 541                  for (var i=0; i<this.barLabels.length; i++) {
 542                      b = this._barLabels[i];
 543                      if (b.show) {
 544                          w = b.getWidth();
 545                          l = this._ticks[i].getLeft() + this._ticks[i].getWidth();
 546                          r = this._ticks[i+1].getLeft();
 547                          b._elem.css('left', (r+l-w)/2+'px');
 548                          b._elem.css('top', this._ticks[i]._elem.css('top'));
 549                          b.pack();
 550                      }
 551                  }
 552              }
 553              else {
 554                  for (var i=0; i<ticks.length; i++) {
 555                      var t = ticks[i];
 556                      if (t.show && t.showLabel) {                        
 557                          var shim;
 558                          if (t.constructor == $.jqplot.CanvasAxisTickRenderer && t.angle) {
 559                              // will need to adjust auto positioning based on which axis this is.
 560                              var temp = (this.name == 'yaxis') ? 1 : -1;
 561                              switch (t.labelPosition) {
 562                                  case 'auto':
 563                                      // position at end
 564                                  case 'end':
 565                                      if (temp * t.angle < 0) {
 566                                          shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
 567                                      }
 568                                      else {
 569                                          shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
 570                                      }
 571                                      break;
 572                                  case 'start':
 573                                      if (t.angle > 0) {
 574                                          shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2;
 575                                      }
 576                                      else {
 577                                          shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2;
 578                                      }
 579                                      break;
 580                                  case 'middle':
 581                                      shim = -t.getHeight()/2;
 582                                      break;
 583                                  default:
 584                                      shim = -t.getHeight()/2;
 585                                      break;
 586                              }
 587                          }
 588                          else {
 589                              shim = -t.getHeight()/2;
 590                          }
 591                          
 592                          var val = this.u2p(t.value) + shim + 'px';
 593                          t._elem.css('top', val);
 594                          t.pack();
 595                      }
 596                  }
 597                  if (lshow) {
 598                      var h = this._label._elem.outerHeight(true);
 599                      this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px');
 600                      if (this.name == 'yaxis') {
 601                          this._label._elem.css('left', '0px');
 602                      }
 603                      else {
 604                          this._label._elem.css('right', '0px');
 605                      }   
 606                      this._label.pack();
 607                  }
 608              }
 609          }
 610      };
 611  })(jQuery);


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