Small layout fixed in report graphics.
[fa-stable.git] / reporting / includes / class.graphic.inc
1 <?php
2 /**
3 *
4 *   graph
5 *   version 1.0
6 *
7 *
8 *
9 * Author: Carlos Reche/Joe Hunt
10 * E-mail: carlosreche@yahoo.com/joe.hunt.consulting@gmail.com
11 * Sorocaba, SP - Brazil/Wellington, New Zealand
12 *
13 * Created: Sep 20, 2004
14 * Last Modification: Sep 20, 2004/Apr 01, 2007
15 *
16 *
17 *
18 *  Authors' comments:
19 *
20 *  graph creates 6 different types of graphics with how many parameters you want. You can
21 *  change the appearance of the graphics in 3 different skins, and you can still cross data from 2 
22 *  graphics in only 1! It's a powerful script, and I recommend you read all the instructions 
23 *  to learn how to use all of this features. Don't worry, it's very simple to use it.
24 *
25 *  This script is free. Please keep the credits.
26 *
27 */
28
29 /**
30
31    INSTRUNCTIONS OF HOW TO USE THIS SCRIPT  (Please, take a minute to read it. It's important!)
32
33
34    NOTE: make sure that your PHP is compiled to work with GD Lib.
35
36 ///// START OF EXAMPLE.PHP /////
37
38 <?php
39
40 require "class.graphics.inc";
41 $pg = new graph;
42
43 $pg->title = "Sex";
44 $pg->type  = "5";
45 $pg->x[0]  = "male";
46 $pg->y[0]  = "50";
47 $pg->x[1]  = "female";
48 $pg->y[1]  = "55";
49 $pg->display();
50 ?>
51
52 In your html file you set it up as:
53 .....
54 <img src="example.php" border="1" />
55 .....
56
57 You can supply extra parameters to display(). Ex. $pg->display("test.png") will save the image to a file.
58 Ex. $pg->display("", true) will paint a border around the image. It might be suitable if you choose to save to
59 file for later presentation.
60
61 ///// END OF EXAMPLE.PHP /////
62
63
64
65    Here is a list of all parameters you may set:
66
67    title      =>  Title of the graphic
68    axis_x     =>  Name of values from Axis X
69    axis_y     =>  Name of values from Axis Y
70    graphic_1  =>  Name of Graphic_1 (only shown if you are gonna cross data from 2 different graphics)
71    graphic_2  =>  Name of Graphic_2 (same comment of above)
72
73    type  =>  Type of graphic (values 1 to 6)
74                 1 => Vertical bars (default)
75                 2 => Horizontal bars
76                 3 => Dots
77                 4 => Lines
78                 5 => Pie
79                 6 => Donut
80
81    skin   => Skin of the graphic (values 1 to 3)
82                 1 => Office (default)
83                 2 => Matrix
84                 3 => Spring
85
86    credits => Only if you want to show my credits in the image. :)
87                 0 => doesn't show (default)
88                 1 => shows
89
90    x[0]  =>  Name of the first parameter in Axis X
91    x[1]  =>  Name of the second parameter in Axis X
92    ... (etc)
93
94    y[0]  =>  Value from "graphic_1" relative for "x[0]"
95    y[1]  =>  Value from "graphic_1" relative for "x[1]"
96    ... (etc)
97
98    z[0]  =>  Value from "graphic_2" relative for "x[0]"
99    z[1]  =>  Value from "graphic_2" relative for "x[1]"
100    ... (etc)
101
102
103    NOTE: You can't cross data between graphics if you use "pie" or "donut" graphic. Values for "z"
104    won't be considerated.
105
106    That's all! Hope you make a good use of it!
107    It would be nice to receive feedback from others users. All comments are welcome!
108
109    Regards,
110
111    Carlos Reche
112
113 */
114
115 class graph 
116 {
117
118     var $x;
119     var $y;
120     var $z;
121
122     var $title;
123     var $axis_x;
124     var $axis_y;
125     var $graphic_1;
126     var $graphic_2;
127     var $type = 1;
128     var $skin = 1;
129     var $credits = 0;
130     var $latin_notation;
131
132     var $width;
133     var $height;
134     var $height_title;
135     var $alternate_x;
136
137         var $size = 2;
138         var $tsize = 5;
139
140     var $total_parameters;
141     var $sum_total;
142     var $biggest_value;
143     var $biggest_parameter;
144     var $available_types;
145     var $dec1 = 0;
146     var $dec2 = 0;
147     var $h3d = 15; // 3D height
148         var $built_in = true;
149         var $fontfile = "";
150         var $encoding;
151         
152     function graph()
153     {
154                 $this->encoding = $_SESSION['language']->encoding;
155                 $path = dirname(__FILE__).'/../fonts/';
156
157                 // If you use utf-8 encoding you have to download and install FreeSans.ttf font.
158                 // It is not bundled with application due to its size.
159                 $this->fontfile = $this->encoding=='UTF-8' ? $path.'FreeSans.ttf' : $path.'LiberationSans-Regular.ttf';
160
161         $this->x = $this->y = $this->z = array();
162         $this->biggest_x        = NULL;
163         $this->biggest_y        = NULL;
164         $this->alternate_x      = false;
165         $this->graphic_2_exists = false;
166         $this->total_parameters = 0;
167         $this->sum_total        = 1;
168                 $this->latin_notation   = false;
169     }
170
171
172     function display($save="", $border=false)
173     {
174         $this->legend_exists        = (preg_match("/(5|6)/", $this->type)) ? true : false;
175         $this->biggest_graphic_name = (strlen($this->graphic_1) > strlen($this->graphic_2)) ? $this->graphic_1 : $this->graphic_2;
176         $this->height_title         = (!empty($this->title)) ? ($this->string_height($this->tsize) + 15) : 0;
177         $this->space_between_bars   = ($this->type == 1) ? 40 : 30;
178         $this->space_between_dots   = 40;
179         $this->higher_value         = 0;
180         $this->higher_value_str     = 0;
181
182         $this->width               = 0;
183         $this->height              = 0;
184         $this->graphic_area_width  = 0;
185         $this->graphic_area_height = 0;
186         $this->graphic_area_x1     = 30;
187         $this->graphic_area_y1     = 20 + $this->height_title;
188         $this->graphic_area_x2     = $this->graphic_area_x1 + $this->graphic_area_width;
189         $this->graphic_area_y2     = $this->graphic_area_y1 + $this->graphic_area_height;
190
191                 if (count($this->z) && (preg_match("/(1|2|3|4)/", $this->type)))
192             $this->graphic_2_exists = true;
193         $this->total_parameters    = count($this->x);
194                 for ($i = 0; $i < $this->total_parameters; $i++)
195                 {
196                         if (strlen($this->x[$i]) > strlen($this->biggest_x))
197                 $this->biggest_x = $this->x[$i];
198                         if ($this->y[$i] > $this->biggest_y)
199                 $this->biggest_y = number_format(round($this->y[$i], 1), 1, ".", "");
200             if ($this->graphic_2_exists)    
201             {
202                 if (isset($this->z[$i]) && $this->z[$i] > $this->biggest_y)
203                         $this->biggest_y = number_format(round($this->z[$i], 1), 1, ".", "");
204             }           
205         }
206
207         if (($this->graphic_2_exists == true)  &&  ((!empty($this->graphic_1)) || (!empty($this->graphic_2))))
208         {
209             $this->legend_exists = true;
210         }
211
212         $this->sum_total           = array_sum($this->y);
213         if ($this->sum_total == 0)
214                 $this->sum_total = 1;
215         $this->space_between_bars += ($this->graphic_2_exists == true) ? 10 : 0;
216
217         $this->calculate_higher_value();
218         $this->calculate_width();
219         $this->calculate_height();
220
221         $this->create_graphic($save, $border);
222     }
223
224     function create_graphic($save="", $border=false)
225     {
226         $size = 3;
227         $this->img = imagecreatetruecolor($this->width, $this->height);
228
229         $this->load_color_palette();
230
231         // Fill background
232         imagefill($this->img, 0, 0, $this->color['background']);
233         //imagefilledrectangle($this->img, 0, 0, $this->width, $this->height, $this->color['background']);
234         //if ($border)
235         //      imagerectangle($this->img, 0, 0, $this->width-1, $this->height-1, imagecolorallocate($this->img, 100, 150, 200));
236
237         // Draw title
238         if (!empty($this->title))
239         {
240             $center = ($this->width / 2) - ($this->string_width($this->title, $this->tsize) / 2);
241             $this->_imagestring($this->img, $this->tsize, $center, 10, $this->title, $this->color['title']);
242         }
243
244
245         // Draw axis and background lines for "vertical bars", "dots" and "lines"
246         if (preg_match("/^(1|3|4)$/", $this->type))
247         {
248             if ($this->legend_exists == true)
249             {
250                 $this->draw_legend();
251             }
252
253             $higher_value_y    = $this->graphic_area_y1 + (0.1 * $this->graphic_area_height);
254             $higher_value_size = 0.9 * $this->graphic_area_height;
255
256             $less  = 7 * strlen($this->higher_value_str);
257
258             imageline($this->img, $this->graphic_area_x1, $higher_value_y, $this->graphic_area_x2, $higher_value_y, $this->color['bg_lines']);
259             $this->_imagestring($this->img, $this->size, ($this->graphic_area_x1-$less-7), ($higher_value_y-7), $this->higher_value_str, $this->color['axis_values']);
260
261             for ($i = 1; $i < 10; $i++)
262             {
263                 $dec_y = $i * ($higher_value_size / 10);
264                 $x1 = $this->graphic_area_x1;
265                 $y1 = $this->graphic_area_y2 - $dec_y;
266                 $x2 = $this->graphic_area_x2;
267                 $y2 = $this->graphic_area_y2 - $dec_y;
268
269                 imageline($this->img, $x1, $y1, $x2, $y2, $this->color['bg_lines']);
270                 if ($i % 2 == 0) 
271                 {
272                     $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
273                     $less = 7 * strlen($value);
274                     $this->_imagestring($this->img, $this->size, ($x1-$less-7), ($y2-7), $value, $this->color['axis_values']);
275                 }
276             }
277
278             // Axis X
279             $this->_imagestring($this->img, $this->size, $this->graphic_area_x2+10, $this->graphic_area_y2+3, $this->axis_x, $this->color['title']);
280             imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
281             // Axis Y
282             $this->_imagestring($this->img, $this->size, 20, $this->graphic_area_y1-20, $this->axis_y, $this->color['title']);
283             imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
284         }
285
286
287         // Draw axis and background lines for "horizontal bars"
288         else if ($this->type == 2)
289         {
290             if ($this->legend_exists == true)
291             {
292                 $this->draw_legend();
293             }
294
295             $higher_value_x    = $this->graphic_area_x2 - (0.2 * $this->graphic_area_width);
296             $higher_value_size = 0.8 * $this->graphic_area_width;
297
298             imageline($this->img, ($this->graphic_area_x1+$higher_value_size), $this->graphic_area_y1, ($this->graphic_area_x1+$higher_value_size), $this->graphic_area_y2, $this->color['bg_lines']);
299             $this->_imagestring($this->img, $this->size, (($this->graphic_area_x1+$higher_value_size) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2+2), $this->higher_value_str, $this->color['axis_values']);
300
301             for ($i = 1, $alt = 15; $i < 10; $i++)
302             {
303                 $dec_x = number_format(round($i * ($higher_value_size  / 10), 1), 1, ".", "");
304
305                 imageline($this->img, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y1, ($this->graphic_area_x1+$dec_x), $this->graphic_area_y2, $this->color['bg_lines']);
306                 if ($i % 2 == 0) 
307                 {
308                     $alt   = (strlen($this->biggest_y) > 4 && $alt != 15) ? 15 : 2;
309                     $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
310                     $this->_imagestring($this->img, $this->size, (($this->graphic_area_x1+$dec_x) - ($this->string_width($this->higher_value, $this->size)/2)), ($this->graphic_area_y2), $value, $this->color['axis_values'], $alt);
311                 }
312             }
313
314             // Axis X
315             $this->_imagestring($this->img, $this->size, ($this->graphic_area_x2+10), ($this->graphic_area_y2+3), $this->axis_y, $this->color['title']);
316             imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
317             // Axis Y
318             $this->_imagestring($this->img, $this->size, 20, ($this->graphic_area_y1-20), $this->axis_x, $this->color['title']);
319             imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
320         }
321
322
323         // Draw legend box for "pie" or "donut"
324         else if (preg_match("/^(5|6)$/", $this->type))
325         {
326             $this->draw_legend();
327         }
328
329
330
331         /**
332         * Draw graphic: VERTICAL BARS
333         */
334         if ($this->type == 1)
335         {
336             $num = 1;
337             $x   = $this->graphic_area_x1 + 20;
338
339             foreach ($this->x as $i => $parameter)
340             {
341                 if (isset($this->z[$i])) 
342                 {
343                     $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
344                     $x1   = $x + 10;
345                     $y1   = ($this->graphic_area_y2 - $size) + 1;
346                     $x2   = $x1 + 20;
347                     $y2   = $this->graphic_area_y2 - 1;
348                     imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_2_shadow']);
349                     imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_2_shadow']);
350                     imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_2_shadow']);
351                     imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
352                 }
353
354                 $size = round($this->y[$i] * $higher_value_size / $this->higher_value);
355                 $alt  = (($num % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
356                 $x1   = $x;
357                 $y1   = ($this->graphic_area_y2 - $size) + 1;
358                 $x2   = $x1 + 20;
359                 $y2   = $this->graphic_area_y2 - 1;
360                 $x   += $this->space_between_bars;
361                 $num++;
362
363                 imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_shadow']);
364                 imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_shadow']);
365                 imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_shadow']);
366                 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
367                 $this->_imagestring($this->img, $this->size, ((($x1+$x2)/2) - (strlen($parameter)*7/2)), ($y2+2), $parameter, $this->color['axis_values'], $alt);
368             }
369         }
370
371
372         /**
373         * Draw graphic: HORIZONTAL BARS
374         */
375         else if ($this->type == 2)
376         {
377             $y = 10;
378
379             foreach ($this->x as $i => $parameter)
380             {
381                 if (isset($this->z[$i])) 
382                 {
383                     $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
384                     $x1   = $this->graphic_area_x1 + 1;
385                     $y1   = $this->graphic_area_y1 + $y + 10;
386                     $x2   = $x1 + $size;
387                     $y2   = $y1 + 15;
388                     imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_2_shadow']);
389                     imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_2_shadow']);
390                     imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_2_shadow']);
391                     imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
392                     $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+7), $this->number_formated($this->z[$i], $this->dec2), $this->color['bars_2_shadow']);
393                 }
394
395                 $size = round(($this->y[$i] / $this->higher_value) * $higher_value_size);
396                 $x1   = $this->graphic_area_x1 + 1;
397                 $y1   = $this->graphic_area_y1 + $y;
398                 $x2   = $x1 + $size;
399                 $y2   = $y1 + 15;
400                 $y   += $this->space_between_bars;
401
402                 imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_shadow']);
403                 imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_shadow']);
404                 imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_shadow']);
405                 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
406                 $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+2), $this->number_formated($this->y[$i], $this->dec2), $this->color['bars_shadow']);
407
408                 //$this->_imagestring($this->img, $this->size, ($x1 - ((strlen($parameter)*7)+7)), ($y1+2), $parameter, $this->color['axis_values']);
409                 $this->_imagestring($this->img, $this->size, 30, ($y1+2), $parameter, $this->color['axis_values']);
410             }
411         }
412
413
414         /**
415         * Draw graphic: DOTS or LINE
416         */
417         else if (preg_match("/^(3|4)$/", $this->type))
418         {
419
420             $x[0] = $this->graphic_area_x1+1;
421
422             foreach ($this->x as $i => $parameter)
423             {
424                 if ($this->graphic_2_exists == true) 
425                 {
426                     $size  = round($this->z[$i] * $higher_value_size / $this->higher_value);
427                     $z[$i] = $this->graphic_area_y2 - $size;
428                 }
429
430                 $alt   = (($i % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
431                 $size  = round($this->y[$i] * $higher_value_size / $this->higher_value);
432                 $y[$i] = $this->graphic_area_y2 - $size;
433
434                 if ($i != 0) 
435                 {
436                     imageline($this->img, $x[$i], ($this->graphic_area_y1+10), $x[$i], ($this->graphic_area_y2-1), $this->color['bg_lines']);
437                 }
438                 $this->_imagestring($this->img, $this->size, ($x[$i] - (strlen($parameter)*7/2 )), ($this->graphic_area_y2+2), $parameter, $this->color['axis_values'], $alt);
439
440                 $x[$i+1] = $x[$i] + 40;
441             }
442
443             foreach ($x as $i => $value_x)
444             {
445                 if ($this->graphic_2_exists == true)
446                 {
447                     if (isset($z[$i+1])) 
448                     {
449                         // Draw lines
450                         if ($this->type == 4)
451                         {
452                             imageline($this->img, $x[$i], $z[$i], $x[$i+1], $z[$i+1], $this->color['line_2']);
453                             imageline($this->img, $x[$i], ($z[$i]+1), $x[$i+1], ($z[$i+1]+1), $this->color['line_2']);
454                         }
455                         imagefilledrectangle($this->img, $x[$i]-1, $z[$i]-1, $x[$i]+2, $z[$i]+2, $this->color['line_2']);
456                     }
457                     else 
458                     { // Draw last dot
459                         imagefilledrectangle($this->img, $x[$i-1]-1, $z[$i-1]-1, $x[$i-1]+2, $z[$i-1]+2, $this->color['line_2']);
460                     }
461                 }
462
463                 if (count($y) > 1)
464                 {
465                     if (isset($y[$i+1])) 
466                     {
467                         // Draw lines
468                         if ($this->type == 4)
469                         {
470                             imageline($this->img, $x[$i], $y[$i], $x[$i+1], $y[$i+1], $this->color['line']);
471                             imageline($this->img, $x[$i], ($y[$i]+1), $x[$i+1], ($y[$i+1]+1), $this->color['line']);
472                         }
473                         imagefilledrectangle($this->img, $x[$i]-1, $y[$i]-1, $x[$i]+2, $y[$i]+2, $this->color['line']);
474                     }
475                     else 
476                     { // Draw last dot
477                         imagefilledrectangle($this->img, $x[$i-1]-1, $y[$i-1]-1, $x[$i-1]+2, $y[$i-1]+2, $this->color['line']);
478                     }
479                 }
480
481             }
482         }
483
484
485         /**
486         * Draw graphic: PIE or DONUT
487         */
488         else if (preg_match("/^(5|6)$/", $this->type))
489         {
490             $center_x = ($this->graphic_area_x1 + $this->graphic_area_x2) / 2;
491             $center_y = ($this->graphic_area_y1 + $this->graphic_area_y2) / 2;
492             $width    = $this->graphic_area_width;
493             $height   = $this->graphic_area_height;
494             $start    = 0;
495             $sizes    = array();
496
497             foreach ($this->x as $i => $parameter)
498             {
499                 $size    = $this->y[$i] * 360 / $this->sum_total;
500                                 $size = round2($size, 0);
501                 $sizes[] = $size;
502                 $start  += $size;
503             }
504             $start = 270;
505
506             // Draw PIE
507             if ($this->type == 5)
508             {
509                 // Draw shadow
510                 foreach ($sizes as $i => $size)
511                 {
512                     $num_color = $i + 1;
513                     while ($num_color > 7) 
514                     {
515                         $num_color -= 5;
516                     }
517                     $color = 'arc_' . $num_color . '_shadow';
518
519                     for ($i = $this->h3d; $i >= 0; $i--)
520                     {
521                         //imagearc($this->img, $center_x, ($center_y+$i), $width, $height, $start, ($start+$size), $this->color[$color]);
522                         if ($size >= 1)
523                                 imagefilledarc($this->img, $center_x, ($center_y+$i), $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_NOFILL);
524                     }
525                     $start += $size;
526                 }
527
528                 $start = 270;
529
530                 // Draw pieces
531                 foreach ($sizes as $i => $size)
532                 {
533                     $num_color = $i + 1;
534                     while ($num_color > 7) 
535                     {
536                         $num_color -= 5;
537                     }
538                     $color = 'arc_' . $num_color;
539                     if ($size >= 1)
540                         imagefilledarc($this->img, $center_x, $center_y, ($width+2), ($height+2), $start, ($start+$size), $this->color[$color], IMG_ARC_EDGED);
541                     $start += $size;
542                 }
543             }
544
545             // Draw DONUT
546             else if ($this->type == 6)
547             {
548                 foreach ($sizes as $i => $size)
549                 {
550                     $num_color = $i + 1;
551                     while ($num_color > 7) 
552                     {
553                         $num_color -= 5;
554                     }
555                     $color        = 'arc_' . $num_color;
556                     $color_shadow = 'arc_' . $num_color . '_shadow';
557                     if ($size >= 1)
558                         imagefilledarc($this->img, $center_x, $center_y, $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_PIE);
559                     $start += $size;
560                 }
561                 imagefilledarc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['background'], IMG_ARC_PIE);
562                 imagearc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['bg_legend']);
563                 imagearc($this->img, $center_x, $center_y, ($width+1), ($height+1), 0, 360, $this->color['bg_legend']);
564             }
565         }
566
567
568         if ($this->credits == true) 
569         {
570             $this->draw_credits();
571         }
572                 if ($save != "")
573                         imagepng($this->img, $save);
574                 else
575                 {
576                 header('Content-type: image/png');
577                 imagepng($this->img);
578         }       
579         imagedestroy($this->img);
580     }
581
582     function calculate_width()
583     {
584         switch ($this->type)
585         {
586             // Vertical bars
587             case 1:
588                 $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->tsize) + 25) : 0;
589                 $this->graphic_area_width = ($this->space_between_bars * $this->total_parameters) + 30;
590                 $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
591                 $this->width += $this->graphic_area_x1 + 20;
592                 $this->width += ($this->legend_exists == true) ? 50 : ((7 * strlen($this->axis_x)) + 10);
593                 break;
594
595             // Horizontal bars
596             case 2:
597                 $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
598                 $this->graphic_area_width = ($this->string_width($this->higher_value_str, $this->size) > 50) ? (5 * ($this->string_width($this->higher_value_str, $this->size)) * 0.85) : 200;
599                 $this->graphic_area_x1 += 7 * strlen($this->biggest_x);
600                 $this->width += ($this->legend_exists == true) ? 60 : ((7 * strlen($this->axis_y)) + 30);
601                 $this->width += $this->graphic_area_x1;
602                 break;
603
604             // Dots
605             case 3:
606                 $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
607                 $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
608                 $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
609                 $this->width += $this->graphic_area_x1 + 20;
610                 $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 30);
611                 break;
612
613             // Lines
614             case 4:
615                 $this->legend_box_width   = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
616                 $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
617                 $this->graphic_area_x1   += $this->string_width(($this->higher_value_str), $this->size);
618                 $this->width += $this->graphic_area_x1 + 20;
619                 $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 30);
620                 break;
621
622             // Pie
623             case 5:
624                 $this->legend_box_width   = $this->string_width($this->biggest_x, $this->size) + 85;
625                 $this->graphic_area_width = 200;
626                 $this->width += 90;
627                 break;
628
629             // Donut
630             case 6:
631                 $this->legend_box_width   = $this->string_width($this->biggest_x, $this->size) + 85;
632                 $this->graphic_area_width = 180;
633                 $this->width += 90;
634                 break;
635         }
636
637         $this->graphic_area_width = max($this->graphic_area_width, $this->string_width($this->title, $this->size));
638         $this->width += $this->graphic_area_width;
639         $this->width += $this->legend_box_width;
640
641
642         $this->graphic_area_x2 = $this->graphic_area_x1 + $this->graphic_area_width;
643         $this->legend_box_x1   = $this->graphic_area_x2 + 40;
644         $this->legend_box_x2   = $this->legend_box_x1 + $this->legend_box_width;
645     }
646
647     function calculate_height()
648     {
649         switch ($this->type)
650         {
651             // Vertical bars
652             case 1:
653                 $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
654                 $this->graphic_area_height = 150;
655                 $this->height += 65;
656                 break;
657
658             // Horizontal bars
659             case 2:
660                 $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
661                 $this->graphic_area_height = ($this->space_between_bars * $this->total_parameters) + 10;
662                 $this->height += 65;
663                 break;
664
665             // Dots
666             case 3:
667                 $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
668                 $this->graphic_area_height = 150;
669                 $this->height += 65;
670                 break;
671
672             // Lines
673             case 4:
674                 $this->legend_box_height   = ($this->graphic_2_exists == true) ? 40 : 0;
675                 $this->graphic_area_height = 150;
676                 $this->height += 65;
677                 break;
678
679             // Pie
680             case 5:
681                 $this->legend_box_height   = (!empty($this->axis_x)) ? 30 : 5;
682                 $this->legend_box_height  += (14 * $this->total_parameters);
683                 $this->graphic_area_height = 150;
684                 $this->height += 50;
685                 break;
686
687             // Donut
688             case 6:
689                 $this->legend_box_height   = (!empty($this->axis_x)) ? 30 : 5;
690                 $this->legend_box_height  += (14 * $this->total_parameters);
691                 $this->graphic_area_height = 180;
692                 $this->height += 50;
693                 break;
694         }
695
696         $this->height += $this->height_title;
697         $this->height += ($this->legend_box_height > $this->graphic_area_height) ? ($this->legend_box_height - $this->graphic_area_height) : 0;
698         $this->height += $this->graphic_area_height;
699
700         $this->graphic_area_y2 = $this->graphic_area_y1 + $this->graphic_area_height;
701         $this->legend_box_y1   = $this->graphic_area_y1 + 10;
702         $this->legend_box_y2   = $this->legend_box_y1 + $this->legend_box_height;
703     }
704
705     function draw_legend()
706     {
707         $x1 = $this->legend_box_x1;
708         $y1 = $this->legend_box_y1;
709         $x2 = $this->legend_box_x2;
710         $y2 = $this->legend_box_y2;
711
712         imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bg_legend']);
713
714         $x = $x1 + 5;
715         $y = $y1 + 5;
716
717
718         // Draw legend values for VERTICAL BARS, HORIZONTAL BARS, DOTS and LINES
719         if (preg_match("/^(1|2|3|4)$/", $this->type))
720         {
721             $color_1 = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars']   : $this->color['line'];
722             $color_2 = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars_2'] : $this->color['line_2'];
723
724             imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_1);
725             imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
726             $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $this->graphic_1, $this->color['axis_values']);
727             $y += 20;
728             imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_2);
729             imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
730             $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $this->graphic_2, $this->color['axis_values']);
731         }
732
733         // Draw legend values for PIE or DONUT
734         else if (preg_match("/^(5|6)$/", $this->type))
735         {
736             if (!empty($this->axis_x))
737             {
738                 $this->_imagestring($this->img, $this->size, ((($x1+$x2)/2) - (strlen($this->axis_x)*7/2)), $y, 
739                         $this->axis_x." (".$this->graphic_1.")", $this->color['title']);
740                 $y += 25;
741             }
742
743             $num = 1;
744
745             foreach ($this->x as $i => $parameter)
746             {
747                 while ($num > 7) 
748                 {
749                     $num -= 5;
750                 }
751                 $color = 'arc_' . $num;
752
753                 $percent = number_format(round(($this->y[$i] * 100 / $this->sum_total), 2), 2, ".", "") . ' %';
754                 $less    = (strlen($percent) * 7);
755
756                 if ($num != 1) 
757                 {
758                     imageline($this->img, ($x1+15), ($y-2), ($x2-5), ($y-2), $this->color['bg_lines']);
759                 }
760                 imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color[$color]);
761                 imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
762                 $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $parameter, $this->color['axis_values']);
763                 $this->_imagestring($this->img, $this->size, ($x2-$less), ($y-2), $percent, $this->color['axis_values']);
764                 $y += 14;
765                 $num++;
766             }
767         }
768     }
769
770
771     function string_width($string, $size) 
772     {
773         $single_width = $size + 4;
774         return $single_width * strlen($string);
775     }
776
777     function string_height($size) 
778     {
779         if ($size <= 1) 
780         {
781             $height = 8;
782         } 
783         else if ($size <= 3) 
784         {
785             $height = 12;
786         } 
787         else if ($size >= 4) 
788         {
789             $height = 14;
790         }
791         return $height;
792     }
793
794     function calculate_higher_value() 
795     {
796         $digits   = strlen(round($this->biggest_y));
797         $interval = pow(10, ($digits-1));
798         $this->higher_value     = round(($this->biggest_y - ($this->biggest_y % $interval) + $interval), 1);
799         $this->higher_value_str = $this->number_formated($this->higher_value, $this->dec1);
800     }
801
802     function number_formated($number, $dec_size = 1)
803     {
804         if ($this->latin_notation == true) 
805             return number_format(round($number, $dec_size), $dec_size, ",", ".");
806         return number_format(round($number, $dec_size), $dec_size, ".", ",");
807     }
808
809     function number_float($number)
810     {
811         if ($this->latin_notation == true) 
812             $number = str_replace(".", "", $number);
813         return (float)str_replace(",", "", $number);
814     }
815
816
817     function draw_credits() 
818     {
819         $this->_imagestring($this->img, $this->size - 2, ($this->width-120), ($this->height-10), "Powered by Carlos Reche", $this->color['title']);
820     }
821
822
823     function load_color_palette()
824     {
825         switch ($this->skin)
826         {
827             // Office
828             case 1:
829                 //$this->color['title']       = imagecolorallocate($this->img,  50,  50,  50);
830                 $this->color['title']       = imagecolorallocate($this->img,  40,  70,  130);
831                 //$this->color['background']  = imagecolorallocate($this->img, 238, 255, 238);
832                 $this->color['background']  = imagecolorallocate($this->img, 255, 255, 255);
833                 $this->color['axis_values'] = imagecolorallocate($this->img,  50,  50,  50);
834                 $this->color['axis_line']   = imagecolorallocate($this->img, 100, 100, 100);
835                 $this->color['bg_lines']    = imagecolorallocate($this->img, 220, 220, 220);
836                 $this->color['bg_legend']   = imagecolorallocate($this->img, 255, 255, 255);
837
838                 if (preg_match("/^(1|2)$/", $this->type))
839                 {
840                     $this->color['bars']          = imagecolorallocate($this->img, 100, 150, 200);
841                     $this->color['bars_shadow']   = imagecolorallocate($this->img,  50, 100, 150);
842                     $this->color['bars_2']        = imagecolorallocate($this->img, 200, 250, 150);
843                     $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 120, 170,  70);
844                 }
845                 else if (preg_match("/^(3|4)$/", $this->type))
846                 {
847                     $this->color['line']   = imagecolorallocate($this->img, 100, 150, 200);
848                     $this->color['line_2'] = imagecolorallocate($this->img, 230, 100, 100);
849                 }
850                 else if (preg_match("/^(5|6)$/", $this->type))
851                 {
852                     $this->color['arc_1']        = imagecolorallocate($this->img, 255, 150,   0);
853                     $this->color['arc_2']        = imagecolorallocate($this->img, 150,   0, 255);
854                     $this->color['arc_3']        = imagecolorallocate($this->img,   0, 255, 255);
855                     $this->color['arc_4']        = imagecolorallocate($this->img, 255,   0,   0);
856                     $this->color['arc_5']        = imagecolorallocate($this->img,   0, 255,   0);
857                     $this->color['arc_6']        = imagecolorallocate($this->img,   0,   0, 255);
858                     $this->color['arc_7']        = imagecolorallocate($this->img, 255, 255,   0);
859                     $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 127,  75,   0);
860                     $this->color['arc_2_shadow'] = imagecolorallocate($this->img,  75,   0, 127);
861                     $this->color['arc_3_shadow'] = imagecolorallocate($this->img,   0, 127, 127);
862                     $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 127,   0,   0);
863                     $this->color['arc_5_shadow'] = imagecolorallocate($this->img,   0, 127,   0);
864                     $this->color['arc_6_shadow'] = imagecolorallocate($this->img,   0,   0, 127);
865                     $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 127, 127,   0);
866                 }
867                 break;
868
869             // Matrix
870             case 2:
871                 $this->color['title']       = imagecolorallocate($this->img, 255, 255, 255);
872                 $this->color['background']  = imagecolorallocate($this->img,   0,   0,   0);
873                 $this->color['axis_values'] = imagecolorallocate($this->img,   0, 230,   0);
874                 $this->color['axis_line']   = imagecolorallocate($this->img,   0, 200,   0);
875                 $this->color['bg_lines']    = imagecolorallocate($this->img, 100, 100, 100);
876                 $this->color['bg_legend']   = imagecolorallocate($this->img,  70,  70,  70);
877
878                 if (preg_match("/^(1|2)$/", $this->type))
879                 {
880                     $this->color['bars']          = imagecolorallocate($this->img,  50, 200,  50);
881                     $this->color['bars_shadow']   = imagecolorallocate($this->img,   0, 150,   0);
882                     $this->color['bars_2']        = imagecolorallocate($this->img, 255, 255, 255);
883                     $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 220, 220, 220);
884                 }
885                 else if (preg_match("/^(3|4)$/", $this->type))
886                 {
887                     $this->color['line']   = imagecolorallocate($this->img, 220, 220, 220);
888                     $this->color['line_2'] = imagecolorallocate($this->img,   0, 180,   0);
889                 }
890                 else if (preg_match("/^(5|6)$/", $this->type))
891                 {
892                     $this->color['arc_1']        = imagecolorallocate($this->img, 255, 255, 255);
893                     $this->color['arc_2']        = imagecolorallocate($this->img, 200, 220, 200);
894                     $this->color['arc_3']        = imagecolorallocate($this->img, 160, 200, 160);
895                     $this->color['arc_4']        = imagecolorallocate($this->img, 135, 180, 135);
896                     $this->color['arc_5']        = imagecolorallocate($this->img, 115, 160, 115);
897                     $this->color['arc_6']        = imagecolorallocate($this->img, 100, 140, 100);
898                     $this->color['arc_7']        = imagecolorallocate($this->img,  90, 120,  90);
899                     $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 127, 127, 127);
900                     $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 100, 110, 100);
901                     $this->color['arc_3_shadow'] = imagecolorallocate($this->img,  80, 100,  80);
902                     $this->color['arc_4_shadow'] = imagecolorallocate($this->img,  67,  90,  67);
903                     $this->color['arc_5_shadow'] = imagecolorallocate($this->img,  57,  80,  57);
904                     $this->color['arc_6_shadow'] = imagecolorallocate($this->img,  50,  70,  50);
905                     $this->color['arc_7_shadow'] = imagecolorallocate($this->img,  45,  60,  45);
906                 }
907                 break;
908
909
910             // Spring
911             case 3:
912                 $this->color['title']       = imagecolorallocate($this->img, 250,  50,  50);
913                 //$this->color['background']  = imagecolorallocate($this->img, 250, 250, 220);
914                 $this->color['background']  = imagecolorallocate($this->img, 255, 255, 255);
915                 $this->color['axis_values'] = imagecolorallocate($this->img,  50, 150,  50);
916                 $this->color['axis_line']   = imagecolorallocate($this->img,  50, 100,  50);
917                 $this->color['bg_lines']    = imagecolorallocate($this->img, 200, 224, 180);
918                 //$this->color['bg_legend']   = imagecolorallocate($this->img, 230, 230, 200);
919                 $this->color['bg_legend']   = imagecolorallocate($this->img, 255, 255, 255);
920
921                 if (preg_match("/^(1|2)$/", $this->type))
922                 {
923                     $this->color['bars']          = imagecolorallocate($this->img, 255, 170,  80);
924                     $this->color['bars_shadow']   = imagecolorallocate($this->img, 200, 120,  30);
925                     $this->color['bars_2']        = imagecolorallocate($this->img, 250, 230,  80);
926                     $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 180, 150,   0);
927                 }
928                 else if (preg_match("/^(3|4)$/", $this->type))
929                 {
930                     $this->color['line']   = imagecolorallocate($this->img, 230, 100,   0);
931                     $this->color['line_2'] = imagecolorallocate($this->img, 220, 200,  50);
932                 }
933                 else if (preg_match("/^(5|6)$/", $this->type))
934                 {
935                     $this->color['arc_1']        = imagecolorallocate($this->img, 100, 150, 200);
936                     $this->color['arc_2']        = imagecolorallocate($this->img, 200, 250, 150);
937                     $this->color['arc_3']        = imagecolorallocate($this->img, 250, 200, 150);
938                     $this->color['arc_4']        = imagecolorallocate($this->img, 250, 150, 150);
939                     $this->color['arc_5']        = imagecolorallocate($this->img, 250, 250, 150);
940                     $this->color['arc_6']        = imagecolorallocate($this->img, 230, 180, 250);
941                     $this->color['arc_7']        = imagecolorallocate($this->img, 200, 200, 150);
942                     $this->color['arc_1_shadow'] = imagecolorallocate($this->img,  50,  75, 100);
943                     $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 100, 125,  75);
944                     $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 125, 100,  75);
945                     $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 125,  75,  75);
946                     $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 125, 125,  75);
947                     $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 115,  90, 125);
948                     $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 100, 100,  75);
949                 }
950                 break;
951
952         }
953     }
954
955     function _imagestring($img, $size, $x, $y, $string, $col, $alt=0)
956     {
957         if ($alt && strlen($string) > 12)
958                 $string = substr($string, 0, 12);
959
960                 if ($this->encoding != 'UTF-8') {
961                         if (function_exists('iconv'))
962                                 $string = iconv($this->encoding, 'UTF-8', $string);
963                         else
964                                 $string = mb_convert_encoding($string, 'UTF-8', $this->encoding);
965                 }
966
967         if ($this->built_in)
968         {
969                 imagestring($img, $size, $x, $y + $alt, $string, $col);
970         }       
971         else    
972         {
973                 if ($size == 1)
974                         $size = 7;
975                 else if ($size == 2)
976                         $size = 8;
977                 else if ($size == 3)
978                         $size = 9;
979                 else if ($size == 4)
980                         $size = 11;
981                 else
982                         $size = 12;
983                 $y += $size + 3;        
984                 //if ($alt)
985                 //      $angle = -15;
986                 //else
987                                 $angle = 0;
988
989                 imagettftext($img, $size, $angle, $x, $y + $alt, $col, $this->fontfile, $string);
990         }
991     }   
992 }
993 ?>