Skip to content

Instantly share code, notes, and snippets.

@cabloo
Last active March 21, 2016 18:10
Show Gist options
  • Save cabloo/5ffa7b2d8f4bb3bd8222 to your computer and use it in GitHub Desktop.
Save cabloo/5ffa7b2d8f4bb3bd8222 to your computer and use it in GitHub Desktop.
Custom PHP graphing library built for GameVue
<?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