Picture It with JpGraph

Let's face it: in the business world, you're bound to encounter individuals who just can't get "the big picture." At the sight of rows and columns of data, their brains disconnect, their eyes cross, their breathing becomes labored, and they pass out. But wouldn't it be nice to avoid all that trauma? Imagine if you could help those poor, spreadsheet-phobic souls grasp what the data actually means with a clear and decisive graph.

Let’s face it: in the business world, you’re bound to encounter individuals who just can’t get “the big picture.” At the sight of rows and columns of data, their brains disconnect, their eyes cross, their breathing becomes labored, and they pass out. But wouldn’t it be nice to avoid all that trauma? Imagine if you could help those poor, spreadsheet-phobic souls grasp what the data actually means with a clear and decisive graph.

Well, you’re guaranteed to make friends for life with the JpGraph library for PHP. JpGraph is an exciting, object-oriented graphing library for PHP that’s easy to install and integrate. In no time, your co-workers will be thanking you profusely for adding some style to their otherwise mundane data collating existence.

The Audience

As JpGraph is a PHP class library, it’s best used as an extension to your existing web application.

The package is not intended for heavy graphing, such as plotting thousands upon thousands of data-points, but is perfectly suited for displaying data sets in your web application.

For example, JpGraph is a great solution to picture your user forums’ posting statistics over the last 12 months.

JpGraph is quite powerful and can add a touch of professionalism to your project or product. Here’s a quick look at JpGraph’s feature set:

The average graph size is 2 K, and graphs can be created as JPEG, PNG, and GIF images.

JpGraph can create spider-plots, pie-charts (both 2D and 3D), scatter-plots, line-plots, filled line-plots, accumulated line-plots, bar plots, accumulated bar plots, grouped bar plots, error plots, line error plots, box plots, and stock plots.

The library automatically detects and supports GD1 and GD2, can create client-side image maps, and uses cubic splines to create smooth curves.

Other features include advanced text integration and manipulation, over two hundred built-in country flags, and over four hundred named colors.

A complete list of features is available on the JpGraph site at http://www.aditus.nu/jpgraph. JpGraph is written in PHP and made available under QPL 1.0 (the Qt Free License) for non-commercial, open-source and educational use. It’s also offered under the JpGraph Professional License for those wanting to incorporate the package into a proprietary or commercial application. The professional package provides BarCode, Tachometer/Odometer and Windose generation, in addition to email support. The latest version of JpGraph boasts 55,549 lines of code, consisting of 234 classes with a total of 1,798 methods/functions.

Getting Started

Installing JpGraph is as easy as copying its src directory into a directory of your choice. However, you must have PHP 4.1 or higher, and GD 1.8.Ix or GD 2.10 or higher. The recommended system configuration requires PHP 4.3.4 with the built-in GD library provided in that release of PHP.

Before proceeding, you should also make absolutely certain that PHP has compiled support for GD. Otherwise, JpGraph won’t work. To make sure GD is available, run phpinfo() in a PHP script. If you are using the recommended PHP 4.3.4, you’ll see the following information:

CGD Supportenabled
CGD Versionbundled (2.0.15 compatible)
CGIF Read Support enabled
CPNG Supportenabled
CWBMP Supportenabled
CXBM Supportenabled

To troubleshoot GD further, try creating some sample PHP images with the imagecreate() function. Also, a support forum on the JpGraph web site provides answers to most common installation problems.

TrueType fonts (TTF) can be used within JpGraph and are recommended. TTF provides for greater control of label appearance, and you’ll need to use TTF if you plan to use accented characters such as ñ in your graphs.

If you’re on Linux, simply download and install the Microsoft TrueType Core Fonts for Linux located at http://corefonts.sourceforge.net. Using TTF is discussed in detail in a moment.

The latest version of JpGraph can be retrieved from http://www.aditus.nu/jpgraph. After you download the tarball, make sure to verify that its MD5 checksum matches the MD5 checksum on the JpGraph download page. You can generate the MD5 checksum by typing md5sum file, where file is the name of the tarball. If the checksum is correct, unpack the tarball.

Next, install JpGraph. You can install JpGraph so that it can be shared among all PHP applications, or you can install it for your own use. To share JpGraph globally, go to the topmost directory of the JpGraph distribution and copy all of the files in src/ to a folder in your PHP include_path, such as /usr/local/lib/php. For personal use, copy the contents of the src/ directory to your application development directory, for example /usr/local/apache/htdocs/myapp/include/jpgraph.

Configuring JpGraph is also quite easy. Go to the directory where you just copied the files and, using your favorite text editor, open the file jpgraph.php. There are many options, but only four are vital: TTF_DIR, CACHE_DIR, USE_CACHE, and READ_CACHE.

Set TTF_DIR to point to the directory that contains your TrueType fonts, as in DEFINE (“TTF_DIR”, “/usr/ share/fonts/ttf/”). (If you use Windows, point TTF_DIR to the standard windows font directory, typically C:\Windows\fonts\.)

It’s also highly recommended that you use JpGraph’s caching as it will greatly reduce the load on your web server. To enable caching, set the cache control variables as follows:

DEFINE (“CACHE_DIR”, “/tmp/jpgraph_cache/”);

The directory you specify for CACHE_DIR must be writable by the Apache process user, or else you’ll wind up with broken images. If you have problems, look at the directory permissions on CACHE_DIR first.

