Dynamically Creating Graphs and Charts with PHP and GDChart

Friday Night Fever

If you’ve been working with PHP for a while, you already know that the language makes dynamic image generation very simple: the GD extension and a few lines of PHP code are all you need to create a JPEG, GIF or PNG image from scratch. However, while this works remarkably well for simple tasks, it can become tedious and complicated if you need to generate more complex images, such as graphs and charts, at run-time.

Take, for example, the task of turning a set of data values into a pie chart image. To arrive at the required result, you would need to allocate colors for each slice of the pie, calculate arc endpoints corresponding to the slice sizes, draw arcs and lines, fill each slice with a different color, write a descriptive text string and percentage value next to each slice, and render the final image. Completing the task might require between 80-100 lines of code and a few hours of debugging time…definitely not the most fun way to spend a Friday evening!

However, there’s a simpler alternative: PHP’s GDChart extension, which provides a full-featured API to efficiently generate charts and graphs. This extension, which is freely available from PECL, can significantly reduce the amount of work involved in dynamically generating graphical representations of numerical data at run-time. Over the next few pages, I’ll introduce you to this extension, illustrating its important features and showing you just how easy it is to get your Friday evening back.

Putting The Pieces Together

GDChart support in PHP comes through PECL’s ext/gdchart extension, which is maintained by Ilia Alshanetsky and Rasmus Lerdorf, and provides an object-oriented API for chart generation. This ext/gdchart extension, in turn, requires you to have GD support compiled into your PHP build. On UNIX systems, this is accomplished by downloading and installing the GD libraries from http://www.boutell.com/gd/ (if you don’t already have them), and then compiling PHP with the –with-gd configuration directive.

Once this is done, you can proceed to install the GDChart extension using the pecl command. Note that at the current time, a Windows version of ext/gdchart is not available; the following steps assume a *NIX system.

The PECL installer will now download the source code, compile it and install it to the appropriate location on your system.

Alternatively, manually download the source code archive (v0.2.0 at this time) from http://pecl.php.net/package/GDChart and compile it into a loadable PHP module with phpize:

This procedure should create a loadable PHP module named gdchart.so in your PHP extension directory. You should now enable the extension in the php.ini configuration file, restart your Web server, and check that the extension is enabled with a quick call to phpinfo():

One important note from the extension’s documentation bears repeating: if you encounter errors related to ‘GDC_title_font’ when compiling the extension, look inside your php_config.h and make sure that it includes a definition for LIBFREETYPE. More detailed instructions for this can be found in the documentation included with the source code.

Rain Dance

Once you’ve got the extension installed and working, it’s time to take it for a test drive. Here’s a simple example, which generates a bar chart for annual rainfall data:

This script begins by creating a new instance of the GDChart class and passing the constructor a constant indicating the type of chart (in this case, a bar chart). Next, the instance’s addValues() method is used to add data points to the chart (as an array), while the setLabels() method is used to set corresponding X-axis labels. Once all these preliminaries have been taken care of, the instance’s out() method takes care of actually preparing and rendering the chart.

The parameters passed to out() include the height and width of the output image, the image format (GIF, JPEG, WBMP or PNG), and an optional filename for the chart. In this case, because the output image is sent directly to the client, no filename is needed.

Here’s what the output looks like:

GDChart supports 20 different chart formats, so it’s pretty easy to represent the same data as, say, a line graph, by merely changing the value passed to the constructor:

And here’s what the revised output looks like:

Prefer an area chart? No problem:

And here’s the output:

Notice that in all these cases, changing the chart type was as simple as passing the object constructor a different argument; the main body of the script remained unchanged. If, on the other hand, you were creating the chart “by hand” using GD functions, it would be a lot of work to switch from one chart type to another. Thus, ext/gdchart offers significant efficiency benefits for dynamic chart generation.

While you’re chewing on that, here’s a complete list of the different chart types supported by ext/gdchart:

