/** * 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($) { $.jqplot.PyramidAxisRenderer = function() { $.jqplot.LinearAxisRenderer.call(this); }; $.jqplot.PyramidAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer(); $.jqplot.PyramidAxisRenderer.prototype.constructor = $.jqplot.PyramidAxisRenderer; // called with scope of axis $.jqplot.PyramidAxisRenderer.prototype.init = function(options){ // Group: Properties // // prop: position // Position of axis. Values are: top, bottom , left, center, right. // By default, x and x2 axes are bottom, y axis is center. this.position = null; // prop: drawBaseline // True to draw the axis baseline. this.drawBaseline = true; // prop: baselineWidth // width of the baseline in pixels. this.baselineWidth = null; // prop: baselineColor // CSS color spec for the baseline. this.baselineColor = null; this.tickSpacingFactor = 25; this._type = 'pyramid'; this._splitAxis = false; this._splitLength = null; this.category = false; this._autoFormatString = ''; this._overrideFormatString = false; $.extend(true, this, options); this.renderer.options = options; this.resetDataBounds = this.renderer.resetDataBounds; this.resetDataBounds(); }; $.jqplot.PyramidAxisRenderer.prototype.resetDataBounds = function() { // Go through all the series attached to this axis and find // the min/max bounds for this axis. var db = this._dataBounds; db.min = null; db.max = null; var temp; for (var i=0; i db.max) || db.max === null) { db.max = temp; } } else { temp = d[j][0]; if ((temp !== null && temp < db.min) || db.min === null) { db.min = temp; } if ((temp !== null && temp > db.max) || db.max === null) { db.max = temp; } } } } }; // called with scope of axis $.jqplot.PyramidAxisRenderer.prototype.draw = function(ctx, plot) { if (this.show) { // populate the axis label and value properties. // createTicks is a method on the renderer, but // call it within the scope of the axis. this.renderer.createTicks.call(this, plot); // fill a div with axes labels in the right direction. // Need to pregenerate each axis to get its bounds and // position it and the labels correctly on the plot. var dim=0; var temp; // Added for theming. if (this._elem) { // Memory Leaks patch //this._elem.empty(); this._elem.emptyForce(); this._elem = null; } this._elem = $(document.createElement('div')); this._elem.addClass('jqplot-axis jqplot-'+this.name); this._elem.css('position', 'absolute'); if (this.name == 'xaxis' || this.name == 'x2axis') { this._elem.width(this._plotDimensions.width); } else { this._elem.height(this._plotDimensions.height); } // create a _label object. this.labelOptions.axis = this.name; this._label = new this.labelRenderer(this.labelOptions); if (this._label.show) { var elem = this._label.draw(ctx, plot); elem.appendTo(this._elem); elem = null; } var t = this._ticks; var tick; for (var i=0; i maxVisibleTicks) { // check for number of ticks we can skip temp = this.numberTicks - 1; for (i=2; i0; i--) { t = new this.tickRenderer(this.tickOptions); t.value = this._ticks[i-1].value + this.tickInterval/2.0; t.label = ''; t.showLabel = false; t.axis = this.name; this._ticks[i].showGridline = false; this._ticks[i].showMark = false; this._ticks.splice(i, 0, t); // temp.push(t); } // merge in the new ticks // for (i=1, l=temp.length; i tumax) { tumin = min - range*(this.padMin - 1); tumax = max + range*(this.padMax - 1); ret = $.jqplot.LinearTickGenerator(tumin, tumax, scalefact); } this.min = ret[0]; this.max = ret[1]; this.numberTicks = ret[2]; this._autoFormatString = ret[3]; this.tickInterval = ret[4]; } else { dim = this._plotDimensions.height; // ticks will be on whole integers like 1, 2, 3, ... or 1, 4, 7, ... min = db.min; max = db.max; s = this._series[0]; this._ticks = []; range = max - min; // if range is a prime, will get only 2 ticks, expand range in that case. if (_primesHash[range]) { range += 1; max += 1; } this.max = max; this.min = min; maxVisibleTicks = Math.round(2.0 + dim/this.tickSpacingFactor); if (range + 1 <= maxVisibleTicks) { this.numberTicks = range + 1; this.tickInterval = 1.0; } else { // figure out a round number of ticks to skip in every interval // range / ti + 1 = nt // ti = range / (nt - 1) for (var i=maxVisibleTicks; i>1; i--) { if (range/(i - 1) === Math.round(range/(i - 1))) { this.numberTicks = i; this.tickInterval = range/(i - 1); break; } } } } if (this._overrideFormatString && this._autoFormatString != '') { this.tickOptions = this.tickOptions || {}; this.tickOptions.formatString = this._autoFormatString; } var labelval; for (i=0; i dim) { dim = temp; } } } if (this.name === 'yMidAxis') { for (i=0; i w) ? dim : w; var temp = dim/2.0 - w/2.0; this._elem.css({'width':dim+'px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css({width: w, left: temp, top: 0}); } } else { dim = dim + w; this._elem.css({'width':dim+'px', right:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } } }; $.jqplot.PyramidAxisRenderer.prototype.pack = function(pos, offsets) { // Add defaults for repacking from resetTickValues function. pos = pos || {}; offsets = offsets || this._offsets; var ticks = this._ticks; var max = this.max; var min = this.min; var offmax = offsets.max; var offmin = offsets.min; var lshow = (this._label == null) ? false : this._label.show; for (var p in pos) { this._elem.css(p, pos[p]); } this._offsets = offsets; // pixellength will be + for x axes and - for y axes becasue pixels always measured from top left. var pixellength = offmax - offmin; var unitlength = max - min; var sl = this._splitLength; // point to unit and unit to point conversions references to Plot DOM element top left corner. if (this._splitAxis) { pixellength -= this._splitLength; // don't know that this one is correct. this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; this.u2p = function(u){ if (u <= 0) { return (u - min) * pixellength / unitlength + offmin; } else { return (u - min) * pixellength / unitlength + offmin + sl; } }; this.series_u2p = function(u){ if (u <= 0) { return (u - min) * pixellength / unitlength; } else { return (u - min) * pixellength / unitlength + sl; } }; // don't know that this one is correct. this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.p2u = function(p){ return (p - offmin) * unitlength / pixellength + min; }; this.u2p = function(u){ return (u - min) * pixellength / unitlength + offmin; }; if (this.name.charAt(0) === 'x'){ this.series_u2p = function(u){ return (u - min) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + min; }; } else { this.series_u2p = function(u){ return (u - max) * pixellength / unitlength; }; this.series_p2u = function(p){ return p * unitlength / pixellength + max; }; } } if (this.show) { if (this.name.charAt(0) === 'x') { for (var i=0; i 0) { shim = -t._textRenderer.height * Math.cos(-t._textRenderer.angle) / 2; } else { shim = -t.getHeight() + t._textRenderer.height * Math.cos(t._textRenderer.angle) / 2; } break; case 'middle': // if (t.angle > 0) { // shim = -t.getHeight()/2 + t._textRenderer.height * Math.sin(-t._textRenderer.angle) / 2; // } // else { // shim = -t.getHeight()/2 - t._textRenderer.height * Math.sin(t._textRenderer.angle) / 2; // } shim = -t.getHeight()/2; break; default: shim = -t.getHeight()/2; break; } } else { shim = -t.getHeight()/2; } var val = this.u2p(t.value) + shim + 'px'; t._elem.css('top', val); t.pack(); } } if (lshow) { var h = this._label._elem.outerHeight(true); if (this.name !== 'yMidAxis') { this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); } if (this.name == 'yaxis') { this._label._elem.css('left', '0px'); } else if (this.name !== 'yMidAxis') { this._label._elem.css('right', '0px'); } this._label.pack(); } } } ticks = null; }; })(jQuery);