Now, you’re ready to code.

Time to Code

If you don’t specify a filename when instantiating a new graph object, caching won’t take place. So, the following snippet represents how a graph object is typically created with JpGraph:

$graph = new Graph(600, 400, “auto”);

The third parameter, “auto”, is the filename for the generated graph. If caching is enabled, the file auto.png (PNG is the default graphic format for JpGraph) is created in CACHE_DIR.

Later, if the same file is referenced (say, by this very same call) and the file already exists in the cache, all JpGraph processing ceases and the image is loaded directly from the file system. If your graphing PHP script processes many sets of data, you should dynamically name each file as its own graph.

For example, if you want to generate a daily ranking of top “Pop” music downloads, you could generate a unique identifier from PHP variables $mediacat and $dayofweek, where $medicat might be Pop and $dayofweek would be one of Sunday, Monday, and so on.

$graphf= $mediacat.$dayofweek.”.png”;
$graph = new Graph(600,400,$graphfn);

This technique guarantees that a unique graph will be created and cached for each music category for each day of the week. Once again, this greatly reduces stress on the server. (JpGraph can also cache client-side image maps. Discussion of that feature can be found on the JpGraph site.)

To jumpstart your project, see the directory src/Examples/ for a plethora of example scripts that demonstrate how to construct bar, line, pie and many other types of graphs. There are even examples of how you can overlay many different datasets and graph-types.

JpGraph in Action

Let’s take a look at a real world example of how to integrate graphing functions within an existing web application. Building on the notion of top music downloads, let’s create a data set and application that, given a song’s unique media ID, generates a graph of the song’s popularity across a ten week span.

Let’s start with a dataset. The following table represents a collection of ten weeks of ranking data for a particular media file. The media ID is represented by the integer 501.

| week_id | media_id | rank |
| 1 | 501 | 10 |
| 2 | 501 | 15 |
| 3 | 501 | 3 |
| 4 | 501 | 40 |
| 5 | 501 | 27 |
| 6 | 501 | 19 |
| 7 | 501 | 2 |
| 8 | 501 | 34 |
| 9 | 501 | 12 |
| 10 | 501 | 20 |

All fields in this collection are integers and the primary key is a combination of week_id and media_id, as there must be only one and only one rank for each media ID for each week.

Listing One shows a script that takes this collection and plots a line graph using the core JpGraph libraries.

Listing One: Using the JpGraph library to create a line graph

// Include jpgraph configuration file
include (“./include/graph/jpgraph.php”);

// Include jpgraph line graph class file
include (“./include/graph/jpgraph_line.php”);

// Create ranking array from a data set. This data could come from MySQL
$ydata = array(“10″, “15″, “3″, “40″, “27″, “19″, “2″, “34″, “12″, “20″);

// Create our x-axis labels, which represent each week’s rank
$xlabels = array(“1″, “2″, “3″, “4″, “5″, “6″, “7″, “8″, “9″, “10″);

// Define which media id we’re generating a graph for

// Define a filename for caching based on datestamp and media id.
// You may also want to create a clean-up cron job to clear the
// filesystem cache of old graphs on a regular basis.

// Instantiate a new graph object given a width of 600 and height of 400.
// The third parameter is the filename used for caching purposes.
// If the local filename is found, all processing ceases and the local image
// is served.
$graph = new Graph(600, 400, $graphfn);

// Let’s set a background image to liven up the graph. If the background
// image is not found, you will have a broken image, ie, no graph will be
// generated. The second parameter allows you to set the position. In this
// case we’ve placed it in the center.
$graph->SetBackgroundImage(“/usr/local/images/sample.gif”, BGIMG_CENTER);

// Make sure to set the scale of the graph. You can supply further

// arguments to this method to manually apply a scale, otherwise
// jpgraph will decide the best scale.

// Set the margins for the graph as left, right, top, bottom in pixels.
$graph->img->SetMargin(40, 30, 25, 30);

// Set the title, font, and font-type of the chart.
$graph->title->Set(“Song 501 Rank History”);
$graph->title->SetFont(FF_FONT1, FS_BOLD);

// Set the x and y axis title, font and font-style.
$graph->yaxis->title->SetFont(FF_FONT1, FS_BOLD);
$graph->xaxis->title->SetFont(FF_FONT1, FS_BOLD);

// Instantiate the line plot object passing the rank data as the rank points.
$lineplot=new LinePlot($ydata);

// Let’s fill-in the line area with light blue with a slight transparency.

// Mark the plot points with a circle to emphasise the rank position.

// Almost done. We now add the line object to the graph.

// Finally, display the graph

This example can be viewed at http://www.internetdj.com/jpgraph_example.php.

There are a few other open source PHP graphing libraries, but none come close to the features and efficiency of JpGraph. It’s simple to install and configure, and even simpler to integrate with your existing data sets. Just slap on your existing MySQL database connection method and you’re in business.

Instead of a hard-coded array, you can build your own data set dynamically with a simple SQL statement. Most importantly, JpGraph is based on a flexible object-oriented framework that allows for limitless expansion.

Michael Bordash is an integration specialist, writer and programmer. His company, IP-soft.net, provides managed proprietary and open source services for Fortune 1000 companies. He is also the developer and manager of InternetDJ.com. Reach him at michael@bordash.com. You can download the source code used in this column from http://www.linux-mag.com/downloads/2004-03/lamp.

Comments are closed.