/** * Copyright (c) 2009 Chris Leonello * jqPlot 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. * * The author would appreciate an email letting him know of any substantial * use of jqPlot. You can reach the author at: chris dot leonello at gmail * dot com or see http://www.jqplot.com/info.php . This is, of course, * not required. * * If you are feeling kind and generous, consider supporting the project by * making a donation at: http://www.jqplot.com/donate.php . * * Thanks for using jqPlot! * */ (function($) { // class: $.jqplot.MekkoAxisRenderer // An axis renderer for a Mekko chart. // Should be used with a Mekko chart where the mekkoRenderer is used on the series. // Displays the Y axis as a range from 0 to 1 (0 to 100%) and the x axis with a tick // for each series scaled to the sum of all the y values. $.jqplot.MekkoAxisRenderer = function() { }; // called with scope of axis object. $.jqplot.MekkoAxisRenderer.prototype.init = function(options){ // prop: tickMode // How to space the ticks on the axis. // 'bar' will place a tick at the width of each bar. // This is the default for the x axis. // 'even' will place ticks at even intervals. This is // the default for x2 axis and y axis. y axis cannot be changed. this.tickMode; // prop: barLabelRenderer // renderer to use to draw labels under each bar. this.barLabelRenderer = $.jqplot.AxisLabelRenderer; // prop: barLabels // array of labels to put under each bar. this.barLabels = this.barLabels || []; // prop: barLabelOptions // options object to pass to the bar label renderer. this.barLabelOptions = {}; this.tickOptions = $.extend(true, {showGridline:false}, this.tickOptions); this._barLabels = []; $.extend(true, this, options); if (this.name == 'yaxis') { this.tickOptions.formatString = this.tickOptions.formatString || "%d\%"; } var db = this._dataBounds; db.min = 0; // for y axes, scale always go from 0 to 1 (0 to 100%) if (this.name == 'yaxis' || this.name == 'y2axis') { db.max = 100; this.tickMode = 'even'; } // For x axes, scale goes from 0 to sum of all y values. else if (this.name == 'xaxis'){ this.tickMode = (this.tickMode == null) ? 'bar' : this.tickMode; for (var i=0; i'); if (this.name == 'xaxis' || this.name == 'x2axis') { this._elem.width(this._plotDimensions.width); } else { this._elem.height(this._plotDimensions.height); } // draw the axis label // 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); elem.appendTo(this._elem); } var t, tick, elem; if (this.showTicks) { t = this._ticks; for (var i=0; i dim) { dim = temp; } } } if (lshow) { w = this._label._elem.outerWidth(true); h = this._label._elem.outerHeight(true); } if (this.name == 'xaxis') { dim = dim + h; this._elem.css({'height':dim+'px', left:'0px', bottom:'0px'}); } else if (this.name == 'x2axis') { dim = dim + h; this._elem.css({'height':dim+'px', left:'0px', top:'0px'}); } else if (this.name == 'yaxis') { dim = dim + w; this._elem.css({'width':dim+'px', left:'0px', top:'0px'}); if (lshow && this._label.constructor == $.jqplot.AxisLabelRenderer) { this._label._elem.css('width', w+'px'); } } 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'); } } } }; // called with scope of axis $.jqplot.MekkoAxisRenderer.prototype.createTicks = function() { // we're are operating on an axis here var ticks = this._ticks; var userTicks = this.ticks; var name = this.name; // databounds were set on axis initialization. var db = this._dataBounds; var dim, interval; var min, max; var pos1, pos2; var t, tt, i, j; // if we already have ticks, use them. // ticks must be in order of increasing value. if (userTicks.length) { // ticks could be 1D or 2D array of [val, val, ,,,] or [[val, label], [val, label], ...] or mixed for (i=0; i 0) { adj = Math.max(Math.log(min)/Math.LN10, 0.05); } min -= adj; max += adj; } var range = max - min; var rmin, rmax; var temp, prev, curr; var ynumticks = [3,5,6,11,21]; // yaxis divide ticks in nice intervals from 0 to 1. if (this.name == 'yaxis' || this.name == 'y2axis') { this.min = 0; this.max = 100; // user didn't specify number of ticks. if (!this.numberTicks){ if (this.tickInterval) { this.numberTicks = 3 + Math.ceil(range / this.tickInterval); } else { temp = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); for (i=0; i 1) { prev = curr; continue; } else if (curr < 1) { // was prev or is curr closer to one? if (Math.abs(prev - 1) < Math.abs(curr - 1)) { this.numberTicks = ynumticks[i-1]; break; } else { this.numberTicks = ynumticks[i]; break; } } else if (i == ynumticks.length -1) { this.numberTicks = ynumticks[i]; } } this.tickInterval = range / (this.numberTicks - 1); } } // user did specify number of ticks. else { this.tickInterval = range / (this.numberTicks - 1); } for (var i=0; i temp) { t = new this.tickRenderer(this.tickOptions); if (!this.showTicks) { t.showLabel = false; t.showMark = false; } else if (!this.showTickMarks) { t.showMark = false; } t.setTick(this.max, this.name); this._ticks.push(t); } } else if (this.tickMode == 'even') { this.min = 0; this.max = this.max || db.max; // get a desired number of ticks var nt = 2 + Math.ceil((dim-(this.tickSpacing-1))/this.tickSpacing); range = this.max - this.min; this.numberTicks = nt; this.tickInterval = range / (this.numberTicks - 1); for (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': 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); this._label._elem.css('top', offmax - pixellength/2 - h/2 + 'px'); if (this.name == 'yaxis') { this._label._elem.css('left', '0px'); } else { this._label._elem.css('right', '0px'); } this._label.pack(); } } } }; })(jQuery);