[ Index ] |
PHP Cross Reference of vtigercrm-6.1.0 |
[Summary view] [Print] [Text view]
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.BarRenderer 34 // A plugin renderer for jqPlot to draw a bar plot. 35 // Draws series as a line. 36 37 $.jqplot.BarRenderer = function(){ 38 $.jqplot.LineRenderer.call(this); 39 }; 40 41 $.jqplot.BarRenderer.prototype = new $.jqplot.LineRenderer(); 42 $.jqplot.BarRenderer.prototype.constructor = $.jqplot.BarRenderer; 43 44 // called with scope of series. 45 $.jqplot.BarRenderer.prototype.init = function(options, plot) { 46 // Group: Properties 47 // 48 // prop: barPadding 49 // Number of pixels between adjacent bars at the same axis value. 50 this.barPadding = 8; 51 // prop: barMargin 52 // Number of pixels between groups of bars at adjacent axis values. 53 this.barMargin = 10; 54 // prop: barDirection 55 // 'vertical' = up and down bars, 'horizontal' = side to side bars 56 this.barDirection = 'vertical'; 57 // prop: barWidth 58 // Width of the bar in pixels (auto by devaul). null = calculated automatically. 59 this.barWidth = null; 60 // prop: shadowOffset 61 // offset of the shadow from the slice and offset of 62 // each succesive stroke of the shadow from the last. 63 this.shadowOffset = 2; 64 // prop: shadowDepth 65 // number of strokes to apply to the shadow, 66 // each stroke offset shadowOffset from the last. 67 this.shadowDepth = 5; 68 // prop: shadowAlpha 69 // transparency of the shadow (0 = transparent, 1 = opaque) 70 this.shadowAlpha = 0.08; 71 // prop: waterfall 72 // true to enable waterfall plot. 73 this.waterfall = false; 74 // prop: groups 75 // group bars into this many groups 76 this.groups = 1; 77 // prop: varyBarColor 78 // true to color each bar of a series separately rather than 79 // have every bar of a given series the same color. 80 // If used for non-stacked multiple series bar plots, user should 81 // specify a separate 'seriesColors' array for each series. 82 // Otherwise, each series will set their bars to the same color array. 83 // This option has no Effect for stacked bar charts and is disabled. 84 this.varyBarColor = false; 85 // prop: highlightMouseOver 86 // True to highlight slice when moused over. 87 // This must be false to enable highlightMouseDown to highlight when clicking on a slice. 88 this.highlightMouseOver = true; 89 // prop: highlightMouseDown 90 // True to highlight when a mouse button is pressed over a slice. 91 // This will be disabled if highlightMouseOver is true. 92 this.highlightMouseDown = false; 93 // prop: highlightColors 94 // an array of colors to use when highlighting a bar. 95 this.highlightColors = []; 96 // prop: transposedData 97 // NOT IMPLEMENTED YET. True if this is a horizontal bar plot and 98 // x and y values are "transposed". Tranposed, or "swapped", data is 99 // required prior to rev. 894 builds of jqPlot with horizontal bars. 100 // Allows backward compatability of bar renderer horizontal bars with 101 // old style data sets. 102 this.transposedData = true; 103 this.renderer.animation = { 104 show: false, 105 direction: 'down', 106 speed: 3000, 107 _supported: true 108 }; 109 this._type = 'bar'; 110 111 // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver 112 if (options.highlightMouseDown && options.highlightMouseOver == null) { 113 options.highlightMouseOver = false; 114 } 115 116 ////// 117 // This is probably wrong here. 118 // After going back and forth on wether renderer should be the thing 119 // or extend the thing, it seems that it it best if it is a property 120 // on the thing. This should be something that is commonized 121 // among series renderers in the future. 122 ////// 123 $.extend(true, this, options); 124 125 // really should probably do this 126 $.extend(true, this.renderer, options); 127 // fill is still needed to properly draw the legend. 128 // bars have to be filled. 129 this.fill = true; 130 131 // if horizontal bar and animating, reset the default direction 132 if (this.barDirection === 'horizontal' && this.rendererOptions.animation && this.rendererOptions.animation.direction == null) { 133 this.renderer.animation.direction = 'left'; 134 } 135 136 if (this.waterfall) { 137 this.fillToZero = false; 138 this.disableStack = true; 139 } 140 141 if (this.barDirection == 'vertical' ) { 142 this._primaryAxis = '_xaxis'; 143 this._stackAxis = 'y'; 144 this.fillAxis = 'y'; 145 } 146 else { 147 this._primaryAxis = '_yaxis'; 148 this._stackAxis = 'x'; 149 this.fillAxis = 'x'; 150 } 151 // index of the currenty highlighted point, if any 152 this._highlightedPoint = null; 153 // total number of values for all bar series, total number of bar series, and position of this series 154 this._plotSeriesInfo = null; 155 // Array of actual data colors used for each data point. 156 this._dataColors = []; 157 this._barPoints = []; 158 159 // set the shape renderer options 160 var opts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, strokeStyle:this.color, fillStyle:this.color, closePath:this.fill}; 161 this.renderer.shapeRenderer.init(opts); 162 // set the shadow renderer options 163 var sopts = {lineJoin:'miter', lineCap:'round', fill:true, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, closePath:this.fill}; 164 this.renderer.shadowRenderer.init(sopts); 165 166 plot.postInitHooks.addOnce(postInit); 167 plot.postDrawHooks.addOnce(postPlotDraw); 168 plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); 169 plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); 170 plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); 171 plot.eventListenerHooks.addOnce('jqplotClick', handleClick); 172 plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); 173 }; 174 175 // called with scope of series 176 function barPreInit(target, data, seriesDefaults, options) { 177 if (this.rendererOptions.barDirection == 'horizontal') { 178 this._stackAxis = 'x'; 179 this._primaryAxis = '_yaxis'; 180 } 181 if (this.rendererOptions.waterfall == true) { 182 this._data = $.extend(true, [], this.data); 183 var sum = 0; 184 var pos = (!this.rendererOptions.barDirection || this.rendererOptions.barDirection === 'vertical' || this.transposedData === false) ? 1 : 0; 185 for(var i=0; i<this.data.length; i++) { 186 sum += this.data[i][pos]; 187 if (i>0) { 188 this.data[i][pos] += this.data[i-1][pos]; 189 } 190 } 191 this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; 192 this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; 193 } 194 if (this.rendererOptions.groups > 1) { 195 this.breakOnNull = true; 196 var l = this.data.length; 197 var skip = parseInt(l/this.rendererOptions.groups, 10); 198 var count = 0; 199 for (var i=skip; i<l; i+=skip) { 200 this.data.splice(i+count, 0, [null, null]); 201 count++; 202 } 203 for (i=0; i<this.data.length; i++) { 204 if (this._primaryAxis == '_xaxis') { 205 this.data[i][0] = i+1; 206 } 207 else { 208 this.data[i][1] = i+1; 209 } 210 } 211 } 212 } 213 214 $.jqplot.preSeriesInitHooks.push(barPreInit); 215 216 // needs to be called with scope of series, not renderer. 217 $.jqplot.BarRenderer.prototype.calcSeriesNumbers = function() { 218 var nvals = 0; 219 var nseries = 0; 220 var paxis = this[this._primaryAxis]; 221 var s, series, pos; 222 // loop through all series on this axis 223 for (var i=0; i < paxis._series.length; i++) { 224 series = paxis._series[i]; 225 if (series === this) { 226 pos = i; 227 } 228 // is the series rendered as a bar? 229 if (series.renderer.constructor == $.jqplot.BarRenderer) { 230 // gridData may not be computed yet, use data length insted 231 nvals += series.data.length; 232 nseries += 1; 233 } 234 } 235 // return total number of values for all bar series, total number of bar series, and position of this series 236 return [nvals, nseries, pos]; 237 }; 238 239 $.jqplot.BarRenderer.prototype.setBarWidth = function() { 240 // need to know how many data values we have on the approprate axis and figure it out. 241 var i; 242 var nvals = 0; 243 var nseries = 0; 244 var paxis = this[this._primaryAxis]; 245 var s, series, pos; 246 var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); 247 nvals = temp[0]; 248 nseries = temp[1]; 249 var nticks = paxis.numberTicks; 250 var nbins = (nticks-1)/2; 251 // so, now we have total number of axis values. 252 if (paxis.name == 'xaxis' || paxis.name == 'x2axis') { 253 if (this._stack) { 254 this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals * nseries - this.barMargin; 255 } 256 else { 257 this.barWidth = ((paxis._offsets.max - paxis._offsets.min)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; 258 // this.barWidth = (paxis._offsets.max - paxis._offsets.min) / nvals - this.barPadding - this.barMargin/nseries; 259 } 260 } 261 else { 262 if (this._stack) { 263 this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals * nseries - this.barMargin; 264 } 265 else { 266 this.barWidth = ((paxis._offsets.min - paxis._offsets.max)/nbins - this.barPadding * (nseries-1) - this.barMargin*2)/nseries; 267 // this.barWidth = (paxis._offsets.min - paxis._offsets.max) / nvals - this.barPadding - this.barMargin/nseries; 268 } 269 } 270 return [nvals, nseries]; 271 }; 272 273 function computeHighlightColors (colors) { 274 var ret = []; 275 for (var i=0; i<colors.length; i++){ 276 var rgba = $.jqplot.getColorComponents(colors[i]); 277 var newrgb = [rgba[0], rgba[1], rgba[2]]; 278 var sum = newrgb[0] + newrgb[1] + newrgb[2]; 279 for (var j=0; j<3; j++) { 280 // when darkening, lowest color component can be is 60. 281 newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); 282 newrgb[j] = parseInt(newrgb[j], 10); 283 } 284 ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); 285 } 286 return ret; 287 } 288 289 function getStart(sidx, didx, comp, plot, axis) { 290 // check if sign change 291 var seriesIndex = sidx, 292 prevSeriesIndex = sidx - 1, 293 start, 294 prevVal, 295 aidx = (axis === 'x') ? 0 : 1; 296 297 // is this not the first series? 298 if (seriesIndex > 0) { 299 prevVal = plot.series[prevSeriesIndex]._plotData[didx][aidx]; 300 301 // is there a sign change 302 if ((comp * prevVal) < 0) { 303 start = getStart(prevSeriesIndex, didx, comp, plot, axis); 304 } 305 306 // no sign change. 307 else { 308 start = plot.series[prevSeriesIndex].gridData[didx][aidx]; 309 } 310 311 } 312 313 // if first series, return value at 0 314 else { 315 316 start = (aidx === 0) ? plot.series[seriesIndex]._xaxis.series_u2p(0) : plot.series[seriesIndex]._yaxis.series_u2p(0); 317 } 318 319 return start; 320 } 321 322 323 $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options, plot) { 324 var i; 325 // Ughhh, have to make a copy of options b/c it may be modified later. 326 var opts = $.extend({}, options); 327 var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; 328 var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; 329 var fill = (opts.fill != undefined) ? opts.fill : this.fill; 330 var xaxis = this.xaxis; 331 var yaxis = this.yaxis; 332 var xp = this._xaxis.series_u2p; 333 var yp = this._yaxis.series_u2p; 334 var pointx, pointy; 335 // clear out data colors. 336 this._dataColors = []; 337 this._barPoints = []; 338 339 if (this.barWidth == null) { 340 this.renderer.setBarWidth.call(this); 341 } 342 343 var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); 344 var nvals = temp[0]; 345 var nseries = temp[1]; 346 var pos = temp[2]; 347 var points = []; 348 349 if (this._stack) { 350 this._barNudge = 0; 351 } 352 else { 353 this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); 354 } 355 if (showLine) { 356 var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); 357 var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); 358 var negativeColor = negativeColors.get(this.index); 359 if (! this.useNegativeColors) { 360 negativeColor = opts.fillStyle; 361 } 362 var positiveColor = opts.fillStyle; 363 var base; 364 var xstart; 365 var ystart; 366 367 if (this.barDirection == 'vertical') { 368 for (var i=0; i<gridData.length; i++) { 369 if (!this._stack && this.data[i][1] == null) { 370 continue; 371 } 372 points = []; 373 base = gridData[i][0] + this._barNudge; 374 375 // stacked 376 if (this._stack && this._prevGridData.length) { 377 ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y'); 378 } 379 380 // not stacked and first series in stack 381 else { 382 if (this.fillToZero) { 383 ystart = this._yaxis.series_u2p(0); 384 } 385 else if (this.waterfall && i > 0 && i < this.gridData.length-1) { 386 ystart = this.gridData[i-1][1]; 387 } 388 else if (this.waterfall && i == 0 && i < this.gridData.length-1) { 389 if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { 390 ystart = this._yaxis.series_u2p(0); 391 } 392 else if (this._yaxis.min > 0) { 393 ystart = ctx.canvas.height; 394 } 395 else { 396 ystart = 0; 397 } 398 } 399 else if (this.waterfall && i == this.gridData.length - 1) { 400 if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { 401 ystart = this._yaxis.series_u2p(0); 402 } 403 else if (this._yaxis.min > 0) { 404 ystart = ctx.canvas.height; 405 } 406 else { 407 ystart = 0; 408 } 409 } 410 else { 411 ystart = ctx.canvas.height; 412 } 413 } 414 if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { 415 if (this.varyBarColor && !this._stack) { 416 if (this.useNegativeColors) { 417 opts.fillStyle = negativeColors.next(); 418 } 419 else { 420 opts.fillStyle = positiveColors.next(); 421 } 422 } 423 else { 424 opts.fillStyle = negativeColor; 425 } 426 } 427 else { 428 if (this.varyBarColor && !this._stack) { 429 opts.fillStyle = positiveColors.next(); 430 } 431 else { 432 opts.fillStyle = positiveColor; 433 } 434 } 435 436 if (!this.fillToZero || this._plotData[i][1] >= 0) { 437 points.push([base-this.barWidth/2, ystart]); 438 points.push([base-this.barWidth/2, gridData[i][1]]); 439 points.push([base+this.barWidth/2, gridData[i][1]]); 440 points.push([base+this.barWidth/2, ystart]); 441 } 442 // for negative bars make sure points are always ordered clockwise 443 else { 444 points.push([base-this.barWidth/2, gridData[i][1]]); 445 points.push([base-this.barWidth/2, ystart]); 446 points.push([base+this.barWidth/2, ystart]); 447 points.push([base+this.barWidth/2, gridData[i][1]]); 448 } 449 this._barPoints.push(points); 450 // now draw the shadows if not stacked. 451 // for stacked plots, they are predrawn by drawShadow 452 if (shadow && !this._stack) { 453 var sopts = $.extend(true, {}, opts); 454 // need to get rid of fillStyle on shadow. 455 delete sopts.fillStyle; 456 this.renderer.shadowRenderer.draw(ctx, points, sopts); 457 } 458 var clr = opts.fillStyle || this.color; 459 this._dataColors.push(clr); 460 this.renderer.shapeRenderer.draw(ctx, points, opts); 461 } 462 } 463 464 else if (this.barDirection == 'horizontal'){ 465 for (var i=0; i<gridData.length; i++) { 466 if (this.data[i][0] == null) { 467 continue; 468 } 469 points = []; 470 base = gridData[i][1] - this._barNudge; 471 xstart; 472 473 if (this._stack && this._prevGridData.length) { 474 xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x'); 475 } 476 // not stacked and first series in stack 477 else { 478 if (this.fillToZero) { 479 xstart = this._xaxis.series_u2p(0); 480 } 481 else if (this.waterfall && i > 0 && i < this.gridData.length-1) { 482 xstart = this.gridData[i-1][1]; 483 } 484 else if (this.waterfall && i == 0 && i < this.gridData.length-1) { 485 if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { 486 xstart = this._xaxis.series_u2p(0); 487 } 488 else if (this._xaxis.min > 0) { 489 xstart = 0; 490 } 491 else { 492 xstart = ctx.canvas.width; 493 } 494 } 495 else if (this.waterfall && i == this.gridData.length - 1) { 496 if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { 497 xstart = this._xaxis.series_u2p(0); 498 } 499 else if (this._xaxis.min > 0) { 500 xstart = 0; 501 } 502 else { 503 xstart = ctx.canvas.width; 504 } 505 } 506 else { 507 xstart = 0; 508 } 509 } 510 if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { 511 if (this.varyBarColor && !this._stack) { 512 if (this.useNegativeColors) { 513 opts.fillStyle = negativeColors.next(); 514 } 515 else { 516 opts.fillStyle = positiveColors.next(); 517 } 518 } 519 } 520 else { 521 if (this.varyBarColor && !this._stack) { 522 opts.fillStyle = positiveColors.next(); 523 } 524 else { 525 opts.fillStyle = positiveColor; 526 } 527 } 528 529 530 if (!this.fillToZero || this._plotData[i][0] >= 0) { 531 points.push([xstart, base + this.barWidth / 2]); 532 points.push([xstart, base - this.barWidth / 2]); 533 points.push([gridData[i][0], base - this.barWidth / 2]); 534 points.push([gridData[i][0], base + this.barWidth / 2]); 535 } 536 else { 537 points.push([gridData[i][0], base + this.barWidth / 2]); 538 points.push([gridData[i][0], base - this.barWidth / 2]); 539 points.push([xstart, base - this.barWidth / 2]); 540 points.push([xstart, base + this.barWidth / 2]); 541 } 542 543 this._barPoints.push(points); 544 // now draw the shadows if not stacked. 545 // for stacked plots, they are predrawn by drawShadow 546 if (shadow && !this._stack) { 547 var sopts = $.extend(true, {}, opts); 548 delete sopts.fillStyle; 549 this.renderer.shadowRenderer.draw(ctx, points, sopts); 550 } 551 var clr = opts.fillStyle || this.color; 552 this._dataColors.push(clr); 553 this.renderer.shapeRenderer.draw(ctx, points, opts); 554 } 555 } 556 } 557 558 if (this.highlightColors.length == 0) { 559 this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors); 560 } 561 562 else if (typeof(this.highlightColors) == 'string') { 563 var temp = this.highlightColors; 564 this.highlightColors = []; 565 for (var i=0; i<this._dataColors.length; i++) { 566 this.highlightColors.push(temp); 567 } 568 } 569 570 }; 571 572 573 // for stacked plots, shadows will be pre drawn by drawShadow. 574 $.jqplot.BarRenderer.prototype.drawShadow = function(ctx, gridData, options, plot) { 575 var i; 576 var opts = (options != undefined) ? options : {}; 577 var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; 578 var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; 579 var fill = (opts.fill != undefined) ? opts.fill : this.fill; 580 var xaxis = this.xaxis; 581 var yaxis = this.yaxis; 582 var xp = this._xaxis.series_u2p; 583 var yp = this._yaxis.series_u2p; 584 var pointx, points, pointy, nvals, nseries, pos; 585 586 if (this._stack && this.shadow) { 587 if (this.barWidth == null) { 588 this.renderer.setBarWidth.call(this); 589 } 590 591 var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); 592 nvals = temp[0]; 593 nseries = temp[1]; 594 pos = temp[2]; 595 596 if (this._stack) { 597 this._barNudge = 0; 598 } 599 else { 600 this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); 601 } 602 if (showLine) { 603 604 if (this.barDirection == 'vertical') { 605 for (var i=0; i<gridData.length; i++) { 606 if (this.data[i][1] == null) { 607 continue; 608 } 609 points = []; 610 var base = gridData[i][0] + this._barNudge; 611 var ystart; 612 613 if (this._stack && this._prevGridData.length) { 614 ystart = getStart(this.index, i, this._plotData[i][1], plot, 'y'); 615 } 616 else { 617 if (this.fillToZero) { 618 ystart = this._yaxis.series_u2p(0); 619 } 620 else { 621 ystart = ctx.canvas.height; 622 } 623 } 624 625 points.push([base-this.barWidth/2, ystart]); 626 points.push([base-this.barWidth/2, gridData[i][1]]); 627 points.push([base+this.barWidth/2, gridData[i][1]]); 628 points.push([base+this.barWidth/2, ystart]); 629 this.renderer.shadowRenderer.draw(ctx, points, opts); 630 } 631 } 632 633 else if (this.barDirection == 'horizontal'){ 634 for (var i=0; i<gridData.length; i++) { 635 if (this.data[i][0] == null) { 636 continue; 637 } 638 points = []; 639 var base = gridData[i][1] - this._barNudge; 640 var xstart; 641 642 if (this._stack && this._prevGridData.length) { 643 xstart = getStart(this.index, i, this._plotData[i][0], plot, 'x'); 644 } 645 else { 646 if (this.fillToZero) { 647 xstart = this._xaxis.series_u2p(0); 648 } 649 else { 650 xstart = 0; 651 } 652 } 653 654 points.push([xstart, base+this.barWidth/2]); 655 points.push([gridData[i][0], base+this.barWidth/2]); 656 points.push([gridData[i][0], base-this.barWidth/2]); 657 points.push([xstart, base-this.barWidth/2]); 658 this.renderer.shadowRenderer.draw(ctx, points, opts); 659 } 660 } 661 } 662 663 } 664 }; 665 666 function postInit(target, data, options) { 667 for (var i=0; i<this.series.length; i++) { 668 if (this.series[i].renderer.constructor == $.jqplot.BarRenderer) { 669 // don't allow mouseover and mousedown at same time. 670 if (this.series[i].highlightMouseOver) { 671 this.series[i].highlightMouseDown = false; 672 } 673 } 674 } 675 } 676 677 // called within context of plot 678 // create a canvas which we can draw on. 679 // insert it before the eventCanvas, so eventCanvas will still capture events. 680 function postPlotDraw() { 681 // Memory Leaks patch 682 if (this.plugins.barRenderer && this.plugins.barRenderer.highlightCanvas) { 683 684 this.plugins.barRenderer.highlightCanvas.resetCanvas(); 685 this.plugins.barRenderer.highlightCanvas = null; 686 } 687 688 this.plugins.barRenderer = {highlightedSeriesIndex:null}; 689 this.plugins.barRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); 690 691 this.eventCanvas._elem.before(this.plugins.barRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-barRenderer-highlight-canvas', this._plotDimensions, this)); 692 this.plugins.barRenderer.highlightCanvas.setContext(); 693 this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); 694 } 695 696 function highlight (plot, sidx, pidx, points) { 697 var s = plot.series[sidx]; 698 var canvas = plot.plugins.barRenderer.highlightCanvas; 699 canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); 700 s._highlightedPoint = pidx; 701 plot.plugins.barRenderer.highlightedSeriesIndex = sidx; 702 var opts = {fillStyle: s.highlightColors[pidx]}; 703 s.renderer.shapeRenderer.draw(canvas._ctx, points, opts); 704 canvas = null; 705 } 706 707 function unhighlight (plot) { 708 var canvas = plot.plugins.barRenderer.highlightCanvas; 709 canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); 710 for (var i=0; i<plot.series.length; i++) { 711 plot.series[i]._highlightedPoint = null; 712 } 713 plot.plugins.barRenderer.highlightedSeriesIndex = null; 714 plot.target.trigger('jqplotDataUnhighlight'); 715 canvas = null; 716 } 717 718 719 function handleMove(ev, gridpos, datapos, neighbor, plot) { 720 if (neighbor) { 721 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 722 var evt1 = jQuery.Event('jqplotDataMouseOver'); 723 evt1.pageX = ev.pageX; 724 evt1.pageY = ev.pageY; 725 plot.target.trigger(evt1, ins); 726 if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { 727 var evt = jQuery.Event('jqplotDataHighlight'); 728 evt.which = ev.which; 729 evt.pageX = ev.pageX; 730 evt.pageY = ev.pageY; 731 plot.target.trigger(evt, ins); 732 highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); 733 } 734 } 735 else if (neighbor == null) { 736 unhighlight (plot); 737 } 738 } 739 740 function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { 741 if (neighbor) { 742 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 743 if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.barRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { 744 var evt = jQuery.Event('jqplotDataHighlight'); 745 evt.which = ev.which; 746 evt.pageX = ev.pageX; 747 evt.pageY = ev.pageY; 748 plot.target.trigger(evt, ins); 749 highlight (plot, neighbor.seriesIndex, neighbor.pointIndex, neighbor.points); 750 } 751 } 752 else if (neighbor == null) { 753 unhighlight (plot); 754 } 755 } 756 757 function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { 758 var idx = plot.plugins.barRenderer.highlightedSeriesIndex; 759 if (idx != null && plot.series[idx].highlightMouseDown) { 760 unhighlight(plot); 761 } 762 } 763 764 function handleClick(ev, gridpos, datapos, neighbor, plot) { 765 if (neighbor) { 766 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 767 var evt = jQuery.Event('jqplotDataClick'); 768 evt.which = ev.which; 769 evt.pageX = ev.pageX; 770 evt.pageY = ev.pageY; 771 plot.target.trigger(evt, ins); 772 } 773 } 774 775 function handleRightClick(ev, gridpos, datapos, neighbor, plot) { 776 if (neighbor) { 777 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 778 var idx = plot.plugins.barRenderer.highlightedSeriesIndex; 779 if (idx != null && plot.series[idx].highlightMouseDown) { 780 unhighlight(plot); 781 } 782 var evt = jQuery.Event('jqplotDataRightClick'); 783 evt.which = ev.which; 784 evt.pageX = ev.pageX; 785 evt.pageY = ev.pageY; 786 plot.target.trigger(evt, ins); 787 } 788 } 789 790 791 })(jQuery);
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:08:37 2014 | Cross-referenced by PHPXref 0.7.1 |