Developer

Create graphics on the fly using PHP

Ever wonder how sites like Yahoo!Finance generate those dynamic bar charts as stock prices change throughout the day? It's not magic--free tools like PHP make generating on-demand graphics a cinch.

PHP has the amazing ability to create dynamic images on the fly using server-side scripts. The basis for this functionality is the GD Library, an ANSI C library designed by Thomas Boutell. The library supports most popular image file formats except for .GIF files (although the author promises to add.GIF support once the LZW patent expires on July 7, 2004).

The GD Library is integrated in PHP versions 4.3 and above. If you are using an older version of PHP, you will have to install the graphics support manually. Plenty of information is available on setup.

Line chart graphics
To illustrate how PHP can create dynamic graphics, we'll build some custom charts. The first example is a line chart set against a grid, shown in Figure A.

Figure A
Line chart generated by grid.php


We've called our page grid.php (Listing A). To call a dynamically generated image in your Web page, all you need to do is reference the PHP page that will stream the graphic into the browser. The IMG element will do the job nicely. Here is an example of code to accomplish this:
<img src="grid.php" />

Now for the actual code that will create the graph. Here is a breakdown of the source code in grid.php:
<?
// Add values to the graph
$graphValues=array(0,80,23,11,190,245,50,80,111,240,55);

First, we define values for our chart. In this example, they are hardcoded in an array, but you can easily bring them in from an XML file, a form, or a database. The values range from 0 to 250 (the dimensions of the image in pixels). The value will determine the initial pixel position of each chart segment on the grid. If you want to use values between 0 and 100 (as in a percentage), all you need to do is multiply the value by 25 to determine the pixel position on the grid.

Next, we send out a PNG header and define the width and height of the image:
// Define .PNG image
header("Content-type: image/png");
$imgWidth=250;
$imgHeight=250;

We send out an image header to trick the browser into thinking our PHP page is actually an image so that it will render properly on the screen. The information sent by the server will be a binary stream resulting from our program.

PNG stands for Portable Network Graphic, a lossless graphic format designed in 1995 in response to the legal problems with GIF's patented LZW algorithm.

Now, we instantiate our image object and define the color we will use in the graph:
// Create image and define colors
$image=imagecreate($imgWidth, $imgHeight);
$colorWhite=imagecolorallocate($image, 255, 255, 255);
$colorGrey=imagecolorallocate($image, 192, 192, 192);
$colorBlue=imagecolorallocate($image, 0, 0, 255);

We set a white background, gray gridlines, and a blue line style chart. You can easily change or add colors by creating new variables and specifying different RGB values.

We then create a gray border around the image using the imageline function, one line at a time:
// Create border around image
imageline($image, 0, 0, 0, 250, $colorGrey);
imageline($image, 0, 0, 250, 0, $colorGrey);
imageline($image, 249, 0, 249, 249, $colorGrey);
imageline($image, 0, 249, 249, 249, $colorGrey);

There are two sets of x/y pixel coordinates. Each of the pair values within the imageline function specifies a start and end position within the image.

To complete the grid, we add a gray line at a regular interval of 25 pixels on both the x and y axis:
// Create grid
for ($i=1; $i<11; $i++){
imageline($image, $i*25, 0, $i*25, 250, $colorGrey);
imageline($image, 0, $i*25, 250, $i*25, $colorGrey);
}

Position (0,0) refers to the top-left corner of the grid, and position (250,250) refers to the bottom right. There are 10 lines on an axis with an interval of 25 pixels, which equals 250 pixels (the dimensions of the image).

To generate the line graph, we simply loop through the array to figure out the start and end position of each line segment:
// Create line graph
for ($i=0; $i<10; $i++){
imageline($image, $i*25, (250-$graphValues[$i]), ($i+1)*25, (250-$graphValues[$i+1]), $colorBlue);
}

PHP will automatically fill in a blue line in between each pair of coordinates. This simple example has only 10 values, but you can easily expand on the technique and create complicated charts that resemble stock market indices, etc.

Finally, we need to output the image to the browser and clean up the memory space on the server storing the image:
// Output graph and clear image from memory
imagepng($image);
imagedestroy($image);
?>

Bar charts
We can easily take the same basic program we used to build a line chart and generate bar charts instead (Figure B).

Figure B
Bar chart generated by barchart.php


The routine (Listing B) is slightly different from the one we used for the line chart. The imagefilledrectangle function creates two sets of rectangles—the dark blue bars representing the values in the $graphValues array and a lighter fill within those dark bars:
// Create bar charts
for ($i=0; $i<10; $i++){
imagefilledrectangle($image, $i*25, (250-$graphValues[$i]), ($i+1)*25, 250, $colorDarkBlue);
imagefilledrectangle($image, ($i*25)+1, (250-$graphValues[$i])+1, (($i+1)*25)-5, 248, $colorLightBlue);
}

Watch the CPU load
You need to be aware of one important consideration when you create these graphics server-side: They're CPU intensive. If you place too many of these dynamic images on your Web site, you may find that you will incur a performance hit.

Beyond simple charts
The examples in this article are just a starting point. For more information about the PHP Graphics Library, be sure to visit the image functions page on PHP.net.

Editor's Picks