[9062] | 1 | /** |
---|
| 2 | * jqPlot |
---|
| 3 | * Pure JavaScript plotting plugin using jQuery |
---|
| 4 | * |
---|
| 5 | * Version: @VERSION |
---|
| 6 | * |
---|
| 7 | * Copyright (c) 2009-2011 Chris Leonello |
---|
| 8 | * jqPlot is currently available for use in all personal or commercial projects |
---|
| 9 | * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL |
---|
| 10 | * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can |
---|
| 11 | * choose the license that best suits your project and use it accordingly. |
---|
| 12 | * |
---|
| 13 | * Although not required, the author would appreciate an email letting him |
---|
| 14 | * know of any substantial use of jqPlot. You can reach the author at: |
---|
| 15 | * chris at jqplot dot com or see http://www.jqplot.com/info.php . |
---|
| 16 | * |
---|
| 17 | * If you are feeling kind and generous, consider supporting the project by |
---|
| 18 | * making a donation at: http://www.jqplot.com/donate.php . |
---|
| 19 | * |
---|
| 20 | * sprintf functions contained in jqplot.sprintf.js by Ash Searle: |
---|
| 21 | * |
---|
| 22 | * version 2007.04.27 |
---|
| 23 | * author Ash Searle |
---|
| 24 | * http://hexmen.com/blog/2007/03/printf-sprintf/ |
---|
| 25 | * http://hexmen.com/js/sprintf.js |
---|
| 26 | * The author (Ash Searle) has placed this code in the public domain: |
---|
| 27 | * "This code is unrestricted: you are free to use it however you like." |
---|
| 28 | * |
---|
| 29 | */ |
---|
| 30 | (function($) { |
---|
| 31 | // Class: $.jqplot.CanvasGridRenderer |
---|
| 32 | // The default jqPlot grid renderer, creating a grid on a canvas element. |
---|
| 33 | // The renderer has no additional options beyond the <Grid> class. |
---|
| 34 | $.jqplot.CanvasGridRenderer = function(){ |
---|
| 35 | this.shadowRenderer = new $.jqplot.ShadowRenderer(); |
---|
| 36 | }; |
---|
| 37 | |
---|
| 38 | // called with context of Grid object |
---|
| 39 | $.jqplot.CanvasGridRenderer.prototype.init = function(options) { |
---|
| 40 | this._ctx; |
---|
| 41 | $.extend(true, this, options); |
---|
| 42 | // set the shadow renderer options |
---|
| 43 | var sopts = {lineJoin:'miter', lineCap:'round', fill:false, isarc:false, angle:this.shadowAngle, offset:this.shadowOffset, alpha:this.shadowAlpha, depth:this.shadowDepth, lineWidth:this.shadowWidth, closePath:false, strokeStyle:this.shadowColor}; |
---|
| 44 | this.renderer.shadowRenderer.init(sopts); |
---|
| 45 | }; |
---|
| 46 | |
---|
| 47 | // called with context of Grid. |
---|
| 48 | $.jqplot.CanvasGridRenderer.prototype.createElement = function(plot) { |
---|
| 49 | var elem; |
---|
| 50 | // Memory Leaks patch |
---|
| 51 | if (this._elem) { |
---|
| 52 | if ($.jqplot.use_excanvas) { |
---|
| 53 | elem = this._elem.get(0); |
---|
| 54 | window.G_vmlCanvasManager.uninitElement(elem); |
---|
| 55 | elem = null; |
---|
| 56 | } |
---|
| 57 | |
---|
| 58 | this._elem.emptyForce(); |
---|
| 59 | this._elem = null; |
---|
| 60 | } |
---|
| 61 | |
---|
| 62 | elem = plot.canvasManager.getCanvas(); |
---|
| 63 | |
---|
| 64 | var w = this._plotDimensions.width; |
---|
| 65 | var h = this._plotDimensions.height; |
---|
| 66 | elem.width = w; |
---|
| 67 | elem.height = h; |
---|
| 68 | this._elem = $(elem); |
---|
| 69 | this._elem.addClass('jqplot-grid-canvas'); |
---|
| 70 | this._elem.css({ position: 'absolute', left: 0, top: 0 }); |
---|
| 71 | |
---|
| 72 | elem = plot.canvasManager.initCanvas(elem); |
---|
| 73 | |
---|
| 74 | this._top = this._offsets.top; |
---|
| 75 | this._bottom = h - this._offsets.bottom; |
---|
| 76 | this._left = this._offsets.left; |
---|
| 77 | this._right = w - this._offsets.right; |
---|
| 78 | this._width = this._right - this._left; |
---|
| 79 | this._height = this._bottom - this._top; |
---|
| 80 | // avoid memory leak |
---|
| 81 | elem = null; |
---|
| 82 | return this._elem; |
---|
| 83 | }; |
---|
| 84 | |
---|
| 85 | $.jqplot.CanvasGridRenderer.prototype.draw = function() { |
---|
| 86 | this._ctx = this._elem.get(0).getContext("2d"); |
---|
| 87 | var ctx = this._ctx; |
---|
| 88 | var axes = this._axes; |
---|
| 89 | // Add the grid onto the grid canvas. This is the bottom most layer. |
---|
| 90 | ctx.save(); |
---|
| 91 | ctx.clearRect(0, 0, this._plotDimensions.width, this._plotDimensions.height); |
---|
| 92 | ctx.fillStyle = this.backgroundColor || this.background; |
---|
| 93 | ctx.fillRect(this._left, this._top, this._width, this._height); |
---|
| 94 | |
---|
| 95 | if (true) { |
---|
| 96 | ctx.save(); |
---|
| 97 | ctx.lineJoin = 'miter'; |
---|
| 98 | ctx.lineCap = 'butt'; |
---|
| 99 | ctx.lineWidth = this.gridLineWidth; |
---|
| 100 | ctx.strokeStyle = this.gridLineColor; |
---|
| 101 | var b, e, s, m; |
---|
| 102 | var ax = ['xaxis', 'yaxis', 'x2axis', 'y2axis']; |
---|
| 103 | for (var i=4; i>0; i--) { |
---|
| 104 | var name = ax[i-1]; |
---|
| 105 | var axis = axes[name]; |
---|
| 106 | var ticks = axis._ticks; |
---|
| 107 | if (axis.show) { |
---|
| 108 | for (var j=ticks.length; j>0; j--) { |
---|
| 109 | var t = ticks[j-1]; |
---|
| 110 | if (t.show) { |
---|
| 111 | var pos = Math.round(axis.u2p(t.value)) + 0.5; |
---|
| 112 | switch (name) { |
---|
| 113 | case 'xaxis': |
---|
| 114 | // draw the grid line |
---|
| 115 | if (t.showGridline && this.drawGridlines) { |
---|
| 116 | drawLine(pos, this._top, pos, this._bottom); |
---|
| 117 | } |
---|
| 118 | |
---|
| 119 | // draw the mark |
---|
| 120 | if (t.showMark && t.mark) { |
---|
| 121 | s = t.markSize; |
---|
| 122 | m = t.mark; |
---|
| 123 | var pos = Math.round(axis.u2p(t.value)) + 0.5; |
---|
| 124 | switch (m) { |
---|
| 125 | case 'outside': |
---|
| 126 | b = this._bottom; |
---|
| 127 | e = this._bottom+s; |
---|
| 128 | break; |
---|
| 129 | case 'inside': |
---|
| 130 | b = this._bottom-s; |
---|
| 131 | e = this._bottom; |
---|
| 132 | break; |
---|
| 133 | case 'cross': |
---|
| 134 | b = this._bottom-s; |
---|
| 135 | e = this._bottom+s; |
---|
| 136 | break; |
---|
| 137 | default: |
---|
| 138 | b = this._bottom; |
---|
| 139 | e = this._bottom+s; |
---|
| 140 | break; |
---|
| 141 | } |
---|
| 142 | // draw the shadow |
---|
| 143 | if (this.shadow) { |
---|
| 144 | this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); |
---|
| 145 | } |
---|
| 146 | // draw the line |
---|
| 147 | drawLine(pos, b, pos, e); |
---|
| 148 | } |
---|
| 149 | break; |
---|
| 150 | case 'yaxis': |
---|
| 151 | // draw the grid line |
---|
| 152 | if (t.showGridline && this.drawGridlines) { |
---|
| 153 | drawLine(this._right, pos, this._left, pos); |
---|
| 154 | } |
---|
| 155 | // draw the mark |
---|
| 156 | if (t.showMark && t.mark) { |
---|
| 157 | s = t.markSize; |
---|
| 158 | m = t.mark; |
---|
| 159 | var pos = Math.round(axis.u2p(t.value)) + 0.5; |
---|
| 160 | switch (m) { |
---|
| 161 | case 'outside': |
---|
| 162 | b = this._left-s; |
---|
| 163 | e = this._left; |
---|
| 164 | break; |
---|
| 165 | case 'inside': |
---|
| 166 | b = this._left; |
---|
| 167 | e = this._left+s; |
---|
| 168 | break; |
---|
| 169 | case 'cross': |
---|
| 170 | b = this._left-s; |
---|
| 171 | e = this._left+s; |
---|
| 172 | break; |
---|
| 173 | default: |
---|
| 174 | b = this._left-s; |
---|
| 175 | e = this._left; |
---|
| 176 | break; |
---|
| 177 | } |
---|
| 178 | // draw the shadow |
---|
| 179 | if (this.shadow) { |
---|
| 180 | this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); |
---|
| 181 | } |
---|
| 182 | drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); |
---|
| 183 | } |
---|
| 184 | break; |
---|
| 185 | case 'x2axis': |
---|
| 186 | // draw the grid line |
---|
| 187 | if (t.showGridline && this.drawGridlines) { |
---|
| 188 | drawLine(pos, this._bottom, pos, this._top); |
---|
| 189 | } |
---|
| 190 | // draw the mark |
---|
| 191 | if (t.showMark && t.mark) { |
---|
| 192 | s = t.markSize; |
---|
| 193 | m = t.mark; |
---|
| 194 | var pos = Math.round(axis.u2p(t.value)) + 0.5; |
---|
| 195 | switch (m) { |
---|
| 196 | case 'outside': |
---|
| 197 | b = this._top-s; |
---|
| 198 | e = this._top; |
---|
| 199 | break; |
---|
| 200 | case 'inside': |
---|
| 201 | b = this._top; |
---|
| 202 | e = this._top+s; |
---|
| 203 | break; |
---|
| 204 | case 'cross': |
---|
| 205 | b = this._top-s; |
---|
| 206 | e = this._top+s; |
---|
| 207 | break; |
---|
| 208 | default: |
---|
| 209 | b = this._top-s; |
---|
| 210 | e = this._top; |
---|
| 211 | break; |
---|
| 212 | } |
---|
| 213 | // draw the shadow |
---|
| 214 | if (this.shadow) { |
---|
| 215 | this.renderer.shadowRenderer.draw(ctx, [[pos,b],[pos,e]], {lineCap:'butt', lineWidth:this.gridLineWidth, offset:this.gridLineWidth*0.75, depth:2, fill:false, closePath:false}); |
---|
| 216 | } |
---|
| 217 | drawLine(pos, b, pos, e); |
---|
| 218 | } |
---|
| 219 | break; |
---|
| 220 | case 'y2axis': |
---|
| 221 | // draw the grid line |
---|
| 222 | if (t.showGridline && this.drawGridlines) { |
---|
| 223 | drawLine(this._left, pos, this._right, pos); |
---|
| 224 | } |
---|
| 225 | // draw the mark |
---|
| 226 | if (t.showMark && t.mark) { |
---|
| 227 | s = t.markSize; |
---|
| 228 | m = t.mark; |
---|
| 229 | var pos = Math.round(axis.u2p(t.value)) + 0.5; |
---|
| 230 | switch (m) { |
---|
| 231 | case 'outside': |
---|
| 232 | b = this._right; |
---|
| 233 | e = this._right+s; |
---|
| 234 | break; |
---|
| 235 | case 'inside': |
---|
| 236 | b = this._right-s; |
---|
| 237 | e = this._right; |
---|
| 238 | break; |
---|
| 239 | case 'cross': |
---|
| 240 | b = this._right-s; |
---|
| 241 | e = this._right+s; |
---|
| 242 | break; |
---|
| 243 | default: |
---|
| 244 | b = this._right; |
---|
| 245 | e = this._right+s; |
---|
| 246 | break; |
---|
| 247 | } |
---|
| 248 | // draw the shadow |
---|
| 249 | if (this.shadow) { |
---|
| 250 | this.renderer.shadowRenderer.draw(ctx, [[b, pos], [e, pos]], {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); |
---|
| 251 | } |
---|
| 252 | drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); |
---|
| 253 | } |
---|
| 254 | break; |
---|
| 255 | default: |
---|
| 256 | break; |
---|
| 257 | } |
---|
| 258 | } |
---|
| 259 | } |
---|
| 260 | t = null; |
---|
| 261 | } |
---|
| 262 | axis = null; |
---|
| 263 | ticks = null; |
---|
| 264 | } |
---|
| 265 | // Now draw grid lines for additional y axes |
---|
| 266 | ax = ['y3axis', 'y4axis', 'y5axis', 'y6axis', 'y7axis', 'y8axis', 'y9axis']; |
---|
| 267 | for (var i=7; i>0; i--) { |
---|
| 268 | var axis = axes[ax[i-1]]; |
---|
| 269 | var ticks = axis._ticks; |
---|
| 270 | if (axis.show) { |
---|
| 271 | var tn = ticks[axis.numberTicks-1]; |
---|
| 272 | var t0 = ticks[0]; |
---|
| 273 | var left = axis.getLeft(); |
---|
| 274 | var points = [[left, tn.getTop() + tn.getHeight()/2], [left, t0.getTop() + t0.getHeight()/2 + 1.0]]; |
---|
| 275 | // draw the shadow |
---|
| 276 | if (this.shadow) { |
---|
| 277 | this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', fill:false, closePath:false}); |
---|
| 278 | } |
---|
| 279 | // draw the line |
---|
| 280 | drawLine(points[0][0], points[0][1], points[1][0], points[1][1], {lineCap:'butt', strokeStyle:axis.borderColor, lineWidth:axis.borderWidth}); |
---|
| 281 | // draw the tick marks |
---|
| 282 | for (var j=ticks.length; j>0; j--) { |
---|
| 283 | var t = ticks[j-1]; |
---|
| 284 | s = t.markSize; |
---|
| 285 | m = t.mark; |
---|
| 286 | var pos = Math.round(axis.u2p(t.value)) + 0.5; |
---|
| 287 | if (t.showMark && t.mark) { |
---|
| 288 | switch (m) { |
---|
| 289 | case 'outside': |
---|
| 290 | b = left; |
---|
| 291 | e = left+s; |
---|
| 292 | break; |
---|
| 293 | case 'inside': |
---|
| 294 | b = left-s; |
---|
| 295 | e = left; |
---|
| 296 | break; |
---|
| 297 | case 'cross': |
---|
| 298 | b = left-s; |
---|
| 299 | e = left+s; |
---|
| 300 | break; |
---|
| 301 | default: |
---|
| 302 | b = left; |
---|
| 303 | e = left+s; |
---|
| 304 | break; |
---|
| 305 | } |
---|
| 306 | points = [[b,pos], [e,pos]]; |
---|
| 307 | // draw the shadow |
---|
| 308 | if (this.shadow) { |
---|
| 309 | this.renderer.shadowRenderer.draw(ctx, points, {lineCap:'butt', lineWidth:this.gridLineWidth*1.5, offset:this.gridLineWidth*0.75, fill:false, closePath:false}); |
---|
| 310 | } |
---|
| 311 | // draw the line |
---|
| 312 | drawLine(b, pos, e, pos, {strokeStyle:axis.borderColor}); |
---|
| 313 | } |
---|
| 314 | t = null; |
---|
| 315 | } |
---|
| 316 | t0 = null; |
---|
| 317 | } |
---|
| 318 | axis = null; |
---|
| 319 | ticks = null; |
---|
| 320 | } |
---|
| 321 | |
---|
| 322 | ctx.restore(); |
---|
| 323 | } |
---|
| 324 | |
---|
| 325 | function drawLine(bx, by, ex, ey, opts) { |
---|
| 326 | ctx.save(); |
---|
| 327 | opts = opts || {}; |
---|
| 328 | if (opts.lineWidth == null || opts.lineWidth != 0){ |
---|
| 329 | $.extend(true, ctx, opts); |
---|
| 330 | ctx.beginPath(); |
---|
| 331 | ctx.moveTo(bx, by); |
---|
| 332 | ctx.lineTo(ex, ey); |
---|
| 333 | ctx.stroke(); |
---|
| 334 | ctx.restore(); |
---|
| 335 | } |
---|
| 336 | } |
---|
| 337 | |
---|
| 338 | if (this.shadow) { |
---|
| 339 | var points = [[this._left, this._bottom], [this._right, this._bottom], [this._right, this._top]]; |
---|
| 340 | this.renderer.shadowRenderer.draw(ctx, points); |
---|
| 341 | } |
---|
| 342 | // Now draw border around grid. Use axis border definitions. start at |
---|
| 343 | // upper left and go clockwise. |
---|
| 344 | if (this.borderWidth != 0 && this.drawBorder) { |
---|
| 345 | drawLine (this._left, this._top, this._right, this._top, {lineCap:'round', strokeStyle:axes.x2axis.borderColor, lineWidth:axes.x2axis.borderWidth}); |
---|
| 346 | drawLine (this._right, this._top, this._right, this._bottom, {lineCap:'round', strokeStyle:axes.y2axis.borderColor, lineWidth:axes.y2axis.borderWidth}); |
---|
| 347 | drawLine (this._right, this._bottom, this._left, this._bottom, {lineCap:'round', strokeStyle:axes.xaxis.borderColor, lineWidth:axes.xaxis.borderWidth}); |
---|
| 348 | drawLine (this._left, this._bottom, this._left, this._top, {lineCap:'round', strokeStyle:axes.yaxis.borderColor, lineWidth:axes.yaxis.borderWidth}); |
---|
| 349 | } |
---|
| 350 | // ctx.lineWidth = this.borderWidth; |
---|
| 351 | // ctx.strokeStyle = this.borderColor; |
---|
| 352 | // ctx.strokeRect(this._left, this._top, this._width, this._height); |
---|
| 353 | |
---|
| 354 | ctx.restore(); |
---|
| 355 | ctx = null; |
---|
| 356 | axes = null; |
---|
| 357 | }; |
---|
| 358 | })(jQuery); |
---|