1 About this manual

1.1 Version history

VersionDateStatusWhoComment
R1.82005-04-01ReleasedJohan Persson Additional info for JpGraph 1.17.

1.2 How was this manual produced?

The bulk of the text was written directly in Emacs on a GNU/Linux system in a mixture of PHP and HTML. A number of PHP functions were used to automate the handling of formatting example code and figures.

To generate the images automatically in the img directory a custom awk-script is used to extract all the used image script from the manual. The script then uses the client version of PHP generate the images from the scripts and stores them in the 'img' directory.

The final set of HTML files was then processes by HTMLDOC to construct table of contents and chapter links.

2 Introduction

2.1 Version

This manual covers version 1.17-beta of JpGraph. A 2D graph plotting library for PHP >=4.3.x and above.

Even though the library is known to work with version of PHP prior to 4.3 the library is not tested nor is it recommended to run with any older versions of PHP.

2.2 Software License

JpGraph 1.x is released under a dual license QPL 1.0 (Qt-License) for non-commercial (including educational) use of the library and the JpGraph Professional License for commercial use.

2.3 JpGraph Features

JpGraph library is an OO graph library which makes it easy to both draw a "quick and dirty" graph with a minimum of code and quite complex graphs which requires a very fine grain of control. The library tries to assign sensible default values for most parameters hence making the learning curve quite flat since for most of the time very few commands is required to draw graphs with a pleasing esthetic look.

Some highlights of available features are

In addition to these high level features the library has been designed to be orthogonal and consistent in its' naming convention. For example, to specify color each object (i.e. axis, grids, texts, titles etc) within the graph implements the method SetColor() with the same signature.

2.4 Getting the latest version

The latest version of jpgraph can always be found on http://www.aditus.nu/jpgraph/

The current version as of this writing is 1.17

Information on version numbering schema

2.5 Planned future addition

All the following features, which have not been marked as tentatively, will be added. The time frame for these versions are:

For the latest update on planned future version see the web-site for JpGraph at http://www.aditus.nu/jpgraph/

2.6 Known bugs and omissions

2.7 Acknowledgments

The idea for writing this library grew out of our own need for a high quality graph drawing library for PHP. When evaluating potential existint libraries we found (at that time cirka 2001) these three

  1. "chart 0.3" http://quimby.gnus.org/circus/chart/chart-0.3.tar.gz, by Lars Magne Ingebrigtsen
  2. "ykcee.php", http://ykcee.sourceforge.net
  3. "phplot.php", http://www.phplot.com

All these libraries implements some fine graphic features but unfortunately none of those completely fulfilled our needs either for available functionality (for example none of these supported both two Y-scales, auto-scaling, and logarithmic scales), or general flexibility. We especially needed the option of two Y-scales, which none of the above packages supported. Our own preferences for design was closest to "chart 0.3" so we started by fixing some bugs in that package and adding some new features. However It was soon realized that to add all the features and flexibility we needed to "chart 0.3" it would require a complete rewrite since the original design wasn't flexible enough, especially adding a second Y-scale would require a more flexible OO architecture.

2.8 Reporting bugs and suggesting improvements

Defects or suggestion for new features can be entered using the JpGraph BugTracker available at http://www.aditus.nu/bugtraq/

Before reporting bugs or feature suggestions may we ask that the following facts are considered.

2.9 Getting support

Customers who have aquired the pro-version of the library are entitled to prioritized e-mail support for a specific time after the purchase. Support tickets may be created by first logging in to http://www.aditus.nu/jpgraph/pro_login.php and then create a support ticket.

For other users a public community forum is available at http://jpgraph.intellit.nl/ where many common questions are answered and discussed.

In addition there is a collection of FAQs available at http://www.aditus.nu/jpgraph/jpgraphfaq.php

Finally, we regret that we are unable to provide general support regarding PHP/GD/TTF/Apache installation outside the specific scope of the JpGraph library. Please see the corresponding documentation and relevant FAQ for those products.

3 Installation

3.1 Preparation

In order to make use of the library it is necessary to ensure that the script files can correctly access the library include files (as described below) and that the PHP installation supports at least one graphic format, i.e. it supports the "image" extension in PHP.

This is easiest verified by eiether checking the output of the phpinfo() standard PHP function or by making sure the PHP installation make the 'imagecreate()' function available.

This means that the insrtallation must have a working GD-library together with PHP before the library JpGraph can be used. Please make sure you have version 4.3.x or above of PHP since JpGraph is not actively tested with versions prior to PHP 4.3.x Ideally you should use at least PHP 4.3.8

Please note that the 1.x version of the library do not support PHP 5.x

3.1.1 Verifying that you have the GD library installed

In order to make sure that the GD installed the following example whould be run. The example creates a very simple image using just pure GD calls and outputs an image in PNG format. This could be considered a smoke-test to see that the GD libary is available from PHP. Please note that this is an absolute pre-requisite in order for the JpGraph library to work at all.

Store the code snippet below somewhere in the document root and make sure it runs correctly.

$im = @ ImageCreate ( 150, 100)
    or die (
"Cannot create a new GD image.");
$background_color = ImageColorAllocate ($im, 255, 255, 255);
$text_color = ImageColorAllocate ($im, 233, 14, 91);
ImageString ($im, 1, 5, 5,  "A Simple Text String", $text_color );
header ("Content-type: image/png");
ImagePng ($im);

If the above script does not work or some error or warnings are printed on the screen then it is necessary to correct those problems before proceeding with the installation.

3.1.2 Verifying that you have GD2 installed

To access the more advanced features of JpGraph needs the GD 2.x library. This will allow the use of features such as alphablending and trucolor images.

The GD 2.x libary is included in all standard PHP versions from 4.2.x and above. To make sure that the GD 2.x libary is installed the following script must be working.

$im = imagecreatetruecolor ( 300, 200);
$black = imagecolorallocate ($im, 0, 0, 0);
$white = imagecolorallocate ($im, 255, 255, 255);

imagefilledrectangle ($im,0, 0,399,99 ,$white);
imagerectangle ($im,20, 20,250,190 ,$black);

header ("Content-type: image/png" );
imagepng ($im);

After running this script you should now see a black rectangle in your browser.

3.1.3 Preparing True Type Font Files

JpGraph contains as default a standard set of bitmap fonts which only supports the standard ASCII 7-bit character set. In order to use accented characters, UTF-8, Chinese, Japanes, etc You need to download TTF fonts. Due to various legal issues no TTF fonts are supplied in the JpGraph package. To enable TTF fonts there are three alternatives:

  1. If you are on a Windows platform you can just point to the TTF directory in JpGraph to the standard fonts directory (e.g C:\windows\fonts\)
  2. If you are on a Unix platform you can download and install the core MS WEB-initiative fonts from http://corefonts.sourceforge.net/
  3. It is also possible to use the Vera Bitsream TTF fonts available from http://www.gnome.org/fonts/

It is also necessary to make sure that the PHP installation supports TTF fonts (either through FreeType 1 or FreeType 2 libraries). I n addition some suitable TTF font files must also be available. To make the font files available for the library the directory path to the location of the font files must be specified in the configuration file, jpg-config.inc

JpGraph uses a standard naming convention for the TTF font files in order to be able to find the correct font files. This naming convention follows the standard naming of the available font files.

If the installation of the library is made on a computer running MS Windows then it is recommended to use the already available font files in Windows (usually located in C:\WINDOWS\FONTS).

If the installation is made on a UNIX derivate running X11 then the font location can differ between versions and UNIX brands. One commonly used path is "/usr/X11R6/lib/X11/fonts/truetype/".

