9 * Author: Carlos Reche/Joe Hunt
10 * E-mail: carlosreche@yahoo.com/joe.hunt.consulting@gmail.com
11 * Sorocaba, SP - Brazil/Wellington, New Zealand
13 * Created: Sep 20, 2004
14 * Last Modification: Sep 20, 2004/Apr 01, 2007
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.
25 * This script is free. Please keep the credits.
31 INSTRUNCTIONS OF HOW TO USE THIS SCRIPT (Please, take a minute to read it. It's important!)
34 NOTE: make sure that your PHP is compiled to work with GD Lib.
36 ///// START OF EXAMPLE.PHP /////
40 require "class.graphics.inc";
52 In your html file you set it up as:
54 <img src="example.php" border="1" />
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.
61 ///// END OF EXAMPLE.PHP /////
65 Here is a list of all parameters you may set:
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)
73 type => Type of graphic (values 1 to 6)
74 1 => Vertical bars (default)
81 skin => Skin of the graphic (values 1 to 3)
86 credits => Only if you want to show my credits in the image. :)
87 0 => doesn't show (default)
90 x[0] => Name of the first parameter in Axis X
91 x[1] => Name of the second parameter in Axis X
94 y[0] => Value from "graphic_1" relative for "x[0]"
95 y[1] => Value from "graphic_1" relative for "x[1]"
98 z[0] => Value from "graphic_2" relative for "x[0]"
99 z[1] => Value from "graphic_2" relative for "x[1]"
103 NOTE: You can't cross data between graphics if you use "pie" or "donut" graphic. Values for "z"
104 won't be considerated.
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!
140 var $total_parameters;
143 var $biggest_parameter;
144 var $available_types;
147 var $h3d = 15; // 3D height
148 var $built_in = false;
155 $this->encoding = strtoupper($_SESSION['language']->encoding);
156 $path = dirname(__FILE__).'/../fonts/';
158 // If you use UTF-8 encoding you have to download and install FreeSans.ttf font.
159 // It is not bundled with application due to its size.
160 // You can also use another UTF-8 font and put it in config.php with the name in $UTF8_fontfile
161 $this->fontfile = $this->encoding == 'UTF-8' ? (isset($SysPrefs->UTF8_fontfile) && $SysPrefs->UTF8_fontfile != "" ?
162 $path.$SysPrefs->UTF8_fontfile : $path.'FreeSans.ttf') : $path.'LiberationSans-Regular.ttf';
164 $this->x = $this->y = $this->z = array();
165 $this->biggest_x = NULL;
166 $this->biggest_y = NULL;
167 $this->alternate_x = false;
168 $this->graphic_2_exists = false;
169 $this->total_parameters = 0;
170 $this->sum_total = 1;
171 $this->latin_notation = false;
175 function display($save="", $border=false)
177 $this->legend_exists = (preg_match("/(5|6)/", $this->type)) ? true : false;
178 $this->biggest_graphic_name = (strlen($this->graphic_1) > strlen($this->graphic_2)) ? $this->graphic_1 : $this->graphic_2;
179 $this->height_title = (!empty($this->title)) ? ($this->string_height($this->tsize) + 15) : 0;
180 $this->space_between_bars = ($this->type == 1) ? 40 : 30;
181 $this->space_between_dots = 40;
182 $this->higher_value = 0;
183 $this->higher_value_str = 0;
187 $this->graphic_area_width = 0;
188 $this->graphic_area_height = 0;
189 $this->graphic_area_x1 = 30;
190 $this->graphic_area_y1 = 20 + $this->height_title;
191 $this->graphic_area_x2 = $this->graphic_area_x1 + $this->graphic_area_width;
192 $this->graphic_area_y2 = $this->graphic_area_y1 + $this->graphic_area_height;
194 if (count($this->z) && (preg_match("/(1|2|3|4)/", $this->type)))
195 $this->graphic_2_exists = true;
196 $this->total_parameters = count($this->x);
197 for ($i = 0; $i < $this->total_parameters; $i++)
199 if (strlen($this->x[$i]) > strlen($this->biggest_x))
200 $this->biggest_x = $this->x[$i];
201 if ($this->y[$i] > $this->biggest_y)
202 $this->biggest_y = number_format(round($this->y[$i], 1), 1, ".", "");
203 if ($this->graphic_2_exists)
205 if (isset($this->z[$i]) && $this->z[$i] > $this->biggest_y)
206 $this->biggest_y = number_format(round($this->z[$i], 1), 1, ".", "");
210 if (($this->graphic_2_exists == true) && ((!empty($this->graphic_1)) || (!empty($this->graphic_2))))
212 $this->legend_exists = true;
215 $this->sum_total = array_sum($this->y);
216 if ($this->sum_total == 0)
217 $this->sum_total = 1;
218 $this->space_between_bars += ($this->graphic_2_exists == true) ? 10 : 0;
220 $this->calculate_higher_value();
221 $this->calculate_width();
222 $this->calculate_height();
224 $this->create_graphic($save, $border);
227 function create_graphic($save="", $border=false)
230 $this->img = imagecreatetruecolor($this->width, $this->height);
232 $this->load_color_palette();
235 imagefill($this->img, 0, 0, $this->color['background']);
238 if (!empty($this->title))
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']);
245 // Draw axis and background lines for "vertical bars", "dots" and "lines"
246 if (preg_match("/^(1|3|4)$/", $this->type))
248 if ($this->legend_exists == true)
250 $this->draw_legend();
253 $higher_value_y = $this->graphic_area_y1 + (0.1 * $this->graphic_area_height);
254 $higher_value_size = 0.9 * $this->graphic_area_height;
256 $less = 7 * strlen($this->higher_value_str);
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']);
261 for ($i = 1; $i < 10; $i++)
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;
269 imageline($this->img, $x1, $y1, $x2, $y2, $this->color['bg_lines']);
272 $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
273 $len1 = strlen($this->higher_value_str);
274 $len2 = strlen($value);
276 $len2 += ($len1-$len2-1);
278 $this->_imagestring($this->img, $this->size, ($x1-$less-7), ($y2-7), $value, $this->color['axis_values']);
283 $this->_imagestring($this->img, $this->size, $this->graphic_area_x2+40, $this->graphic_area_y2+3, $this->axis_x, $this->color['title']);
284 imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
286 $this->_imagestring($this->img, $this->size, 20, $this->graphic_area_y1-20, $this->axis_y, $this->color['title']);
287 imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
291 // Draw axis and background lines for "horizontal bars"
292 else if ($this->type == 2)
294 if ($this->legend_exists == true)
296 $this->draw_legend();
299 $higher_value_x = $this->graphic_area_x2 - (0.2 * $this->graphic_area_width);
300 $higher_value_size = 0.8 * $this->graphic_area_width;
302 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']);
303 $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']);
305 for ($i = 1, $alt = 15; $i < 10; $i++)
307 $dec_x = number_format(round($i * ($higher_value_size / 10), 1), 1, ".", "");
309 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']);
312 $alt = (strlen($this->biggest_y) > 4 && $alt != 15) ? 15 : 2;
313 $value = $this->number_formated($this->higher_value * $i / 10, $this->dec1);
314 $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);
319 $this->_imagestring($this->img, $this->size, ($this->graphic_area_x2+10), ($this->graphic_area_y2+3), $this->axis_y, $this->color['title']);
320 imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y2, $this->graphic_area_x2, $this->graphic_area_y2, $this->color['axis_line']);
322 $this->_imagestring($this->img, $this->size, 20, ($this->graphic_area_y1-20), $this->axis_x, $this->color['title']);
323 imageline($this->img, $this->graphic_area_x1, $this->graphic_area_y1, $this->graphic_area_x1, $this->graphic_area_y2, $this->color['axis_line']);
327 // Draw legend box for "pie" or "donut"
328 else if (preg_match("/^(5|6)$/", $this->type))
330 $this->draw_legend();
336 * Draw graphic: VERTICAL BARS
338 if ($this->type == 1)
341 $x = $this->graphic_area_x1 + 20;
343 foreach ($this->x as $i => $parameter)
345 if (isset($this->z[$i]))
347 $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
349 $y1 = ($this->graphic_area_y2 - $size) + 1;
351 $y2 = $this->graphic_area_y2 - 1;
352 imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_2_shadow']);
353 imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_2_shadow']);
354 imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_2_shadow']);
355 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
358 $size = round($this->y[$i] * $higher_value_size / $this->higher_value);
359 $alt = (($num % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
361 $y1 = ($this->graphic_area_y2 - $size) + 1;
363 $y2 = $this->graphic_area_y2 - 1;
364 $x += $this->space_between_bars;
367 imageline($this->img, ($x1+1), ($y1-1), $x2, ($y1-1), $this->color['bars_shadow']);
368 imageline($this->img, ($x2+1), ($y1-1), ($x2+1), $y2, $this->color['bars_shadow']);
369 imageline($this->img, ($x2+2), ($y1-1), ($x2+2), $y2, $this->color['bars_shadow']);
370 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
371 $this->_imagestring($this->img, $this->size, $x1, ($y2+2), $parameter, $this->color['axis_values'], $alt);
377 * Draw graphic: HORIZONTAL BARS
379 else if ($this->type == 2)
383 foreach ($this->x as $i => $parameter)
385 if (isset($this->z[$i]))
387 $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
388 $x1 = $this->graphic_area_x1 + 1;
389 $y1 = $this->graphic_area_y1 + $y + 10;
392 imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_2_shadow']);
393 imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_2_shadow']);
394 imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_2_shadow']);
395 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars_2']);
396 $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+7), $this->number_formated($this->z[$i], $this->dec2), $this->color['bars_2_shadow']);
399 $size = round(($this->y[$i] / $this->higher_value) * $higher_value_size);
400 $x1 = $this->graphic_area_x1 + 1;
401 $y1 = $this->graphic_area_y1 + $y;
404 $y += $this->space_between_bars;
406 imageline($this->img, ($x1), ($y2+1), $x2, ($y2+1), $this->color['bars_shadow']);
407 imageline($this->img, ($x1), ($y2+2), $x2, ($y2+2), $this->color['bars_shadow']);
408 imageline($this->img, ($x2+1), ($y1+1), ($x2+1), ($y2+2), $this->color['bars_shadow']);
409 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bars']);
410 $this->_imagestring($this->img, $this->size, ($x2+7), ($y1+2), $this->number_formated($this->y[$i], $this->dec2), $this->color['bars_shadow']);
412 $this->_imagestring($this->img, $this->size, 30, ($y1+2), $parameter, $this->color['axis_values']);
418 * Draw graphic: DOTS or LINE
420 else if (preg_match("/^(3|4)$/", $this->type))
423 $x[0] = $this->graphic_area_x1+1;
425 foreach ($this->x as $i => $parameter)
427 if ($this->graphic_2_exists == true)
429 $size = round($this->z[$i] * $higher_value_size / $this->higher_value);
430 $z[$i] = $this->graphic_area_y2 - $size;
433 $alt = (($i % 2 == 0) && (strlen($this->biggest_x) > 5)) ? 15 : 2;
434 $size = round($this->y[$i] * $higher_value_size / $this->higher_value);
435 $y[$i] = $this->graphic_area_y2 - $size;
439 imageline($this->img, $x[$i], ($this->graphic_area_y1+10), $x[$i], ($this->graphic_area_y2-1), $this->color['bg_lines']);
441 $this->_imagestring($this->img, $this->size, $x[$i], ($this->graphic_area_y2+2), $parameter, $this->color['axis_values'], $alt);
443 $x[$i+1] = $x[$i] + 40;
446 foreach ($x as $i => $value_x)
448 if ($this->graphic_2_exists == true)
453 if ($this->type == 4)
455 imageline($this->img, $x[$i], $z[$i], $x[$i+1], $z[$i+1], $this->color['line_2']);
456 imageline($this->img, $x[$i], ($z[$i]+1), $x[$i+1], ($z[$i+1]+1), $this->color['line_2']);
458 imagefilledrectangle($this->img, $x[$i]-1, $z[$i]-1, $x[$i]+2, $z[$i]+2, $this->color['line_2']);
462 imagefilledrectangle($this->img, $x[$i-1]-1, $z[$i-1]-1, $x[$i-1]+2, $z[$i-1]+2, $this->color['line_2']);
471 if ($this->type == 4)
473 imageline($this->img, $x[$i], $y[$i], $x[$i+1], $y[$i+1], $this->color['line']);
474 imageline($this->img, $x[$i], ($y[$i]+1), $x[$i+1], ($y[$i+1]+1), $this->color['line']);
476 imagefilledrectangle($this->img, $x[$i]-1, $y[$i]-1, $x[$i]+2, $y[$i]+2, $this->color['line']);
480 imagefilledrectangle($this->img, $x[$i-1]-1, $y[$i-1]-1, $x[$i-1]+2, $y[$i-1]+2, $this->color['line']);
489 * Draw graphic: PIE or DONUT
491 else if (preg_match("/^(5|6)$/", $this->type))
493 $center_x = ($this->graphic_area_x1 + $this->graphic_area_x2) / 2;
494 $center_y = ($this->graphic_area_y1 + $this->graphic_area_y2) / 2;
495 $width = $this->graphic_area_width;
496 $height = $this->graphic_area_height;
500 foreach ($this->x as $i => $parameter)
502 $size = $this->y[$i] * 360 / $this->sum_total;
503 $size = round2($size, 0);
510 if ($this->type == 5)
513 foreach ($sizes as $i => $size)
516 while ($num_color > 7)
520 $color = 'arc_' . $num_color . '_shadow';
522 for ($i = $this->h3d; $i >= 0; $i--)
525 imagefilledarc($this->img, $center_x, ($center_y+$i), $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_NOFILL);
533 foreach ($sizes as $i => $size)
536 while ($num_color > 7)
540 $color = 'arc_' . $num_color;
542 imagefilledarc($this->img, $center_x, $center_y, ($width+2), ($height+2), $start, ($start+$size), $this->color[$color], IMG_ARC_EDGED);
548 else if ($this->type == 6)
550 foreach ($sizes as $i => $size)
553 while ($num_color > 7)
557 $color = 'arc_' . $num_color;
558 $color_shadow = 'arc_' . $num_color . '_shadow';
560 imagefilledarc($this->img, $center_x, $center_y, $width, $height, $start, ($start+$size), $this->color[$color], IMG_ARC_PIE);
563 imagefilledarc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['background'], IMG_ARC_PIE);
564 imagearc($this->img, $center_x, $center_y, 100, 100, 0, 360, $this->color['bg_legend']);
565 imagearc($this->img, $center_x, $center_y, ($width+1), ($height+1), 0, 360, $this->color['bg_legend']);
570 if ($this->credits == true)
572 $this->draw_credits();
575 imagepng($this->img, $save);
578 header('Content-type: image/png');
579 imagepng($this->img);
581 imagedestroy($this->img);
584 function calculate_width()
590 $this->legend_box_width = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->tsize) + 25) : 0;
591 $this->graphic_area_width = ($this->space_between_bars * $this->total_parameters) + 30;
592 $this->graphic_area_x1 += $this->string_width(($this->higher_value_str), $this->size);
593 $this->width += $this->graphic_area_x1 + 20;
594 $this->width += ($this->legend_exists == true) ? 50 : ((7 * strlen($this->axis_x)) + 10);
599 $this->legend_box_width = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
600 $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;
601 $this->graphic_area_x1 += 7 * strlen($this->biggest_x);
602 $this->width += ($this->legend_exists == true) ? 60 : ((7 * strlen($this->axis_y)) + 30);
603 $this->width += $this->graphic_area_x1;
608 $this->legend_box_width = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
609 $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
610 $this->graphic_area_x1 += $this->string_width(($this->higher_value_str), $this->size);
611 $this->width += $this->graphic_area_x1 + 20;
612 $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 30);
617 $this->legend_box_width = ($this->legend_exists == true) ? ($this->string_width($this->biggest_graphic_name, $this->size) + 25) : 0;
618 $this->graphic_area_width = ($this->space_between_dots * $this->total_parameters) - 10;
619 $this->graphic_area_x1 += $this->string_width(($this->higher_value_str), $this->size);
620 $this->width += $this->graphic_area_x1 + 20;
621 $this->width += ($this->legend_exists == true) ? 40 : ((7 * strlen($this->axis_x)) + 30);
626 $this->legend_box_width = $this->string_width($this->biggest_x, $this->size) + 85;
627 $this->graphic_area_width = 200;
633 $this->legend_box_width = $this->string_width($this->biggest_x, $this->size) + 85;
634 $this->graphic_area_width = 180;
639 $this->graphic_area_width = max($this->graphic_area_width, $this->string_width($this->title, $this->size));
640 $this->width += $this->graphic_area_width;
641 $this->width += $this->legend_box_width;
644 $this->graphic_area_x2 = $this->graphic_area_x1 + $this->graphic_area_width;
645 $this->legend_box_x1 = $this->graphic_area_x2 + 40;
646 $this->legend_box_x2 = $this->legend_box_x1 + $this->legend_box_width;
649 function calculate_height()
655 $this->legend_box_height = ($this->graphic_2_exists == true) ? 40 : 0;
656 $this->graphic_area_height = 150;
662 $this->legend_box_height = ($this->graphic_2_exists == true) ? 40 : 0;
663 $this->graphic_area_height = ($this->space_between_bars * $this->total_parameters) + 10;
669 $this->legend_box_height = ($this->graphic_2_exists == true) ? 40 : 0;
670 $this->graphic_area_height = 150;
676 $this->legend_box_height = ($this->graphic_2_exists == true) ? 40 : 0;
677 $this->graphic_area_height = 150;
683 $this->legend_box_height = (!empty($this->axis_x)) ? 30 : 5;
684 $this->legend_box_height += (14 * $this->total_parameters);
685 $this->graphic_area_height = 150;
691 $this->legend_box_height = (!empty($this->axis_x)) ? 30 : 5;
692 $this->legend_box_height += (14 * $this->total_parameters);
693 $this->graphic_area_height = 180;
698 $this->height += $this->height_title;
699 $this->height += ($this->legend_box_height > $this->graphic_area_height) ? ($this->legend_box_height - $this->graphic_area_height) : 0;
700 $this->height += $this->graphic_area_height;
702 $this->graphic_area_y2 = $this->graphic_area_y1 + $this->graphic_area_height;
703 $this->legend_box_y1 = $this->graphic_area_y1 + 10;
704 $this->legend_box_y2 = $this->legend_box_y1 + $this->legend_box_height;
707 function draw_legend()
709 $x1 = $this->legend_box_x1;
710 $y1 = $this->legend_box_y1;
711 $x2 = $this->legend_box_x2;
712 $y2 = $this->legend_box_y2;
714 imagefilledrectangle($this->img, $x1, $y1, $x2, $y2, $this->color['bg_legend']);
720 // Draw legend values for VERTICAL BARS, HORIZONTAL BARS, DOTS and LINES
721 if (preg_match("/^(1|2|3|4)$/", $this->type))
723 $color_1 = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars'] : $this->color['line'];
724 $color_2 = (preg_match("/^(1|2)$/", $this->type)) ? $this->color['bars_2'] : $this->color['line_2'];
726 imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_1);
727 imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
728 $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $this->graphic_1, $this->color['axis_values']);
730 imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $color_2);
731 imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
732 $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $this->graphic_2, $this->color['axis_values']);
735 // Draw legend values for PIE or DONUT
736 else if (preg_match("/^(5|6)$/", $this->type))
738 if (!empty($this->axis_x))
740 $this->_imagestring($this->img, $this->size, ((($x1+$x2)/2) - (strlen($this->axis_x)*7/2)), $y,
741 $this->axis_x." (".$this->graphic_1.")", $this->color['title']);
747 foreach ($this->x as $i => $parameter)
753 $color = 'arc_' . $num;
755 $percent = number_format(round(($this->y[$i] * 100 / $this->sum_total), 2), 2, ".", "") . ' %';
756 $less = (strlen($percent) * 7);
760 imageline($this->img, ($x1+15), ($y-2), ($x2-5), ($y-2), $this->color['bg_lines']);
762 imagefilledrectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color[$color]);
763 imagerectangle($this->img, $x, $y, ($x+10), ($y+10), $this->color['title']);
764 $this->_imagestring($this->img, $this->size, ($x+15), ($y-2), $parameter, $this->color['axis_values']);
765 $this->_imagestring($this->img, $this->size, ($x2-$less), ($y-2), $percent, $this->color['axis_values']);
773 function string_width($string, $size)
775 $single_width = $size + 4;
776 if ($this->encoding == "UTF-8")
777 $width = mb_strlen($string, "UTF-8");
779 $width = strlen($string);
780 return $single_width * $width;
783 function string_height($size)
800 function calculate_higher_value()
802 $digits = strlen(round($this->biggest_y));
803 $interval = pow(10, ($digits-1));
804 $this->higher_value = round(($this->biggest_y - ($this->biggest_y % $interval) + $interval), 1);
805 $this->higher_value_str = $this->number_formated($this->higher_value, $this->dec1);
808 function number_formated($number, $dec_size = 1)
810 if ($this->latin_notation == true)
811 return number_format(round($number, $dec_size), $dec_size, ",", ".");
812 return number_format(round($number, $dec_size), $dec_size, ".", ",");
815 function number_float($number)
817 if ($this->latin_notation == true)
818 $number = str_replace(".", "", $number);
819 return (float)str_replace(",", "", $number);
823 function draw_credits()
825 $this->_imagestring($this->img, $this->size - 2, ($this->width-120), ($this->height-10), "Powered by Carlos Reche", $this->color['title']);
829 function load_color_palette()
835 $this->color['title'] = imagecolorallocate($this->img, 40, 70, 130);
836 $this->color['background'] = imagecolorallocate($this->img, 255, 255, 255);
837 $this->color['axis_values'] = imagecolorallocate($this->img, 50, 50, 50);
838 $this->color['axis_line'] = imagecolorallocate($this->img, 100, 100, 100);
839 $this->color['bg_lines'] = imagecolorallocate($this->img, 220, 220, 220);
840 $this->color['bg_legend'] = imagecolorallocate($this->img, 255, 255, 255);
842 if (preg_match("/^(1|2)$/", $this->type))
844 $this->color['bars'] = imagecolorallocate($this->img, 100, 150, 200);
845 $this->color['bars_shadow'] = imagecolorallocate($this->img, 50, 100, 150);
846 $this->color['bars_2'] = imagecolorallocate($this->img, 200, 250, 150);
847 $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 120, 170, 70);
849 else if (preg_match("/^(3|4)$/", $this->type))
851 $this->color['line'] = imagecolorallocate($this->img, 100, 150, 200);
852 $this->color['line_2'] = imagecolorallocate($this->img, 230, 100, 100);
854 else if (preg_match("/^(5|6)$/", $this->type))
856 $this->color['arc_1'] = imagecolorallocate($this->img, 255, 150, 0);
857 $this->color['arc_2'] = imagecolorallocate($this->img, 150, 0, 255);
858 $this->color['arc_3'] = imagecolorallocate($this->img, 0, 255, 255);
859 $this->color['arc_4'] = imagecolorallocate($this->img, 255, 0, 0);
860 $this->color['arc_5'] = imagecolorallocate($this->img, 0, 255, 0);
861 $this->color['arc_6'] = imagecolorallocate($this->img, 0, 0, 255);
862 $this->color['arc_7'] = imagecolorallocate($this->img, 255, 255, 0);
863 $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 127, 75, 0);
864 $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 75, 0, 127);
865 $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 0, 127, 127);
866 $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 127, 0, 0);
867 $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 0, 127, 0);
868 $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 0, 0, 127);
869 $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 127, 127, 0);
875 $this->color['title'] = imagecolorallocate($this->img, 255, 255, 255);
876 $this->color['background'] = imagecolorallocate($this->img, 0, 0, 0);
877 $this->color['axis_values'] = imagecolorallocate($this->img, 0, 230, 0);
878 $this->color['axis_line'] = imagecolorallocate($this->img, 0, 200, 0);
879 $this->color['bg_lines'] = imagecolorallocate($this->img, 100, 100, 100);
880 $this->color['bg_legend'] = imagecolorallocate($this->img, 70, 70, 70);
882 if (preg_match("/^(1|2)$/", $this->type))
884 $this->color['bars'] = imagecolorallocate($this->img, 50, 200, 50);
885 $this->color['bars_shadow'] = imagecolorallocate($this->img, 0, 150, 0);
886 $this->color['bars_2'] = imagecolorallocate($this->img, 255, 255, 255);
887 $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 220, 220, 220);
889 else if (preg_match("/^(3|4)$/", $this->type))
891 $this->color['line'] = imagecolorallocate($this->img, 220, 220, 220);
892 $this->color['line_2'] = imagecolorallocate($this->img, 0, 180, 0);
894 else if (preg_match("/^(5|6)$/", $this->type))
896 $this->color['arc_1'] = imagecolorallocate($this->img, 255, 255, 255);
897 $this->color['arc_2'] = imagecolorallocate($this->img, 200, 220, 200);
898 $this->color['arc_3'] = imagecolorallocate($this->img, 160, 200, 160);
899 $this->color['arc_4'] = imagecolorallocate($this->img, 135, 180, 135);
900 $this->color['arc_5'] = imagecolorallocate($this->img, 115, 160, 115);
901 $this->color['arc_6'] = imagecolorallocate($this->img, 100, 140, 100);
902 $this->color['arc_7'] = imagecolorallocate($this->img, 90, 120, 90);
903 $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 127, 127, 127);
904 $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 100, 110, 100);
905 $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 80, 100, 80);
906 $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 67, 90, 67);
907 $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 57, 80, 57);
908 $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 50, 70, 50);
909 $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 45, 60, 45);
916 $this->color['title'] = imagecolorallocate($this->img, 250, 50, 50);
917 $this->color['background'] = imagecolorallocate($this->img, 255, 255, 255);
918 $this->color['axis_values'] = imagecolorallocate($this->img, 50, 150, 50);
919 $this->color['axis_line'] = imagecolorallocate($this->img, 50, 100, 50);
920 $this->color['bg_lines'] = imagecolorallocate($this->img, 200, 224, 180);
921 //$this->color['bg_legend'] = imagecolorallocate($this->img, 230, 230, 200);
922 $this->color['bg_legend'] = imagecolorallocate($this->img, 255, 255, 255);
924 if (preg_match("/^(1|2)$/", $this->type))
926 $this->color['bars'] = imagecolorallocate($this->img, 255, 170, 80);
927 $this->color['bars_shadow'] = imagecolorallocate($this->img, 200, 120, 30);
928 $this->color['bars_2'] = imagecolorallocate($this->img, 250, 230, 80);
929 $this->color['bars_2_shadow'] = imagecolorallocate($this->img, 180, 150, 0);
931 else if (preg_match("/^(3|4)$/", $this->type))
933 $this->color['line'] = imagecolorallocate($this->img, 230, 100, 0);
934 $this->color['line_2'] = imagecolorallocate($this->img, 220, 200, 50);
936 else if (preg_match("/^(5|6)$/", $this->type))
938 $this->color['arc_1'] = imagecolorallocate($this->img, 100, 150, 200);
939 $this->color['arc_2'] = imagecolorallocate($this->img, 200, 250, 150);
940 $this->color['arc_3'] = imagecolorallocate($this->img, 250, 200, 150);
941 $this->color['arc_4'] = imagecolorallocate($this->img, 250, 150, 150);
942 $this->color['arc_5'] = imagecolorallocate($this->img, 250, 250, 150);
943 $this->color['arc_6'] = imagecolorallocate($this->img, 230, 180, 250);
944 $this->color['arc_7'] = imagecolorallocate($this->img, 200, 200, 150);
945 $this->color['arc_1_shadow'] = imagecolorallocate($this->img, 50, 75, 100);
946 $this->color['arc_2_shadow'] = imagecolorallocate($this->img, 100, 125, 75);
947 $this->color['arc_3_shadow'] = imagecolorallocate($this->img, 125, 100, 75);
948 $this->color['arc_4_shadow'] = imagecolorallocate($this->img, 125, 75, 75);
949 $this->color['arc_5_shadow'] = imagecolorallocate($this->img, 125, 125, 75);
950 $this->color['arc_6_shadow'] = imagecolorallocate($this->img, 115, 90, 125);
951 $this->color['arc_7_shadow'] = imagecolorallocate($this->img, 100, 100, 75);
958 function _imagestring($img, $size, $x, $y, $string, $col, $alt=0)
960 if ($this->encoding != 'UTF-8') {
961 if (function_exists('iconv'))
962 $string = iconv($this->encoding, 'UTF-8', $string);
964 $string = mb_convert_encoding($string, 'UTF-8', $this->encoding);
967 // Handling ev. RTL languages
970 if ($this->encoding == 'UTF-8' && is_arabic($string))
974 if (strlen($string) > $alt_len)
975 $string = substr($string, 0, $alt_len);
977 if ($this->encoding == 'UTF-8')
979 if (is_arabic($string))
980 $string = arabic($string, "we");
981 elseif (is_hebrew($string))
982 $string = hebrew($string);
987 imagestring($img, $size, $x, $y + $alt, $string, $col);
1004 if ($this->encoding == 'UTF-8' && is_arabic($string))
1007 $string = str_replace(" ", " ", $string);
1010 imagettftext($img, $size, $angle, $x, $y + $alt, $col, $this->fontfile, $string);
1015 // The following is for handling RTL texts. GD does not handle RTL at all.
1016 // The function, arabic, has been taken from Milad Rastian and
1017 // modified by Bagram Siadat.
1018 // The function has been further modified and several bugs are fixed.
1020 function is_arabic($text)
1022 return preg_match('/\p{Arabic}/u', $text);
1025 function is_hebrew($text)
1027 return preg_match('/\p{Hebrew}/u', $text);
1030 function utf8_strlen($str)
1032 return preg_match_all('/[\x00-\x7F\xC0-\xFD]/', $str, $dummy);
1035 function utf8_chr($uni)
1038 # ASCII range (including control chars)
1039 if ( ($uni >= 0) && ($uni <= 0x007f) )
1041 elseif ($uni <= 0x07ff) // 2 byte sequence
1043 $r .= chr(0xc0 | ($uni >> 6));
1044 $r .= chr(0x80 | ($uni & 0x003f));
1046 elseif($uni == 0xFEFF) // Byte order mark (skip)
1047 return chr(0); // nop -- zap the BOM
1048 elseif ($uni >= 0xD800 && $uni <= 0xDFFF) // Test for illegal surrogates
1049 return chr(0); // found a surrogate
1050 elseif ($uni <= 0xffff) // 3 byte sequence
1052 $r .= chr(0xe0 | ($uni >> 12));
1053 $r .= chr(0x80 | (($uni >> 6) & 0x003f));
1054 $r .= chr(0x80 | ($uni & 0x003f));
1056 elseif ($uni <= 0x10ffff) // 4 byte sequence
1058 $r .= chr(0xf0 | ($uni >> 18));
1059 $r .= chr(0x80 | (($uni >> 12) & 0x3f));
1060 $r .= chr(0x80 | (($uni >> 6) & 0x3f));
1061 $r .= chr(0x80 | ($uni & 0x3f));
1069 function arabic($str,$z="",$method='normal')
1072 utf8_chr(0x0622) => array (utf8_chr(0xfe82), utf8_chr(0xfe82), utf8_chr(0x0622)),
1073 utf8_chr(0x0627) => array (utf8_chr(0xfe8e), utf8_chr(0xfe8e), utf8_chr(0x0627)),
1074 utf8_chr(0x0628) => array (utf8_chr(0xfe90), utf8_chr(0xfe92), utf8_chr(0xfe91)),
1075 utf8_chr(0x067e) => array (utf8_chr(0xfb57), utf8_chr(0xfb59), utf8_chr(0xfb58)),
1076 utf8_chr(0x062a) => array (utf8_chr(0xfe96), utf8_chr(0xfe98), utf8_chr(0xfe97)),
1077 utf8_chr(0x062b) => array (utf8_chr(0xfe9a), utf8_chr(0xfe9c), utf8_chr(0xfe9b)),
1078 utf8_chr(0x062c) => array (utf8_chr(0xfe9e), utf8_chr(0xfea0), utf8_chr(0xfe9f)),
1079 utf8_chr(0x0686) => array (utf8_chr(0xfb7b), utf8_chr(0xfb7d), utf8_chr(0xfb7c)),
1080 utf8_chr(0x062d) => array (utf8_chr(0xfea2), utf8_chr(0xfea4), utf8_chr(0xfea3)),
1081 utf8_chr(0x062e) => array (utf8_chr(0xfea6), utf8_chr(0xfea8), utf8_chr(0xfea7)),
1082 utf8_chr(0x062f) => array (utf8_chr(0xfeaa), utf8_chr(0xfeaa), utf8_chr(0xfea9)),
1083 utf8_chr(0x0630) => array (utf8_chr(0xfeac), utf8_chr(0xfeac), utf8_chr(0xfeab)),
1084 utf8_chr(0x0631) => array (utf8_chr(0xfeae), utf8_chr(0xfeae), utf8_chr(0xfead)),
1085 utf8_chr(0x0632) => array (utf8_chr(0xfeb0), utf8_chr(0xfeb0), utf8_chr(0xfeaf)),
1086 utf8_chr(0x0698) => array (utf8_chr(0xfb8b), utf8_chr(0xfb8b), utf8_chr(0xfb8a)),
1087 utf8_chr(0x0633) => array (utf8_chr(0xfeb2), utf8_chr(0xfeb4), utf8_chr(0xfeb3)),
1088 utf8_chr(0x0634) => array (utf8_chr(0xfeb6), utf8_chr(0xfeb8), utf8_chr(0xfeb7)),
1089 utf8_chr(0x0635) => array (utf8_chr(0xfeba), utf8_chr(0xfebc), utf8_chr(0xfebb)),
1090 utf8_chr(0x0636) => array (utf8_chr(0xfebe), utf8_chr(0xfec0), utf8_chr(0xfebf)),
1091 utf8_chr(0x0637) => array (utf8_chr(0xfec2), utf8_chr(0xfec4), utf8_chr(0xfec3)),
1092 utf8_chr(0x0638) => array (utf8_chr(0xfec6), utf8_chr(0xfec8), utf8_chr(0xfec7)),
1093 utf8_chr(0x0639) => array (utf8_chr(0xfeca), utf8_chr(0xfecc), utf8_chr(0xfecb)),
1094 utf8_chr(0x063a) => array (utf8_chr(0xfece), utf8_chr(0xfed0), utf8_chr(0xfecf)),
1095 utf8_chr(0x0641) => array (utf8_chr(0xfed2), utf8_chr(0xfed4), utf8_chr(0xfed3)),
1096 utf8_chr(0x0642) => array (utf8_chr(0xfed6), utf8_chr(0xfed8), utf8_chr(0xfed7)),
1097 utf8_chr(0x06a9) => array (utf8_chr(0xfeda), utf8_chr(0xfedc), utf8_chr(0xfedb)),
1098 utf8_chr(0x06af) => array (utf8_chr(0xfb93), utf8_chr(0xfb95), utf8_chr(0xfb94)),
1099 utf8_chr(0x0644) => array (utf8_chr(0xfede), utf8_chr(0xfee0), utf8_chr(0xfedf)),
1100 utf8_chr(0x0645) => array (utf8_chr(0xfee2), utf8_chr(0xfee4), utf8_chr(0xfee3)),
1101 utf8_chr(0x0646) => array (utf8_chr(0xfee6), utf8_chr(0xfee8), utf8_chr(0xfee7)),
1102 utf8_chr(0x0648) => array (utf8_chr(0xfeee), utf8_chr(0xfeee), utf8_chr(0xfeed)),
1103 utf8_chr(0x06cc) => array (utf8_chr(0xfbfd), utf8_chr(0xfbff), utf8_chr(0xfbfe)),
1104 utf8_chr(0x0643) => array (utf8_chr(0xfeda), utf8_chr(0xfedc), utf8_chr(0xfedb)),
1105 utf8_chr(0x064a) => array (utf8_chr(0xfef2), utf8_chr(0xfef4), utf8_chr(0xfef3)),
1106 utf8_chr(0x0623) => array (utf8_chr(0xfe84), utf8_chr(0xfe84), utf8_chr(0xfe83)),
1107 utf8_chr(0x0624) => array (utf8_chr(0xfe86), utf8_chr(0xfe86), utf8_chr(0xfe85)),
1108 utf8_chr(0x0625) => array (utf8_chr(0xfe88), utf8_chr(0xfe88), utf8_chr(0xfe87)),
1109 utf8_chr(0x0626) => array (utf8_chr(0xfe8a), utf8_chr(0xfe8c), utf8_chr(0xfe8b)),
1110 utf8_chr(0x0629) => array (utf8_chr(0xfe94), utf8_chr(0xfe98), utf8_chr(0xfe97))
1113 $nastaligh = array (
1114 utf8_chr(0x0647) => array (utf8_chr(0xfbab), utf8_chr(0xfbad), utf8_chr(0xfbac))
1118 utf8_chr(0x0647) => array (utf8_chr(0xfeea), utf8_chr(0xfeec), utf8_chr(0xfeeb))
1121 $mp_chars = array (utf8_chr(0x0622), utf8_chr(0x0627), utf8_chr(0x062f), utf8_chr(0x0630), utf8_chr(0x0631), utf8_chr(0x0632),
1122 utf8_chr(0x0698), utf8_chr(0x0648), utf8_chr(0x0623), utf8_chr(0x0625), utf8_chr(0x0624));
1124 $ignorelist = array (utf8_chr(0x0000), utf8_chr(0x064c), utf8_chr(0x064d), utf8_chr(0x064b), utf8_chr(0x064f), utf8_chr(0x0650),
1125 utf8_chr(0x064e), utf8_chr(0x0651), utf8_chr(0x0653), utf8_chr(0x0670), utf8_chr(0x0654), utf8_chr(0xfe76), utf8_chr(0xfe7a),
1126 utf8_chr(0xfe78), utf8_chr(0xfe7c), utf8_chr(0xfe7e), utf8_chr(0xfe74), utf8_chr(0xfe70), utf8_chr(0xfc5e), utf8_chr(0xfc5f),
1127 utf8_chr(0xfc60), utf8_chr(0xfc61), utf8_chr(0xfc62), utf8_chr(0xfc63));
1129 $str_back = $output = $e_output = $str_next = $str1 = $num = "";
1130 if ($method == 'nastaligh')
1131 $p_chars = array_merge($p_chars, $nastaligh);
1133 $p_chars = array_merge($p_chars, $normal);
1134 $str_len = utf8_strlen($str);
1135 preg_match_all("/./u", $str, $ar);
1136 for ($i = 0; $i < $str_len; $i++)
1138 if (isset($ar[0][$i]))
1140 if(isset($ar[0][$i+1]) && in_array($ar[0][$i+1], $ignorelist))
1142 if (isset($ar[0][$i+2]))
1143 $str_next = $ar[0][$i+2];
1145 $str_back = $ar[0][$i-2];
1146 if ($i > 1 && $i != 2)
1147 $str_back = $ar[0][$i-1];
1149 elseif ($i > 0 && isset($ar[0][$i-1]) && !in_array($ar[0][$i-1], $ignorelist))
1151 if (isset($ar[0][$i+1]))
1152 $str_next = $ar[0][$i+1];
1154 $str_back = $ar[0][$i-1];
1158 if (isset($ar[0][$i+1]) && !empty($ar[0][$i+1]))
1159 $str_next = $ar[0][$i+1];
1160 elseif ($i > 0 && isset($ar[0][$i-1]))
1161 $str_next = $ar[0][$i-1];
1162 if ($i > 1 && isset($ar[0][$i-2]))
1163 $str_back = $ar[0][$i-2];
1165 if (!in_array($str1,$ignorelist))
1167 if (array_key_exists($str1,$p_chars))
1169 if (!$str_back || $str_back==" " || !array_key_exists($str_back,$p_chars))
1171 if (!array_key_exists($str_back, $p_chars) && !array_key_exists($str_next, $p_chars))
1172 $output = $str1.$output;
1174 $output = $p_chars[$str1][2].$output;
1177 elseif (array_key_exists($str_next, $p_chars) && array_key_exists($str_back, $p_chars))
1179 if (in_array($str_back, $mp_chars) && array_key_exists($str_next, $p_chars))
1180 $output = $p_chars[$str1][2].$output;
1182 $output = $p_chars[$str1][1].$output;
1185 elseif (array_key_exists($str_back, $p_chars) && !array_key_exists($str_next, $p_chars))
1187 if (in_array($str_back, $mp_chars))
1188 $output = $str1.$output;
1190 $output = $p_chars[$str1][0].$output;
1196 $number = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
1197 "\xD9\xA0", "\xD9\xA1", "\xD9\xA2", "\xD9\xA3", "\xD9\xA4", "\xD9\xA5", "\xD9\xA6",
1198 "\xD9\xA7", "\xD9\xA8", "\xD9\xA9", "\xDB\xB0", "\xDB\xB1", "\xDB\xB2", "\xDB\xB3",
1199 "\xDB\xB4", "\xDB\xB5", "\xDB\xB6", "\xDB\xB7", "\xDB\xB8", "\xDB\xB9");
1200 if (in_array($str1, $number))
1205 if (!in_array($str_next, $number))
1210 //$output = $str1.$output;
1211 $output = $output.$str1;
1215 $number = array (utf8_chr(0x0660), utf8_chr(0x0661), utf8_chr(0x0662),
1216 utf8_chr(0x0663), utf8_chr(0x0664), utf8_chr(0x0665), utf8_chr(0x0666),
1217 utf8_chr(0x0667), utf8_chr(0x0668), utf8_chr(0x0669), utf8_chr(0x06f4),
1218 utf8_chr(0x06f5), utf8_chr(0x06f6), utf8_chr(0x0030), utf8_chr(0x0031),
1219 utf8_chr(0x0032), utf8_chr(0x0033), utf8_chr(0x0034), utf8_chr(0x0035),
1220 utf8_chr(0x0036), utf8_chr(0x0037), utf8_chr(0x0038), utf8_chr(0x0039));
1248 if (in_array($str1, $number))
1253 if (!in_array($str_next, $number))
1258 $output = $str1.$output;
1262 if (($str1 == utf8_chr(0x060c)) || ($str1 == utf8_chr(0x061f)) || ($str1 == utf8_chr(0x0621)) ||
1263 (array_key_exists($str_next, $p_chars) && array_key_exists($str_back, $p_chars)) ||
1264 ($str1 == " " && array_key_exists($str_back, $p_chars)) || ($str1 == " " &&
1265 array_key_exists($str_next, $p_chars)))
1269 $output = $e_output.$output;
1272 $output = $str1.$output;
1277 if (array_key_exists($str_next, $p_chars) || $str_next == "")
1279 $output = $e_output.$output;
1286 $output = $str1.$output;