Constant Chart Type
HILOCLOSE High/Low/Close (HLC)
COMBO_LINE_BAR Combination Line and Bar
COMBO_HLC_BAR Combination HLC and Bar
COMBO_LINE_AREA Combination Line and Area
COMBO_LINE_LINE Combination Line and Line
COMBO_HLC_AREA Combination HLC and Area
PIE_2D 2D Pie
PIE_3D 3D Pie
BAR_3D 3D Bar
AREA_3D 3D Area
LINE_3D 3D Line
COMBO_LINE_BAR_3D 3D Combination Line and Bar
COMBO_LINE_AREA_3D 3D Combination Line and Area
COMBO_LINE_LINE_3D 3D Combination Line and Line
COMBO_HLC_BAR_3D 3D Combination HLC and Bar
COMBO_HLC_AREA_3D 3D Combination HLC and Area
FLOATINGBAR_3D 3D Floating Bar

Stack Me Up

To compare one data set with another, simply call the addValues() method again with a different set of values. GDChart will automatically create a new plot for you, making comparative analysis easy. To illustrate, here’s an example of two data sets in the same line graph:

Here’s the output:

With the ‘stackType’ property, you can even stack data sets together in the same chart. Here’s an example of a bar chart, with the bars stacked besides each other:

Here’s the output:

Alternatively, set the ‘stackType’ property to STACK_LAYER, to generate a chart with the bars stacked inside each other:

You can also add X- and Y- axis labels, as well as a title for the chart. Here’s an example:

And here’s the output:

An Eye For Color

Adjusting chart colors is accomplished through the careful use of the GDChart object’s setColors() method and ‘bgColor’, ‘gridColor’ and ‘lineColor’ properties. The setColors() method accepts an array of colors (in hexadecimal notation) for the graph itself, while the ‘bgColor’, ‘gridColor’ and ‘lineColor’ properties control, respectively, the color of the chart background, the color of the grid and the color of the gridlines. Here’s an example illustrating these properties and methods in action:

This example sets the chart background color to white, the bars to blue and the gridlines to pink. Flashy? Maybe, maybe not…here’s the result:

If you like, you can give each bar of a bar chart a different color, with the setExtColors() method. Here’s an example:

And here’s the output:

It’s also possible to customize the colors of the X- and Y-axis labels and titles, the chart title, and the chart grid and borders. The following listing illustrates:

The ‘titleColor’, ‘xtitleColor’, ‘ytitleColor’, ‘xlabelColor’ and ‘ylabelColor’ properties should be self-explanatory, but the ‘grid’, ‘zeroShelf’ and ‘border’ properties require a little more explanation. The ‘grid’ property controls the chart’s background grid, while the ‘zeroShelf’ property indicates whether or not the horizontal X-axis should be displayed. The ‘border’ property controls the chart border, and can accept any of the values BORDER_NONE, BORDER_ALL, BORDER_X, BORDER_Y, BORDER_Y2 or BORDER_TOP. Here’s the result:

The ‘titleSize’, ‘xtitleSize’ and ‘ytitleSize’ properties allow you to control the size of the chart title, X-axis title and Y-axis title respectively; these may be set to any of the self-explanatory values FONT_TINY, FONT_SMALL, FONT_MEDBOLD, FONT_LARGE or FONT_GIANT. Similarly, the ‘barWidth’ property allows precise control over the width of each bar in a bar chart. Here’s an example of these properties in action:

And here’s the output:

Finally, the ‘bgImage’ property allows you to place a GIF image as the background for your chart. Here’s an example:

And here’s the output:

Not My Type

Now that you know how to make your charts look pretty, let’s talk a little bit more about the different types of charts supported by ext/gdchart. In addition to the standard bar and line charts, you’ve seen so far, ext/gdchart also supports scatter plots, high/low/close graphs and pie charts.

Let’s look at scatter plots first. Here’s a simple example:

Here’s the output:

The only unfamiliar thing in this script is the addScatter() method. This method accepts five parameters: a point value, a position, a constant indicating the symbol to use for the point marker, a hexadecimal color code, and a size value. These parameters are then used to plot the corresponding point on the chart. You can call addScatter() as many times as you need for a single chart.

How about a high/low/close chart then? Here’s how to create one:

Here’s what the output looks like:

In this chart type, three different data sets – one each for high, low and close – are attached to the chart by repeatedly calling the addValues() method. The ‘hlcStyle’ property is used to control the appearance of the ‘close’ marker, and can take any one of the values HLC_DIAMOND, HLC_CLOSE_CONNECTED, HLC_CONNECTING or HLC_I_CAP. Play with these a little to see what each one does.

Pie In The Sky

Pie charts are extremely popular, and so it’s no surprise that GDChart comes with various properties and methods specifically for these types of charts. First up, the basic pie chart:

A pie chart is created in the same manner as other types of charts: initialize a GDChart object with the chart type, attach values and descriptive labels to the pie slices with the addValues() and setLabels() methods, and render the chart with out(). Here’s the result:

A nice touch would be to display the percentage of the pie occupied by each slice. With GDChart, this is a snap (and hey, it even calculates the percentages for you!):

Here, the ‘percentLabels’ property tells GDChart where to display the percentage value relative to each slice’s label (above, below, left or right), while the ‘percentFmt’ property lets you apply printf()-style formatting to the percentage display. Here’s the result:

Why stop there? GDChart also lets you customize the color of each slice and slice label, and even “explode” one or more slices for greater visual effect. Take a look:

As before, the setColors() method accepts an array of color codes (in hexadecimal notation) corresponding to the array of data values, and sets each slice to the corresponding color. The edges of each slice can be further outlined in a different color with the ‘edgeColor’ attribute, which is similar to the ‘lineColor’ attribute seen in earlier examples.

The labels that appear next to each pie slice may also be customized via the ‘labelLine’, ‘labelDist’ and ‘labelSize’ properties. The ‘labelLine’ property accepts a Boolean value indicating whether each pie slice should be linked with its descriptive label with a short line pointer, while the ‘labelDist’ property defines the distance between a pie slice and its corresponding label. The size of each label may be further adjusted with the ‘labelSize’ property, which accepts any one of the five pre-defined font sizes discussed earlier.

It’s also possible to detach one or more slices of the pie and “explode” it outwards for emphasis, with the setExplode() method. This method accepts an array of values corresponding to the array of data values, with each value representing the distance of the corresponding pie slice from the center; the higher the value, the greater that slice’s distance from the center. In the previous example, the slice representing the UK has been “exploded” outwards, to display the following result:

Finally, no discussion of GDChart’s pie charts would be complete without a mention of the setMissing() method, which lets you “hide” one or more slices of the pie. This method accepts an array of Boolean values corresponding to the array of data values, and hides those slices flagged as Boolean true. Here’s an example, which hides the slice for India:

And here’s the result:

Searching For Answers

Now that you’ve seen what the GDChart extension can do, let’s wrap this up with a practical example. Assume for a moment that you have a reasonably popular Web site with lots of interesting articles and tutorials, and that you’ve got a little bit of PHP code that’s diligently logging the searches performed by users on your site to a database. Assume further that the database table to which these queries are being logged looks like this:

Now, wouldn’t it be nice to see all this search log data neatly summarized by day in a graph? Of course it would…and with ext/gdchart, it’s a snap to do! Here’s the code:

Nothing too complex here – the script connects to the MySQL database, executes a GROUP BY query that essentially returns a count of the number of search queries executed in each day of the current month, and turns the result into an array. This array is then passed to the GDChart object’s addValues() and setLabels() methods, and used to generate a neat bar graph of the number of queries per day.

Here’s a sample of the output:

As these examples illustrate, the GDChart extension provides a way to quickly and efficiently turn numerical data into easy-on-the-eyes graphs and charts. Take a look at it the next time you have a chart to generate…and happy charting!

This article copyright Melonfire, 2008. All rights reserved.