Finally we note that it is possible to install additional fonts not natively supported by the library. Since this requires augmenting the library files this is considered advanced use and not further discussed in this introduction.

3.1.4 Using non-latin based fonts with JpGraph

In addition to European font it is also possible to use non-latin based fonts such as Cyrillic, Japanese and Chinese.

In all cases a suitable TTF font that supports the non-latin based language must be available.

For Cyrillic support the define LANGUAGE_CYRILLIC in jpg-config.php must be set to true. It is then possible to use a suitable Cyrillic font as replacement for the ordinary fonts.

For Chinese charcter set JpGraph supports both BIG5 and GB2312 encoding. For BIG5 encoding the PHP installation must have support for the "iconv()" function. Furthermore the define CHINESE_TTF_FONT must be set to the name of the Chinese BIG5 font that is to be used. By default this is set to "bkai00mp.ttf". To use the Chinese BIG5 font in the scripts one must then specify the font family as FF_CHINESE.

To use the alternative font files "simsun.ttc" and "simhei.ttf" (which uses the GB2312 encoding) the only step needed is to install those fonts in the normal TTF font directory and then specify the font family as FF_SIMSUN, the "simhei.ttf" is used when the font style is specified as FS_BOLD.

3.2 Customizing the installation

In order for JpGraph to work it is necessary to adjust the cache and TTF directory to suit the specific installation. By default the TTF directory is "/usr/X11R6/lib/X11/fonts/truetype/" and for the cache "/tmp/jpgraph_cache/". These are defined as PHP defines at the top of jpg-config.inc

Please make sure that PHP has write permissions to the cache directory if the cache feature snhould be used. If this is not the case a "Can't write file xxx.yyy" error will occur when a graph that uses the cache feature are generate. More information regarding the cache feature of JpGraph is availble in the section Making sense of caching system in JpGraph

3.3 Required files

This is the base library files, which you must have

3.3.1 Plot extension modules

To add plots to the graph you will need one or more of the following files plot extension files depending on what kind of graph you need to create.

In the pro-version the following additional files are available

3.4 Image formats and external image libraries

Per default the standard GD image library supports PNG graphic formats. You will need to have that installed together with your PHP module for this library to work at all. Please refer to PHP documentation on specifics. Note that the newer versions of GD does not support the GIF format due to copyright problems. Hence by default only PNG is supported.

If you want JPEG support you will also need an additional library for PHP, again please see PHP documentation for specifics. For most practical purposes PNG is a better format since it normally achieves better compression then GIF (typically by a factor of 2 for the types of images generated by JpGraph). In comparison with JPEG format PNG is also better for the type of images generated by this library. So, the bottom line is, you should have a very good reason to choose any other format then PNG.

By default the image format is set to "auto". This means that JpGraph automatically chooses the best available graphic using the preferred order "PNG", "GIF", "JPG".

3.5 Detailed steps to install JpGraph

  1. Make sure the PHP version used is at least 4.3.x (preferable 4.3.7 or higher) and that the PHP version have compiled support for GD library. It is absolutely critical that GD is fully working. Please see the earlier sections on how to make sure. JpGraph supports both GD 1.x and GD 2.x However it is strongly recommended to use GD 2.x since that will improve performance and support true color images as well as alphablending.
  2. Unzip and copy the files to a directory of your choice.
  3. Set up the directory paths in jpg-config.inc where the cache directory should be and where your TTF directory is. Note that Apache/PHP must have write permission in your cache directory.
  4. Check that all rest of the DEFINE in the top of JpGraph.php is setup to your preference. The default should be fine for most users. (See also Note 5. below) Specifically check that the settings of USE_GD2_LIBRARY reflects your installation, (should be true if you have GD2 installed, false otherwise).
  5. Make sure PHP have write privileges to your cache directory if you plan on using the cache feature.
  6. Some windows installations seems to have a problem with a PHP script ending in a newline (This newline seems to be sent to the browser and will cause a Header already sent error). If you have this problem try remove all trailing newlines in the jpgraph* files
  7. Read (really!) the JpGraph FAQ.

3.6 Troubleshooting your installation

For 99% of the users this library will work directly with a recent installation of PHP without any problem.

Experience shows that most of the trouble are caused by either an old buggy version of the free-type TTF library or using an old antiquated version of the GD library. In order to narrow it down the problem the following steps is helpfull.

  1. If no background images are disaplayed (instead a solid black box are displayed) chances are that GD 2.x is available but the jpg-config.inc has been changed so that true color images are disabled. Correct this by enabling the USE_TRUECOLOR define.
  2. If background images does not work make sure the settings of USE_GD2_LIBRARY corresponds to the actual installation, i.e. If the GD2 library is not available then this define must be false!
  3. If you are running IIS and Win2k and get the error "Can't find font" when trying to use TTF fonts then try to change the paths to UNIX style, i.e. "/usr/local/fonts/ttf/". Remember that the path is absolute and not relative to the htdocs catalogue.
  4. If no images and no error messages gets sent back to the browser then there is a big chance that HTTP-Server PHP module (e.g. Apache-PHP) has crashed. This is often due to a broken PHP installation and more than often a problem with the True Type libraries. The best way to track these types of problem down is to investigate the HTTP-Server logs or the general system logs for evidence of a PHP crash. The other reasons is that in some rare cases the auto detection of the GD library could fail. If only the GD1 library is available and the JpGraph library mistakenly detects the GD2 this could in rare cases cause PHP to crash. Please try re-run the example by setting the DEFINE USE_GD2_LIBRARY to "false".
  5. If the system is running IIS on Windows and some images which uses TTF fonts just return an empty page then try to set the TTF_DIR path manually (in jpg-config.php) to the directory where all the TTF fonts are stored (normally c:/WINDOWS/fonts)
  6. If the cache is enabled please make sure that the permissions are correctly set for the cache directory so that the process running Apache/PHP has write access to the cache directory.
  7. If the TTF fonts only shows up as yellow then you have a buggy installation of the freetype font library and the only thing to do is to re-install and setup PHP+GD again.

3.7 Compiling PHP 4

This is not meant to be a complete discussion about configuring or compiling PHP. It is meant as an example of a configuration of PHP that is known to work well with JpGraph.

Below is an example of a standard configuration that can be used to configure and compile PHP for use with the JpGraph Library

Please note that depending on the specific installation requirements other options might have to be specified, specifically the paths to external libraries might need to be adjusted.

./configure --prefix=/usr/share \
--datadir=/usr/share/php \
--with-apxs=/usr/sbin/apxs \
--libdir=/usr/share \
--includedir=/usr/include \
--bindir=/usr/bin \
--with-config-file-path=/etc \
--enable-mbstring --enable-mbregex \
--with-pdflib=/usr \
--with-mysql  \
--with-ttf-dir=/usr/lib \
--with-freetype-dir=/usr/lib \
--with-gd --enable-gd-imgstrttf --enable-gd-native-ttf \
--with-zlib-dir=/usr/lib \
--with-png-dir=/usr/lib --with-jpeg-dir=/usr/lib --with-xpm-dir=/usr/X11R6 \
--with-tiff-dir=/usr/lib \
--enable-ftp \
--enable-memory-limit --enable-safe-mode \
--bindir=/usr/bin \
--enable-bcmath -enable-calendar \
--enable-ctype --with-ftp \
--enable-magic-quotes \
--enable-inline-optimization \
--with-bz2 \
--with-iconv

4 Quick Start: Dynamic Image Generation

