Posted By

jatkins on 03/04/12


Tagged

gd bar generator chart graph pie GD2


Versions (?)

Pie/Bar Chart Generator


 / Published in: PHP
 

Released under the MIT license by Josh Atkins. Requires Antialiased filled Arcs/Ellipses for PHP by Ulrich Mierendorff (also under the MIT license).

  1. <?php
  2. require_once('imageSmoothArc.php');
  3. global $font_path;
  4. $font_path = 'C:/Windows/Fonts/arialbd.ttf';
  5.  
  6. function get_dimensions_from_bbox($bbox) {
  7. return array('width' => abs($bbox[2]-$bbox[0]), 'height'=>abs($bbox[1]-$bbox[7]));
  8. }
  9.  
  10. function new_piechart($radius, $data, $title) {
  11. $data_labels = array_keys($data);
  12. $data_values = array_values($data);
  13. $total_value = array_sum($data_values); // work out the total value
  14. $title_dimensions = get_dimensions_from_bbox(imagettfbbox(28, 0, $GLOBALS['font_path'], $title)); // work out dimensions of the title
  15.  
  16. $labels = array();
  17. $max_label_width = 0;
  18. for($i=0;$i<count($data_values);$i++) {
  19. $labels[] = array();
  20. $labels[$i][] = $data_labels[$i] . ' (' . $data_values[$i] . ' / ' . round($data_values[$i]/$total_value*100) . '%)'; // "label (value/percentage)"
  21. $labels[$i][] = get_dimensions_from_bbox(imagettfbbox(12, 0, $GLOBALS['font_path'], $labels[$i][0])); // work out the dimensions of the label
  22. if($labels[$i][1]['width']>$max_label_width)
  23. $max_label_width = $labels[$i][1]['width'];
  24. }
  25.  
  26. $title_pie_gap = 30;
  27. $pie_legend_gap = 30;
  28. $legend_gaps = 5;
  29. $extra_width = 5;
  30. $extra_height = 5;
  31. $piechart = imagecreatetruecolor(max($title_dimensions['width'], $radius, $max_label_width+25)+$extra_width, $title_dimensions['height']+$radius*0.5+16*count($labels)+$title_pie_gap+$pie_legend_gap+$legend_gaps*(count($data_labels)-1)+10+$extra_height);
  32.  
  33. imagealphablending($piechart, true); // for anti-aliasing
  34. imagefilledrectangle($piechart, 0, 0, imagesx($piechart), imagesy($piechart), imagecolorallocate($piechart, 255, 255, 255)); // make the background white
  35. imagettftext($piechart, 28, 0, imagesx($piechart)/2-$title_dimensions['width']/2, 28, null, $GLOBALS['font_path'], $title); // write the title
  36. $current_angle = 0;
  37. $colors = array();
  38. $angles = array();
  39.  
  40. foreach($data_values as $value) {
  41. $colors_rgb = array(rand(50, 255), rand(50, 255), rand(50, 255)); // choose a random color
  42. $colors[] = array($colors_rgb[0] - 50, $colors_rgb[1] - 50, $colors_rgb[2] - 50, 0); // last value of 0 means complete opaqueness
  43. $three_d_colors[] = array(abs($colors_rgb[0] - 65), abs($colors_rgb[1] - 65), abs($colors_rgb[2] - 65), 0);
  44. $angles[] = array(deg2rad($current_angle), deg2rad($current_angle+$value/$total_value*360));
  45. $current_angle += $value / $total_value * 360; // update for the starting angle of the next segment
  46. }
  47.  
  48. for($n=60;$n>50;$n--) {
  49. for($m=0;$m<count($angles);$m++)
  50. imageSmoothArc($piechart, imagesx($piechart)/2, $title_dimensions['height']+$title_pie_gap+$n, $radius, $radius * 0.5, $three_d_colors[$m], $angles[$m][0], $angles[$m][1]); // draw segment
  51. }
  52. $current_angle = 0;
  53. $i = 0;
  54. foreach($data_values as $value) { // iterate through values, printing and coloring segments for each
  55. imageSmoothArc($piechart, imagesx($piechart)/2, $title_dimensions['height']+$title_pie_gap+50, $radius, $radius * 0.5, $colors[$i], deg2rad($current_angle), deg2rad($current_angle + $value / $total_value * 360)); // draw segment
  56. $current_angle += $value / $total_value * 360; // update for the starting angle of the next segment
  57. $i++;
  58. }
  59. // START: Legend
  60. $legend_offset_top = $title_dimensions['height']+$title_pie_gap+$radius/2+$pie_legend_gap;
  61. for($i=0;$i<count($data_values);$i++) {
  62. $label_left = imagesx($piechart)/2-(16+5+$max_label_width)/2;
  63. imagefilledrectangle($piechart, $label_left, $legend_offset_top, $label_left+16, $legend_offset_top+16, imagecolorallocate($piechart, $colors[$i][0], $colors[$i][1], $colors[$i][2])); // draw a box for color-coding
  64. imagettftext($piechart, 12, 0, $label_left + 16 + 5, $legend_offset_top + 16, imagecolorallocate($piechart, $colors[$i][0], $colors[$i][1], $colors[$i][2]), $GLOBALS['font_path'], $labels[$i][0]); // write the label
  65. $legend_offset_top += 16 + $legend_gaps;
  66. }
  67. // END: Legend
  68. header('Content-Type: image/png');
  69. imagepng($piechart);
  70. }
  71.  
  72. function new_barchart($chart_width, $data, $axes, $title) {
  73. // chart width = bar_width * bar_count + bar_spacing * (bar_count - 1) + vertical_axis_width+vertical_axis_label_width
  74. // chart height = title_height + max_bar_height + horizontal_axis_height
  75.  
  76. $bar_spacing = 10;
  77. $axis_width = 5;
  78. $max_value = 0;
  79. $labels = array();
  80. $values = array();
  81. $colors = array();
  82. $bar_count = 0;
  83.  
  84. foreach($data as $barset) {
  85. $labels[] = array_keys($barset);
  86. $barset_values = array_values($barset);
  87. $values[] = $barset_values;
  88. foreach($barset_values as $value) {
  89. $bar_count++;
  90. if($value>$max_value)
  91. $max_value = $value;
  92. }
  93. }
  94.  
  95. $title_dimensions = get_dimensions_from_bbox(imagettfbbox(48, 0, $GLOBALS['font_path'], $title));
  96. $horizontal_axis_label_dimensions = get_dimensions_from_bbox(imagettfbbox(14, 0, $GLOBALS['font_path'], $axes[0]));
  97. $vertical_axis_label_dimensions = get_dimensions_from_bbox(imagettfbbox(14, 90, $GLOBALS['font_path'], $axes[1]));
  98.  
  99. $legend_labels = array();
  100. $max_label_width = 0;
  101. $m = 0;
  102. for($n=0;$n<count($data);$n++) {
  103. for($i=0;$i<count($data[$n]);$i++) {
  104. $legend_labels[] = array();
  105. $legend_labels[$m][] = $labels[$n][$i] . ' (' . $values[$n][$i] . ')'; // "label (value)"
  106. $legend_labels[$m][] = get_dimensions_from_bbox(imagettfbbox(12, 0, $GLOBALS['font_path'], $legend_labels[$m][0])); // work out the dimensions of the label
  107. if($legend_labels[$m][1]['width']>$max_label_width)
  108. $max_label_width = $legend_labels[$m][1]['width'];
  109. $m++;
  110. }
  111. }
  112. $max_label_width += $axis_width;
  113.  
  114. if($title_dimensions['width']>$chart_width)
  115. $chart_width = $title_dimensions['width'];
  116. $max_value_label = imagettfbbox(12, 0, $GLOBALS['font_path'], $max_value);
  117. $max_value_label_dimensions = get_dimensions_from_bbox($max_value_label);
  118. $chart_width += $max_value_label_dimensions['width'] + 25;
  119. $chart_height = $chart_width * 1.5;
  120. $scale_factor = ($chart_height - $axis_width - $title_dimensions['height']) / $max_value;
  121. $max_bar_height = $title_dimensions['height'] + $max_value * $scale_factor + $max_label_width;
  122. $bar_width = ($chart_width - $max_value_label_dimensions['width'] - $vertical_axis_label_dimensions['width'] - 25 - $axis_width - ($bar_spacing * count($data))) / $bar_count;
  123.  
  124. $barchart = imagecreatetruecolor($chart_width, $max_bar_height);
  125. imagefilledrectangle($barchart, 0, 0, imagesx($barchart), imagesy($barchart), imagecolorallocate($barchart, 255, 255, 255)); // fill the background white
  126. imagettftext($barchart, 48, 0, imagesx($barchart)/2-$title_dimensions['width']/2, 48, null, $GLOBALS['font_path'], $title);
  127. imagefilledrectangle($barchart, 25 + $max_value_label_dimensions['width'], $max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor, 25 + $axis_width + $max_value_label_dimensions['width'], $max_bar_height - $max_label_width, 0); // draw y-axis
  128. imagefilledrectangle($barchart, 25 + $max_value_label_dimensions['width'], $max_bar_height - $max_label_width, imagesx($barchart), $max_bar_height - $max_label_width - $axis_width, 0); // draw x-axis
  129.  
  130. $label_gaps = abs(($max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor) - ($max_bar_height - $max_label_width - $axis_width)) / 9;
  131. for($i=0;$i<10;$i++) {
  132. imagefilledrectangle($barchart, $max_value_label_dimensions['width'], $max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor + $i * $label_gaps, $max_value_label_dimensions['width'] + 25, $axis_width + $max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor + $i * $label_gaps, 0);
  133. //imagettftext($barchart, 12, 0, 0, $axis_width + $max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor + $i * $label_gaps, 0, $GLOBALS['font_path'], round($max_value - ($max_value / 9 * $i)));
  134. imagettftext($barchart, 12, 0, 0, $axis_width + $max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor + $i * $label_gaps + 3, 0, $GLOBALS['font_path'], round($max_value - ($max_value / 9 * $i)));
  135. }
  136.  
  137. $prev_bar_x = 25 + $max_value_label_dimensions['width'] + $axis_width + 1;
  138. $y_axis_height = abs(($max_bar_height - $max_label_width + $axis_width - $max_value * $scale_factor) - ($max_bar_height - $axis_width - 1 - $max_label_width));
  139. for($i=0;$i<count($data);$i++) {
  140. for($n=0;$n<count($data[$i]);$n++) {
  141. if(!isset($colors[$n]))
  142. $colors[$n] = imagecolorallocate($barchart, rand(0, 255), rand(0, 255), rand(0, 255));
  143. //$values[$i][$n] * $scale_factor
  144. //$max_bar_height - $max_label_width - 1 - $axis_width
  145. //imagesy($barchart) - 1 - $axis_width - $max_label_width
  146. $bar_height = $values[$i][$n]*($y_axis_height/$max_value);
  147. imagefilledrectangle($barchart, $prev_bar_x, $max_bar_height - $max_label_width - $axis_width - $bar_height, $prev_bar_x + $bar_width, $max_bar_height - $axis_width - 1 - $max_label_width, $colors[$n]);
  148. $prev_bar_x += $bar_width + 1;
  149. }
  150. $prev_bar_x += $bar_spacing;
  151. }
  152.  
  153. // START: Legend
  154. $legend_offset_top = $max_bar_height - $max_label_width + 1;
  155. $legend_gaps = 10;
  156. $label_left = $max_value_label_dimensions['width'] + $axis_width*2 + 16 + $bar_width/2 - 8;
  157. $n = 0;
  158.  
  159. $i = 0;
  160. for($n=0;$n<count($labels);$n++) {
  161. $m = 0;
  162.  
  163. foreach($labels[$n] as $label) {
  164. imagettftext($barchart, 12, 90, $label_left + 16, imagesy($barchart) + $axis_width - abs($legend_labels[$i][1]['width'] - $max_label_width), $colors[$m], $GLOBALS['font_path'], $legend_labels[$i][0]); // write the label
  165. $label_left += $bar_width;
  166. $i++;
  167. $m++;
  168. }
  169. $label_left += $bar_spacing;
  170. }
  171. // END: Legend
  172.  
  173. header('Content-Type: image/png');
  174. imagepng($barchart);
  175. }
  176.  
  177. /*if(isset($_GET['pie']))
  178. new_piechart(200, array('Apple'=>123, 'Orange'=>456, 'Banana'=>789, 'Pineapple'=>520), 'Fruits');
  179. else
  180. new_barchart(200, array(array('Apple #1'=>100, 'Apple #2'=>200, 'Apple #3'=>300), array('Orange #1' => 200, 'Orange #2' => 300, 'Orange #3' => 400), array('Banana #1' => 300, 'Banana #2' => 400, 'Banana #3' => 500, 'Apple Pie' => 400)), array('X Axis', 'Y Axis'), 'A');*/
  181.  
  182. if(isset($_GET['pie']))
  183. new_piechart(200, array('Apple'=>123, 'Orange'=>456, 'Banana'=>789, 'Pineapple'=>520), 'Fruits');
  184. else {
  185. $_GET['labels'] = explode('><', $_GET['labels']);
  186. $_GET['values'] = explode('|', $_GET['values']);
  187. $data = array();
  188. for($i=0;$i<count($_GET['labels']);$i++) {
  189. $labels = explode('<>', $_GET['labels'][$i]);
  190. $values = explode(',', $_GET['values'][$i]);
  191. $barset = array();
  192. for($n=0;$n<count($labels);$n++)
  193. $barset[$labels[$n]] = $values[$n];
  194. $data[] = $barset;
  195. }
  196.  
  197. new_barchart(100, $data, array('X Axis', 'Y Axis'), 'John');
  198. }
  199. ?>

Report this snippet  

You need to login to post a comment.