merged cont.
[opensuse:yast-rest-service.git] / webservice / public / javascripts / plugin / jqplot.categoryAxisRenderer.js
1 /**
2  * Copyright (c) 2009 Chris Leonello
3  * jqPlot is currently available for use in all personal or commercial projects 
4  * under both the MIT and GPL version 2.0 licenses. This means that you can 
5  * choose the license that best suits your project and use it accordingly. 
6  *
7  * The author would appreciate an email letting him know of any substantial
8  * use of jqPlot.  You can reach the author at: chris dot leonello at gmail 
9  * dot com or see http://www.jqplot.com/info.php .  This is, of course, 
10  * not required.
11  *
12  * If you are feeling kind and generous, consider supporting the project by
13  * making a donation at: http://www.jqplot.com/donate.php .
14  *
15  * Thanks for using jqPlot!
16  * 
17  */
18 (function($) {   
19     /**
20     *  class: $.jqplot.CategoryAxisRenderer
21     *  A plugin for jqPlot to render a category style axis, with equal pixel spacing between y data values of a series.
22     *  This renderer has no options beyond those supplied by the <Axis> class. 
23     *  
24     *  To use this renderer, include the plugin in your source
25     *  > <script type="text/javascript" language="javascript" src="plugins/jqplot.categoryAxisRenderer.js"></script>
26     *  
27     *  and supply the appropriate options to your plot
28     *  
29     *  > {axes:{xaxis:{renderer:$.jqplot.CategoryAxisRenderer}}}
30     **/
31     $.jqplot.CategoryAxisRenderer = function() {
32         $.jqplot.LinearAxisRenderer.call(this);
33     };
34     
35     $.jqplot.CategoryAxisRenderer.prototype = new $.jqplot.LinearAxisRenderer();
36     $.jqplot.CategoryAxisRenderer.prototype.constructor = $.jqplot.CategoryAxisRenderer;
37     
38     $.jqplot.CategoryAxisRenderer.prototype.init = function(options){
39         // prop: tickRenderer
40         // A class of a rendering engine for creating the ticks labels displayed on the plot, 
41         // See <$.jqplot.AxisTickRenderer>.
42         // this.tickRenderer = $.jqplot.AxisTickRenderer;
43         // this.labelRenderer = $.jqplot.AxisLabelRenderer;
44         $.extend(true, this, {tickOptions:{formatString:'%d'}}, options);
45         var db = this._dataBounds;
46         // Go through all the series attached to this axis and find
47         // the min/max bounds for this axis.
48         for (var i=0; i<this._series.length; i++) {
49             var s = this._series[i];
50             var d = s.data;
51             
52             for (var j=0; j<d.length; j++) { 
53                 if (this.name == 'xaxis' || this.name == 'x2axis') {
54                     if (d[j][0] < db.min || db.min == null) {
55                         db.min = d[j][0];
56                     }
57                     if (d[j][0] > db.max || db.max == null) {
58                         db.max = d[j][0];
59                     }
60                 }              
61                 else {
62                     if (d[j][1] < db.min || db.min == null) {
63                         db.min = d[j][1];
64                     }
65                     if (d[j][1] > db.max || db.max == null) {
66                         db.max = d[j][1];
67                     }
68                 }              
69             }
70         }
71     };
72  
73
74     $.jqplot.CategoryAxisRenderer.prototype.createTicks = function() {
75         // we're are operating on an axis here
76         var ticks = this._ticks;
77         var userTicks = this.ticks;
78         var name = this.name;
79         // databounds were set on axis initialization.
80         var db = this._dataBounds;
81         var dim, interval;
82         var min, max;
83         var pos1, pos2;
84         var tt, i;
85
86         // if we already have ticks, use them.
87         if (userTicks.length) {
88             this.min = 0.5;
89             this.max = userTicks.length + 0.5;
90             var range = this.max - this.min;
91             this.numberTicks = 2*userTicks.length + 1;
92             for (i=0; i<userTicks.length; i++){
93                 tt = this.min + 2 * i * range / (this.numberTicks-1);
94                 // need a marker before and after the tick
95                 var t = new this.tickRenderer(this.tickOptions);
96                 t.showLabel = false;
97                 t.showMark = true;
98                 t.setTick(tt, this.name);
99                 this._ticks.push(t);
100                 var t = new this.tickRenderer(this.tickOptions);
101                 t.label = userTicks[i];
102                 t.showLabel = true;
103                 t.showMark = false;
104                 t.showGridline = false;
105                 t.setTick(tt+0.5, this.name);
106                 this._ticks.push(t);
107             }
108             // now add the last tick at the end
109             var t = new this.tickRenderer(this.tickOptions);
110             t.showLabel = false;
111             t.showMark = true;
112             t.setTick(tt+1, this.name);
113             this._ticks.push(t);
114         }
115
116         // we don't have any ticks yet, let's make some!
117         else {
118             if (name == 'xaxis' || name == 'x2axis') {
119                 dim = this._plotDimensions.width;
120             }
121             else {
122                 dim = this._plotDimensions.height;
123             }
124             
125             // if min, max and number of ticks specified, user can't specify interval.
126             if (this.min != null && this.max != null && this.numberTicks != null) {
127                 this.tickInterval = null;
128             }
129             
130             // if max, min, and interval specified and interval won't fit, ignore interval.
131             if (this.min != null && this.max != null && this.tickInterval != null) {
132                 if (parseInt((this.max-this.min)/this.tickInterval, 10) != (this.max-this.min)/this.tickInterval) {
133                     this.tickInterval = null;
134                 }
135             }
136         
137             // find out how many categories are in the lines and collect labels
138             var labels = [];
139             var numcats = 0;
140             var min = 0.5;
141             var max, val;
142             for (var i=0; i<this._series.length; i++) {
143                 var s = this._series[i];
144                 for (var j=0; j<s.data.length; j++) {
145                     if (this.name == 'xaxis' || this.name == 'x2axis') {
146                         val = s.data[j][0];
147                     }
148                     else {
149                         val = s.data[j][1];
150                     }
151                     if ($.inArray(val, labels) == -1) {
152                         numcats += 1;      
153                         labels.push(val);
154                     }
155                 }
156             }
157             
158             // keep a reference to these tick labels to use for redrawing plot (see bug #57)
159             this.ticks = labels;
160             
161             // now bin the data values to the right lables.
162             for (var i=0; i<this._series.length; i++) {
163                 var s = this._series[i];
164                 for (var j=0; j<s.data.length; j++) {
165                     if (this.name == 'xaxis' || this.name == 'x2axis') {
166                         val = s.data[j][0];
167                     }
168                     else {
169                         val = s.data[j][1];
170                     }
171                     // for category axis, force the values into category bins.
172                     // we should have the value in the label array now.
173                     var idx = $.inArray(val, labels)+1;
174                     if (this.name == 'xaxis' || this.name == 'x2axis') {
175                         s.data[j][0] = idx;
176                     }
177                     else {
178                         s.data[j][1] = idx;
179                     }
180                 }
181             }
182         
183             max = numcats + 0.5;
184             if (this.numberTicks == null) {
185                 this.numberTicks = 2*numcats + 1;
186             }
187
188             var range = max - min;
189             this.min = min;
190             this.max = max;
191             var track = 0;
192             
193             // todo: adjust this so more ticks displayed.
194             var maxVisibleTicks = parseInt(3+dim/20, 10);
195             var skip = parseInt(numcats/maxVisibleTicks, 10);
196
197             if (this.tickInterval == null) {
198
199                 this.tickInterval = range / (this.numberTicks-1);
200
201             }
202             // if tickInterval is specified, we will ignore any computed maximum.
203             for (var i=0; i<this.numberTicks; i++){
204                 tt = this.min + i * this.tickInterval;
205                 var t = new this.tickRenderer(this.tickOptions);
206                 // if even tick, it isn't a category, it's a divider
207                 if (i/2 == parseInt(i/2, 10)) {
208                     t.showLabel = false;
209                     t.showMark = true;
210                 }
211                 else {
212                     if (skip>0 && track<skip) {
213                         t.showLabel = false;
214                         track += 1;
215                     }
216                     else {
217                         t.showLabel = true;
218                         track = 0;
219                     } 
220                     t.label = t.formatter(t.formatString, labels[(i-1)/2]);
221                     t.showMark = false;
222                     t.showGridline = false;
223                 }
224                 if (!this.showTicks) {
225                     t.showLabel = false;
226                     t.showMark = false;
227                 }
228                 else if (!this.showTickMarks) {
229                     t.showMark = false;
230                 }
231                 t.setTick(tt, this.name);
232                 this._ticks.push(t);
233             }
234         }
235     };
236     
237     
238 })(jQuery);