The purpose of this chapter is to put dynamic image generation in perspective and illustrate how HTML tags is used to call image generating scripts. Even if You are familiar with PHP it is stronly recommended to quickly browse through this chapter to make sure all concepts are known.

If You fully understand and can explain the concept of MIME types, HTTP streams and why the "Headers already sent error" error is very common when generating dynamic images with PHP it is probably safe to skip this chapter. Otherwise it might be wise to read through this chapter once.

4.1 Scope of this chapeter

4.1.1 What you will learn in this chapter

  1. The principle of generating dynamic images in PHP
  2. How to choose a specific image format (e.g. JPG, PNG, GIF)
  3. Various ways of using the generated image, streaming it back to the browser, sending it to a file or getting hold of the image handle for further post processing
  4. How to specify fonts (both bit-mapped and TTF) in JpGraph
  5. How to extend JpGraph with your own fonts
  6. How to work with Cyrillic fonts
  7. How to specify colors in JpGraph
  8. List all available named colors in JpGraph
  9. How to effectively use the built in cache schema in JpGraph

4.1.2 What you will NOT learn in this chapter

  1. Any details on how to generate graphs with the JpGraph library

4.2 How to generate images with PHP

As a general rule each PHP script which generates an image must be specified in a separate file which is then called in an HTML <IMG> tag. For example, the following HTML excerpt includes the image generated by the PHP script in "fig1.php".

<img src="fig1.php" border=0 align=center width=300 height=200>

Strictly speaking the "align", "width" and "height" are not necessary but helps the browser position the image correctly before the image has been fully sent back to the browser.

The library will automatically generate the necessary headers to be sent back to the browser so that it correctly recognize the data stream received as an image of either PNG/GIF/JPEG format. The browser can then correctly decode the image

Observe that you can't return anything else than an image from the image script. By definition each HTML page (or more correctly each HTTP stream) can only consist of one mime type which is determined by the header for that particular stream.

A common mistake is to have a space in the beginning of the image script which the HTTP server will send back to the browser. The browser now assumes that the data coming back from this script is text since it hasn't received an explicit header. When then the image headers get sent back to the browser to forewarn the browser of the forthcoming image the browser will not like that as it has already assumed the data stream was a text stream. The browser will then give the infamous "Headers already sent error".

To include several images together with text on a page you need to have a parent page with several <IMG> tags which each refers to an image script (or the same image script with GET/POST data).

4.2.1 Using the JpGraph library to send back images

To get access to the JpGraph library you will need to include at least two files, the base library and one or more of the plot extensions. So for example to create a basic line plot the top of your PHP file must have the lines:


include ( 'jpgraph.php');
include (
'jpgraph_line.php');
...
// Code that uses the jpgraph library
...

Note: You might also use the PHP directive require. The difference is subtle in that include will only include the code if the include statement is actually executed. While require() will always be replaced by the file specified. See PHP documentation for further explanation. For most practical purposes they are identical.

4.3 Using PHP directly

It is also possible to generate images directly using the command line version of PHP. This works the same way as the normal "through the browser" generation with the exception that no HTTP headers will be generated. Only the bianry image data.

Please make sure that you run the command line version of PHP (cli). Using the CGI SAPI version will not work since then the HTTP headers will be generated. You can easily check this by running

php --version

you should then get a response with something like

PHP 4.3.8 (cli) (built: Aug 29 2004 22:48:10)
Copyright (c) 1997-2004 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies

The important thing here is the

(cli)

marker. The JpGraph library check from what SAPI API it is invoked from and adjusts the header generation accordingly.

If all the above requirements are met then images can be generated directly on the command line and stored in a suitable file. For example by

$> php myimage.php > image.png

Please note that the file extension on the image file must match the format in which the image is generated.

4.4 The basic principle of JpGraph and the creation of images

The common pattern for creating graphs is

  1. Create a script that constructs the image, type, colors size and so on.
  2. A wrapper script which contains one or more <IMG> tags to position the graphs on the proper HTML page.

Of course it is of perfectly possible to call the image script directly in the browser to just display the generated image in the browser.

You should remember that it is also possible to pass arguments to the image script via the normal HTTP GET/POST arguments. For example

<img src ="showgraph.php?a=1&b=2" >

This could for example be used to control the appearance of the image or perhaps send data to the image which will be displayed. Note that this is probably not the best way to send large amount of data to plot. Instead the only practical way, for large data sizes, is to get all the data in the image script, perhaps from a DB. Another alternative for large amount of data to be sent to the image script is by creating a POST request to the image script.

Note: Forcing the browser to update your image Some browser may not send back a request to the web browser unless the user presses "Refresh" (F5 - in most browsers). This can lead to problems that the user is seeing old data. A simple trick is to add a dummy time argument which is not used in the script. For example
echo '<img src="myimagescript.php?dummy='.now().'">';
It is also important to be aware of any internal caching the browser might do. The general problem with dynamically generated images is that the image generating script (file) remains the same. This makes the browser believe that the data hasn't changed and if the browser already has issues a previous GET request and has the data cached it will not send a new GET if the timestamp on the file is the same since it then believes it my use the old cached version.

When it comes to the structure of your imaging script they will generally have the structure

// ... Include necessary headers

$graph = new Graph($width, $height, ...);

// ... code to construct the graph details

$graph->Stroke();

JpGraph is completely Object oriented so all calls will be action on specific instances of classes. One of the fundamental classes is the Graph() class which represents the entire graph.

After the creation of the Graph() object all the code lines to construct the details of the graph are added.

The final method called in an image script will most likely be the Graph::Stroke() method. This will send the constructed image back to the browser. A variation of this is used if the graph are supposed to have image maps. In that case the final method will be Graph::StrokeCSIM()

In addition to this standard usage pattern you can also choose to

The cache system, which lessens the burden of the PHP server, works by avoiding o run all the code that follows the initial Graph() call by checking if the image has already been created and in that case directly send back the previously created (and stored in a file) image to the browser. When using the cache system a filename must be specified in the initial Graph() call which is used to store the image in the cache system and possibly also a timeout value to indicate how long the image in the cache directory should be valid.

In many of the examples in this manual teh following pattern will be used

$graph = new Graph(300,200 ,"auto");

The two first parameters specify the width and height of the graph and the third parameter the name of the image file in the cache directory. The special name 'auto' indicates that the image file will be given the same name as the image script but with the extension changed to indicate the graphic format used, i.e '.jpg', '.png' and so on.

Please note that the cache system by default is disbled and must be enabled by setting the proper define in the file "jpg-config.inc"

4.5 Choosing the image format for JpGraph

By default JpGraph automatically chooses the image format to use in the order PNG, JPEG and GIF. The exact format depends on what is available on your system. There are two ways you can influence the way the graphic format is chosen.

  1. Change the default graphic format by changing the DEFINE
    DEFINE ("DEFAULT_GFORMAT" ,"auto");

  2. Set the graphic format in your script by calling the method SetImgFormat() For example, to force your script to use JPEG in one specific image use
    $graph-> img-> SetImgFormat( "jpeg")

4.6 Alternatives to streaming back the image

If you like to save the image directly to a file instead of streaming it back to the browser then you just have to specify an absolute filename in the final call to Graph::Stroke(), i.e.

$graph-> Stroke( "/usr/home/peter/images/result2002.png");

Please note that the user running as Apache/PHP must have write access to the specified directory.

There are also two predefined filenames which have special meaning.

4.7 Working with fonts in JpGraph

