[ 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.PieRenderer 34 * Plugin renderer to draw a pie chart. 35 * x values, if present, will be used as slice labels. 36 * y values give slice size. 37 * 38 * To use this renderer, you need to include the 39 * pie renderer plugin, for example: 40 * 41 * > <script type="text/javascript" src="plugins/jqplot.pieRenderer.js"></script> 42 * 43 * Properties described here are passed into the $.jqplot function 44 * as options on the series renderer. For example: 45 * 46 * > plot2 = $.jqplot('chart2', [s1, s2], { 47 * > seriesDefaults: { 48 * > renderer:$.jqplot.PieRenderer, 49 * > rendererOptions:{ 50 * > sliceMargin: 2, 51 * > startAngle: -90 52 * > } 53 * > } 54 * > }); 55 * 56 * A pie plot will trigger events on the plot target 57 * according to user interaction. All events return the event object, 58 * the series index, the point (slice) index, and the point data for 59 * the appropriate slice. 60 * 61 * 'jqplotDataMouseOver' - triggered when user mouseing over a slice. 62 * 'jqplotDataHighlight' - triggered the first time user mouses over a slice, 63 * if highlighting is enabled. 64 * 'jqplotDataUnhighlight' - triggered when a user moves the mouse out of 65 * a highlighted slice. 66 * 'jqplotDataClick' - triggered when the user clicks on a slice. 67 * 'jqplotDataRightClick' - tiggered when the user right clicks on a slice if 68 * the "captureRightClick" option is set to true on the plot. 69 */ 70 $.jqplot.PieRenderer = function(){ 71 $.jqplot.LineRenderer.call(this); 72 }; 73 74 $.jqplot.PieRenderer.prototype = new $.jqplot.LineRenderer(); 75 $.jqplot.PieRenderer.prototype.constructor = $.jqplot.PieRenderer; 76 77 // called with scope of a series 78 $.jqplot.PieRenderer.prototype.init = function(options, plot) { 79 // Group: Properties 80 // 81 // prop: diameter 82 // Outer diameter of the pie, auto computed by default 83 this.diameter = null; 84 // prop: padding 85 // padding between the pie and plot edges, legend, etc. 86 this.padding = 20; 87 // prop: sliceMargin 88 // angular spacing between pie slices in degrees. 89 this.sliceMargin = 0; 90 // prop: fill 91 // true or false, wether to fil the slices. 92 this.fill = true; 93 // prop: shadowOffset 94 // offset of the shadow from the slice and offset of 95 // each succesive stroke of the shadow from the last. 96 this.shadowOffset = 2; 97 // prop: shadowAlpha 98 // transparency of the shadow (0 = transparent, 1 = opaque) 99 this.shadowAlpha = 0.07; 100 // prop: shadowDepth 101 // number of strokes to apply to the shadow, 102 // each stroke offset shadowOffset from the last. 103 this.shadowDepth = 5; 104 // prop: highlightMouseOver 105 // True to highlight slice when moused over. 106 // This must be false to enable highlightMouseDown to highlight when clicking on a slice. 107 this.highlightMouseOver = true; 108 // prop: highlightMouseDown 109 // True to highlight when a mouse button is pressed over a slice. 110 // This will be disabled if highlightMouseOver is true. 111 this.highlightMouseDown = false; 112 // prop: highlightColors 113 // an array of colors to use when highlighting a slice. 114 this.highlightColors = []; 115 // prop: dataLabels 116 // Either 'label', 'value', 'percent' or an array of labels to place on the pie slices. 117 // Defaults to percentage of each pie slice. 118 this.dataLabels = 'percent'; 119 // prop: showDataLabels 120 // true to show data labels on slices. 121 this.showDataLabels = false; 122 // prop: dataLabelFormatString 123 // Format string for data labels. If none, '%s' is used for "label" and for arrays, '%d' for value and '%d%%' for percentage. 124 this.dataLabelFormatString = null; 125 // prop: dataLabelThreshold 126 // Threshhold in percentage (0-100) of pie area, below which no label will be displayed. 127 // This applies to all label types, not just to percentage labels. 128 this.dataLabelThreshold = 3; 129 // prop: dataLabelPositionFactor 130 // A Multiplier (0-1) of the pie radius which controls position of label on slice. 131 // Increasing will slide label toward edge of pie, decreasing will slide label toward center of pie. 132 this.dataLabelPositionFactor = 0.52; 133 // prop: dataLabelNudge 134 // Number of pixels to slide the label away from (+) or toward (-) the center of the pie. 135 this.dataLabelNudge = 2; 136 // prop: dataLabelCenterOn 137 // True to center the data label at its position. 138 // False to set the inside facing edge of the label at its position. 139 this.dataLabelCenterOn = true; 140 // prop: startAngle 141 // Angle to start drawing pie in degrees. 142 // According to orientation of canvas coordinate system: 143 // 0 = on the positive x axis 144 // -90 = on the positive y axis. 145 // 90 = on the negaive y axis. 146 // 180 or - 180 = on the negative x axis. 147 this.startAngle = 0; 148 this.tickRenderer = $.jqplot.PieTickRenderer; 149 // Used as check for conditions where pie shouldn't be drawn. 150 this._drawData = true; 151 this._type = 'pie'; 152 153 // if user has passed in highlightMouseDown option and not set highlightMouseOver, disable highlightMouseOver 154 if (options.highlightMouseDown && options.highlightMouseOver == null) { 155 options.highlightMouseOver = false; 156 } 157 158 $.extend(true, this, options); 159 160 if (this.sliceMargin < 0) { 161 this.sliceMargin = 0; 162 } 163 164 this._diameter = null; 165 this._radius = null; 166 // array of [start,end] angles arrays, one for each slice. In radians. 167 this._sliceAngles = []; 168 // index of the currenty highlighted point, if any 169 this._highlightedPoint = null; 170 171 // set highlight colors if none provided 172 if (this.highlightColors.length == 0) { 173 for (var i=0; i<this.seriesColors.length; i++){ 174 var rgba = $.jqplot.getColorComponents(this.seriesColors[i]); 175 var newrgb = [rgba[0], rgba[1], rgba[2]]; 176 var sum = newrgb[0] + newrgb[1] + newrgb[2]; 177 for (var j=0; j<3; j++) { 178 // when darkening, lowest color component can be is 60. 179 newrgb[j] = (sum > 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); 180 newrgb[j] = parseInt(newrgb[j], 10); 181 } 182 this.highlightColors.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); 183 } 184 } 185 186 this.highlightColorGenerator = new $.jqplot.ColorGenerator(this.highlightColors); 187 188 plot.postParseOptionsHooks.addOnce(postParseOptions); 189 plot.postInitHooks.addOnce(postInit); 190 plot.eventListenerHooks.addOnce('jqplotMouseMove', handleMove); 191 plot.eventListenerHooks.addOnce('jqplotMouseDown', handleMouseDown); 192 plot.eventListenerHooks.addOnce('jqplotMouseUp', handleMouseUp); 193 plot.eventListenerHooks.addOnce('jqplotClick', handleClick); 194 plot.eventListenerHooks.addOnce('jqplotRightClick', handleRightClick); 195 plot.postDrawHooks.addOnce(postPlotDraw); 196 }; 197 198 $.jqplot.PieRenderer.prototype.setGridData = function(plot) { 199 // set gridData property. This will hold angle in radians of each data point. 200 var stack = []; 201 var td = []; 202 var sa = this.startAngle/180*Math.PI; 203 var tot = 0; 204 // don't know if we have any valid data yet, so set plot to not draw. 205 this._drawData = false; 206 for (var i=0; i<this.data.length; i++){ 207 if (this.data[i][1] != 0) { 208 // we have data, O.K. to draw. 209 this._drawData = true; 210 } 211 stack.push(this.data[i][1]); 212 td.push([this.data[i][0]]); 213 if (i>0) { 214 stack[i] += stack[i-1]; 215 } 216 tot += this.data[i][1]; 217 } 218 var fact = Math.PI*2/stack[stack.length - 1]; 219 220 for (var i=0; i<stack.length; i++) { 221 td[i][1] = stack[i] * fact; 222 td[i][2] = this.data[i][1]/tot; 223 } 224 this.gridData = td; 225 }; 226 227 $.jqplot.PieRenderer.prototype.makeGridData = function(data, plot) { 228 var stack = []; 229 var td = []; 230 var tot = 0; 231 var sa = this.startAngle/180*Math.PI; 232 // don't know if we have any valid data yet, so set plot to not draw. 233 this._drawData = false; 234 for (var i=0; i<data.length; i++){ 235 if (this.data[i][1] != 0) { 236 // we have data, O.K. to draw. 237 this._drawData = true; 238 } 239 stack.push(data[i][1]); 240 td.push([data[i][0]]); 241 if (i>0) { 242 stack[i] += stack[i-1]; 243 } 244 tot += data[i][1]; 245 } 246 var fact = Math.PI*2/stack[stack.length - 1]; 247 248 for (var i=0; i<stack.length; i++) { 249 td[i][1] = stack[i] * fact; 250 td[i][2] = data[i][1]/tot; 251 } 252 return td; 253 }; 254 255 function calcRadiusAdjustment(ang) { 256 return Math.sin((ang - (ang-Math.PI) / 8 / Math.PI )/2.0); 257 } 258 259 function calcRPrime(ang1, ang2, sliceMargin, fill, lineWidth) { 260 var rprime = 0; 261 var ang = ang2 - ang1; 262 var absang = Math.abs(ang); 263 var sm = sliceMargin; 264 if (fill == false) { 265 sm += lineWidth; 266 } 267 268 if (sm > 0 && absang > 0.01 && absang < 6.282) { 269 rprime = parseFloat(sm) / 2.0 / calcRadiusAdjustment(ang); 270 } 271 272 return rprime; 273 } 274 275 $.jqplot.PieRenderer.prototype.drawSlice = function (ctx, ang1, ang2, color, isShadow) { 276 if (this._drawData) { 277 var r = this._radius; 278 var fill = this.fill; 279 var lineWidth = this.lineWidth; 280 var sm = this.sliceMargin; 281 if (this.fill == false) { 282 sm += this.lineWidth; 283 } 284 ctx.save(); 285 ctx.translate(this._center[0], this._center[1]); 286 287 var rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth); 288 289 var transx = rprime * Math.cos((ang1 + ang2) / 2.0); 290 var transy = rprime * Math.sin((ang1 + ang2) / 2.0); 291 292 if ((ang2 - ang1) <= Math.PI) { 293 r -= rprime; 294 } 295 else { 296 r += rprime; 297 } 298 299 ctx.translate(transx, transy); 300 301 if (isShadow) { 302 for (var i=0, l=this.shadowDepth; i<l; i++) { 303 ctx.save(); 304 ctx.translate(this.shadowOffset*Math.cos(this.shadowAngle/180*Math.PI), this.shadowOffset*Math.sin(this.shadowAngle/180*Math.PI)); 305 doDraw(r); 306 } 307 for (var i=0, l=this.shadowDepth; i<l; i++) { 308 ctx.restore(); 309 } 310 } 311 312 else { 313 doDraw(r); 314 } 315 ctx.restore(); 316 } 317 318 function doDraw (rad) { 319 // Fix for IE and Chrome that can't seem to draw circles correctly. 320 // ang2 should always be <= 2 pi since that is the way the data is converted. 321 // 2Pi = 6.2831853, Pi = 3.1415927 322 if (ang2 > 6.282 + this.startAngle) { 323 ang2 = 6.282 + this.startAngle; 324 if (ang1 > ang2) { 325 ang1 = 6.281 + this.startAngle; 326 } 327 } 328 // Fix for IE, where it can't seem to handle 0 degree angles. Also avoids 329 // ugly line on unfilled pies. 330 if (ang1 >= ang2) { 331 return; 332 } 333 334 ctx.beginPath(); 335 ctx.fillStyle = color; 336 ctx.strokeStyle = color; 337 ctx.lineWidth = lineWidth; 338 ctx.arc(0, 0, rad, ang1, ang2, false); 339 ctx.lineTo(0,0); 340 ctx.closePath(); 341 342 if (fill) { 343 ctx.fill(); 344 } 345 else { 346 ctx.stroke(); 347 } 348 } 349 }; 350 351 // called with scope of series 352 $.jqplot.PieRenderer.prototype.draw = function (ctx, gd, options, plot) { 353 var i; 354 var opts = (options != undefined) ? options : {}; 355 // offset and direction of offset due to legend placement 356 var offx = 0; 357 var offy = 0; 358 var trans = 1; 359 var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); 360 if (options.legendInfo && options.legendInfo.placement == 'insideGrid') { 361 var li = options.legendInfo; 362 switch (li.location) { 363 case 'nw': 364 offx = li.width + li.xoffset; 365 break; 366 case 'w': 367 offx = li.width + li.xoffset; 368 break; 369 case 'sw': 370 offx = li.width + li.xoffset; 371 break; 372 case 'ne': 373 offx = li.width + li.xoffset; 374 trans = -1; 375 break; 376 case 'e': 377 offx = li.width + li.xoffset; 378 trans = -1; 379 break; 380 case 'se': 381 offx = li.width + li.xoffset; 382 trans = -1; 383 break; 384 case 'n': 385 offy = li.height + li.yoffset; 386 break; 387 case 's': 388 offy = li.height + li.yoffset; 389 trans = -1; 390 break; 391 default: 392 break; 393 } 394 } 395 396 var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; 397 var fill = (opts.fill != undefined) ? opts.fill : this.fill; 398 var cw = ctx.canvas.width; 399 var ch = ctx.canvas.height; 400 var w = cw - offx - 2 * this.padding; 401 var h = ch - offy - 2 * this.padding; 402 var mindim = Math.min(w,h); 403 var d = mindim; 404 405 // Fixes issue #272. Thanks hugwijst! 406 // reset slice angles array. 407 this._sliceAngles = []; 408 409 var sm = this.sliceMargin; 410 if (this.fill == false) { 411 sm += this.lineWidth; 412 } 413 414 var rprime; 415 var maxrprime = 0; 416 417 var ang, ang1, ang2, shadowColor; 418 var sa = this.startAngle / 180 * Math.PI; 419 420 // have to pre-draw shadows, so loop throgh here and calculate some values also. 421 for (var i=0, l=gd.length; i<l; i++) { 422 ang1 = (i == 0) ? sa : gd[i-1][1] + sa; 423 ang2 = gd[i][1] + sa; 424 425 this._sliceAngles.push([ang1, ang2]); 426 427 rprime = calcRPrime(ang1, ang2, this.sliceMargin, this.fill, this.lineWidth); 428 429 if (Math.abs(ang2-ang1) > Math.PI) { 430 maxrprime = Math.max(rprime, maxrprime); 431 } 432 } 433 434 if (this.diameter != null && this.diameter > 0) { 435 this._diameter = this.diameter - 2*maxrprime; 436 } 437 else { 438 this._diameter = d - 2*maxrprime; 439 } 440 441 // Need to check for undersized pie. This can happen if 442 // plot area too small and legend is too big. 443 if (this._diameter < 6) { 444 $.jqplot.log('Diameter of pie too small, not rendering.'); 445 return; 446 } 447 448 var r = this._radius = this._diameter/2; 449 450 this._center = [(cw - trans * offx)/2 + trans * offx + maxrprime * Math.cos(sa), (ch - trans*offy)/2 + trans * offy + maxrprime * Math.sin(sa)]; 451 452 if (this.shadow) { 453 for (var i=0, l=gd.length; i<l; i++) { 454 shadowColor = 'rgba(0,0,0,'+this.shadowAlpha+')'; 455 this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], shadowColor, true); 456 } 457 } 458 459 for (var i=0; i<gd.length; i++) { 460 461 this.renderer.drawSlice.call (this, ctx, this._sliceAngles[i][0], this._sliceAngles[i][1], colorGenerator.next(), false); 462 463 if (this.showDataLabels && gd[i][2]*100 >= this.dataLabelThreshold) { 464 var fstr, avgang = (this._sliceAngles[i][0] + this._sliceAngles[i][1])/2, label; 465 466 if (this.dataLabels == 'label') { 467 fstr = this.dataLabelFormatString || '%s'; 468 label = $.jqplot.sprintf(fstr, gd[i][0]); 469 } 470 else if (this.dataLabels == 'value') { 471 fstr = this.dataLabelFormatString || '%d'; 472 label = $.jqplot.sprintf(fstr, this.data[i][1]); 473 } 474 else if (this.dataLabels == 'percent') { 475 fstr = this.dataLabelFormatString || '%d%%'; 476 label = $.jqplot.sprintf(fstr, gd[i][2]*100); 477 } 478 else if (this.dataLabels.constructor == Array) { 479 fstr = this.dataLabelFormatString || '%s'; 480 label = $.jqplot.sprintf(fstr, this.dataLabels[i]); 481 } 482 483 var fact = (this._radius ) * this.dataLabelPositionFactor + this.sliceMargin + this.dataLabelNudge; 484 485 var x = this._center[0] + Math.cos(avgang) * fact + this.canvas._offsets.left; 486 var y = this._center[1] + Math.sin(avgang) * fact + this.canvas._offsets.top; 487 488 var labelelem = $('<div class="jqplot-pie-series jqplot-data-label" style="position:absolute;">' + label + '</div>').insertBefore(plot.eventCanvas._elem); 489 if (this.dataLabelCenterOn) { 490 x -= labelelem.width()/2; 491 y -= labelelem.height()/2; 492 } 493 else { 494 x -= labelelem.width() * Math.sin(avgang/2); 495 y -= labelelem.height()/2; 496 } 497 x = Math.round(x); 498 y = Math.round(y); 499 labelelem.css({left: x, top: y}); 500 } 501 } 502 }; 503 504 $.jqplot.PieAxisRenderer = function() { 505 $.jqplot.LinearAxisRenderer.call(this); 506 }; 507 508 $.jqplot.PieAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); 509 $.jqplot.PieAxisRenderer.prototype.constructor = $.jqplot.PieAxisRenderer; 510 511 512 // There are no traditional axes on a pie chart. We just need to provide 513 // dummy objects with properties so the plot will render. 514 // called with scope of axis object. 515 $.jqplot.PieAxisRenderer.prototype.init = function(options){ 516 // 517 this.tickRenderer = $.jqplot.PieTickRenderer; 518 $.extend(true, this, options); 519 // I don't think I'm going to need _dataBounds here. 520 // have to go Axis scaling in a way to fit chart onto plot area 521 // and provide u2p and p2u functionality for mouse cursor, etc. 522 // for convienence set _dataBounds to 0 and 100 and 523 // set min/max to 0 and 100. 524 this._dataBounds = {min:0, max:100}; 525 this.min = 0; 526 this.max = 100; 527 this.showTicks = false; 528 this.ticks = []; 529 this.showMark = false; 530 this.show = false; 531 }; 532 533 534 535 536 $.jqplot.PieLegendRenderer = function(){ 537 $.jqplot.TableLegendRenderer.call(this); 538 }; 539 540 $.jqplot.PieLegendRenderer.prototype = new $.jqplot.TableLegendRenderer(); 541 $.jqplot.PieLegendRenderer.prototype.constructor = $.jqplot.PieLegendRenderer; 542 543 /** 544 * Class: $.jqplot.PieLegendRenderer 545 * Legend Renderer specific to pie plots. Set by default 546 * when user creates a pie plot. 547 */ 548 $.jqplot.PieLegendRenderer.prototype.init = function(options) { 549 // Group: Properties 550 // 551 // prop: numberRows 552 // Maximum number of rows in the legend. 0 or null for unlimited. 553 this.numberRows = null; 554 // prop: numberColumns 555 // Maximum number of columns in the legend. 0 or null for unlimited. 556 this.numberColumns = null; 557 $.extend(true, this, options); 558 }; 559 560 // called with context of legend 561 $.jqplot.PieLegendRenderer.prototype.draw = function() { 562 var legend = this; 563 if (this.show) { 564 var series = this._series; 565 566 567 this._elem = $(document.createElement('table')); 568 this._elem.addClass('jqplot-table-legend'); 569 570 var ss = {position:'absolute'}; 571 if (this.background) { 572 ss['background'] = this.background; 573 } 574 if (this.border) { 575 ss['border'] = this.border; 576 } 577 if (this.fontSize) { 578 ss['fontSize'] = this.fontSize; 579 } 580 if (this.fontFamily) { 581 ss['fontFamily'] = this.fontFamily; 582 } 583 if (this.textColor) { 584 ss['textColor'] = this.textColor; 585 } 586 if (this.marginTop != null) { 587 ss['marginTop'] = this.marginTop; 588 } 589 if (this.marginBottom != null) { 590 ss['marginBottom'] = this.marginBottom; 591 } 592 if (this.marginLeft != null) { 593 ss['marginLeft'] = this.marginLeft; 594 } 595 if (this.marginRight != null) { 596 ss['marginRight'] = this.marginRight; 597 } 598 599 this._elem.css(ss); 600 601 // Pie charts legends don't go by number of series, but by number of data points 602 // in the series. Refactor things here for that. 603 604 var pad = false, 605 reverse = false, 606 nr, 607 nc; 608 var s = series[0]; 609 var colorGenerator = new $.jqplot.ColorGenerator(s.seriesColors); 610 611 if (s.show) { 612 var pd = s.data; 613 if (this.numberRows) { 614 nr = this.numberRows; 615 if (!this.numberColumns){ 616 nc = Math.ceil(pd.length/nr); 617 } 618 else{ 619 nc = this.numberColumns; 620 } 621 } 622 else if (this.numberColumns) { 623 nc = this.numberColumns; 624 nr = Math.ceil(pd.length/this.numberColumns); 625 } 626 else { 627 nr = pd.length; 628 nc = 1; 629 } 630 631 var i, j; 632 var tr, td1, td2; 633 var lt, rs, color; 634 var idx = 0; 635 var div0, div1; 636 637 for (i=0; i<nr; i++) { 638 tr = $(document.createElement('tr')); 639 tr.addClass('jqplot-table-legend'); 640 641 if (reverse){ 642 tr.prependTo(this._elem); 643 } 644 645 else{ 646 tr.appendTo(this._elem); 647 } 648 649 for (j=0; j<nc; j++) { 650 if (idx < pd.length){ 651 lt = this.labels[idx] || pd[idx][0].toString(); 652 color = colorGenerator.next(); 653 if (!reverse){ 654 if (i>0){ 655 pad = true; 656 } 657 else{ 658 pad = false; 659 } 660 } 661 else{ 662 if (i == nr -1){ 663 pad = false; 664 } 665 else{ 666 pad = true; 667 } 668 } 669 rs = (pad) ? this.rowSpacing : '0'; 670 671 672 673 td1 = $(document.createElement('td')); 674 td1.addClass('jqplot-table-legend jqplot-table-legend-swatch'); 675 td1.css({textAlign: 'center', paddingTop: rs}); 676 677 div0 = $(document.createElement('div')); 678 div0.addClass('jqplot-table-legend-swatch-outline'); 679 div1 = $(document.createElement('div')); 680 div1.addClass('jqplot-table-legend-swatch'); 681 div1.css({backgroundColor: color, borderColor: color}); 682 td1.append(div0.append(div1)); 683 684 td2 = $(document.createElement('td')); 685 td2.addClass('jqplot-table-legend jqplot-table-legend-label'); 686 td2.css('paddingTop', rs); 687 688 if (this.escapeHtml){ 689 td2.text(lt); 690 } 691 else { 692 td2.html(lt); 693 } 694 if (reverse) { 695 td2.prependTo(tr); 696 td1.prependTo(tr); 697 } 698 else { 699 td1.appendTo(tr); 700 td2.appendTo(tr); 701 } 702 pad = true; 703 } 704 idx++; 705 } 706 } 707 } 708 } 709 return this._elem; 710 }; 711 712 $.jqplot.PieRenderer.prototype.handleMove = function(ev, gridpos, datapos, neighbor, plot) { 713 if (neighbor) { 714 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 715 plot.target.trigger('jqplotDataMouseOver', ins); 716 if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { 717 plot.target.trigger('jqplotDataHighlight', ins); 718 highlight (plot, ins[0], ins[1]); 719 } 720 } 721 else if (neighbor == null) { 722 unhighlight (plot); 723 } 724 }; 725 726 727 // this.eventCanvas._elem.bind($.jqplot.eventListenerHooks[i][0], {plot:this}, $.jqplot.eventListenerHooks[i][1]); 728 729 // setup default renderers for axes and legend so user doesn't have to 730 // called with scope of plot 731 function preInit(target, data, options) { 732 options = options || {}; 733 options.axesDefaults = options.axesDefaults || {}; 734 options.legend = options.legend || {}; 735 options.seriesDefaults = options.seriesDefaults || {}; 736 // only set these if there is a pie series 737 var setopts = false; 738 if (options.seriesDefaults.renderer == $.jqplot.PieRenderer) { 739 setopts = true; 740 } 741 else if (options.series) { 742 for (var i=0; i < options.series.length; i++) { 743 if (options.series[i].renderer == $.jqplot.PieRenderer) { 744 setopts = true; 745 } 746 } 747 } 748 749 if (setopts) { 750 options.axesDefaults.renderer = $.jqplot.PieAxisRenderer; 751 options.legend.renderer = $.jqplot.PieLegendRenderer; 752 options.legend.preDraw = true; 753 options.seriesDefaults.pointLabels = {show: false}; 754 } 755 } 756 757 function postInit(target, data, options) { 758 for (var i=0; i<this.series.length; i++) { 759 if (this.series[i].renderer.constructor == $.jqplot.PieRenderer) { 760 // don't allow mouseover and mousedown at same time. 761 if (this.series[i].highlightMouseOver) { 762 this.series[i].highlightMouseDown = false; 763 } 764 } 765 } 766 } 767 768 // called with scope of plot 769 function postParseOptions(options) { 770 for (var i=0; i<this.series.length; i++) { 771 this.series[i].seriesColors = this.seriesColors; 772 this.series[i].colorGenerator = $.jqplot.colorGenerator; 773 } 774 } 775 776 function highlight (plot, sidx, pidx) { 777 var s = plot.series[sidx]; 778 var canvas = plot.plugins.pieRenderer.highlightCanvas; 779 canvas._ctx.clearRect(0,0,canvas._ctx.canvas.width, canvas._ctx.canvas.height); 780 s._highlightedPoint = pidx; 781 plot.plugins.pieRenderer.highlightedSeriesIndex = sidx; 782 s.renderer.drawSlice.call(s, canvas._ctx, s._sliceAngles[pidx][0], s._sliceAngles[pidx][1], s.highlightColorGenerator.get(pidx), false); 783 } 784 785 function unhighlight (plot) { 786 var canvas = plot.plugins.pieRenderer.highlightCanvas; 787 canvas._ctx.clearRect(0,0, canvas._ctx.canvas.width, canvas._ctx.canvas.height); 788 for (var i=0; i<plot.series.length; i++) { 789 plot.series[i]._highlightedPoint = null; 790 } 791 plot.plugins.pieRenderer.highlightedSeriesIndex = null; 792 plot.target.trigger('jqplotDataUnhighlight'); 793 } 794 795 function handleMove(ev, gridpos, datapos, neighbor, plot) { 796 if (neighbor) { 797 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 798 var evt1 = jQuery.Event('jqplotDataMouseOver'); 799 evt1.pageX = ev.pageX; 800 evt1.pageY = ev.pageY; 801 plot.target.trigger(evt1, ins); 802 if (plot.series[ins[0]].highlightMouseOver && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { 803 var evt = jQuery.Event('jqplotDataHighlight'); 804 evt.which = ev.which; 805 evt.pageX = ev.pageX; 806 evt.pageY = ev.pageY; 807 plot.target.trigger(evt, ins); 808 highlight (plot, ins[0], ins[1]); 809 } 810 } 811 else if (neighbor == null) { 812 unhighlight (plot); 813 } 814 } 815 816 function handleMouseDown(ev, gridpos, datapos, neighbor, plot) { 817 if (neighbor) { 818 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 819 if (plot.series[ins[0]].highlightMouseDown && !(ins[0] == plot.plugins.pieRenderer.highlightedSeriesIndex && ins[1] == plot.series[ins[0]]._highlightedPoint)) { 820 var evt = jQuery.Event('jqplotDataHighlight'); 821 evt.which = ev.which; 822 evt.pageX = ev.pageX; 823 evt.pageY = ev.pageY; 824 plot.target.trigger(evt, ins); 825 highlight (plot, ins[0], ins[1]); 826 } 827 } 828 else if (neighbor == null) { 829 unhighlight (plot); 830 } 831 } 832 833 function handleMouseUp(ev, gridpos, datapos, neighbor, plot) { 834 var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; 835 if (idx != null && plot.series[idx].highlightMouseDown) { 836 unhighlight(plot); 837 } 838 } 839 840 function handleClick(ev, gridpos, datapos, neighbor, plot) { 841 if (neighbor) { 842 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 843 var evt = jQuery.Event('jqplotDataClick'); 844 evt.which = ev.which; 845 evt.pageX = ev.pageX; 846 evt.pageY = ev.pageY; 847 plot.target.trigger(evt, ins); 848 } 849 } 850 851 function handleRightClick(ev, gridpos, datapos, neighbor, plot) { 852 if (neighbor) { 853 var ins = [neighbor.seriesIndex, neighbor.pointIndex, neighbor.data]; 854 var idx = plot.plugins.pieRenderer.highlightedSeriesIndex; 855 if (idx != null && plot.series[idx].highlightMouseDown) { 856 unhighlight(plot); 857 } 858 var evt = jQuery.Event('jqplotDataRightClick'); 859 evt.which = ev.which; 860 evt.pageX = ev.pageX; 861 evt.pageY = ev.pageY; 862 plot.target.trigger(evt, ins); 863 } 864 } 865 866 // called within context of plot 867 // create a canvas which we can draw on. 868 // insert it before the eventCanvas, so eventCanvas will still capture events. 869 function postPlotDraw() { 870 // Memory Leaks patch 871 if (this.plugins.pieRenderer && this.plugins.pieRenderer.highlightCanvas) { 872 this.plugins.pieRenderer.highlightCanvas.resetCanvas(); 873 this.plugins.pieRenderer.highlightCanvas = null; 874 } 875 876 this.plugins.pieRenderer = {highlightedSeriesIndex:null}; 877 this.plugins.pieRenderer.highlightCanvas = new $.jqplot.GenericCanvas(); 878 879 // do we have any data labels? if so, put highlight canvas before those 880 var labels = $(this.targetId+' .jqplot-data-label'); 881 if (labels.length) { 882 $(labels[0]).before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this)); 883 } 884 // else put highlight canvas before event canvas. 885 else { 886 this.eventCanvas._elem.before(this.plugins.pieRenderer.highlightCanvas.createElement(this._gridPadding, 'jqplot-pieRenderer-highlight-canvas', this._plotDimensions, this)); 887 } 888 889 var hctx = this.plugins.pieRenderer.highlightCanvas.setContext(); 890 this.eventCanvas._elem.bind('mouseleave', {plot:this}, function (ev) { unhighlight(ev.data.plot); }); 891 } 892 893 $.jqplot.preInitHooks.push(preInit); 894 895 $.jqplot.PieTickRenderer = function() { 896 $.jqplot.AxisTickRenderer.call(this); 897 }; 898 899 $.jqplot.PieTickRenderer.prototype = new $.jqplot.AxisTickRenderer(); 900 $.jqplot.PieTickRenderer.prototype.constructor = $.jqplot.PieTickRenderer; 901 902 })(jQuery); 903 904
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 |