php goal thermometer
introduction
you’ve seen them all over the internet: non-profit ‘money raised’ goal thermometers. you know, where the ‘temperature’ is the current amount of money raised. i just got finished constructing one an i thought id share.
gd library
the gd graphics library is a library for dynamically manipulating images. it can create images composed of lines, arcs, text (using program-selected fonts), other images, and multiple colors. version 2.0 adds support for truecolor images, alpha channels, resampling (for smooth resizing of truecolor images), and many other features. gd is extensively used with php and has been included by default as of php 4.3. to create the goal thermometer we are going to utilize the power of this library.
getting started
we are going to be using php to create an image and then reference the php file in the src attribute of an img tag in html. the browser has to know to render the file as an image so we will need to set the header to reflect that:
<?php
header("Content-type: image/jpg");
we will also include some get variables in the query string of the src attribute to tell the php file the size of the goal thermometer so the next step is to grab those values:
$width = $_GET['width']; $height = $_GET['height']; $goal = $_GET['goal']; $current = $_GET['current'];
then we use the information to calculate our current progress towards our goal. notice that i’ve put a check to set the goal progress to 100% if we’ve exceeded it, this way the goal thermometer doesn’t display anything higher than 100%:
if ($current > $goal) {
$percent= "100%!";
} else {
$percent = round(($current/$goal)*100) . "%";
}
begin image creation
now we have some data to work with so we can begin to create the image using the gd library. first let’s just create the canvas for the image:
$im = imagecreate($width, $height);
now we can define the colors we will be using for the image as well as the text size:
$background_color = imagecolorallocate($im,200,200,200); $fill_color = imagecolorallocate($im,255,0,0); $notch_color = imagecolorallocate($im,255,200,200); $text_color = imagecolorallocate($im, 0, 0, 0); $text_size = 5;
the next step is to determine how much fill color to use, or in other words, what ‘temperature’ to set the goal thermometer at. since i’m constructing a horizontal goal thermometer i work with the $width variable:
$fill = (($current/$goal)*width);
once we have our fill amount we need to create a rectangle of that size to mimic the goal thermometers’s mercury:
imagefilledrectangle($im, 0, 0, $fill, $height, $fill_color);
next i will generate the notches along the goal thermometer so someone viewing it can get a bearing on how far along the progress is. for this example i’m going to put a notch every 10% of goal thermometer size:
$inc = $width / 10;
for($i=0;$i<=$width;$i+=$inc){
if ($i > 0) imageline($im,$i,0,$i,4,$notch+color);
}
to make the goal thermometer easier to read, i want the current progress displayed in the center of the thermometer. so we calculate the dead center of the goal thermometer and set coordinates accordingly (don’t forget to adjust the coordinates relative to the font size):
$text_x = ($width / 2) - 12; $text_y = ($height / 2) - 7; imagestring($im, $text_size, $text_x, $text_y, $percent, $text_color);
display the image
now that php has generated all the pieces of the image all we have left to do is put them together and then free up the memory that was used to generate the image.
imagejpeg($im); imagedestroy($im); ?>
make sure to use the imagedestroy() whenever creating an image. using php to generate images is easy and powerful but it does use a substantial amount of memory and if you use it too often without freeing the memory (let’s say in an image gallery for example) you may experience server bloat. save the document as thermometer.php.
the only step left is to call the php image from html:
<img src="thermometer.php?width=200&height=15&goal=1000¤t=200" />
the above img tag will generate a goal thermometer that’s 200px wide and 15px tall that has currently raised $200 of a $1000 goal. to make it completely dynamic you’d probably want to calculate the current when the pages loads rather than leaving it as a static number.
closing
you can see just how easy it really is to use php and the gd library to create images. there are plenty of practical uses for this other than a simple goal thermometer. one that immediately comes to mind is a captcha device.