JpGraph supports both a set of built in bit-mapped fonts as well as True Type Fonts. For scale values on axis it is strongly recommended that you just use the built in bitmap fonts for the simple reason that they are, for most people, easier to read (they are also quicker to render). Try to use TTF only for headlines and perhaps the title for a graph and it's axis. By default the TTF will be drawn with anti-aliasing turned on.

In many of the example you can see examples of both TrueType and Bitmap fonts.

There are a number of subtle differences in the way builtin fonts and TrueType fonts are rendered to the screen. However, JpGraph, abstracts away 99.9% of the differences so it will be, for the user, completely transparent to switch between the different fonts.

4.7.1 Installing TrueType fonts

Since Internally TrueType fonts are rendered by locating a font specification file you must install the accompanying TrueType fonts in directory of your choice. You must then tell JpGraph where these fonts may be found by specifying the font-path in the FONT_PATH define (in jpg-config.inc). Please note that this must be the absolute file path and not relative to the htdocs directory. By default the path is set to

DEFINE( "TTF_DIR", "/usr/local/fonts/ttf/");

Since JpGraph must be able to tell the difference between the italic and bold versions of the same font family a standard naming convention is used to name the files. The available fonts are also defined by DEFINES and hence you can't just copy your own TTF files to the directory and expect it to work. At the moment there is no "easy" way to add new fonts but to make some (small) mods to the code. However this is expected to change in future version of JpGraph.

4.7.2 Verifying that the TTF fonts work

In order to get TTF fonts working with JpGraph you should first check that the following pure GD scripts work correctly. Please adjust the font path according to your installation.

DEFINE ("TTF_DIR","/usr/X11R6/lib/X11/fonts/truetype/" );

$im = imagecreatetruecolor (400, 100);
$black = imagecolorallocate ($im, 0, 0, 0);
$white = imagecolorallocate ($im, 255, 255, 255);

imagerectangle ($im,0, 0,399,99 ,$black);
imagefilledrectangle ($im,0, 0,399,99 ,$white);

imagettftext ($im, 30, 0, 10, 40 , $black, TTF_DIR. "arial.ttf", "Hello World!");

header ("Content-type: image/png" );
imagepng ($im);

The above script assumes you have the GD2 library and will create an image with the classical "Hello World!" text printed in black.

4.7.3 Specifying fonts

All graph objects that uses text allows you to specify the font to be used by calling the SetFont() method and specifying three parameters

  1. Font family, Specified with a FF_ define
  2. Font style, Specified with a FS_ define
  3. Font size, Numeric value (only used for TTF fonts)

For the builtin fonts the third, size, parameter is ignored since the size is fixed for the three builtin fonts. The available font families and the corresponding name (in JpGraph 1.7) are listed in the table below.

Font familyTypeNote
FF_FONT0Builtin fontA very small font, only one style
FF_FONT1Builtin fontA medium sized font
FF_FONT2Builtin fontThe largest bit mapped font
FF_ARIALTTF fontArial font
FF_VERDANATTF fontVerdana font
FF_COURIERTTF fontFix pitched courier
FF_BOOKTTF fontBookman
FF_COMICTTF fontComic sans
FF_TIMESTTF fontTimes New Roman
FF_GEORGIATTF fontGeorgia
FF_TREBUCHETTF fontTrebuche
FF_VERATTF fontGnome Vera font, Available from http://www.gnome.org/fonts/
FF_VERAMONOTTF fontGnome Vera Mono font, Available from http://www.gnome.org/fonts/
FF_VERASERIFTTF fontGnome Vera Serif font, Available from http://www.gnome.org/fonts/
FF_CHINESETTF fontInstalled chinese font
FF_SIMSUNTTF fontInstalled chinese font
FF_BIG5TTF fontInstalled chinese BIG5 font (needs iconv())

Please note that not all font families support all styles. The figure below illustrates each of the available font families and what styles you may use.



Figure 1: Illustration of some of the available fonts in JpGraph [src]  

We finally show some example of valid font specifications

$graph ->title->SetFont( FF_FONT2);
$graph->title-> SetFont( FF_FONT2, FS_BOLD);
$graph->title-> SetFont( FF_ARIAL);
$graph->title-> SetFont( FF_ARIAL, FS_BOLD,24);

4.7.4 Adding additional fonts to JpGraph

Note: This information is only given here for very advanced users. No free support will be given in the case you run into difficulties trying to add new fonts. At the moment adding new fonts require code modifications as outlined below.

In order to add you favorite fonts there are three steps you need to follow :

  1. Define a new "FF_" constant naming your font family with a suitable high index number
  2. Get the TTF file(s) and add it to your font directory. You need separate files for each of the styles you want to support. You then need to add the file names of the font as definitions in the class TTF. Use the previous defined "FF_" name as index in the font specification array.

4.7.5 Understanding text alignment in JpGraph

For everyday use of JpGraph understanding of the alignment of text strings in not necessary. However, if you like to add arbitrary strings to the graph (with Graph::AddText()) or when working directly on a canvas it will help understand this.

Text is added to a graph with the creation of a Text() object. And the alignment is specified with Text::Align() Text alignment might actually be a misguiding name. What you specify is rather the anchor point for the text, i.e. when you specify that a text should be positioned at position (x,y) how is that coordinate to be interpretated.

The image below shows a text string aligned in the 9 possible combinations. In the image the red crosses indicate what coordinate that text string was positioned at. The alignment used for each of the cases is shown below.



Figure 2: Specifying alignment (anchor-point) for text strings [src]  

4.8 Specifying colors in JpGraph

Colors can be specified in three different ways

  1. By using one of the, roughly, 400 pre-defined color names, e.g
    SetColor ("khaki");

    A named color can also be modified by adding a adjustment factor. An adjustment factor, 0 < f < 1, a smaller value will give a darker version and a value of 0 or 1 will return the original color. A value > 1 will make the color brighter. A few examples

    SetColor ("khaki:0.5"); // A darker version of "khaki"
    SetColor ("yellow:1.2" ); // A slightly lighter version of "yellow"

  2. By specifying a RGB triple, e.g.
    SetColor(array(65, 100,176));

  3. By specifying the color as a hex string value
    SetColor ("#A16BFF");

4.8.1 Adjusting the transparency

From version 1.10 JpGraph also supports the use of Alpha Blending together with GD2.x This lets you specify how much of the underlying color should be visible. You specify the amount of transparency for a color by adding an extra parameter to the color specification separated by an '@' (at) character.

For example to specify a red color which is 40% transparent you write

SetColor( "red@0.4");

or to specify 90% transperancy you write

SetColor ("red@0.9");

Below is an example of how a bar graph with a background image can make use of transperancy

4.8.2 Available named colors

The chart below shows all available named colors.


4.8.3 Theme colors for pie's

For more on how to use the different themes to set the colors of Pie plots please refer to "Working with 2D &3D pie plots"


Theme 1: Earth


Theme 2: Pastel


Theme 3: Water


Theme 4: Sand

5 Understanding the JpGraph caching system

To reduce load on the web server JpGraph implements an advanced caching system which avoids the burden of always having to run the full image script.

Depending on the complexity of the image script (for example if it is doing several DB lookups) this could significantly improve performance.

The rationale behind this is of course performance, and the observation that very few graphs are really real-time, i.e. needs to be updated absolutely every time the graphing script is called.

5.1 Enabling the cache system

The enabling disabling of the cache system is controlled by two defines (in jpg-config.php)

DEFINE( "USE_CACHE", true);
DEFINE("READ_CACHE", true)

