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