[ Index ]

PHP Cross Reference of vtigercrm-6.1.0

title

Body

[close]

/libraries/jquery/jqplot/plugins/ -> jqplot.canvasOverlay.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      var objCounter = 0;
  33      // class: $.jqplot.CanvasOverlay
  34      $.jqplot.CanvasOverlay = function(opts){
  35          var options = opts || {};
  36          this.options = {
  37              show: $.jqplot.config.enablePlugins,
  38              deferDraw: false
  39          };
  40          // prop: objects
  41          this.objects = [];
  42          this.objectNames = [];
  43          this.canvas = null;
  44          this.markerRenderer = new $.jqplot.MarkerRenderer({style:'line'});
  45          this.markerRenderer.init();
  46          this.highlightObjectIndex = null;
  47          if (options.objects) {
  48              var objs = options.objects,
  49                  obj;
  50              for (var i=0; i<objs.length; i++) {
  51                  obj = objs[i];
  52                  for (var n in obj) {
  53                      switch (n) {
  54                          case 'line':
  55                              this.addLine(obj[n]);
  56                              break;
  57                          case 'horizontalLine':
  58                              this.addHorizontalLine(obj[n]);
  59                              break;
  60                          case 'dashedHorizontalLine':
  61                              this.addDashedHorizontalLine(obj[n]);
  62                              break;
  63                          case 'verticalLine':
  64                              this.addVerticalLine(obj[n]);
  65                              break;
  66                          case 'dashedVerticalLine':
  67                              this.addDashedVerticalLine(obj[n]);
  68                              break;
  69                          default:
  70                              break;
  71                      }
  72                  }   
  73              }
  74          }
  75          $.extend(true, this.options, options);
  76      };
  77      
  78      // called with scope of a plot object
  79      $.jqplot.CanvasOverlay.postPlotInit = function (target, data, opts) {
  80          var options = opts || {};
  81          // add a canvasOverlay attribute to the plot
  82          this.plugins.canvasOverlay = new $.jqplot.CanvasOverlay(options.canvasOverlay);     
  83      };
  84  
  85  
  86      function LineBase() {
  87          this.uid = null;
  88          this.type = null;
  89          this.gridStart = null;
  90          this.gridStop = null;
  91          this.tooltipWidthFactor = 0;
  92          this.options = {           
  93              // prop: name
  94              // Optional name for the overlay object.
  95              // Can be later used to retrieve the object by name.
  96              name: null,
  97              // prop: show
  98              // true to show (draw), false to not draw.
  99              show: true,
 100              // prop: lineWidth
 101              // Width of the line.
 102              lineWidth: 2,
 103              // prop: lineCap
 104              // Type of ending placed on the line ['round', 'butt', 'square']
 105              lineCap: 'round',
 106              // prop: color
 107              // color of the line
 108              color: '#666666',
 109              // prop: shadow
 110              // wether or not to draw a shadow on the line
 111              shadow: true,
 112              // prop: shadowAngle
 113              // Shadow angle in degrees
 114              shadowAngle: 45,
 115              // prop: shadowOffset
 116              // Shadow offset from line in pixels
 117              shadowOffset: 1,
 118              // prop: shadowDepth
 119              // Number of times shadow is stroked, each stroke offset shadowOffset from the last.
 120              shadowDepth: 3,
 121              // prop: shadowAlpha
 122              // Alpha channel transparency of shadow.  0 = transparent.
 123              shadowAlpha: '0.07',
 124              // prop: xaxis
 125              // X axis to use for positioning/scaling the line.
 126              xaxis: 'xaxis',
 127              // prop: yaxis
 128              // Y axis to use for positioning/scaling the line.
 129              yaxis: 'yaxis',
 130              // prop: showTooltip
 131              // Show a tooltip with data point values.
 132              showTooltip: false,
 133              // prop: showTooltipPrecision
 134              // Controls how close to line cursor must be to show tooltip.
 135              // Higher number = closer to line, lower number = farther from line.
 136              // 1.0 = cursor must be over line.
 137              showTooltipPrecision: 0.6,
 138              // prop: tooltipLocation
 139              // Where to position tooltip, 'n', 'ne', 'e', 'se', 's', 'sw', 'w', 'nw'
 140              tooltipLocation: 'nw',
 141              // prop: fadeTooltip
 142              // true = fade in/out tooltip, flase = show/hide tooltip
 143              fadeTooltip: true,
 144              // prop: tooltipFadeSpeed
 145              // 'slow', 'def', 'fast', or number of milliseconds.
 146              tooltipFadeSpeed: "fast",
 147              // prop: tooltipOffset
 148              // Pixel offset of tooltip from the highlight.
 149              tooltipOffset: 4,
 150              // prop: tooltipFormatString
 151              // Format string passed the x and y values of the cursor on the line.
 152              // e.g., 'Dogs: %.2f, Cats: %d'.
 153              tooltipFormatString: '%d, %d'
 154          };
 155      }
 156  
 157      /**
 158       * Class: Line
 159       * A straight line.
 160       */
 161      function Line(options) {
 162          LineBase.call(this);
 163          this.type = 'line';
 164          var opts = {
 165              // prop: start
 166              // [x, y] coordinates for the start of the line.
 167              start: [],
 168              // prop: stop
 169              // [x, y] coordinates for the end of the line.
 170              stop: []
 171          };
 172          $.extend(true, this.options, opts, options);
 173  
 174          if (this.options.showTooltipPrecision < 0.01) {
 175              this.options.showTooltipPrecision = 0.01;
 176          }
 177      }
 178  
 179      Line.prototype = new LineBase();
 180      Line.prototype.constructor = Line;
 181  
 182  
 183      /**
 184       * Class: HorizontalLine
 185       * A straight horizontal line.
 186       */
 187      function HorizontalLine(options) {
 188          LineBase.call(this);
 189          this.type = 'horizontalLine';
 190          var opts = {
 191              // prop: y
 192              // y value to position the line
 193              y: null,
 194              // prop: xmin
 195              // x value for the start of the line, null to scale to axis min.
 196              xmin: null,
 197              // prop: xmax
 198              // x value for the end of the line, null to scale to axis max.
 199              xmax: null,
 200              // prop xOffset
 201              // offset ends of the line inside the grid.  Number 
 202              xOffset: '6px', // number or string.  Number interpreted as units, string as pixels.
 203              xminOffset: null,
 204              xmaxOffset: null
 205          };
 206          $.extend(true, this.options, opts, options);
 207  
 208          if (this.options.showTooltipPrecision < 0.01) {
 209              this.options.showTooltipPrecision = 0.01;
 210          }
 211      }
 212  
 213      HorizontalLine.prototype = new LineBase();
 214      HorizontalLine.prototype.constructor = HorizontalLine;
 215      
 216  
 217      /**
 218       * Class: DashedHorizontalLine
 219       * A straight dashed horizontal line.
 220       */
 221      function DashedHorizontalLine(options) {
 222          LineBase.call(this);
 223          this.type = 'dashedHorizontalLine';
 224          var opts = {
 225              y: null,
 226              xmin: null,
 227              xmax: null,
 228              xOffset: '6px', // number or string.  Number interpreted as units, string as pixels.
 229              xminOffset: null,
 230              xmaxOffset: null,
 231              // prop: dashPattern
 232              // Array of line, space settings in pixels.
 233              // Default is 8 pixel of line, 8 pixel of space.
 234              // Note, limit to a 2 element array b/c of bug with higher order arrays.
 235              dashPattern: [8,8]
 236          };
 237          $.extend(true, this.options, opts, options);
 238  
 239          if (this.options.showTooltipPrecision < 0.01) {
 240              this.options.showTooltipPrecision = 0.01;
 241          }
 242      }
 243  
 244      DashedHorizontalLine.prototype = new LineBase();
 245      DashedHorizontalLine.prototype.constructor = DashedHorizontalLine;
 246      
 247  
 248      /**
 249       * Class: VerticalLine
 250       * A straight vertical line.
 251       */
 252      function VerticalLine(options) {
 253          LineBase.call(this);
 254          this.type = 'verticalLine';
 255          var opts = {
 256              x: null,
 257              ymin: null,
 258              ymax: null,
 259              yOffset: '6px', // number or string.  Number interpreted as units, string as pixels.
 260              yminOffset: null,
 261              ymaxOffset: null
 262          };
 263          $.extend(true, this.options, opts, options);
 264  
 265          if (this.options.showTooltipPrecision < 0.01) {
 266              this.options.showTooltipPrecision = 0.01;
 267          }
 268      }
 269  
 270      VerticalLine.prototype = new LineBase();
 271      VerticalLine.prototype.constructor = VerticalLine;
 272      
 273  
 274      /**
 275       * Class: DashedVerticalLine
 276       * A straight dashed vertical line.
 277       */
 278      function DashedVerticalLine(options) {
 279          LineBase.call(this);
 280          this.type = 'dashedVerticalLine';
 281          this.start = null;
 282          this.stop = null;
 283          var opts = {
 284              x: null,
 285              ymin: null,
 286              ymax: null,
 287              yOffset: '6px', // number or string.  Number interpreted as units, string as pixels.
 288              yminOffset: null,
 289              ymaxOffset: null,
 290              // prop: dashPattern
 291              // Array of line, space settings in pixels.
 292              // Default is 8 pixel of line, 8 pixel of space.
 293              // Note, limit to a 2 element array b/c of bug with higher order arrays.
 294              dashPattern: [8,8]
 295          };
 296          $.extend(true, this.options, opts, options);
 297  
 298          if (this.options.showTooltipPrecision < 0.01) {
 299              this.options.showTooltipPrecision = 0.01;
 300          }
 301      }
 302  
 303      DashedVerticalLine.prototype = new LineBase();
 304      DashedVerticalLine.prototype.constructor = DashedVerticalLine;
 305      
 306      $.jqplot.CanvasOverlay.prototype.addLine = function(opts) {
 307          var line = new Line(opts);
 308          line.uid = objCounter++;
 309          this.objects.push(line);
 310          this.objectNames.push(line.options.name);
 311      };
 312      
 313      $.jqplot.CanvasOverlay.prototype.addHorizontalLine = function(opts) {
 314          var line = new HorizontalLine(opts);
 315          line.uid = objCounter++;
 316          this.objects.push(line);
 317          this.objectNames.push(line.options.name);
 318      };
 319      
 320      $.jqplot.CanvasOverlay.prototype.addDashedHorizontalLine = function(opts) {
 321          var line = new DashedHorizontalLine(opts);
 322          line.uid = objCounter++;
 323          this.objects.push(line);
 324          this.objectNames.push(line.options.name);
 325      };
 326      
 327      $.jqplot.CanvasOverlay.prototype.addVerticalLine = function(opts) {
 328          var line = new VerticalLine(opts);
 329          line.uid = objCounter++;
 330          this.objects.push(line);
 331          this.objectNames.push(line.options.name);
 332      };
 333      
 334      $.jqplot.CanvasOverlay.prototype.addDashedVerticalLine = function(opts) {
 335          var line = new DashedVerticalLine(opts);
 336          line.uid = objCounter++;
 337          this.objects.push(line);
 338          this.objectNames.push(line.options.name);
 339      };
 340      
 341      $.jqplot.CanvasOverlay.prototype.removeObject = function(idx) {
 342          // check if integer, remove by index
 343          if ($.type(idx) == 'number') {
 344              this.objects.splice(idx, 1);
 345              this.objectNames.splice(idx, 1);
 346          }
 347          // if string, remove by name
 348          else {
 349              var id = $.inArray(idx, this.objectNames);
 350              if (id != -1) {
 351                  this.objects.splice(id, 1);
 352                  this.objectNames.splice(id, 1);
 353              }
 354          }
 355      };
 356      
 357      $.jqplot.CanvasOverlay.prototype.getObject = function(idx) {
 358          // check if integer, remove by index
 359          if ($.type(idx) == 'number') {
 360              return this.objects[idx];
 361          }
 362          // if string, remove by name
 363          else {
 364              var id = $.inArray(idx, this.objectNames);
 365              if (id != -1) {
 366                  return this.objects[id];
 367              }
 368          }
 369      };
 370      
 371      // Set get as alias for getObject.
 372      $.jqplot.CanvasOverlay.prototype.get = $.jqplot.CanvasOverlay.prototype.getObject;
 373      
 374      $.jqplot.CanvasOverlay.prototype.clear = function(plot) {
 375          this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
 376      };
 377      
 378      $.jqplot.CanvasOverlay.prototype.draw = function(plot) {
 379          var obj, 
 380              objs = this.objects,
 381              mr = this.markerRenderer,
 382              start,
 383              stop;
 384          if (this.options.show) {
 385              this.canvas._ctx.clearRect(0,0,this.canvas.getWidth(), this.canvas.getHeight());
 386              for (var k=0; k<objs.length; k++) {
 387                  obj = objs[k];
 388                  var opts = $.extend(true, {}, obj.options);
 389                  if (obj.options.show) {
 390                      // style and shadow properties should be set before
 391                      // every draw of marker renderer.
 392                      mr.shadow = obj.options.shadow;
 393                      obj.tooltipWidthFactor = obj.options.lineWidth / obj.options.showTooltipPrecision;
 394                      switch (obj.type) {
 395                          case 'line':
 396                              // style and shadow properties should be set before
 397                              // every draw of marker renderer.
 398                              mr.style = 'line';
 399                              opts.closePath = false;
 400                              start = [plot.axes[obj.options.xaxis].series_u2p(obj.options.start[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.start[1])];
 401                              stop = [plot.axes[obj.options.xaxis].series_u2p(obj.options.stop[0]), plot.axes[obj.options.yaxis].series_u2p(obj.options.stop[1])];
 402                              obj.gridStart = start;
 403                              obj.gridStop = stop;
 404                              mr.draw(start, stop, this.canvas._ctx, opts);
 405                              break;
 406                          case 'horizontalLine':
 407                              
 408                              // style and shadow properties should be set before
 409                              // every draw of marker renderer.
 410                              if (obj.options.y != null) {
 411                                  mr.style = 'line';
 412                                  opts.closePath = false;
 413                                  var xaxis = plot.axes[obj.options.xaxis],
 414                                      xstart,
 415                                      xstop,
 416                                      y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
 417                                      xminoff = obj.options.xminOffset || obj.options.xOffset,
 418                                      xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
 419                                  if (obj.options.xmin != null) {
 420                                      xstart = xaxis.series_u2p(obj.options.xmin);
 421                                  }
 422                                  else if (xminoff != null) {
 423                                      if ($.type(xminoff) == "number") {
 424                                          xstart = xaxis.series_u2p(xaxis.min + xminoff);
 425                                      }
 426                                      else if ($.type(xminoff) == "string") {
 427                                          xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
 428                                      }
 429                                  }
 430                                  if (obj.options.xmax != null) {
 431                                      xstop = xaxis.series_u2p(obj.options.xmax);
 432                                  }
 433                                  else if (xmaxoff != null) {
 434                                      if ($.type(xmaxoff) == "number") {
 435                                          xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
 436                                      }
 437                                      else if ($.type(xmaxoff) == "string") {
 438                                          xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
 439                                      }
 440                                  }
 441                                  if (xstop != null && xstart != null) {
 442                                      obj.gridStart = [xstart, y];
 443                                      obj.gridStop = [xstop, y];
 444                                      mr.draw([xstart, y], [xstop, y], this.canvas._ctx, opts);
 445                                  }
 446                              }
 447                              break;
 448  
 449                          case 'dashedHorizontalLine':
 450                              
 451                              var dashPat = obj.options.dashPattern;
 452                              var dashPatLen = 0;
 453                              for (var i=0; i<dashPat.length; i++) {
 454                                  dashPatLen += dashPat[i];
 455                              }
 456  
 457                              // style and shadow properties should be set before
 458                              // every draw of marker renderer.
 459                              if (obj.options.y != null) {
 460                                  mr.style = 'line';
 461                                  opts.closePath = false;
 462                                  var xaxis = plot.axes[obj.options.xaxis],
 463                                      xstart,
 464                                      xstop,
 465                                      y = plot.axes[obj.options.yaxis].series_u2p(obj.options.y),
 466                                      xminoff = obj.options.xminOffset || obj.options.xOffset,
 467                                      xmaxoff = obj.options.xmaxOffset || obj.options.xOffset;
 468                                  if (obj.options.xmin != null) {
 469                                      xstart = xaxis.series_u2p(obj.options.xmin);
 470                                  }
 471                                  else if (xminoff != null) {
 472                                      if ($.type(xminoff) == "number") {
 473                                          xstart = xaxis.series_u2p(xaxis.min + xminoff);
 474                                      }
 475                                      else if ($.type(xminoff) == "string") {
 476                                          xstart = xaxis.series_u2p(xaxis.min) + parseFloat(xminoff);
 477                                      }
 478                                  }
 479                                  if (obj.options.xmax != null) {
 480                                      xstop = xaxis.series_u2p(obj.options.xmax);
 481                                  }
 482                                  else if (xmaxoff != null) {
 483                                      if ($.type(xmaxoff) == "number") {
 484                                          xstop = xaxis.series_u2p(xaxis.max - xmaxoff);
 485                                      }
 486                                      else if ($.type(xmaxoff) == "string") {
 487                                          xstop = xaxis.series_u2p(xaxis.max) - parseFloat(xmaxoff);
 488                                      }
 489                                  }
 490                                  if (xstop != null && xstart != null) {
 491                                      obj.gridStart = [xstart, y];
 492                                      obj.gridStop = [xstop, y];
 493                                      var numDash = Math.ceil((xstop - xstart)/dashPatLen);
 494                                      var b=xstart, e;
 495                                      for (var i=0; i<numDash; i++) {
 496                                          for (var j=0; j<dashPat.length; j+=2) {
 497                                              e = b+dashPat[j];
 498                                              mr.draw([b, y], [e, y], this.canvas._ctx, opts);
 499                                              b += dashPat[j];
 500                                              if (j < dashPat.length-1) {
 501                                                  b += dashPat[j+1];
 502                                              }
 503                                          }
 504                                      }
 505                                  }
 506                              }
 507                              break;
 508  
 509                          case 'verticalLine':
 510                              
 511                              // style and shadow properties should be set before
 512                              // every draw of marker renderer.
 513                              if (obj.options.x != null) {
 514                                  mr.style = 'line';
 515                                  opts.closePath = false;
 516                                  var yaxis = plot.axes[obj.options.yaxis],
 517                                      ystart,
 518                                      ystop,
 519                                      x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
 520                                      yminoff = obj.options.yminOffset || obj.options.yOffset,
 521                                      ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
 522                                  if (obj.options.ymin != null) {
 523                                      ystart = yaxis.series_u2p(obj.options.ymin);
 524                                  }
 525                                  else if (yminoff != null) {
 526                                      if ($.type(yminoff) == "number") {
 527                                          ystart = yaxis.series_u2p(yaxis.min - yminoff);
 528                                      }
 529                                      else if ($.type(yminoff) == "string") {
 530                                          ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
 531                                      }
 532                                  }
 533                                  if (obj.options.ymax != null) {
 534                                      ystop = yaxis.series_u2p(obj.options.ymax);
 535                                  }
 536                                  else if (ymaxoff != null) {
 537                                      if ($.type(ymaxoff) == "number") {
 538                                          ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
 539                                      }
 540                                      else if ($.type(ymaxoff) == "string") {
 541                                          ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
 542                                      }
 543                                  }
 544                                  if (ystop != null && ystart != null) {
 545                                      obj.gridStart = [x, ystart];
 546                                      obj.gridStop = [x, ystop];
 547                                      mr.draw([x, ystart], [x, ystop], this.canvas._ctx, opts);
 548                                  }
 549                              }
 550                              break;
 551  
 552                          case 'dashedVerticalLine':
 553                              
 554                              var dashPat = obj.options.dashPattern;
 555                              var dashPatLen = 0;
 556                              for (var i=0; i<dashPat.length; i++) {
 557                                  dashPatLen += dashPat[i];
 558                              }
 559  
 560                              // style and shadow properties should be set before
 561                              // every draw of marker renderer.
 562                              if (obj.options.x != null) {
 563                                  mr.style = 'line';
 564                                  opts.closePath = false;
 565                                  var yaxis = plot.axes[obj.options.yaxis],
 566                                      ystart,
 567                                      ystop,
 568                                      x = plot.axes[obj.options.xaxis].series_u2p(obj.options.x),
 569                                      yminoff = obj.options.yminOffset || obj.options.yOffset,
 570                                      ymaxoff = obj.options.ymaxOffset || obj.options.yOffset;
 571                                  if (obj.options.ymin != null) {
 572                                      ystart = yaxis.series_u2p(obj.options.ymin);
 573                                  }
 574                                  else if (yminoff != null) {
 575                                      if ($.type(yminoff) == "number") {
 576                                          ystart = yaxis.series_u2p(yaxis.min - yminoff);
 577                                      }
 578                                      else if ($.type(yminoff) == "string") {
 579                                          ystart = yaxis.series_u2p(yaxis.min) - parseFloat(yminoff);
 580                                      }
 581                                  }
 582                                  if (obj.options.ymax != null) {
 583                                      ystop = yaxis.series_u2p(obj.options.ymax);
 584                                  }
 585                                  else if (ymaxoff != null) {
 586                                      if ($.type(ymaxoff) == "number") {
 587                                          ystop = yaxis.series_u2p(yaxis.max + ymaxoff);
 588                                      }
 589                                      else if ($.type(ymaxoff) == "string") {
 590                                          ystop = yaxis.series_u2p(yaxis.max) + parseFloat(ymaxoff);
 591                                      }
 592                                  }
 593  
 594  
 595                                  if (ystop != null && ystart != null) {
 596                                      obj.gridStart = [x, ystart];
 597                                      obj.gridStop = [x, ystop];
 598                                      var numDash = Math.ceil((ystart - ystop)/dashPatLen);
 599                                      var firstDashAdjust = ((numDash * dashPatLen) - (ystart - ystop))/2.0;
 600                                      var b=ystart, e, bs, es;
 601                                      for (var i=0; i<numDash; i++) {
 602                                          for (var j=0; j<dashPat.length; j+=2) {
 603                                              e = b - dashPat[j];
 604                                              if (e < ystop) {
 605                                                  e = ystop;
 606                                              }
 607                                              if (b < ystop) {
 608                                                  b = ystop;
 609                                              }
 610                                              // es = e;
 611                                              // if (i == 0) {
 612                                              //  es += firstDashAdjust;
 613                                              // }
 614                                              mr.draw([x, b], [x, e], this.canvas._ctx, opts);
 615                                              b -= dashPat[j];
 616                                              if (j < dashPat.length-1) {
 617                                                  b -= dashPat[j+1];
 618                                              }
 619                                          }
 620                                      }
 621                                  }
 622                              }
 623                              break;
 624  
 625                          default:
 626                              break;
 627                      }
 628                  }
 629              }
 630          }
 631      };
 632      
 633      // called within context of plot
 634      // create a canvas which we can draw on.
 635      // insert it before the eventCanvas, so eventCanvas will still capture events.
 636      $.jqplot.CanvasOverlay.postPlotDraw = function() {
 637          var co = this.plugins.canvasOverlay;
 638          // Memory Leaks patch    
 639          if (co && co.highlightCanvas) {
 640              co.highlightCanvas.resetCanvas();
 641              co.highlightCanvas = null;
 642          }
 643          co.canvas = new $.jqplot.GenericCanvas();
 644          
 645          this.eventCanvas._elem.before(co.canvas.createElement(this._gridPadding, 'jqplot-overlayCanvas-canvas', this._plotDimensions, this));
 646          co.canvas.setContext();
 647          if (!co.deferDraw) {
 648              co.draw(this);
 649          }
 650  
 651          var elem = document.createElement('div');
 652          co._tooltipElem = $(elem);
 653          elem = null;
 654          co._tooltipElem.addClass('jqplot-canvasOverlay-tooltip');
 655          co._tooltipElem.css({position:'absolute', display:'none'});
 656          
 657          this.eventCanvas._elem.before(co._tooltipElem);
 658          this.eventCanvas._elem.bind('mouseleave', { elem: co._tooltipElem }, function (ev) { ev.data.elem.hide(); });
 659  
 660          var co = null;
 661      };
 662  
 663  
 664      function showTooltip(plot, obj, gridpos, datapos) {
 665          var co = plot.plugins.canvasOverlay;
 666          var elem = co._tooltipElem;
 667  
 668          var opts = obj.options, x, y;
 669  
 670          elem.html($.jqplot.sprintf(opts.tooltipFormatString, datapos[0], datapos[1]));
 671          
 672          switch (opts.tooltipLocation) {
 673              case 'nw':
 674                  x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
 675                  y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
 676                  break;
 677              case 'n':
 678                  x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
 679                  y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
 680                  break;
 681              case 'ne':
 682                  x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
 683                  y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
 684                  break;
 685              case 'e':
 686                  x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
 687                  y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
 688                  break;
 689              case 'se':
 690                  x = gridpos[0] + plot._gridPadding.left + opts.tooltipOffset;
 691                  y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
 692                  break;
 693              case 's':
 694                  x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true)/2;
 695                  y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
 696                  break;
 697              case 'sw':
 698                  x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
 699                  y = gridpos[1] + plot._gridPadding.top + opts.tooltipOffset;
 700                  break;
 701              case 'w':
 702                  x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
 703                  y = gridpos[1] + plot._gridPadding.top - elem.outerHeight(true)/2;
 704                  break;
 705              default: // same as 'nw'
 706                  x = gridpos[0] + plot._gridPadding.left - elem.outerWidth(true) - opts.tooltipOffset;
 707                  y = gridpos[1] + plot._gridPadding.top - opts.tooltipOffset - elem.outerHeight(true);
 708                  break;
 709          }
 710  
 711          elem.css('left', x);
 712          elem.css('top', y);
 713          if (opts.fadeTooltip) {
 714              // Fix for stacked up animations.  Thnanks Trevor!
 715              elem.stop(true,true).fadeIn(opts.tooltipFadeSpeed);
 716          }
 717          else {
 718              elem.show();
 719          }
 720          elem = null;
 721      }
 722  
 723  
 724      function isNearLine(point, lstart, lstop, width) {
 725          // r is point to test, p and q are end points.
 726          var rx = point[0];
 727          var ry = point[1];
 728          var px = Math.round(lstop[0]);
 729          var py = Math.round(lstop[1]);
 730          var qx = Math.round(lstart[0]);
 731          var qy = Math.round(lstart[1]);
 732  
 733          var l = Math.sqrt(Math.pow(px-qx, 2) + Math.pow(py-qy, 2));
 734  
 735          // scale error term by length of line.
 736          var eps = width*l;
 737          var res = Math.abs((qx-px) * (ry-py) - (qy-py) * (rx-px));
 738          var ret = (res < eps) ? true : false;
 739          return ret;
 740      }
 741  
 742  
 743      function handleMove(ev, gridpos, datapos, neighbor, plot) {
 744          var co = plot.plugins.canvasOverlay;
 745          var objs = co.objects;
 746          var l = objs.length;
 747          var obj, haveHighlight=false;
 748          var elem;
 749          for (var i=0; i<l; i++) {
 750              obj = objs[i];
 751              if (obj.options.showTooltip) {
 752                  var n = isNearLine([gridpos.x, gridpos.y], obj.gridStart, obj.gridStop, obj.tooltipWidthFactor);
 753                  datapos = [plot.axes[obj.options.xaxis].series_p2u(gridpos.x), plot.axes[obj.options.yaxis].series_p2u(gridpos.y)];
 754  
 755                  // cases:
 756                  //    near line, no highlighting
 757                  //    near line, highliting on this line
 758                  //    near line, highlighting another line
 759                  //    not near any line, highlighting
 760                  //    not near any line, no highlighting
 761  
 762                  // near line, not currently highlighting
 763                  if (n && co.highlightObjectIndex == null) {
 764                      switch (obj.type) {
 765                          case 'line':
 766                              showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
 767                              break;
 768  
 769                          case 'horizontalLine':
 770                          case 'dashedHorizontalLine':
 771                              showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
 772                              break;
 773  
 774                          case 'verticalLine':
 775                          case 'dashedVerticalLine':
 776                              showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
 777                              break;
 778                          default:
 779                              break;
 780                      } 
 781                      co.highlightObjectIndex = i;
 782                      haveHighlight = true;
 783                      break;
 784                  }
 785  
 786                  // near line, highlighting another line.
 787                  else if (n && co.highlightObjectIndex !== i) {
 788                      // turn off tooltip.
 789                      elem = co._tooltipElem;
 790                      if (obj.fadeTooltip) {
 791                          elem.fadeOut(obj.tooltipFadeSpeed);
 792                      }
 793                      else {
 794                          elem.hide();
 795                      }
 796  
 797                      // turn on right tooltip.
 798                      switch (obj.type) {
 799                          case 'line':
 800                              showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
 801                              break;
 802  
 803                          case 'horizontalLine':
 804                          case 'dashedHorizontalLine':
 805                              showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
 806                              break;
 807  
 808                          case 'verticalLine':
 809                          case 'dashedVerticalLine':
 810                              showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
 811                              break;
 812                          default:
 813                              break;
 814                      }
 815  
 816                      co.highlightObjectIndex = i;
 817                      haveHighlight = true;
 818                      break;
 819                  }
 820  
 821                  // near line, already highlighting this line, update
 822                  else if (n) {
 823                      switch (obj.type) {
 824                          case 'line':
 825                              showTooltip(plot, obj, [gridpos.x, gridpos.y], datapos);
 826                              break;
 827  
 828                          case 'horizontalLine':
 829                          case 'dashedHorizontalLine':
 830                              showTooltip(plot, obj, [gridpos.x, obj.gridStart[1]], [datapos[0], obj.options.y]);
 831                              break;
 832  
 833                          case 'verticalLine':
 834                          case 'dashedVerticalLine':
 835                              showTooltip(plot, obj, [obj.gridStart[0], gridpos.y], [obj.options.x, datapos[1]]);
 836                              break;
 837                          default:
 838                              break;
 839                      }
 840  
 841                      haveHighlight = true;
 842                      break;
 843                  }
 844              }
 845          }
 846  
 847          // check if we are highlighting and not near a line, turn it off.
 848          if (!haveHighlight && co.highlightObjectIndex !== null) {
 849              elem = co._tooltipElem;
 850              obj = co.getObject(co.highlightObjectIndex);
 851              if (obj.fadeTooltip) {
 852                  elem.fadeOut(obj.tooltipFadeSpeed);
 853              }
 854              else {
 855                  elem.hide();
 856              }
 857              co.highlightObjectIndex = null;
 858          }
 859      }
 860      
 861      $.jqplot.postInitHooks.push($.jqplot.CanvasOverlay.postPlotInit);
 862      $.jqplot.postDrawHooks.push($.jqplot.CanvasOverlay.postPlotDraw);
 863      $.jqplot.eventListenerHooks.push(['jqplotMouseMove', handleMove]);
 864  
 865  })(jQuery);


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