The first of these, USE_CACHE, is the master-switch which must be set to true to enable the caching system. The second switch READ_CACHE very seldom needs to be changed.

This second switch basically tells whether or not JpGraph should ever look in the cache. Setting this to false and the master-switch to true would then always generate an new updated image file in the cache and this new image would be send back to the browser. The main use for this (admittedly) strange setting is if you like to have the side effect of the script that a fresh image is always stored in the cache directory.

Once you have enabled the cache you must also make sure that a valid cache directory is setup. The cache directory is specified with the define

DEFINE( "CACHE_DIR", "/tmp/jpgraph_cache/");

You can of course change the default directory to whatever directory you fancy. But, you must remember one important thing. The cache directory must be writable for the user running Apache/PHP .

5.2 Using the cache in your script

To use caching in your script you must supply a suitable file name which will be used to store the image in the cache. You can also supply a timeout value indicating how many minutes the cached image should be considered valid.

These parameters are supplied in the initial Graph() method call which should be among the first in your script. Instead of manually specifying a file name to be used you could often use the special name "auto". If the filename is specified as "auto" the cashed image will then be named the same as the image script but with the correct extension depending on what image format have been chosen.

If you don't specify a file name no caching will be used no matter the settings of USE_CACHE (without a file name it is impossible!)

The following call to Graph() shows a typical use of the cache.

$graph = new Graph(300,200 ,"auto",60)

The above code will use the automatic filename and a make the cache valid for 60 minutes.

So, how does this all work now?

The first time you call your script (no cached image) everything will be as usual, the script will run and you will in the end send back the image to the browser. However if you have the caching enabled JpGraph will automatically have stored a copy of the generated image in the cache directory.

The next time you call the script the first thing that happens in the initial Graph() is that it will go and check in the cache directory if the named image exists there. If this is the case it will also checks that the image isn't too old (as compared to the specified timeout value). If the image is valid then the image will be streamed straight back from the image file to the browser and the script will end it's execution.

Hence, if the image is found in the cache no code lines after the initial Graph() call will be executed

The design decision behind this is that your image script code never has to include anything special to make full use of the cache. It will just automatically work.

5.3 Using the cache with Client Side Image Maps

You can also use the cache system for CSIM as well. The cache system interface is slightly different in this case since the cache needs to store both the cached image and the cached image-map. It also needs to change due to the way CSIM HTML paradigm work. The two major differences from the "standard" cache is

  1. The cached version will not be stored in the previous defined cache directory. See more below.
  2. You must call an extra method, CheckCSIMCache(), to check the cache, see more below.

The performance benefits even for simple CSIM images is around 50% if the cache can be used and can of course be several 1000% if construction of the image requires DB calls and other complex operations which can be avoided.

Before reading further you should have an understanding on how the CSIM works by reading the section "sing Client side image maps".

Please remember that when using CSIM you must end your script with a call to Graph::StrokeCSIM() method instead of the Graph::Stroke() used for non-csim.

To use the cache with CSIM you have to call the Graph::CheckCSIMCache(). As with the caching for non-CSIM you have to supply a name to be used for the cached version as well as an optional timeout value. The default timeout value if nothing else is specified is 60 minutes.

The name argument requires some more explanations. You must specify a relative name here. For example "myimage" or perhaps "firstpage/image3". Depending on your installation of JpGraph this will now end up in the directory specified in the CSIMCACHE_DIR define. This must also be a directory accessible by the normal web server. By default a directory called "csimcache" will be created in the same directory as the image script itself.

This has the drawback that the directory from where the script is executed must be writable by the process running PHP. Best practice for this is to keep the number of writable directory for PHP down to a minimum and re-use the same directory as is used for the standard cache. This however, require that your system administrator setup that cache directory so that it also accessible by the HTTP server from the htdocs root.

The CheckCSIMCache() method checks the cache for an existing cached version and if found it returns it and halts execution of the script. So, this call should be the first call after the creation of the Graph() and before any heavy work is done to create the image so that you can minimize the execution of the script in the case a match is found.

So, the general structure of a script that uses CSIM and the cache is

$graph = new Graph(400,300 );

// Check cache, 10 min timeout
$graph->CheckCSIMCache( "image1",10);

// !! If cached version exists, execution halts here !!

//
// ... Construct the image with heavy DB calls etc, etc
//

$graph->StrokeCSIM();

Please note that you do not need to pass any argument to the final call to StrokeCSIM() as you do when not using the cache.

Note: The CSIM caching works by storing two files in the cache directory. One file being the image and the other file being the corresponding image map as a pure HTML file.

5.4 Some final comments

5.5 Common feature for all graphs

This is a summary of the available feature for all Graph based charts, i.e. line plots, error plots, scatter plots, etc.

5.5.1 Clipping

By default all plots are clipped outside the plot area. This means that if you manually specify a scale and then try to plot which has values smaller/larger than the scale those values will not show.

The clipping algorithm is "perfect" in the sense that for example line plots where the plot area cuts the line between two data points the line will be drawn up to the edge of the plot area. The algorithm used is O(1) in number of data points.

The disabling/enabling of clipping manually is controlled by Graph::SetClipping()

5.5.2 Commonly used properties

  1. Each graph can have three titles accessed through the properties 'Graph::title', ''Graph::subtitle' and ''Graph::subsubtitle'
  2. Each graph have a legend accessed through the 'Graph::legend' property
  3. Each graph can have a left, center and right footer accessed through 'Graph::footer::left','Graph::footer::center' and 'Graph::footer::right'
  4. You access the axis through 'Graph::xaxis', 'Graph::yaxis' and 'Graph::y2axis'
  5. You access the grids through 'Graph::xgrid', 'Graph::ygrid' and 'Graph::y2grid'

5.5.3 Commonly used methods

  1. You add plot objects (bar plots, pie plots, texts, bands, lines etc) with the 'Graph::Add() method.
  2. Each graph can have a specified margin set by 'Graph::SetMargin()'
  3. Each graph can have a fill color in the plot area 'Graph::SetColor()'
  4. The plot areas may have a box around it 'Graph::SetBox()'
  5. Each graph can have a specified margin color 'Graph::SetMarginColor()'
  6. Each graph can have a frame or not 'Graph::SetFrame()'
  7. Each graph can have a specified drop shadow 'Graph::SetShadow()'
  8. The grid lines can be either behind or in front of the plots 'Graph::SetGridDepth()'
  9. The plot can be rotated an arbitrary angle with 'Graph::SetAngle()'
  10. You can add a background image with 'Graph::SetBackgroundImage'
  11. You can change the overall appearance of the axis with 'Graph::SetAxisStyle'

6 Using image maps with JpGraph

Image maps, or client side image (CSIM) as they are known is fully supported in JpGraph. It gives you the opportunity to create hot-spots in the graphs which allows you to build a set of "drill-down" graphs.

In the following section is based on the assumption that the reader is familiar with the basic concepts of client side image map in HTML.

To shortly recapitulate. Client side image maps consiste of two parts. The first part is the actual image and the second part is a mapping that gives the coordinates for areas in the image which should be marked as hot spots (i.e. clickabe by the user). The library can automatically generate these coordinate maps from a given graph.

Through out the manual areas of the graph that may be used as a hotspot is given in conjuction with the general description of that area.

6.1 The basic structure of an image map script

The standard structure for an HTML page using client side image maps would be something along the lines of

// Image map specification with name "mapname"
<MAP NAME=...>
... specification ...
</MAP>

// Image tag
<img src="..." ISMAP USEMAP="mapname">

This poses an interesting question.

