**Disclaimer:
My blog contains content that may be objectionable. Some of the posts in this blog may contain strong language or (because of my religious and personal views) may be offensive to some readers. In the future I may separate my programming posts from personal posts, but for now they are all contained in this blog. I should not have to even mention this, however some readers may be looking at my blog for programming help, therefore I am giving an advanced warning. All posts with material that may be offensive contain 'Objectionable material' at the end of the post title. If you see a post with "Objectionable material" in the title, and you are closed-minded or think that you may get queasy, don't fucking read it.


Tuesday, August 10, 2010

Creating a line graph using dates with JpGraph

If you need to present data in a graph or chart on your web page, there are a few options. One of them that I found useful is JpGraph. There were a few others I found as well, but I chose this one for the following reasons:
  • It includes many different types of charts and graphs, from your basic line and pie charts to geolocation and stock charts.
  • It is flexible and very customizable
  • It is well documented, and there are plenty of examples (images along with the source code) included with the download.

JpGraph uses the PHP GD library to build the graphs into images. The images can be returned and presented directly in the browser, or saved to a cache file (or both).

For my uses, I needed a line graph using dates taken from a MySQL Timestamp. I also wanted to save the images to a cache file with a timeout, to prevent a new image from being generated if a recent version already exists.

I created a new PHP file and placed the code to create the graph into its own function. This way, I can add another graph function in the file later if need-be, and I can somewhat customize the graph through the function arguments while still keeping a consistent format and not re-writing code. To keep the example as simple as possible, I am not passing the title and legend text as arguments to the function. First I will show an example of how to create and save the graph, then I will show how I used it in my page.

Source Code:
function newLineGraph($cachefilename, $ydata, $xdata)
{
 require_once ('jpgraph-3.0.7/src/jpgraph.php');
 require_once ('jpgraph-3.0.7/src/jpgraph_line.php');
 require_once ('jpgraph-3.0.7/src/jpgraph_utils.inc.php');
 require_once ('jpgraph-3.0.7/src/jpgraph_date.php');
 // First we create the graph with a size of 600 x 500. 
 $graph = new Graph(600, 500);
 // Check if the image already exists in the cache and is valid
 $valid = $graph -> cache -> IsValid($cachefilename);
 if ($valid)
 {
  // The cached file exists and has not expired, so we do not 
  // need to create a new one
  return;
 }
 else
 {
  // The cache file does not exists or has expired, so we
  // create the graph as normal
 
  // Tell the graph that we want to cache this image
  // with a timeout of 60
  $graph -> SetupCache($cachefilename, 60);
  //Set the scale to use DateScale
  $graph -> SetScale("datlin");
  //Set the text for the graph Title
  $graph -> title -> Set('My Date Graph');
  //Enable clipping to prevent the line from extending
  // outside of the plot area
  $graph -> SetClipping(true);
  // Set the date format to use for the date labels
  $graph -> xaxis -> scale -> SetDateFormat('M-d');
  // Since we're taking in dates from MySQL, we need to
  // convert them to time
  $xDates = array ();
  for ($i = 0; $i < sizeof($xdata); $i++)
  {
   $time = strtotime($xdata[$i]);
   array_push($xDates, $time);
  }
  $dateUtils = new DateScaleUtils();
  // We'll let getAutoTicks calculate all of the ticks between
  // our min and max dates. We also set the max number of
  // ticks to 5.'
  $autoTicks = $dateUtils -> getAutoTicks($xDates[0],
$xDates[sizeof($xDates) - 1], 10); // Se the tick positions to the ones returned by getAutoTicks $graph -> xaxis -> SetTickPositions($autoTicks[1]); // Now we create the actual plot line $lineplot = new LinePlot($ydata, $xDates); $lineplot -> SetLegend('My Plot Line'); // Add the plot line to the graph $graph -> Add($lineplot); // Get the filepath where the cache file will be saved // NOTE: You MUST specify an absolute filepath here, // for example '/myCacheFiles/filename' will not work $absolutePath = (CACHE_DIR . "" . $cachefilename); // And finally, set the filepath when we call the Stroke function $graph -> Stroke($absolutePath); } }

Now that we have the graph created and saved to the cache, we can present it on the page. We will place it just as any other image in HTML, using the <img> tag. You can use any filename you wish, whether it be static or dynamic. For my purpose I chose to use a dynamic generated filename, which includes the date and hour, as well as a unique ID. If you choose to generate a filename, be sure that it is unique enough so that if the image has not expired in the cache and the browser pulls it up, it does not present the wrong data. For this example I will use a simple static filename called myFile.png. The default image type in JpGraph is .png.

Important Note: The graph must be created before anything is written to the page. Create the graph, save the filename to a variable, then use the variable in your image tag.

Another Note: I found that when I use full Timestamps directly from MySQL, the graph works for the most part, however the leftmost label disappears on the x-axis, and the right label and plot point is pushed to the left slightly. It is not a big concern, but enough to prevent a professional looking graph. I didn't spend much time trying to figure this out, as simply selecting only the date from the timestamp in the MySQL query solved the issue. I have not tried using times in place of dates, so I'm not sure if the issue is present here or not.

Source Code:
<?php
$ydata = array ( 11, 12, 11, 10, 10.5);
$xdata = array ('2010-07-01', '2010-07-02', '2010-07-03',
'2010-07-04', '2010-07-05'); $filename = 'myFile.png'; $graph = newLineGraph($filename, $ydata, $xdata); ?> <html> <title>My Graph Page</title> <body> <img src='<?php echo $filename; ?>'></img> </body> </html>

The result:

And there ya have it, folks - a simple line graph with dates using JpGraph. Here are a few links that helped me that you may want to look in to:

No comments:

Post a Comment