diff --git a/web-app/js/jqplot-plugins/jqplot.BezierCurveRenderer.js b/web-app/js/jqplot-plugins/jqplot.BezierCurveRenderer.js new file mode 100644 index 0000000..8bb205e --- /dev/null +++ b/web-app/js/jqplot-plugins/jqplot.BezierCurveRenderer.js @@ -0,0 +1,312 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.0b2_r947 + * + * Copyright (c) 2009-2011 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + // Class: $.jqplot.BezierCurveRenderer.js + // Renderer which draws lines as stacked bezier curves. + // Data for the line will not be specified as an array of + // [x, y] data point values, but as a an array of [start piont, bezier curve] + // So, the line is specified as: [[xstart, ystart], [cp1x, cp1y, cp2x, cp2y, xend, yend]]. + $.jqplot.BezierCurveRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BezierCurveRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BezierCurveRenderer.prototype.constructor = $.jqplot.BezierCurveRenderer; + + + // Method: setGridData + // converts the user data values to grid coordinates and stores them + // in the gridData array. + // Called with scope of a series. + $.jqplot.BezierCurveRenderer.prototype.setGridData = function(plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + // this._plotData should be same as this.data + var data = this.data; + this.gridData = []; + this._prevGridData = []; + // if seriesIndex = 0, fill to x axis. + // if seriesIndex > 0, fill to previous series data. + var idx = this.index; + if (data.length == 2) { + if (idx == 0) { + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, psd[1][4]), yp.call(this._yaxis, psd[1][5])], + [xp.call(this._xaxis, psd[1][2]), yp.call(this._yaxis, psd[1][3]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + else { + if (idx == 0) { + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, data[3][1]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + this.gridData = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, psd[3][0]), yp.call(this._yaxis, psd[3][1])], + [xp.call(this._xaxis, psd[2][0]), yp.call(this._yaxis, psd[2][1]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + }; + + // Method: makeGridData + // converts any arbitrary data values to grid coordinates and + // returns them. This method exists so that plugins can use a series' + // linerenderer to generate grid data points without overwriting the + // grid data associated with that series. + // Called with scope of a series. + $.jqplot.BezierCurveRenderer.prototype.makeGridData = function(data, plot) { + // recalculate the grid data + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var gd = []; + var pgd = []; + // if seriesIndex = 0, fill to x axis. + // if seriesIndex > 0, fill to previous series data. + var idx = this.index; + if (data.length == 2) { + if (idx == 0) { + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[1][2]), yp.call(this._yaxis, data[1][3]), + xp.call(this._xaxis, data[1][4]), yp.call(this._yaxis, data[1][5])], + [xp.call(this._xaxis, psd[1][4]), yp.call(this._yaxis, psd[1][5])], + [xp.call(this._xaxis, psd[1][2]), yp.call(this._yaxis, psd[1][3]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + else { + if (idx == 0) { + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, data[3][1]), yp.call(this._yaxis, this._yaxis.min)], + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, this._yaxis.min)] + ]; + } + else { + var psd = plot.series[idx-1].data; + gd = [ + [xp.call(this._xaxis, data[0][0]), yp.call(this._yaxis, data[0][1])], + [xp.call(this._xaxis, data[1][0]), yp.call(this._yaxis, data[1][1]), + xp.call(this._xaxis, data[2][0]), yp.call(this._yaxis, data[2][1]), + xp.call(this._xaxis, data[3][0]), yp.call(this._yaxis, data[3][1])], + [xp.call(this._xaxis, psd[3][0]), yp.call(this._yaxis, psd[3][1])], + [xp.call(this._xaxis, psd[2][0]), yp.call(this._yaxis, psd[2][1]), + xp.call(this._xaxis, psd[1][0]), yp.call(this._yaxis, psd[1][1]), + xp.call(this._xaxis, psd[0][0]), yp.call(this._yaxis, psd[0][1])] + ]; + } + } + return gd; + }; + + + // called within scope of series. + $.jqplot.BezierCurveRenderer.prototype.draw = function(ctx, gd, options) { + var i; + ctx.save(); + if (gd.length) { + if (this.showLine) { + ctx.save(); + var opts = (options != null) ? options : {}; + ctx.fillStyle = opts.fillStyle || this.color; + ctx.beginPath(); + ctx.moveTo(gd[0][0], gd[0][1]); + ctx.bezierCurveTo(gd[1][0], gd[1][1], gd[1][2], gd[1][3], gd[1][4], gd[1][5]); + ctx.lineTo(gd[2][0], gd[2][1]); + if (gd[3].length == 2) { + ctx.lineTo(gd[3][0], gd[3][1]); + } + else { + ctx.bezierCurveTo(gd[3][0], gd[3][1], gd[3][2], gd[3][3], gd[3][4], gd[3][5]); + } + ctx.closePath(); + ctx.fill(); + ctx.restore(); + } + } + + ctx.restore(); + }; + + $.jqplot.BezierCurveRenderer.prototype.drawShadow = function(ctx, gd, options) { + // This is a no-op, shadows drawn with lines. + }; + + $.jqplot.BezierAxisRenderer = function() { + $.jqplot.LinearAxisRenderer.call(this); + }; + + $.jqplot.BezierAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); + $.jqplot.BezierAxisRenderer.prototype.constructor = $.jqplot.BezierAxisRenderer; + + + // Axes on a plot with Bezier Curves + $.jqplot.BezierAxisRenderer.prototype.init = function(options){ + $.extend(true, this, options); + var db = this._dataBounds; + // Go through all the series attached to this axis and find + // the min/max bounds for this axis. + for (var i=0; i db.max || db.max == null) { + db.max = d[j][0]; + } + } + else { + if (d[j][1] < db.min || db.min == null) { + db.min = d[j][1]; + } + if (d[j][1] > db.max || db.max == null) { + db.max = d[j][1]; + } + } + } + } + else { + if (this.name == 'xaxis' || this.name == 'x2axis') { + if (d[0][0] < db.min || db.min == null) { + db.min = d[0][0]; + } + if (d[0][0] > db.max || db.max == null) { + db.max = d[0][0]; + } + for (var j=0; j<5; j+=2) { + if (d[1][j] < db.min || db.min == null) { + db.min = d[1][j]; + } + if (d[1][j] > db.max || db.max == null) { + db.max = d[1][j]; + } + } + } + else { + if (d[0][1] < db.min || db.min == null) { + db.min = d[0][1]; + } + if (d[0][1] > db.max || db.max == null) { + db.max = d[0][1]; + } + for (var j=1; j<6; j+=2) { + if (d[1][j] < db.min || db.min == null) { + db.min = d[1][j]; + } + if (d[1][j] > db.max || db.max == null) { + db.max = d[1][j]; + } + } + } + } + } + }; + + // setup default renderers for axes and legend so user doesn't have to + // called with scope of plot + function preInit(target, data, options) { + options = options || {}; + options.axesDefaults = $.extend(true, {pad:0}, options.axesDefaults); + options.legend = $.extend(true, {placement:'outside'}, options.legend); + // only set these if there is a pie series + var setopts = false; + if (options.seriesDefaults.renderer == $.jqplot.BezierCurveRenderer) { + setopts = true; + } + else if (options.series) { + for (var i=0; i < options.series.length; i++) { + if (options.series[i].renderer == $.jqplot.BezierCurveRenderer) { + setopts = true; + } + } + } + + if (setopts) { + options.axesDefaults.renderer = $.jqplot.BezierAxisRenderer; + } + } + + $.jqplot.preInitHooks.push(preInit); + +})(jQuery); \ No newline at end of file diff --git a/web-app/js/jqplot-plugins/jqplot.BezierCurveRenderer.min.js b/web-app/js/jqplot-plugins/jqplot.BezierCurveRenderer.min.js new file mode 100644 index 0000000..70fdd32 --- /dev/null +++ b/web-app/js/jqplot-plugins/jqplot.BezierCurveRenderer.min.js @@ -0,0 +1,57 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.0b2_r947 + * + * Copyright (c) 2009-2011 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + * included jsDate library by Chris Leonello: + * + * Copyright (c) 2010-2011 Chris Leonello + * + * jsDate is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * jsDate borrows many concepts and ideas from the Date Instance + * Methods by Ken Snyder along with some parts of Ken's actual code. + * + * Ken's origianl Date Instance Methods and copyright notice: + * + * Ken Snyder (ken d snyder at gmail dot com) + * 2008-09-10 + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) + * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) + * + * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js. + * Larry has generously given permission to adapt his code for inclusion + * into jqPlot. + * + * Larry's original code can be found here: + * + * https://github.com/lsiden/export-jqplot-to-png + * + * + */ +(function(b){b.jqplot.BezierCurveRenderer=function(){b.jqplot.LineRenderer.call(this)};b.jqplot.BezierCurveRenderer.prototype=new b.jqplot.LineRenderer();b.jqplot.BezierCurveRenderer.prototype.constructor=b.jqplot.BezierCurveRenderer;b.jqplot.BezierCurveRenderer.prototype.setGridData=function(h){var e=this._xaxis.series_u2p;var g=this._yaxis.series_u2p;var f=this.data;this.gridData=[];this._prevGridData=[];var d=this.index;if(f.length==2){if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,f[1][4]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[1][2]),g.call(this._yaxis,f[1][3]),e.call(this._xaxis,f[1][4]),g.call(this._yaxis,f[1][5])],[e.call(this._xaxis,c[1][4]),g.call(this._yaxis,c[1][5])],[e.call(this._xaxis,c[1][2]),g.call(this._yaxis,c[1][3]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}else{if(d==0){this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,f[3][1]),g.call(this._yaxis,this._yaxis.min)],[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,this._yaxis.min)]]}else{var c=h.series[d-1].data;this.gridData=[[e.call(this._xaxis,f[0][0]),g.call(this._yaxis,f[0][1])],[e.call(this._xaxis,f[1][0]),g.call(this._yaxis,f[1][1]),e.call(this._xaxis,f[2][0]),g.call(this._yaxis,f[2][1]),e.call(this._xaxis,f[3][0]),g.call(this._yaxis,f[3][1])],[e.call(this._xaxis,c[3][0]),g.call(this._yaxis,c[3][1])],[e.call(this._xaxis,c[2][0]),g.call(this._yaxis,c[2][1]),e.call(this._xaxis,c[1][0]),g.call(this._yaxis,c[1][1]),e.call(this._xaxis,c[0][0]),g.call(this._yaxis,c[0][1])]]}}};b.jqplot.BezierCurveRenderer.prototype.makeGridData=function(g,i){var f=this._xaxis.series_u2p;var h=this._yaxis.series_u2p;var e=[];var j=[];var d=this.index;if(g.length==2){if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,g[1][4]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[1][2]),h.call(this._yaxis,g[1][3]),f.call(this._xaxis,g[1][4]),h.call(this._yaxis,g[1][5])],[f.call(this._xaxis,c[1][4]),h.call(this._yaxis,c[1][5])],[f.call(this._xaxis,c[1][2]),h.call(this._yaxis,c[1][3]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}else{if(d==0){e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,g[3][1]),h.call(this._yaxis,this._yaxis.min)],[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,this._yaxis.min)]]}else{var c=i.series[d-1].data;e=[[f.call(this._xaxis,g[0][0]),h.call(this._yaxis,g[0][1])],[f.call(this._xaxis,g[1][0]),h.call(this._yaxis,g[1][1]),f.call(this._xaxis,g[2][0]),h.call(this._yaxis,g[2][1]),f.call(this._xaxis,g[3][0]),h.call(this._yaxis,g[3][1])],[f.call(this._xaxis,c[3][0]),h.call(this._yaxis,c[3][1])],[f.call(this._xaxis,c[2][0]),h.call(this._yaxis,c[2][1]),f.call(this._xaxis,c[1][0]),h.call(this._yaxis,c[1][1]),f.call(this._xaxis,c[0][0]),h.call(this._yaxis,c[0][1])]]}}return e};b.jqplot.BezierCurveRenderer.prototype.draw=function(c,g,d){var e;c.save();if(g.length){if(this.showLine){c.save();var f=(d!=null)?d:{};c.fillStyle=f.fillStyle||this.color;c.beginPath();c.moveTo(g[0][0],g[0][1]);c.bezierCurveTo(g[1][0],g[1][1],g[1][2],g[1][3],g[1][4],g[1][5]);c.lineTo(g[2][0],g[2][1]);if(g[3].length==2){c.lineTo(g[3][0],g[3][1])}else{c.bezierCurveTo(g[3][0],g[3][1],g[3][2],g[3][3],g[3][4],g[3][5])}c.closePath();c.fill();c.restore()}}c.restore()};b.jqplot.BezierCurveRenderer.prototype.drawShadow=function(c,e,d){};b.jqplot.BezierAxisRenderer=function(){b.jqplot.LinearAxisRenderer.call(this)};b.jqplot.BezierAxisRenderer.prototype=new b.jqplot.LinearAxisRenderer();b.jqplot.BezierAxisRenderer.prototype.constructor=b.jqplot.BezierAxisRenderer;b.jqplot.BezierAxisRenderer.prototype.init=function(f){b.extend(true,this,f);var c=this._dataBounds;for(var g=0;gc.max||c.max==null){c.max=k[e][0]}}else{if(k[e][1]c.max||c.max==null){c.max=k[e][1]}}}}else{if(this.name=="xaxis"||this.name=="x2axis"){if(k[0][0]c.max||c.max==null){c.max=k[0][0]}for(var e=0;e<5;e+=2){if(k[1][e]c.max||c.max==null){c.max=k[1][e]}}}else{if(k[0][1]c.max||c.max==null){c.max=k[0][1]}for(var e=1;e<6;e+=2){if(k[1][e]c.max||c.max==null){c.max=k[1][e]}}}}}};function a(g,f,d){d=d||{};d.axesDefaults=b.extend(true,{pad:0},d.axesDefaults);d.legend=b.extend(true,{placement:"outside"},d.legend);var c=false;if(d.seriesDefaults.renderer==b.jqplot.BezierCurveRenderer){c=true}else{if(d.series){for(var e=0;e0) { + this.data[i][pos] += this.data[i-1][pos]; + } + } + this.data[this.data.length] = (pos == 1) ? [this.data.length+1, sum] : [sum, this.data.length+1]; + this._data[this._data.length] = (pos == 1) ? [this._data.length+1, sum] : [sum, this._data.length+1]; + } + if (this.rendererOptions.groups > 1) { + this.breakOnNull = true; + var l = this.data.length; + var skip = parseInt(l/this.rendererOptions.groups, 10); + var count = 0; + for (var i=skip; i 570) ? newrgb[j] * 0.8 : newrgb[j] + 0.3 * (255 - newrgb[j]); + newrgb[j] = parseInt(newrgb[j], 10); + } + ret.push('rgb('+newrgb[0]+','+newrgb[1]+','+newrgb[2]+')'); + } + return ret; + } + + $.jqplot.BarRenderer.prototype.draw = function(ctx, gridData, options) { + var i; + // Ughhh, have to make a copy of options b/c it may be modified later. + var opts = $.extend({}, options); + var shadow = (opts.shadow != undefined) ? opts.shadow : this.shadow; + var showLine = (opts.showLine != undefined) ? opts.showLine : this.showLine; + var fill = (opts.fill != undefined) ? opts.fill : this.fill; + var xaxis = this.xaxis; + var yaxis = this.yaxis; + var xp = this._xaxis.series_u2p; + var yp = this._yaxis.series_u2p; + var pointx, pointy; + // clear out data colors. + this._dataColors = []; + this._barPoints = []; + + if (this.barWidth == null) { + this.renderer.setBarWidth.call(this); + } + + var temp = this._plotSeriesInfo = this.renderer.calcSeriesNumbers.call(this); + var nvals = temp[0]; + var nseries = temp[1]; + var pos = temp[2]; + var points = []; + + if (this._stack) { + this._barNudge = 0; + } + else { + this._barNudge = (-Math.abs(nseries/2 - 0.5) + pos) * (this.barWidth + this.barPadding); + } + if (showLine) { + var negativeColors = new $.jqplot.ColorGenerator(this.negativeSeriesColors); + var positiveColors = new $.jqplot.ColorGenerator(this.seriesColors); + var negativeColor = negativeColors.get(this.index); + if (! this.useNegativeColors) { + negativeColor = opts.fillStyle; + } + var positiveColor = opts.fillStyle; + var base; + var xstart; + var ystart; + + if (this.barDirection == 'vertical') { + for (var i=0; i 0 && i < this.gridData.length-1) { + ystart = this.gridData[i-1][1]; + } + else if (this.waterfall && i == 0 && i < this.gridData.length-1) { + if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { + ystart = this._yaxis.series_u2p(0); + } + else if (this._yaxis.min > 0) { + ystart = ctx.canvas.height; + } + else { + ystart = 0; + } + } + else if (this.waterfall && i == this.gridData.length - 1) { + if (this._yaxis.min <= 0 && this._yaxis.max >= 0) { + ystart = this._yaxis.series_u2p(0); + } + else if (this._yaxis.min > 0) { + ystart = ctx.canvas.height; + } + else { + ystart = 0; + } + } + else { + ystart = ctx.canvas.height; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor && !this._stack) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + else { + opts.fillStyle = negativeColor; + } + } + else { + if (this.varyBarColor && !this._stack) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + if (!this.fillToZero || this._plotData[i][1] >= 0) { + points.push([base-this.barWidth/2, ystart]); + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, gridData[i][1]]); + points.push([base+this.barWidth/2, ystart]); + } + // for negative bars make sure points are always ordered clockwise + else { + points.push([base-this.barWidth/2, gridData[i][1]]); + points.push([base-this.barWidth/2, ystart]); + points.push([base+this.barWidth/2, ystart]); + points.push([base+this.barWidth/2, gridData[i][1]]); + } + this._barPoints.push(points); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + var sopts = $.extend(true, {}, opts); + // need to get rid of fillStyle on shadow. + delete sopts.fillStyle; + this.renderer.shadowRenderer.draw(ctx, points, sopts); + } + var clr = opts.fillStyle || this.color; + this._dataColors.push(clr); + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + + else if (this.barDirection == 'horizontal'){ + for (var i=0; i 0 && i < this.gridData.length-1) { + xstart = this.gridData[i-1][1]; + } + else if (this.waterfall && i == 0 && i < this.gridData.length-1) { + if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { + xstart = this._xaxis.series_u2p(0); + } + else if (this._xaxis.min > 0) { + xstart = 0; + } + else { + xstart = ctx.canvas.width; + } + } + else if (this.waterfall && i == this.gridData.length - 1) { + if (this._xaxis.min <= 0 && this._xaxis.max >= 0) { + xstart = this._xaxis.series_u2p(0); + } + else if (this._xaxis.min > 0) { + xstart = 0; + } + else { + xstart = ctx.canvas.width; + } + } + else { + xstart = 0; + } + } + if ((this.fillToZero && this._plotData[i][1] < 0) || (this.waterfall && this._data[i][1] < 0)) { + if (this.varyBarColor && !this._stack) { + if (this.useNegativeColors) { + opts.fillStyle = negativeColors.next(); + } + else { + opts.fillStyle = positiveColors.next(); + } + } + } + else { + if (this.varyBarColor && !this._stack) { + opts.fillStyle = positiveColors.next(); + } + else { + opts.fillStyle = positiveColor; + } + } + + + if (!this.fillToZero || this._plotData[i][0] >= 0) { + points.push([xstart, base + this.barWidth / 2]); + points.push([xstart, base - this.barWidth / 2]); + points.push([gridData[i][0], base - this.barWidth / 2]); + points.push([gridData[i][0], base + this.barWidth / 2]); + } + else { + points.push([gridData[i][0], base + this.barWidth / 2]); + points.push([gridData[i][0], base - this.barWidth / 2]); + points.push([xstart, base - this.barWidth / 2]); + points.push([xstart, base + this.barWidth / 2]); + } + + this._barPoints.push(points); + // now draw the shadows if not stacked. + // for stacked plots, they are predrawn by drawShadow + if (shadow && !this._stack) { + var sopts = $.extend(true, {}, opts); + delete sopts.fillStyle; + this.renderer.shadowRenderer.draw(ctx, points, sopts); + } + var clr = opts.fillStyle || this.color; + this._dataColors.push(clr); + this.renderer.shapeRenderer.draw(ctx, points, opts); + } + } + } + + if (this.highlightColors.length == 0) { + this.highlightColors = $.jqplot.computeHighlightColors(this._dataColors); + } + + else if (typeof(this.highlightColors) == 'string') { + var temp = this.highlightColors; + this.highlightColors = []; + for (var i=0; i0){this.data[p][t]+=this.data[p-1][t]}}this.data[this.data.length]=(t==1)?[this.data.length+1,r]:[r,this.data.length+1];this._data[this._data.length]=(t==1)?[this._data.length+1,r]:[r,this._data.length+1]}if(this.rendererOptions.groups>1){this.breakOnNull=true;var m=this.data.length;var u=parseInt(m/this.rendererOptions.groups,10);var q=0;for(var p=u;p570)?m[o]*0.8:m[o]+0.3*(255-m[o]);m[o]=parseInt(m[o],10)}p.push("rgb("+m[0]+","+m[1]+","+m[2]+")")}return p}d.jqplot.BarRenderer.prototype.draw=function(D,J,p){var G;var z=d.extend({},p);var u=(z.shadow!=undefined)?z.shadow:this.shadow;var M=(z.showLine!=undefined)?z.showLine:this.showLine;var E=(z.fill!=undefined)?z.fill:this.fill;var o=this.xaxis;var H=this.yaxis;var x=this._xaxis.series_u2p;var I=this._yaxis.series_u2p;var C,B;this._dataColors=[];this._barPoints=[];if(this.barWidth==null){this.renderer.setBarWidth.call(this)}var L=this._plotSeriesInfo=this.renderer.calcSeriesNumbers.call(this);var w=L[0];var v=L[1];var r=L[2];var F=[];if(this._stack){this._barNudge=0}else{this._barNudge=(-Math.abs(v/2-0.5)+r)*(this.barWidth+this.barPadding)}if(M){var t=new d.jqplot.ColorGenerator(this.negativeSeriesColors);var A=new d.jqplot.ColorGenerator(this.seriesColors);var K=t.get(this.index);if(!this.useNegativeColors){K=z.fillStyle}var s=z.fillStyle;var q;var N;var n;if(this.barDirection=="vertical"){for(var G=0;G0&&G=0){n=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){n=D.canvas.height}else{n=0}}}else{if(this.waterfall&&G==this.gridData.length-1){if(this._yaxis.min<=0&&this._yaxis.max>=0){n=this._yaxis.series_u2p(0)}else{if(this._yaxis.min>0){n=D.canvas.height}else{n=0}}}else{n=D.canvas.height}}}}}if((this.fillToZero&&this._plotData[G][1]<0)||(this.waterfall&&this._data[G][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){z.fillStyle=t.next()}else{z.fillStyle=A.next()}}else{z.fillStyle=K}}else{if(this.varyBarColor&&!this._stack){z.fillStyle=A.next()}else{z.fillStyle=s}}if(!this.fillToZero||this._plotData[G][1]>=0){F.push([q-this.barWidth/2,n]);F.push([q-this.barWidth/2,J[G][1]]);F.push([q+this.barWidth/2,J[G][1]]);F.push([q+this.barWidth/2,n])}else{F.push([q-this.barWidth/2,J[G][1]]);F.push([q-this.barWidth/2,n]);F.push([q+this.barWidth/2,n]);F.push([q+this.barWidth/2,J[G][1]])}this._barPoints.push(F);if(u&&!this._stack){var y=d.extend(true,{},z);delete y.fillStyle;this.renderer.shadowRenderer.draw(D,F,y)}var m=z.fillStyle||this.color;this._dataColors.push(m);this.renderer.shapeRenderer.draw(D,F,z)}}else{if(this.barDirection=="horizontal"){for(var G=0;G0&&G=0){N=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){N=0}else{N=D.canvas.width}}}else{if(this.waterfall&&G==this.gridData.length-1){if(this._xaxis.min<=0&&this._xaxis.max>=0){N=this._xaxis.series_u2p(0)}else{if(this._xaxis.min>0){N=0}else{N=D.canvas.width}}}else{N=0}}}}}if((this.fillToZero&&this._plotData[G][1]<0)||(this.waterfall&&this._data[G][1]<0)){if(this.varyBarColor&&!this._stack){if(this.useNegativeColors){z.fillStyle=t.next()}else{z.fillStyle=A.next()}}}else{if(this.varyBarColor&&!this._stack){z.fillStyle=A.next()}else{z.fillStyle=s}}if(!this.fillToZero||this._plotData[G][0]>=0){F.push([N,q+this.barWidth/2]);F.push([N,q-this.barWidth/2]);F.push([J[G][0],q-this.barWidth/2]);F.push([J[G][0],q+this.barWidth/2])}else{F.push([J[G][0],q+this.barWidth/2]);F.push([J[G][0],q-this.barWidth/2]);F.push([N,q-this.barWidth/2]);F.push([N,q+this.barWidth/2])}this._barPoints.push(F);if(u&&!this._stack){var y=d.extend(true,{},z);delete y.fillStyle;this.renderer.shadowRenderer.draw(D,F,y)}var m=z.fillStyle||this.color;this._dataColors.push(m);this.renderer.shapeRenderer.draw(D,F,z)}}}}if(this.highlightColors.length==0){this.highlightColors=d.jqplot.computeHighlightColors(this._dataColors)}else{if(typeof(this.highlightColors)=="string"){var L=this.highlightColors;this.highlightColors=[];for(var G=0;G [[x1, y1, "label 1", {css}], [x2, y2, "label 2", {css}], ...] + * + * The label and css object are optional. If the label is ommitted, the + * box will collapse unless a css height and/or width is specified. + * + * The css object is an object specifying css properties + * such as: + * + * > {background:'#4f98a5', border:'3px solid gray', padding:'1px'} + * + * Note that css properties specified with the data point override defaults + * specified with the series. + * + */ + $.jqplot.BlockRenderer = function(){ + $.jqplot.LineRenderer.call(this); + }; + + $.jqplot.BlockRenderer.prototype = new $.jqplot.LineRenderer(); + $.jqplot.BlockRenderer.prototype.constructor = $.jqplot.BlockRenderer; + + // called with scope of a series + $.jqplot.BlockRenderer.prototype.init = function(options) { + // Group: Properties + // + // prop: css + // default css styles that will be applied to all data blocks. + // these values will be overridden by css styles supplied with the + // individulal data points. + this.css = {padding:'2px', border:'1px solid #999', textAlign:'center'}; + // prop: escapeHtml + // true to escape html in the box label. + this.escapeHtml = false; + // prop: insertBreaks + // true to turn spaces in data block label into html breaks
. + this.insertBreaks = true; + // prop: varyBlockColors + // true to vary the color of each block in this series according to + // the seriesColors array. False to set each block to the color + // specified on this series. This has no effect if a css background color + // option is specified in the renderer css options. + this.varyBlockColors = false; + $.extend(true, this, options); + if (this.css.backgroundColor) { + this.color = this.css.backgroundColor; + } + else if (this.css.background) { + this.color = this.css.background; + } + else if (!this.varyBlockColors) { + this.css.background = this.color; + } + this.canvas = new $.jqplot.BlockCanvas(); + this.shadowCanvas = new $.jqplot.BlockCanvas(); + this.canvas._plotDimensions = this._plotDimensions; + this.shadowCanvas._plotDimensions = this._plotDimensions; + this._type = 'block'; + + // group: Methods + // + // Method: moveBlock + // Moves an individual block. More efficient than redrawing + // the whole series by calling plot.drawSeries(). + // Properties: + // idx - the 0 based index of the block or point in this series. + // x - the x coordinate in data units (value on x axis) to move the block to. + // y - the y coordinate in data units (value on the y axis) to move the block to. + // duration - optional parameter to create an animated movement. Can be a + // number (higher is slower animation) or 'fast', 'normal' or 'slow'. If not + // provided, the element is moved without any animation. + this.moveBlock = function (idx, x, y, duration) { + // update plotData, stackData, data and gridData + // x and y are in data coordinates. + var el = this.canvas._elem.children(':eq('+idx+')'); + this.data[idx][0] = x; + this.data[idx][1] = y; + this._plotData[idx][0] = x; + this._plotData[idx][1] = y; + this._stackData[idx][0] = x; + this._stackData[idx][1] = y; + this.gridData[idx][0] = this._xaxis.series_u2p(x); + this.gridData[idx][1] = this._yaxis.series_u2p(y); + var w = el.outerWidth(); + var h = el.outerHeight(); + var left = this.gridData[idx][0] - w/2 + 'px'; + var top = this.gridData[idx][1] - h/2 + 'px'; + if (duration) { + if (parseInt(duration, 10)) { + duration = parseInt(duration, 10); + } + el.animate({left:left, top:top}, duration); + } + else { + el.css({left:left, top:top}); + } + el = null; + }; + }; + + // called with scope of series + $.jqplot.BlockRenderer.prototype.draw = function (ctx, gd, options) { + if (this.plugins.pointLabels) { + this.plugins.pointLabels.show = false; + } + var i, el, d, gd, t, css, w, h, left, top; + var opts = (options != undefined) ? options : {}; + var colorGenerator = new $.jqplot.ColorGenerator(this.seriesColors); + this.canvas._elem.empty(); + for (i=0; i'); + } + css = $.extend(true, {}, this.css, css); + // create a div + el = $('
'); + this.canvas._elem.append(el); + // set text + this.escapeHtml ? el.text(t) : el.html(t); + // style it + // remove styles we don't want overridden. + delete css.position; + delete css.marginRight; + delete css.marginLeft; + if (!css.background && !css.backgroundColor && !css.backgroundImage){ + css.background = colorGenerator.next(); + } + el.css(css); + w = el.outerWidth(); + h = el.outerHeight(); + left = gd[0] - w/2 + 'px'; + top = gd[1] - h/2 + 'px'; + el.css({left:left, top:top}); + el = null; + } + }; + + $.jqplot.BlockCanvas = function() { + $.jqplot.ElemContainer.call(this); + this._ctx; + }; + + $.jqplot.BlockCanvas.prototype = new $.jqplot.ElemContainer(); + $.jqplot.BlockCanvas.prototype.constructor = $.jqplot.BlockCanvas; + + $.jqplot.BlockCanvas.prototype.createElement = function(offsets, clss, plotDimensions) { + this._offsets = offsets; + var klass = 'jqplot-blockCanvas'; + if (clss != undefined) { + klass = clss; + } + var elem; + // if this canvas already has a dom element, don't make a new one. + if (this._elem) { + elem = this._elem.get(0); + } + else { + elem = document.createElement('div'); + } + // if new plotDimensions supplied, use them. + if (plotDimensions != undefined) { + this._plotDimensions = plotDimensions; + } + + var w = this._plotDimensions.width - this._offsets.left - this._offsets.right + 'px'; + var h = this._plotDimensions.height - this._offsets.top - this._offsets.bottom + 'px'; + this._elem = $(elem); + this._elem.css({ position: 'absolute', width:w, height:h, left: this._offsets.left, top: this._offsets.top }); + + this._elem.addClass(klass); + return this._elem; + }; + + $.jqplot.BlockCanvas.prototype.setContext = function() { + this._ctx = { + canvas:{ + width:0, + height:0 + }, + clearRect:function(){return null;} + }; + return this._ctx; + }; + +})(jQuery); + + \ No newline at end of file diff --git a/web-app/js/jqplot-plugins/jqplot.blockRenderer.min.js b/web-app/js/jqplot-plugins/jqplot.blockRenderer.min.js new file mode 100644 index 0000000..b0dbe37 --- /dev/null +++ b/web-app/js/jqplot-plugins/jqplot.blockRenderer.min.js @@ -0,0 +1,57 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.0b2_r947 + * + * Copyright (c) 2009-2011 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + * included jsDate library by Chris Leonello: + * + * Copyright (c) 2010-2011 Chris Leonello + * + * jsDate is currently available for use in all personal or commercial projects + * under both the MIT and GPL version 2.0 licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * jsDate borrows many concepts and ideas from the Date Instance + * Methods by Ken Snyder along with some parts of Ken's actual code. + * + * Ken's origianl Date Instance Methods and copyright notice: + * + * Ken Snyder (ken d snyder at gmail dot com) + * 2008-09-10 + * version 2.0.2 (http://kendsnyder.com/sandbox/date/) + * Creative Commons Attribution License 3.0 (http://creativecommons.org/licenses/by/3.0/) + * + * jqplotToImage function based on Larry Siden's export-jqplot-to-png.js. + * Larry has generously given permission to adapt his code for inclusion + * into jqPlot. + * + * Larry's original code can be found here: + * + * https://github.com/lsiden/export-jqplot-to-png + * + * + */ +(function(a){a.jqplot.BlockRenderer=function(){a.jqplot.LineRenderer.call(this)};a.jqplot.BlockRenderer.prototype=new a.jqplot.LineRenderer();a.jqplot.BlockRenderer.prototype.constructor=a.jqplot.BlockRenderer;a.jqplot.BlockRenderer.prototype.init=function(b){this.css={padding:"2px",border:"1px solid #999",textAlign:"center"};this.escapeHtml=false;this.insertBreaks=true;this.varyBlockColors=false;a.extend(true,this,b);if(this.css.backgroundColor){this.color=this.css.backgroundColor}else{if(this.css.background){this.color=this.css.background}else{if(!this.varyBlockColors){this.css.background=this.color}}}this.canvas=new a.jqplot.BlockCanvas();this.shadowCanvas=new a.jqplot.BlockCanvas();this.canvas._plotDimensions=this._plotDimensions;this.shadowCanvas._plotDimensions=this._plotDimensions;this._type="block";this.moveBlock=function(l,j,i,e){var c=this.canvas._elem.children(":eq("+l+")");this.data[l][0]=j;this.data[l][1]=i;this._plotData[l][0]=j;this._plotData[l][1]=i;this._stackData[l][0]=j;this._stackData[l][1]=i;this.gridData[l][0]=this._xaxis.series_u2p(j);this.gridData[l][1]=this._yaxis.series_u2p(i);var k=c.outerWidth();var f=c.outerHeight();var d=this.gridData[l][0]-k/2+"px";var g=this.gridData[l][1]-f/2+"px";if(e){if(parseInt(e,10)){e=parseInt(e,10)}c.animate({left:d,top:g},e)}else{c.css({left:d,top:g})}c=null}};a.jqplot.BlockRenderer.prototype.draw=function(q,o,r){if(this.plugins.pointLabels){this.plugins.pointLabels.show=false}var f,c,l,o,p,k,n,g,e,m;var b=(r!=undefined)?r:{};var j=new a.jqplot.ColorGenerator(this.seriesColors);this.canvas._elem.empty();for(f=0;f")}k=a.extend(true,{},this.css,k);c=a('
');this.canvas._elem.append(c);this.escapeHtml?c.text(p):c.html(p);delete k.position;delete k.marginRight;delete k.marginLeft;if(!k.background&&!k.backgroundColor&&!k.backgroundImage){k.background=j.next()}c.css(k);n=c.outerWidth();g=c.outerHeight();e=o[0]-n/2+"px";m=o[1]-g/2+"px";c.css({left:e,top:m});c=null}};a.jqplot.BlockCanvas=function(){a.jqplot.ElemContainer.call(this);this._ctx};a.jqplot.BlockCanvas.prototype=new a.jqplot.ElemContainer();a.jqplot.BlockCanvas.prototype.constructor=a.jqplot.BlockCanvas;a.jqplot.BlockCanvas.prototype.createElement=function(i,e,c){this._offsets=i;var b="jqplot-blockCanvas";if(e!=undefined){b=e}var g;if(this._elem){g=this._elem.get(0)}else{g=document.createElement("div")}if(c!=undefined){this._plotDimensions=c}var d=this._plotDimensions.width-this._offsets.left-this._offsets.right+"px";var f=this._plotDimensions.height-this._offsets.top-this._offsets.bottom+"px";this._elem=a(g);this._elem.css({position:"absolute",width:d,height:f,left:this._offsets.left,top:this._offsets.top});this._elem.addClass(b);return this._elem};a.jqplot.BlockCanvas.prototype.setContext=function(){this._ctx={canvas:{width:0,height:0},clearRect:function(){return null}};return this._ctx}})(jQuery); \ No newline at end of file diff --git a/web-app/js/jqplot-plugins/jqplot.bubbleRenderer.js b/web-app/js/jqplot-plugins/jqplot.bubbleRenderer.js new file mode 100644 index 0000000..e9cdfad --- /dev/null +++ b/web-app/js/jqplot-plugins/jqplot.bubbleRenderer.js @@ -0,0 +1,754 @@ +/** + * jqPlot + * Pure JavaScript plotting plugin using jQuery + * + * Version: 1.0.0b2_r947 + * + * Copyright (c) 2009-2011 Chris Leonello + * jqPlot is currently available for use in all personal or commercial projects + * under both the MIT (http://www.opensource.org/licenses/mit-license.php) and GPL + * version 2.0 (http://www.gnu.org/licenses/gpl-2.0.html) licenses. This means that you can + * choose the license that best suits your project and use it accordingly. + * + * Although not required, the author would appreciate an email letting him + * know of any substantial use of jqPlot. You can reach the author at: + * chris at jqplot dot com or see http://www.jqplot.com/info.php . + * + * If you are feeling kind and generous, consider supporting the project by + * making a donation at: http://www.jqplot.com/donate.php . + * + * sprintf functions contained in jqplot.sprintf.js by Ash Searle: + * + * version 2007.04.27 + * author Ash Searle + * http://hexmen.com/blog/2007/03/printf-sprintf/ + * http://hexmen.com/js/sprintf.js + * The author (Ash Searle) has placed this code in the public domain: + * "This code is unrestricted: you are free to use it however you like." + * + */ +(function($) { + var arrayMax = function( array ){ + return Math.max.apply( Math, array ); + }; + var arrayMin = function( array ){ + return Math.min.apply( Math, array ); + }; + + /** + * Class: $.jqplot.BubbleRenderer + * Plugin renderer to draw a bubble chart. A Bubble chart has data points displayed as + * colored circles with an optional text label inside. To use + * the bubble renderer, you must include the bubble renderer like: + * + * > + * + * Data must be supplied in + * the form: + * + * > [[x1, y1, r1,