Since we normally call the graphing script directly in the <img> tag how do we get hold of the image map (which is available only in the image script) in this "HTML wrapper" script?

In JpGraph there is actually two ways of solving this.

  1. Use the preferred "builtin" way using the modified Stroke() method Graph::StrokeCSIM() instead of the standard Graph::Stroke() method.
  2. Directly use the Graph::GetHTMLImageMap() which gives you fine control at the expense of more complex coding.

The first (and preferred) way modifies the stroke method so that instead of returning an image (like the standard Stroke() method) StrokeCSIM() actually returns an HTML page containing both the image map specification and the correct <IMG> tag.

This of course means that it is necessary to treat an image map returning image script differently from a non-CSIM image script, for example you can't use it directly as the target for the "src" attribute of the <IMG> tag since it sends back an actual HTML page containing both an image tag together with anj image map.

6.2 Specifying targets for image map plots

To turn a standard image script into a CSIM script the first thing needed to do is to supply the appropriate URL targets for the hotspots in the image.

What the hotspots represent depends on the type of plot you are doing. The following plot types and graph areas support image maps.

To specify a link for each hotspot you have to use the SetCSIMTargets() method for each plot (or specific area) in the graph which should be a hotspot.

There are two arguments to this method

  1. $aTargets, an array of valid URL targets. One URL per hot spot, for example if you have a 10 values bar plot you need 10 URLs. If the SetCSIMTarget() is applied to, for example, a texte then of course only one URL target should be specified.
  2. $aAlts, an array of valid alt-texts. Many browsers (but not all) will show this text string if the mouse hovers over a hotspot.

6.3 Using StrokeCSIM()

The simplest way of creating a creating a CSIM image is with the StrokeCSIM() method. As mentioned before this method actually returns a (small) HTML page containing both the image-tag as well as the image map specification. Hence it is not possible to use a script that ends with this method in a standard image-tags src property.

There are two ways to create CSIM (or get hold of) the image maps

  1. Use the CSIM image script as the target in a standard anchor reference, for example
    <a href="mycsimscript.html">
    
    This has the drawback that the image page will only contain the image and nothing else.
  2. The other way will allow the image script to be included in an arbitrary HTML page by just including the image script at the wanted place in the HTML page using any of the standard "include" php statement. For example
    <h2> This is an CSIM image </h2>
    
    <?php
    include "mycsimscript.php"
    ?>
    

Note: If there are several CSIM images on the same page it is necessary to use "include_once" in the scripts for the inclusion of "jpgraph.php" and the other jpgraph library files since the files will be included multiple times on the same page and one or more "Already defined error" will be displayed.

The process to replace Stroke() with StrokeCSIM() is straitforward. Replace all existing calls to Stroke() with the equivalent calls to StrokeCSIM().

The only difference is that it is necesasry ti supply a minmum of ond file name in the StrokeCSIM() method. The first argument must be the name of the actual image script file including the extension. So for example if the image script is called "mycsimscript.php" it is necessary to write
 

$graph-> StrokeCSIM( 'mycsimscript.php')


However, it is possible to apply a small "trick" here. PHP maintain a special variable called "__FILE__" which is always set to the current file name. This means you could use the following construction:

$graph-> StrokeCSIM( basename( __FILE__))

This is a better way since the script can now be renamed without having to change any code in the file which otherwise would be needed.

Note: Why does the script name need to be used as the first parameter? The reason is that in the creation of the HTML page which is sent back we need to refer to the script in the image tag. So why is it not possible to use the PHP_SELF reference? The problem with PHP_SELF is that in the case where we include the image-script in an HTML page and use the PHP_SELF we will get the name of the HTML page and not the actual script in which the PHP_SELF is used. We also can not use the __FILE__ trick in the library since in the context __FILE__ is set to "jpgraph.php". Hence, this must be specified by the client as shown above.

The other arguments to StrokeCSIM() are optional. Please note that if several CSIM images are used in the same HTML page it is also necessary to specify the image map name as the second parameter since all image maps must be unique to properly match each image map against each image. Please consult the class reference StrokeCSIM() for more details.

6.4 Examples of Image maps

In the Example/ directory there are a number of examples of how to setup the various types of image maps. The following examples are currently available

In order to easily access all of these examples it is possible to call the testsuit.php example with an additional argument "t=2". By following the link testsuit.php?t=2 a separate window will open with all the possible CSIM examples.

6.5 How does StrokeCSIM() work?

Knowledge of the exact technical details of the way StrokeCSIM() works is probably not needed by many people but for completeness we outline those details in this short section.

The fundamental issue we have to solve is that we must be able to call the image script in two modes. When the user includes the image script the StrokeCSIM() method should return the HTML page but when the image script is later called directly in the image tag it must not return an HTML page but rather the actual image.

The way this is solved is by using one HTTP argument which is passed on automatically when we use the image script name in the image-tag.

If you look at the generated HTML you will see that the argument to the src-property of the image tag is not simply the script name but the script name with a additional argument.

In the JpGraph internal code this pre-defined argument is checked for and if it exists the image is send back and not the HTML page.

The name of this argument is defined by a DEFINE() statement in JpGraph. The define is _CSIM_DISPLAY.

6.6 Getting hold of the image map

In the case where you want to store the image on disk and later use it in an img-tag you need to get hold of the image map. For this you will have to use the function Graph::GetHTMLImageMap()

An example of the use of this is shown below. With these lines the image will be written to a file. The script then returns a HTML page which contains the Client side image map and an img-tag which will retrieve the previously stored file.

$graph-> Stroke( "/usr/local/httpd/htdocs/img/image001.png" );
echo
$graph ->GetHTMLImageMap ("myimagemap001" );
echo
"<img src=\"img/image001.png\" ISMAP USEMAP=\"#myimagemap001\" border=0>" ;

6.7 Image maps and the cache system

For version 1.9 the cache system has been extended to include even the CSIM maps. For each CSIM graph two files are stored in the cache, the image file itself as well as the wrapper HTML with the actual image map. For further information see the chapter on "Understanding the Cache system"

7 Working with orthogonal X,Y-plots

The purpose of this chapter is to introduce the basic concepts of creating scripts with JpGraph that will generate various types of basic plots. Throughout the text it is possible to view the exact source for all the graphs by clicking on the "[src]" link in the caption of the image shown. This will open the image together with the source in a separate window. This way it is easy to compare the actual image with the script that generated the image.

7.1 Line plots

The first example draws a line graph consisting of 10 Y-values. In this first example we show the full code. In the following examples we will only show interesting piece of the code.

(File: example0.php)
<?php
include ( "../jpgraph.php");
include (
"../jpgraph_line.php");

// Some data
$ydata = array(11,3, 8,12,5 ,1,9, 13,5,7 );

// Create the graph. These two calls are always required
$graph = new Graph(350, 250,"auto");    
$graph->SetScale( "textlin");

// Create the linear plot
$lineplot =new LinePlot($ydata);
$lineplot ->SetColor("blue");

// Add the plot to the graph
$graph->Add( $lineplot);

// Display the graph
$graph->Stroke();
?>


Figure 3: A simple line graph [src] 

You might note a few things

This is a perfect fine graph but looks a little bit "sparse". To make it more interesting we might want to add a few things like

From looking at the previous example you can see that you access all properties of JpGraph through the objects you create. Graph(), LinePlot() and so on. In general all objects you can see in the graph is accessed through a named instance.

For example the title of the graph is accessed through the 'Graph::title' property. So to specify a title string you make a call to the 'Set()' method on the title property as in:

