Last active
March 21, 2016 18:10
-
-
Save cabloo/5ffa7b2d8f4bb3bd8222 to your computer and use it in GitHub Desktop.
Custom PHP graphing library built for GameVue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
class image | |
{ | |
public $registry; | |
public function resize( $new_img, $tempFile, $saveTo, $MaxWidth, $MaxHeight ) | |
{ | |
$path = pathinfo( $saveTo ); | |
if( !is_dir( $path['dirname'] ) ) | |
{ | |
mkdir( $path['dirname'], 0755, true ); | |
} | |
list( $width, $height ) = getimagesize( $tempFile ); | |
$old_width = $width; | |
$old_height = $height; | |
if( $height > $MaxHeight ) | |
{ | |
$scale_ratio = $MaxHeight / $height; | |
$height = $MaxHeight; | |
$width = $scale_ratio * $width; | |
} | |
if( $width > $MaxWidth ) | |
{ | |
$scale_ratio = $MaxWidth / $width; | |
$width = $MaxWidth; | |
$height = $scale_ratio * $height; | |
} | |
$resized_img = imagecreatetruecolor( $width, $height ); | |
imagecopyresized( $resized_img, $new_img, 0, 0, 0, 0, $width, $height, $old_width, $old_height ); | |
imagejpeg( $resized_img, $saveTo ); | |
} | |
/* | |
* Graphing functions | |
* | |
* @colors array: | |
* r: red | |
* g: green | |
* b: blue | |
* Max: 255 | |
* Min: 0 | |
*/ | |
public $colors = array( | |
'background' => array( | |
'r' => 234, | |
'g' => 235, | |
'b' => 236, | |
), | |
'text' => array( | |
'r' => 59, | |
'g' => 89, | |
'b' => 152, | |
), | |
'graph' => array( | |
'r' => 25, | |
'g' => 25, | |
'b' => 25, | |
), | |
); | |
/* | |
* Color generator for $im (image) and $Type (e.g. background/text) | |
*/ | |
public function Color( $im, $Type ) | |
{ | |
return imagecolorallocate( $im, $this->colors[$Type]['r'], $this->colors[$Type]['g'], $this->colors[$Type]['b'] ); | |
} | |
/* | |
* Graph users in certain $type with optional id $id | |
*/ | |
public function CreateImage( $type, $id = NULL ) | |
{ | |
if( !$id ) $id = $_GET['id']; | |
$y_max = $x_max = 0; | |
$months = array( ); | |
switch( $type ) | |
{ | |
case 'forum': | |
$months = array( ); | |
$time = time( ) - 60 * 60 * 24 * 150; | |
$get = $this->registry->mysql->Query( "SELECT `time` FROM `forum_threads` WHERE `forum` = '{$id}' AND `time` > '{$time}' ORDER BY `time` DESC" ); | |
while( $result = $this->registry->mysql->FetchArray( $get ) ) | |
{ | |
$month = date( 'F, Y', $result['time'] ); | |
$t = strtotime( $month ); | |
$months[$t]++; | |
if( $y_max < $months[$t] ) $y_max = $months[$t]; | |
} | |
break; | |
} | |
return $this->CreateStatisticsImage( $months, $x_max, $y_max ); | |
} | |
public function CreateStatisticsImage( $months, $x_max, $y_max ) | |
{ | |
/* | |
* The dimensions of the image | |
* These are used to make an image size multiplier | |
* if the image is too small or too large | |
* so the image will fit. | |
*/ | |
if( !function_exists( 'imagecreate' ) ) die( "GD PHP image extension not installed." ); | |
/* | |
* Check cache for encoded version of $months | |
*/ | |
$md5 = md5( json_encode( $months ) . $x_max . $y_max ); | |
/* | |
* First check if user sends last modified header | |
*/ | |
$cache_dir = 'uploads/stats_imgs'; | |
if( !is_dir( $cache_dir ) ) | |
{ | |
mkdir( $cache_dir, 0777, true ); | |
} | |
$file = $cache_dir . '/' . $md5; | |
$time = time( ); | |
$contents = false; | |
if( is_dir( $cache_dir ) && file_exists( $file ) ) | |
$time = filemtime( $file ); | |
else | |
{ | |
$x_max_necessary = 500; | |
$y_max_necessary = 250; | |
if( $months ) | |
{ | |
$y_padding = 20; | |
$x_padding = 10; | |
$x_gap = 50; // The gap between each point in x axis (pixels) | |
$x_max = $x_gap * count( $months ); // Width of the graph or horizontal axis | |
$x_mult = $x_max_necessary / $x_max; | |
$x_max = $x_max_necessary; | |
$y_mult = ( $y_max_necessary - $y_padding ) / $y_max; | |
$y_max = $y_max_necessary; | |
$im = imagecreate( $x_max, $y_max ) or die( "Could not create GD image." ); | |
$background_color = $this->Color( $im, 'background' ); | |
$text_color = $this->Color( $im, 'text' ); | |
$graph_color = $this->Color( $im, 'graph' ); | |
$x1 = 0; | |
$y1 = 0; | |
$x = 0; | |
$texts = array( ); | |
ksort( $months ); | |
foreach( $months as $Month => $Objects ) | |
{ | |
$Month = date( 'M, y', $Month ); | |
if( $x == 0 ) | |
{ | |
$x2 = $x_padding; | |
} | |
else | |
{ | |
$x2 = $x1 + ( $x_gap * $x_mult ); // Shifting in X axis | |
} | |
$y2 = $y_max - ( $Objects * $y_mult ); // Coordinate of Y axis | |
if( $x != 0 ) | |
{ | |
imageline( $im, $x1, $y1, $x2, $y2, $graph_color ); // Drawing the line between two points | |
/* | |
* Calculate difference in x1/x2 and y1/y2 for angle | |
*/ | |
$angle = - rad2deg( atan( ($y2 - $y1)/($x2 - $x1) ) ); | |
$texts[count( $texts ) - 1]['a'] = $angle; | |
/* | |
* Push text a little bit away from line | |
*/ | |
/*$diff = 5; | |
$diff_x = $diff * sin( $angle ); | |
$diff_y = $diff * cos( $angle ); | |
$texts[count( $texts ) - 1]['x'] += $diff_x; | |
$texts[count( $texts ) - 1]['y'] += $diff_y;*/ | |
} | |
/* | |
* Store text in array to draw later (on top of lines) | |
*/ | |
$texts[] = array( | |
'x' => $x2, | |
'y' => $y2, | |
't' => $Month . ' (' . $Objects . ')', | |
'a' => 0, | |
); | |
//imagestring( $im, 2, $x2, $y2, $Month . ' (' . $Objects . ')', $text_color ); // Print name of month: users | |
$x1 = $x2; // Storing the value for next draw | |
$y1 = $y2; | |
$x++; // Allow the drawing of lines | |
} | |
foreach( $texts as $key => $value ) | |
{ | |
imagettftext( $im, 8, $value['a'], $value['x'], $value['y'], $text_color, '../global/assets/fonts/eurostileltstd-webfont.ttf', $value['t'] ); | |
} | |
} | |
else | |
{ | |
$im = imagecreate( $x_max_necessary, $y_max_necessary ) or die( "Could not create GD image." ); | |
$background_color = $this->Color( $im, 'background' ); | |
$text_color = $this->Color( $im, 'text' ); | |
imagettftext( $im, 20, 0, round( $x_max_necessary / 2 - 90 ), round( $y_max_necessary / 2 ), $text_color, '../global/assets/fonts/eurostileltstd-webfont.ttf', 'No activity yet!' ); | |
//imagestring( $im, 4, $x_max_necessary / 2 - 70, $y_max_necessary / 2 - 15, 'No activity yet!', $text_color ); | |
} | |
imagepng( $im, $file, 9, PNG_ALL_FILTERS ); | |
//imagejpeg( $im, null, 100 ); | |
imagedestroy( $im ); | |
} | |
$date = gmdate( 'D, d M Y H:i:s', $time ) . ' GMT'; | |
$status = 200; | |
if( isset( $_SERVER['HTTP_IF_MODIFIED_SINCE'] ) && $_SERVER['HTTP_IF_MODIFIED_SINCE'] == $date ) | |
{ | |
$status = 304; | |
} | |
header( 'Last-Modified: ' . $date, true, $status ); | |
if( $status == 304 ) die( '' ); | |
die( file_get_contents( $file ) ); | |
} | |
/* | |
* Generate a line in $image from ($x1,$y1) to ($x2,$y2) with color $color and thickness $thick | |
*/ | |
public function imagelinethick( $image, $x1, $y1, $x2, $y2, $color, $thick = 1 ) | |
{ | |
if( $thick == 1 ) | |
{ | |
return imageline( $image, $x1, $y1, $x2, $y2, $color ); | |
} | |
/* | |
* More than 1px thick, need to generate a rectangle/polygon | |
*/ | |
$t = $thick / 2 - 0.5; | |
if( $x1 == $x2 || $y1 == $y2 ) | |
{ | |
/* | |
* X or Y coordinates are equal, all we need is a rectangle | |
*/ | |
return imagefilledrectangle( $image, round( min( $x1, $x2 ) - $t ), round( min( $y1, $y2 ) - $t ), round( max( $x1, $x2 ) + $t ), round( max( $y1, $y2 ) + $t ), $color ); | |
} | |
/* | |
* Generate a polygon | |
*/ | |
$k = ( $y2 - $y1 ) / ( $x2 - $x1 ); | |
$a = $t / sqrt( 1 + pow( $k, 2 ) ); | |
$points = array( | |
round( $x1 - ( 1 + $k ) * $a ), round( $y1 + ( 1 - $k ) * $a ), | |
round( $x1 - ( 1 - $k ) * $a ), round( $y1 - ( 1 + $k ) * $a ), | |
round( $x2 + ( 1 + $k ) * $a ), round( $y2 - ( 1 - $k ) * $a ), | |
round( $x2 + ( 1 - $k ) * $a ), round( $y2 + ( 1 + $k ) * $a ), | |
); | |
imagefilledpolygon( $image, $points, 4, $color ); | |
return imagepolygon( $image, $points, 4, $color ); | |
} | |
} | |
?> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment