[ Index ] |
PHP Cross Reference of MyBB |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * MyBB 1.6 4 * Copyright 2010 MyBB Group, All Rights Reserved 5 * 6 * Website: http://mybb.com 7 * License: http://mybb.com/about/license 8 * 9 * $Id $ 10 */ 11 12 class Graph { 13 14 /** 15 * The width of the image. 16 * 17 * @var integer 18 */ 19 public $img_width = 1000; 20 21 /** 22 * The height of the image. 23 * 24 * @var integer 25 */ 26 public $img_height = 300; 27 28 /** 29 * The image resource handle. 30 * 31 * @var resource 32 */ 33 private $im; 34 35 /** 36 * The amount of x pixels to start inside the image for the graph 37 * 38 * @var integer 39 */ 40 public $inside_x = 65; 41 42 /** 43 * The amount of y pixels to start inside the image for the graph 44 * 45 * @var integer 46 */ 47 public $inside_y = 30; 48 49 /** 50 * The width of the inside graph 51 * 52 * @var integer 53 */ 54 public $inside_width = 930; 55 56 /** 57 * The height of the inside graph 58 * 59 * @var integer 60 */ 61 public $inside_height = 220; 62 63 /** 64 * The x, y points for the graph 65 * 66 * @var array 67 */ 68 public $points = array(); 69 70 /** 71 * The corresponding x labels for the graph 72 * 73 * @var integer 74 */ 75 public $x_labels = array(); 76 77 /** 78 * The bottom label for the graph 79 * 80 * @var integer 81 */ 82 public $bottom_label = array(); 83 84 /** 85 * Constructor of class. Initializes the barebore graph. 86 * 87 * @return Graph 88 */ 89 public function __construct() 90 { 91 // Setup initial graph layout 92 93 // Check for GD >= 2, create base image 94 if(gd_version() >= 2) 95 { 96 $this->im = imagecreatetruecolor($this->img_width, $this->img_height); 97 } 98 else 99 { 100 $this->im = imagecreate($this->img_width, $this->img_height); 101 } 102 103 // No GD support, die. 104 if(!$this->im) 105 { 106 return false; 107 } 108 109 if(function_exists("imageantialias")) 110 { 111 imageantialias($this->im, true); 112 } 113 114 // Fill the background 115 imagefill($this->im, 0, 0, $this->color(239, 239, 239)); 116 117 // Create our internal working graph box 118 $inside_end_x = $this->inside_x+$this->inside_width; 119 $inside_end_y = $this->inside_y+$this->inside_height; 120 $this->image_create_rectangle($this->inside_x, $this->inside_y, $inside_end_x, $inside_end_y, 4, $this->color(254, 254, 254)); 121 122 // Draw our three lines inside our internal working graph area 123 for($i = 1; $i < 4; ++$i) 124 { 125 $y_value = $this->inside_y+(($this->inside_height/4)*$i); 126 imageline($this->im, $this->inside_x, $y_value, $inside_end_x, $y_value, $this->color(185, 185, 185)); 127 } 128 } 129 130 /** 131 * Select and allocate a color to the internal image resource 132 * 133 * @param integer The red value 134 * @param integer The green value 135 * @param integer The blue value 136 * @return integer A color identifier 137 */ 138 private function color($red, $green, $blue) 139 { 140 return imagecolorallocate($this->im, $red, $green, $blue); 141 } 142 143 /** 144 * Creates a filled rectangle with optional rounded corners 145 * 146 * @param integer The initial x value 147 * @param integer The initial y value 148 * @param integer The ending x value 149 * @param integer The ending y value 150 * @param integer The optional radius 151 * @param integer The optional rectangle color (defaults to black) 152 */ 153 private function image_create_rectangle($x1, $y1, $x2, $y2, $radius=1, $color=null) 154 { 155 if($color == null) 156 { 157 $color = $this->color(0, 0, 0); 158 } 159 160 // Draw our rectangle 161 imagefilledrectangle($this->im, $x1, $y1+$radius, $x2, $y2-$radius, $color); 162 imagefilledrectangle($this->im, $x1+$radius, $y1, $x2-$radius, $y2, $color); 163 164 if($radius > 0) 165 { 166 $diameter = $radius*2; 167 168 // Now draw our four corners on the rectangle 169 imagefilledellipse($this->im, $x1+$radius, $y1+$radius, $diameter, $diameter, $color); 170 imagefilledellipse($this->im, $x1+$radius, $y2-$radius, $diameter, $diameter, $color); 171 imagefilledellipse($this->im, $x2-$radius, $y2-$radius, $diameter, $diameter, $color); 172 imagefilledellipse($this->im, $x2-$radius, $y1+$radius, $diameter, $diameter, $color); 173 } 174 } 175 176 /** 177 * Creates a nicer thick line for angled lines 178 * 179 * @param integer The initial x value 180 * @param integer The initial y value 181 * @param integer The ending x value 182 * @param integer The ending y value 183 * @param integer The optional rectangle color (defaults to black) 184 * @param integer The optional thickness (defaults to 1) 185 */ 186 private function imagelinethick($x1, $y1, $x2, $y2, $color, $thick = 1) 187 { 188 if ($thick == 1) 189 { 190 return imageline($this->im, $x1, $y1, $x2, $y2, $color); 191 } 192 193 $t = $thick / 2 - 0.5; 194 if ($x1 == $x2 || $y1 == $y2) 195 { 196 return imagefilledrectangle($this->im, round(min($x1, $x2) - $t), round(min($y1, $y2) - $t), round(max($x1, $x2) + $t), round(max($y1, $y2) + $t), $color); 197 } 198 199 $k = ($y2 - $y1) / ($x2 - $x1); //y = kx + q 200 $a = $t / sqrt(1 + pow($k, 2)); 201 $points = array( 202 round($x1 - (1+$k)*$a), round($y1 + (1-$k)*$a), 203 round($x1 - (1-$k)*$a), round($y1 - (1+$k)*$a), 204 round($x2 + (1+$k)*$a), round($y2 - (1-$k)*$a), 205 round($x2 + (1-$k)*$a), round($y2 + (1+$k)*$a), 206 ); 207 imagefilledpolygon($this->im, $points, 4, $color); 208 209 return imagepolygon($this->im, $points, 4, $color); 210 } 211 212 /** 213 * Adds an array of x, y points to the internal points array 214 * 215 * @param array The array of x, y points to add 216 */ 217 public function add_points($points) 218 { 219 $this->points = array_merge($this->points, $points); 220 } 221 222 /** 223 * Adds an array of x labels to the internal labels array 224 * 225 * @param array The array of x labels to add 226 */ 227 public function add_x_labels($labels) 228 { 229 $this->x_labels = array_merge($this->x_labels, $labels); 230 } 231 232 /** 233 * Sets a bottom label 234 * 235 * @param string The bottom label to set 236 */ 237 public function set_bottom_label($label) 238 { 239 $this->bottom_label = $label; 240 } 241 242 /** 243 * Renders the graph to memory 244 * 245 */ 246 public function render() 247 { 248 // Get our max's and min's 249 $asorted = $this->points; 250 sort($asorted, SORT_NUMERIC); 251 $min = $asorted[0]; 252 $max = $asorted[count($asorted)-1]; 253 254 // Scale based on how many points we need to shove into 930 pixels of width 255 $x_delta = $this->inside_width/count($this->points); 256 257 // Scale our y axis to 220 pixels 258 $y_scale_factor = ($max-$min)/$this->inside_height; 259 260 // Get our Y initial 261 $y_initial = $this->inside_y+$this->inside_height; 262 263 // Get our scale for finding our points of reference to place our x axis labels 264 $x_label_scale = ceil(count($this->points)/20); 265 $x_label_points = array(); 266 267 foreach($this->points as $x => $y) 268 { 269 if(($x_label_scale == 0 || (($x+1) % $x_label_scale) == 0) && $x != 0) 270 { 271 $x_label_points[] = $x; 272 273 imagedashedline($this->im, $this->inside_x+($x_delta*$x), 30, $this->inside_x+($x_delta*$x), $y_initial, $this->color(185, 185, 185)); 274 275 imagefilledellipse($this->im, $this->inside_x+($x_delta*$x), $y_initial-$next_y_scaled+0.5, 8, 8, $this->color(84, 92, 209)); 276 } 277 278 // Look ahead to find our next point, if there is one 279 if(!array_key_exists($x+1, $this->points)) 280 { 281 break; 282 } 283 $next_y = $this->points[$x+1]; 284 285 if($y_scale_factor == 0) 286 { 287 $y_scaled = $next_y_scaled = 0; 288 } 289 else 290 { 291 $y_scaled = ($y-$min)/$y_scale_factor; 292 $next_y_scaled = ($next_y-$min)/$y_scale_factor; 293 } 294 295 // Draw our line 296 $this->imagelinethick($this->inside_x+($x_delta*$x), $y_initial-$y_scaled, $this->inside_x+($x_delta*($x+1)), $y_initial-$next_y_scaled, $this->color(84, 92, 209), 3); 297 } 298 299 // Draw our x labels 300 foreach($x_label_points as $x) 301 { 302 $label = $this->x_labels[$x]; 303 $text_width = imagefontwidth(2)*strlen($label); 304 $x = $this->inside_x+($x_delta*$x)-($text_width/2); 305 306 imagestring($this->im, 2, $x, $y_initial+5, $label, $this->color(0, 0, 0)); 307 } 308 309 // Draw our bottom label 310 imagestring($this->im, 2, ($this->img_width / 2), $y_initial+25, $this->bottom_label, $this->color(0, 0, 0)); 311 312 if($max > 4) 313 { 314 // Draw our y labels 315 for($i = 1; $i < 4; ++$i) 316 { 317 $y_value = $this->inside_y+(($this->inside_height/4)*$i); 318 imagestring($this->im, 2, 5, $y_value-7, my_number_format(round($min+(($max-$min)/4)*(4-$i))), $this->color(0, 0, 0)); 319 } 320 } 321 imagestring($this->im, 2, 5, $this->inside_y+$this->inside_height-7, my_number_format($min), $this->color(0, 0, 0)); 322 imagestring($this->im, 2, 5, $this->inside_y-7, my_number_format($max), $this->color(0, 0, 0)); 323 } 324 325 /** 326 * Outputs the graph to the screen in PNG format 327 * 328 */ 329 public function output() 330 { 331 // Output the image 332 header("Content-type: image/png"); 333 imagepng($this->im); 334 imagedestroy($this->im); 335 exit; 336 } 337 } 338 339 ?>
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Oct 8 19:19:50 2013 | Cross-referenced by PHPXref 0.7.1 |