$graph->title->Set ('Example 2');

So by adding just a few more lines to the previous code we get a graph as shown below.



Figure 4: Same basic graph as in previous figure but with a titles for graph and axis. [src] 

To achieve this we just needed to add a few more lines. (We only show the part of example 1 we changed, to look at the full source just click the [src] link in the caption. )

// Setup margin and titles
$graph->img-> SetMargin(40,20 ,20,40);
$graph->title-> Set("Example 2");
$graph->xaxis-> title->Set("X-title" );
$graph->yaxis-> title->Set("Y-title" );

Again there are a couple of things you should note here

A nice change would now be to have all the titles in a bold font and the line plot a little bit thicker and in blue color. Let's do that by adding the lines

$graph-> title->SetFont(FF_FONT1 ,FS_BOLD);
$graph->yaxis-> title->SetFont(FF_FONT1 ,FS_BOLD);
$graph->xaxis-> title->SetFont(FF_FONT1 ,FS_BOLD);
$lineplot ->SetColor("blue");
$lineplot ->SetWeight(2);   // Two pixel wide

Again please note the consistent interface. To change font you just have to invoke the SetFont() method on the appropriate object. This principle is true for most methods you will learn. The methods may be applied to a variety of objects in JpGraph. So for example it might not come as a big surprise that to have the Y-axis in red you have to say:

$graph->yaxis->SetColor ("red")

or perhaps we also want to make the Y-axis a bit wider by

$graph ->yaxis->SetWidth( 2)

As a final touch let's add a frame and a drop shadow around the image since this is by default turned off. This is done with

$graph ->SetShadow()

The result of all these modifications are shown below.



Figure 5: Making the image a little bit more interesting by adding som colors and changing the fonts [src] 

7.1.1 Adding plot marks to line-plots XXX

It might sometimes be desirable to highlight the data-points with marks in the intersection between the given x and Y-coordinates. This is accomplished by specifying the wanted plot mark type for the "mark" property of the line graph. A full list of all available marks is given in the class reference PlotMarks

For now let's just add a triangle shape marker to our previous graph by adding the line

$lineplot-> mark->SetType(MARK_UTRIANGLE );

This will give the graph as shown below



Figure 6: Adding markers to the previous example [src] 

If you like you can of course both change the size, fill-color and frame color of the chosen plot mark.

The colors of the marks will, if you don't specify them explicitly, follow the line color. Please note that if you want different colors for the marks and the line the call to SetColor() for the marks must be done after the call to the line since the marks color will always be reset to the lines color when you set the line.

7.1.2 Displaying the values for each data point

As a final easy modification we can enable the display of the data value above each data point. The value is represented by the 'value' property in the plot. (You can read more about the possibilities of the display value in the class reference.)

To enable the display of the value you just need to call the Show() method of the value as in

$lineplot->value-> Show()

Adding that line to the previous line plot would give the result shown below.



Figure 7: Displaying the value for each data point [src] 

We can of course change both color, font and format of the displayed value. So for example if we wanted the display values to be dark red, use a bold font and have a '$' in front we need to add the lines

$lineplot ->value->SetColor( "darkred");
$lineplot ->value->SetFont( FF_FONT1, FS_BOLD);
$lineplot ->value->SetFormat( "$ %0.1f");

This would then result in the following image



Figure 8: Making the display values a little bit more interesting [src] 

Note: You can achieve more advanced formatting by using not just the printf() style format string by a format callback function. This could allow you to change the displayed value with more advanced formatting such as displaying money values with "," to separate thousands.

7.1.3 Adding several plots to the same graph

What if we want to add a second plot to the graph we just produced? Well, this is quite straightforward and just requires two simple step:

  1. Create the second plot
  2. Add it to the graph

To create the second plot we need some data (we could of course use the same data as for the first plot but then we wouldn't be able to see the new plot!)

The following lines show how to create the new plot and add it to the graph (we only show the new lines - not the full script)

$ydata2 = array(1,19, 15,7,22 ,14,5, 9,21,13 );
$lineplot2 =new LinePlot($ydata2);
$lineplot2 ->SetColor("orange");
$lineplot2 ->SetWeight(2);

$graph->Add( $lineplot2);

Making these changes to the previous graph script would generate a new graph as illustrated below.



Figure 9: Adding a second plot to the previous graph [src] 

There is a few things worth noting here

7.1.4 Adding a second Y-scale

As you saw in the preceding example you could add multiple plots to the same graph and Y-axis. However what if the two plots you want to display in the graph has very different ranges. One might for example have Y-values like above but the other might have Y-values in the 100:s. Even though it is perfectly possible to add them as above the graph with the smallest values will have a very low dynamic range since the scale must accomplish the bigger dynamic range of the second plot.

The solution to this is to use a second Y-axis with a different scale and add the second plot to this Y-axis instead. Let's take a look at how that is accomplished.

First we need to create a new data array with large values and secondly we need to specify a scale for the Y2 axis. This is done by the lines

$y2data = array( 354,200,265 ,99,111, 91,198,225 ,293,251);
$graph->SetY2Scale( "lin");

and finally we create a new line plot and add that to the second Y-axis. Note that we here use a new method, AddY2(), since we want this plot to be added to the second Y-axis. Note that JpGraph will only support two different Y-axis. This is not considered a limitation since using more than two scales in the same graph would make it very difficult to interpret the meaning of the graph.

To make the graph a little bit more esthetic pleasing we use different colors for the different plots and let the two different Y-axis get the same colors as the plots.

The resulting graph is shown below. source)



Figure 10: Adding a second Y-scale plot to the same graph [src] 

7.1.5 Adding a legend to the graph

With more than one plot on the same graph it is necessary to somehow indicate which plot is which. This is normally done by adding a legend to the graph.

You will see that each plot type has a 'SetLegend()' method which is used to name that plot in the legend. SO to name the two plots in the example we have been working with so far we need to add the lines

$lineplot ->SetLegend("Plot 1");
$lineplot2 ->SetLegend("Plot 2");

to the previous code. The resulting graph is shown below As you can see the legend gets automatically sized depending on how many plots there are that have legend texts to display. By default it is placed with it's top right corner close to the upper right edge of the image. Depending on the image you might want to adjust this or you might want to add a larger margin which is big enough to accompany the legend. Let's do both.

First we increase the right margin and then we place the legend so that it is roughly centered. We will also enlarge the overall image so the plot area doesn't get too squeezed.

To modify the legend you access the 'legend' property of the graph. For a full reference on all the possibilities (changing colors, layout, etc) see class legend in the class reference

For this we use the legends 'SetPos()' method as in

$graph ->legend->Pos( 0.05,0.5,"right" ,"center");

Doing this small modification will give the result shown below



Figure 11: Adjusting the layout to give more rooms for the legend [src] 

The above method 'SetPos()' deserves some explanation since it might not be obvious. You specify the position as a fraction of the overall width and height of the entire image. This makes it possible for you to resize the image within disturbing the relative position of the legend. We will later see that the same method is just to place arbitrary text in the image.

To give added flexibility one must also specify to what edge of the legend the position given should be relative to. In the example above we have specified "right" edge on the legend for the for the horizontal positioning and "center" for the vertical position.

This means that the right edge of the legend should be position 5 % of the image width from the right. If you had specified "left" the the legends left edge would be positioned 5 % of the image width from the image left side.

By default the legends in the legend box gets stacked on top of each other. The other possibility is to have them sideways. To adjust this you use the SetLayout() method. Using a horizontal layout with the previous example give the following result.



