revert fix #7522
[g.raphael] / g.bar.overlay.js
1 /*!
2  * g.Raphael 0.51 - Charting library, based on RaphaĆ«l
3  *
4  * Copyright (c) 2009-2012 Dmitry Baranovskiy (http://g.raphaeljs.com)
5  * Licensed under the MIT (http://www.opensource.org/licenses/mit-license.php) license.
6  */
7
8 if (typeof(Raphael) == 'undefined') {
9     // support for seed/simple browser usage
10     importz = imports['seed/importz.js'].importz;
11
12     Raphael = importz('Raphael');
13     Roo = importz('Roo');
14 }
15
16 (function () {
17     
18     function clearAr(ar) {
19         var ret = new Array();
20         //Roo.log(JSON.stringify(ar));
21         for (var i = 0; i < ar.length; i++) {
22             //print(typeof(ar[i]));
23             if (Raphael.is(ar[i], "object")) {
24                 ret.push(clearAr(ar[i]));
25                 continue;
26             }
27             ret.push(parseInt(ar[i]));
28         }
29         return ret;
30     }
31  
32
33 /*\
34  * Paper.vbarchart
35  [ method ]
36  **
37  * Creates a vertical bar chart
38  **
39  > Parameters
40  **
41  - x (number) x coordinate of the chart
42  - y (number) y coordinate of the chart
43  - width (number) width of the chart (respected by all elements in the set)
44  - height (number) height of the chart (respected by all elements in the set)
45  - values (array) values
46  - opts (object) options for the chart
47  o {
48  o type (string) type of endings of the bar. Default: 'square'. Other options are: 'round', 'sharp', 'soft'.
49  o gutter (number)(string) default '20%' (WHAT DOES IT DO?)
50  o vgutter (number)
51  o colors (array) colors be used repeatedly to plot the bars. If multicolumn bar is used each sequence of bars with use a different color.
52  o stacked (boolean) whether or not to tread values as in a stacked bar chart
53  o to
54  o stretch (boolean)
55  o }
56  **
57  = (object) path element of the popup
58  > Usage
59  | r.vbarchart(0, 0, 620, 260, [[76, 70], [67, 71]], {})
60  \*/
61
62  
63     function MVBarchart(paper, x, y, width, height, values, opts) {
64         opts = opts || {};
65         values = clearAr(values);
66        
67         var chartinst = this,
68             chart = paper.set(),
69             bars = paper.set(),
70             covers = paper.set(),
71             barsteps = opts.barsteps || 20,
72             colors = opts.colors || chartinst.colors;
73             
74         
75         opts.axis = opts.axis || "";
76         opts.baroffset = opts.baroffset || 10;
77         opts.asixxheight = opts.asixxheight || 100;
78         opts.asixywidth = opts.asixywidth || 100;
79         opts.axisxlabels = opts.axisxlabels || [];
80         opts.legendheight = opts.legendheight || 80;
81         opts.legends = opts.legends || 100;
82         
83         // background
84         paper.rect(0, 0, width, height).attr({ stroke: "none", fill: (opts.background || "#F0F4F7") });
85 //        background.toBack();
86         
87         // bar border
88         var barwidth = Math.floor((width - x - opts.asixywidth - opts.baroffset) / barsteps);
89         var barheight = height - y - opts.asixxheight - opts.legendheight || 100;
90         var path = ["M", x + 1, y + opts.legendheight, "l", 0, barheight]
91         
92         for (var i = 0; i < barsteps; i++) {
93             path = path.concat(["M", x + (i * barwidth), y + opts.legendheight + 1, "l", barwidth, 0, "l", 0, barheight]);
94         }
95         
96         paper.path(path).attr({ stroke: "#fff", "stroke-width": 2 });
97         
98         var max = 0;
99         
100         values.forEach(function(value,i) {
101             if (!Raphael.is(values[0], "array")) {
102                 value = [value];
103             }
104     
105             value.forEach(function(v,k)  {
106                 max = (v > max) ? v : max;
107             });
108             
109         });
110         
111         values.forEach(function(value,i) {
112             if (!Raphael.is(value, "array")) {
113                 value = [value];
114             }
115             
116             paper.circle(x + (i * 400) + 8, y + 10, 8).attr({ fill: colors[i%colors.length], "stroke": "#fff" });
117             
118             paper.text(x + (i * 400) + 18, y + 8, opts.legends[i%opts.legends.length]).attr({ 
119                 "font-size": "14",
120                 "font-family": "'Fontin Sans', Fontin-Sans, sans-serif",
121                 "font-weight": "bold",
122                 "text-anchor": "start",
123                 fill : "#0C014D"
124             });
125         });
126         
127         //bars
128         var unit = barheight / max;
129         
130         values.forEach(function(value,i) {
131             if (!Raphael.is(values, "array")) {
132                 value = [value];
133             }
134             
135             value.forEach(function(v,k)  {
136                 if(v == 0) {
137                     return;
138                 }
139                 
140                 paper.rect(x + 1 + (k * barwidth) , y + opts.legendheight + 1 + (max - v) * unit, barwidth - 2, v * unit).attr({ stroke: "none", fill: colors[i%colors.length] });
141                 
142                 var indicator_y = y + opts.legendheight + (max - v) * unit - 42;
143                 
144                 if(i == 0) {
145                     indicator_y = y + opts.legendheight - 42;
146                 }
147                 
148                 var fontSize = barsteps > 10 ? 10 : 12;
149                 
150                 paper.rect(x + 1 + (k * barwidth) + 5 , indicator_y, barwidth - 10, 30, 5).attr({ stroke: "none", fill: colors[i%colors.length] });
151                 paper.path(["M", x + 1 + (k * barwidth) + barwidth / 4 + 10, indicator_y + 30, "l", 5, 10, "l", 5, -10]).attr({ stroke: "none", fill: colors[i%colors.length] });
152                 paper.text(x + 1 + (k * barwidth) + barwidth / 2, indicator_y + 14, Roo.util.Format.number(v, 0)).attr({ 
153                     "font-size": fontSize,
154                     "font-family": "'Fontin Sans', Fontin-Sans, sans-serif",
155                     "font-weight": "bold",
156                     fill : "#fff"
157                 });
158             });
159         });
160         
161         var ax = (opts.axis + "").split(/[,\s]+/),
162             axis = paper.set();
163         
164         // right axis
165         +ax[1] && axis.push(
166             chartinst.rightAxis(
167                 width - opts.asixywidth,
168                 height - opts.asixxheight,
169                 height - y - opts.asixxheight - opts.legendheight,
170                 max,
171                 opts.axisystep || 10,
172                 opts.asixywidth,
173                 barsteps,
174                 paper
175             )
176         );
177         
178         // bottom axis
179         +ax[2] && axis.push(
180             chartinst.bottomAxis(
181                 x ,
182                 height - opts.asixxheight,
183                 width,
184                 opts.axisxlabels.length,
185                 opts.axisxlabels,
186                 barwidth,
187                 opts.asixxheight,
188                 paper
189             )
190         );
191         
192         chart.push(bars, covers);
193         chart.bars = bars;
194         chart.covers = covers;
195         return chart;
196     };
197     
198     //inheritance
199     var F = function() {};
200     F.prototype = Raphael.g;
201     MVBarchart.prototype = new F; //prototype reused by hbarchart
202     
203     Raphael.fn.mbarchart = function(x, y, width, height, values, opts) {
204         return new MVBarchart(this, x, y, width, height, values, opts);
205     };
206     
207     MVBarchart.prototype.rightAxis = function (x, y, length, max, steps, asixywidth, barsteps, paper)
208     {
209 //        Roo.log('Right Axis');
210 //        Roo.log([x, y, length, max, steps, asixywidth]);
211         
212         var path = [],
213             color = "#bababa",
214             text = paper.set(),
215             d = Math.ceil(max / steps);
216         
217         var label = 0,
218             dx = length / steps;
219         
220         var Y = y;
221         
222         for(var i = 0; i <= steps; i++) {
223             
224             if(i != 0) {
225                 paper.text(x + (asixywidth / 2), Y + 15, label).attr({ 
226                     "font-size": (barsteps > 10) ? "12" : "14",
227                     "font-family": "'Fontin Sans', Fontin-Sans, sans-serif",
228                     "font-weight": "bold",
229                     "text-anchor": "end",
230                     fill : color
231                 });
232                 path = path.concat(["M", x, Y, "l", (asixywidth / 2), 0]);
233                 
234             }
235             
236             label += d;
237             Y -= dx;
238         }
239         
240         var res = paper.path(path).attr({ stroke: color, "stroke-width": 2 });
241
242         res.text = text;
243         res.all = paper.set([res, text]);
244         res.remove = function () {
245             this.text.remove();
246             this.constructor.prototype.remove.call(this);
247         };
248
249         return res;
250     }
251     
252     MVBarchart.prototype.bottomAxis = function (x, y, length, steps, labels, barwidth, eheight, paper)
253     {
254 //        Roo.log('Bottom Axis');
255 //        Roo.log([x, y, length, steps, labels, barwidth]);
256         
257         var path = ["M", x, y, "l", length, 0],
258             color = "#bababa",
259             text = paper.set(),
260             offset = Math.round(barwidth / 2);
261     
262         labels.forEach(function(v,k)  {
263             paper.text(x + (k * barwidth) + offset, y + (eheight / 2), v).attr({ 
264                 "font-size": (steps > 10) ? "12" : "14",
265                 "font-family": "'Fontin Sans', Fontin-Sans, sans-serif",
266                 "font-weight": "bold",
267                 fill : color
268             });
269         });
270         
271         var res = paper.path(path).attr({ stroke: color, "stroke-width": 2 });
272
273         res.text = text;
274         res.all = paper.set([res, text]);
275         res.remove = function () {
276             this.text.remove();
277             this.constructor.prototype.remove.call(this);
278         };
279
280         return res;
281     }
282     
283 })();