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