Figure 12: Using a horizontal layout for the legends [src] 

7.1.6 Handling null-values in line plots

JpGraph offers two ways of handling null values (or discontinuities) in the data. You can either have a "whole" in the data or the line may be extended between the previous and next data point in the graph.

If the data value is null ("") or the special value "x" then the data point will not be plotted and will leave a gap in the line.

If the data value is "-" then the line will be drawn between the previous and next point in the data ignoring the "-" point.

The following example shows both these possibilities.



Figure 13: Handling null values in line graphs [src] 

7.1.7 Using the step-style to render line plots

Step style refers to an alternate way of rendering line plots by not drawing a direct line between two adjacent points but rather draw two segments. The first segment being a horizontal line to the next X-value and then a vertical line from that point to the correct Y-value. This is perhaps easier demonstrated by an example as seen below.

You specify that you want the plot to be rendered with this style by calling the method SetStepStyle() on the lineplot.



Figure 14: Rendering a line plot with the step style [src] 

7.1.8 Using logarithmic scale

Using a logarithmic scale requires you to include the logarithmic add on module in "jpgraph_log.php". So you must have the line

include("jpgraph_log.php" );

on the top of your code. To Illustrate how to use a logarithmic scale let's make the right Y scale in the previous example a logarithmic scale. This is done by the line

$graph-> SetY2Scale( "log");

This will then give the following result



Figure 15: Using a logarithmic scale for both the Y2 axis [src] 

You can of course also use a logarithmic X-scale as well. The following example shows this.



Figure 16: Example of using log scale on both X and Y axis together with a linear Y2 scale [src] 

Even though we have so far only shown line graphs logarithmic scale can also be used for bar, error, scatter plots as well. Even radar plots supports the use of logarithmic plots. The following example shows how to use a logarithmic scale for a bar graph.



Figure 17: Example of using logarithmic scale togther with bar plots [src]  

7.1.9 More on scales

As you saw in the previous example it is possible to use different types of scales. In JpGraph you can use the following scales

Any combination of these may be used. Linear and logarithmic scales are pretty straightforward. The text scale might deserve some explanation. The easiest way to think of the text scale is as a linear scale consisting of only natural numbers, i.e. 0,1,2,3,4,... . This scale is used when you just have a number of Y-values you want to plot in a consecutive order and don't care about the X-values. For the above example it will also work fine to use a linear X-scale (try it!). However, the scale is now treated as consisting or real numbers so the auto scaling, depending on the size of the image an the number of data points, might decide to display other labels then the natural numbers., i.e. a label might be 2.5 say. This is not going to happen if you use a text scale.

The normal practice for text scale is to specify text strings as labels instead as the default natural numbers. You can specify text strings for the labels by calling the SetTickLabels() method on the Axis.

To specify the scale you use the SetScale() method. A few examples might help clarify this.

As you can see all your graphs will require at least one call to SetScale() in the beginning of your script. Normally it will come right after the creation of the Graph().

To specify the scale for the Y2 axis you use the SetY2Scale() Since you only specify one axis you only specify "half" of the string in the previous examples. So to set a logarithmic Y2 scale you will call SetY2Scale("log");'; ShowCodeSnippet($t); ?>

7.1.10 Adjusting the grid lines in the plot

By default only the Y-axis have grid lines and then only on major ticks, i.e. ticks which have a label. It is of course possible to change this. Both the X , Y and Y2 can have grid lines. It is also possible to let the gridlines also be drawn on the minor tick marks, i.e. ticks without a label. Lets see how we can apply this to the graph above.

The grid is modified by accessing the xgrid (or ygrid) component of the graph. So to display minor grid lines for the Y graph we make the call

$graph->ygrid->Show (true,true)

The first parameter determines if the grid should be displayed at all and the second parameter determines whether or not the minor grid lines should be displayed.

If you also wanted the grid lines to be displayed for the Y2 axis you would call

$graph-> y2grid->Show(true ,true)

Note. In general it is not a good idea to display both the Y and Y2 grid lines since the resulting image becomes difficult to read for a viewer.

We can also enable the X-grid lines with the call

$graph ->xgrid->Show( true)

In the above line we will of course only just enable the major grid lines.

To bring all this together we will display a graph with grid lines for both Y and X axis enabled.



Figure 18: Enabling major and minor gridlines for Y-axis and major grid lines for the X-axis [src] 

Note: If you think the first value of the Y-axis is to close to the first label of the X-axis you have the option of either increasing the margin (with a call to SetLabelMargin() ) or to hide the first label (with a call to HideFirstTickLabel() )

7.1.11 Using filled grid lines

Another option for the grid lines is the possibility to have the area between the grid lines filled with alternating two colors. The example below illustrates this.



Figure 19: Using two alternating colors between the gridlines [src] 

In the example above we have also made use of alphablending (requires GD 2.x or higher). By default the filled grid lines are disabled. To enable this style you have to call the Grid::SetFill() method.

7.1.12 Specifying text labels for the X-axis

You might want to have specific labels you want to use for the X-axis when this has been specified as a "text" scale. In the previous example each Y-point might represent a specific measurement for each of the first 10 month. We might then want to display the name of the months as X-scale.

To specify the labels on the scale you make use of the SetTickLabels() method.

To get a localized version of the name of the month you can use a nice feature in JpGraph, the global '$gDateLocal' object which is an instance of the DateLocale

This class has a number of methods to get localized versions of relevant names for dates, (months and weekdays).

So to specify the X-axis with the short form of the month names we use the construction

$a = $gDateLocale-> GetShortMonth();
$graph->xaxis-> SetTickLabels( $a);

This will, now result in the image displayed below



Figure 20: Specifying text labels for the X-axis [src] 

Note: It is also perfectly legal to override the default labels for the Y (and Y2) axis in the same way, however there is seldom need for that. Please note that the supplied labels will be applied to each major tick label. If there are insufficient number of supplied labels the non-existent positions will have empty labels.

7.1.13 Adjusting the ticks on a text scale

As can be seen in the previous example the X-axis is slightly cluttered with the labels very close to each other. We might rectify this by either enlarging the image or just displaying fewer tick label on the x-axis.

Specifying that we only want, for example, to print every second label on the axis is done by a call to the method SetTextLabelInterval() Which would result in the graph



Figure 21: Just printing every second label on the X-axis [src] 

If the text labels are long (for example full dates) then another way might be to adjust the angle of the text. We could for example choose to rotate the labels on the X-axis by 90 degrees. With the help of the SetLabelAngle()

Which would then result in the image below



Figure 22: Rotating the X-labels 90 degrees [src] 

Note: The internal fonts which we have been using so only supports 0 or 90 degrees rotation. To use arbitrary angles you must specify TTF fonts. More on fonts later.

7.1.14 Using filled line graphs

Using a filled line plot is not much different from using a normal line plot, in fact the only difference is that you must call the method SetFillColor() on a normal line plot. This will then fill the area under the line graph with the chosen color.

In the example below we have also, as an example, specified plot marks (see previous sections).



Figure 23: Filled line graph with plot marks [src] 

Note 1. If you add multiple filled line plots to one graph make sure you add the one with the highest Y-values first since it will otherwise overwrite the other plots and they will not be visible. Plots are stroked in the order they are added to the graph, so the graph you want front-most must be added last.

Note 2. When using legends with filled line plot the legend will show the fill color and not the bounding line color.

Note 3. Filled line plots is only supposed to be used with positive values. Filling line plots which have negative data values will probably not have the appearance you expect.

As you can see from the graph above the grid lines are below the filled line graph. If you want