/** * jqPlot * Pure JavaScript plotting plugin using jQuery * * Version: @VERSION * Revision: @REVISION * * Copyright (c) 2009-2013 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.seriesDefaults = options.seriesDefaults || {}; 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);