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.

This is a truly 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.

Supports unlimited number of plots in each graph, makes it easy to
compose complex graph which consists of several plot types

User specified position of axis

Supports color gradient fill in seven styles

Designed as a flexible OO framework which makes it easy to add new
types of plots

Supports automatic legend generation

Supports both vertical and horizontal grids

Supports anti-aliasing of lines

Supports background images as well as unlimited number of icons in
the graph

Supports rotation of linear graphs

More then 400 named colors

Designed modularly - you don't have to include code which isn't used

...and many many more features

In addition to these high level features the library has been designed
to be orthogonal and very coherent 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.

Note. I keep a strait-forward version scheme to avoid the version
number inflation. This means

1.x -> 1.x.1, Bug fix release for version 1.x

1.x -> 1.(x+1), Added functionality. Mostly keeping backwards
compatibility unless a very good reason not to. All SC breaks will be
well announced in release notes and might be small things like a
misspelled method name compared to the proper English spelling.

The idea for writing this library grew out of my own needs for a high
quality graph drawing library for PHP4. Before reinventing the wheel I
searched the net to see if there where anything already available that
would meet my needs. When searching I found three other PHP graph
plotting libraries:

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, I especially needed the option of two Y-scales, which none
of the above packages supported. My own preference for design was
closest to "chart 0.3" so I started by fixing some small bugs in that
package and adding some new features. However I soon realized that to
add all the features and flexibility I wanted 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. Since at the time I was also interested in
giving PHP a try to see how well it would support a fully object
oriented design so I started designing this library. The library is
completely written from scratch but I have taken some ideas, especially
the caching feature from "chart 0.3" and implemented this. I'm
therefore thankful for those ideas. Any bugs and faults within the code
are completely my own.

In terms of OO support PHP is still at loss to Java, Eiffel or C++ but
since it always been my view that OO design is more a state of mind
then of implementation details it is still possible to arrive with a
decent OO design even in PHP. One of the big obstacles is probably the
very different assigning semantics used by PHP as compared to other OO
languages since it is always copies of the object that is passed around
by default and not references. This took some time for me personally to
get used to (giving my own background in OO design in Java, Eiffel and
C++). There is also a bug (present in all versions <=4.04pl1) that
makes it impossible to use a reference to the '$this' pointer in the
constructor. This has an easy workaround by adding an extra method, say
Init(), which is called immediately after the constructor and may
safely use a reference to '$this' pointer. As an example of JpGraph's
OO features this is, to my knowledge, the only piece of PHP code to
fully implement the Observer pattern.

Bug reports and suggestions are always welcome. We only ask you to make
sure that you read the requirements and the FAQ before submitting bugs
and making sure you have an up to date version of PHP4, the necessary
graphic libraries etc. We will unfortunately not be able to answer
standard OO or PHP4 questions. Neither do we have the time to give
PHP/GD/TTF/Apache installation support. Please see the corresponding
documentation and relevant FAQ. We simply don't have the bandwidth to
help with these kinds of installations.

In general the only thing you need to do is to make sure your PHP files
can include the required library files (as described below) and that
your PHP installation supports at least one graphic format, i.e. it
supports the "image" extension to PHP.

You can easily verify this by making sure that your installation of
PHP supports some of the 'imagecreate()' functions.

This means that you
must have a working GD-library together with PHP
before even thinking of running JpGraph. Please make sure you have
version 4.1 or above of PHP since JpGraph is not
tested with versions prior to PHP 4.1. Ideally you should use at least
PHP 4.3.x

If you want to use TTF fonts you must also make sure that your PHP
installation supports TTF fonts (either through FreeType 1 or FreeType
2 libraries). In additions to this you need at least a couple of TTF
fonts. In preparation of using TTF fonts with JpGraph you must specify,
in jpgraph.php , where those font files can be found.

JpGraph uses a naming convention for the TTF font files in order to
be able to find the correct font files. You should therefore use the
font files that can be downloaded together with JpGraph.

To access the more advanced features of JpGraph you need GD 2.x
library. This will allow you to use features as alphablending and
trucolor images. To make sure that you have GD 2.x the following script
must be working.

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

In all cases you must have a suitable TTF font that supports the
non-latin based language you want to use.

For Cyrillic support you need to set the define LANGUAGE_CYRILLIC in
jpgraph.php to true. You can then use a suitable Cyrillic font as
replacement for the ordinary fonts.

For Chinese JpGraph supports both BIG5 and gb2312 encoding. For BIG5
encoding your PHP installation must have support for the "iconv()"
function. Furthermore you need to set the define CHINESE_TTF_FONT to
the name of the Chinese BIG5 font you want to use. By default this is
set to "bkai00mp.ttf". To use the Chinese BIG5 font for your texts you
need to specify the font family as FF_CHINESE.

If you instead want to use the simsun.ttc of simhei.ttf fonts which
use the gb2312 encoding you only need 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 you specify the fonts style as FS_BOLD.

In order for JpGraph to work you must adjust the cache and TTF
directory to suit your installation. By default the TTF directory is
"/usr/local/fonts/ttf/" 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 you plan to use the cache feature. If not you will get a
"Can't write file xxx.yyy" error when you try to generate a graph. You
can read more about how to use the cache in the chapter
Making sense of caching system in JpGraph

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".

Make sure your PHP is AT LEAST 4.2 (preferable 4.3.1 >= 1) and that
you have compiled support for GD library. You must make absolutely sure
that you have GD 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.

Unzip and copy the files to a directory of your choice.

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.

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).

Make sure PHP have write privileges to your cache directory if you
plan on using the cache feature.

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

For 99% of the users this library will work directly with a recent
installation of PHP without any problem. However if you are
experiencing problem this can Unfortunately be tricky to hunt down due
to the complex nature of the full PHP setup.

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 you
could try the following steps.

If you don't get any background images (but rather a solid black
box) you are using GD 2.x but have forgotten to enable true color
support. Correct this by enabling the USE_TRUECOLOR define.

If background images does not work make sure the settings of
USE_GD2_LIBRARY corresponds to your installation, i.e. If you don't
have GD2 then this define must be false!

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 you paths to UNIX
style, i.e. "/usr/local/fonts/ttf/". Remember that the path is absolute
and not relative to the htdocs catalogue.

If you don't get any image back at all then there is a big chance
that your Apache module has crashed. This is often due to a broken PHP
installation and more than often problem with the True Type libraries.
Please look in your Apache error log or system log to try to trace any
crashes.

The other reasons is that in some rare cases the auto detection of
the GD library could get it wrong. If you in fact only have GD1 when
the library mistakenly thinks you have 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".

If you are running IIS on windows and some images which uses TTF
fonts just return an empty page 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)

If you are using the cache please make sure that you have set the
permissions correctly for the cache directory so that Apache/PHP can
write to that directory.

If your 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

There are many options that could be tweaked when configuring PHP4 to
compile. Below we give you an example of a standard configuration that
we use to setup our PHP compilation. Please note that depending on your
installation you might have to change some of the paths we use (which
are suitable for our setup)

As a general rule each PHP script which generates an image must be
specified in a separate file which is then called in an <IMG> tag
reference. 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>

The library will automatically generate the necessary headers to be
sent back to the browser to correctly recognize the data stream 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 can only
consist of one mime type which is determined by the sent headers.

A common mistake is to have a space in the beginning of the image
script file which the HTTP server will send back to the browser. The
browser now assumes that the data coming back from this script is
normal ASCII. When then the image headers get send back to the browser
to forewarn the browser of the forthcoming image the browser will not
like that. It has already determined that the script should only send
ASCII data back and will then give you a "Headers already sent error".

To include several images together with text on a page you need to
have a parent page with several <IMG> which each refers to an image
script.

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

Sidebar: You might also use the PHP
directive requires(). 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.

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

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

Create a script that constructs the image, type, colors size and so
on.

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 parameters, 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.

Tips: 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()."'>"

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 you add all your lines of
code to construct the details of the graph.

As the final call you will send the generated image back to the
browser with a call to the Stroke() method.

Note: This is not always true, but to keep things simple for
the moment we assume this.

In addition to this standard usage pattern you can also send the
graph directly to a file, get the GD image handler for the image and
also make use of the builtin cache system. 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 filed) image to the browser. When using the cache system
you must specify a filename 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. For this reason you might
in the following examples, for example, see the code

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

in the start of all the examples. 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.

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.

Change the default graphic format by changing the DEFINE

DEFINE("DEFAULT_GFORMAT","auto");

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

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.

"auto", This will create a file in the same directory as the script
with the same name as the script but with the correct image extension.

_IMG_HANDLER, (This is defined in jpgraph.php). Specifying this
filename will not create a an image to file or stram it back to the
browser. Instead it will instruct the Stroke() method to just return
the handle for the GD image. This is useful if you later want to
manipulate the image in ways that are not yet supported by Jpgraph. For
example include the image in generated PDF files.
Example:

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.

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.

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

Font family, Specified with a FF_ define

Font style, Specified with a FS_ define

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 family

Type

Note

FF_FONT0

Builtin font

A very small font, only
one style

FF_FONT1

Builtin font

A medium sized font

FF_FONT2

Builtin font

The largest bit mapped
font

FF_ARIAL

TTF font

Arial font

FF_VERDANA

TTF font

Verdana font

FF_COURIER

TTF font

Fix pitched courier

FF_BOOK

TTF font

Bookman

FF_COMIC

TTF font

Comic sans

FF_TIMES

TTF font

Times New Roman

FF_GEORGIA

TTF font

Georgia

FF_TREBUCHE

TTF font

Trebuche

FF_VERA

TTF font

Gnome Vera font, Available from
http://www.gnome.org/fonts/

FF_VERAMONO

TTF font

Gnome Vera Mono font,
Available from http://www.gnome.org/fonts/

FF_VERASERIF

TTF font

Gnome Vera Serif font,
Available from http://www.gnome.org/fonts/

FF_CHINESE

TTF font

Installed chinese font

FF_SIMSUN

TTF font

Installed chinese font

FF_BIG5

TTF font

Installed 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]

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 :

Define a new "FF_" constant naming your font family with a suitable
high index number

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.

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.

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"

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

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
.

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.

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

The cached version will not be stored in the
previous defined cache directory. See more below.

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.

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.

Technical 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.

If you want the timeout value to be "forever" then you can specify a
0 as the timeout value (or leave the parameter blank). To regenerate
the image you will have to remove the image files from the cache. This
removal could for example be handled by a nightly cron-job

If you use images where you have enabled the anti-aliasing you
should strongly consider using caching since anti-aliasing is quite
time consuming compared to standard line drawings.

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 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. The full code for the examples
shown below is always available by clicking the '[src]' link in the
caption of the images below.

Both the X and Y axis have been automatically scaled. We will later
on show how you might control the auto scaling how it determines the
number of ticks which is displayed.

By default the Y-grid is displayed in a "soft" color

By default the image is bordered and the margins are slightly gray.

By default the 0 label on the Y-axis is not displayed

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

A title for the graph

Title for the axis

Increase the margins to account for the title of the axis

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. )

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]

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

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.

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.

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

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

Sidebar: 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.

The Y-scale has changed to accommodate the larger range of Y-values
for the second graph.

If you add several plots to the same graph they should contain the
same number of data points. This is not a requirement (the graph will
be automatically scaled to accommodate the plot with the largest number
of points) but it will not look very good since one of the plot end in
the middle of the graph.

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

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.

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.

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.

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.

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.

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

Linear scale, the standard "scale"

Logarithmic scale

Integer scale, very similar to linear scale but restricts the scale
values (and labels) to integer values.

Text scale, Similar to integer scale and used when only the
numbering of items is relevant. A text scale is almost exclusively used
for the X-axis. A typical example for this is the X-axis for a bar
plot. The labels for the text scale is usually replaced by user
supplied texts. Text scales can only be used for the X-axis (it doesn't
make sense for the Y-scale).

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.

"textlin", text-scale for X-axis, Linear scale for Y-axis

"linlin", linear-scale for X-axis, Linear scale for Y-axis

"linlog", linear-scale for X-axis, Logarithmic scale for Y-axis

"loglog", Logarithmic scale for X-axis, Logarithmic scale for
Y-axis

"textint", text-scale for X-axis, Integer scale for Y-axis

"textlog", Text scale for X-axis, Logarithmic scale for Y-axis

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); ?>

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() )

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.

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.

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.

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

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()

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).

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 the grid lines in front of the graph you
can adjust the depth with call to
Graph::SetGridDepth() As the following example shows

Accumulated line graphs are line graphs that are "stacked" on top of
each other. That is, the values in the supplied data for the Y-axis is
not the absolute value but rather the relative value from graph below.
For example if you have two line graphs with three points each, say
[3,7,5] and [6,9,7]. The first graph will be plotted on the absolute
Y-values [3,7,5] the second plot will be plotted at [3+6, 7+9, 5+7],
hence the values of the previous graphs will be used as offsets.

You may add any number of ordinary line graphs together. If you want
to use three line plots in an accumulated line plot graph you write the
following code

If you only have access to a few data points but still want a smooth
curve between those data points JpGraph can help you achieving that by
letting you construct cubic splines. If you never have heard of cubic
splines before, don't worry. You only have to supply the data points
you know tell JpGraph how many interpolated points in total you want in
the graph. JpGraph will now take care of constructing a smooth curve
between all you data points. The new, smooth, curve will be made up of
exactly as many interpolated points as you have specified.

To construct a spline you need both the X and Y coordinates for the
known data points.

You start by constructing a new Spline instance. To
get access to the Spline class you must first remember to include the
file "jpgraph_regstat.php". You instantiate this class by calling it
with your two known data arrays (X and Y) as follows.

$spline = new Spline($xdata,$ydata);

This call initializes the spline with the data points you have.
These data points are also known as Control points for the
spline. This helper class doesn't draw any line itself. Instead it is
merely used to get a new (larger) data array which have all the
interpolated values. You then use these new value in your plot. This
way give you great flexibility in how you want to use this interpolated
data.

Continuing the above line we now use the Spline::Get()
method to get an interpolated array containing a specified number of
points. So for example the line

list($sdatax,$sdatay) =
$spline->Get(50);

Will construct the two new data arrays '$sdatax' and '$sdatay' which
contains 50 data points. These two arrays are constructed from the
control point we specified when we created the '$spline' object.

You would then use these two new data array in exactly the same way
as you would form ordinary data vectors.

The following example illustrates this

Figure 26: Using spline to get a smooth curve
between the control points.
[src]

Note: In order to make the example more interesting we actually use
two plots. First a line plot to get the smooth curve and then a
standard scatter plot which is used to illustrate where the control
points are.

To emphasize the specific data points it is possible to add plot marks
at each data point. Plot marks can be either

Simple shapes, (e.g. square, circle, cross, etc)

Arbitrary images loaded from a file

One of the built-in images

You access the plot mark through the "mark" instance variable in the
plot, as in

$lineplot->mark->SetColor("red");

To choose between the different plot marks you call the
PlotMark::SetType() method with the correct define to choose the
plot type you want to use.

The simple shape type of plot marks are

MARK_SQUARE

MARK_UTRIANGLE

MARK_DTRIANGLE

MARK_DIAMOND

MARK_CIRCLE

MARK_FILLEDCIRCLE

MARK_CROSS

MARK_STAR

MARK_X

MARK_LEFTTRIANGLE

MARK_RIGHTTRIANGLE

MARK_FLASH

To specify an arbitrary image you use the special define

MARK_IMG

In this case you must also specify a image file name and an optional
scaling constant. For example as in

$lineplot->mark->SetTYPE(MARK_IMG,"myimage.jpg",1.5);

If you want to use one of the built-in images the following images
are available. Please note that not all images are available in all
possible colors. The available colors for each image is listed below.

The following shape (the first class) plot marks are available

MARK_SQUARE, A filled square

MARK_UTRIANGLE, A triangle pointed upwards

MARK_DTRIANGLE, A triangle pointed downwards

MARK_DIAMOND, A diamond

MARK_CIRCLE, A circle

MARK_FILLEDCIRCLE, A filled circle

MARK_CROSS, A cross

MARK_STAR, A star

MARK_X, An 'X'

MARK_FLASH, A "flash" shape

MARK_IMAGE, Use the image specified with the filename and scale as
the second and third argument as the mark.

For the second class (built-in images) the following table list the
different images as well as what color they are available in. For the
built-in images you specify the color with the second argument.

Note that some of the images are available in different sizes. The
reason is that even though you can scale them by the third argument
there is a visual degradation to scale an image larger than it's
original size since some pixels needs to be interpolated. Reducing the
size with a scale < 1.0 gives much better visual apperance.

The scaling works with both GD 1 and GD 2 but with GD 2 the quality
of the scaling is much better.

Jpgraph also supports 2D vertical bar plots. Before you can use any bar
plots you must make sure that you included the file "jpgraph_bar.php"
in your script.

Using bar plots is quite straightforward and works in much the same
way as line plots which you are already familiar with from the previous
examples. Assuming you have a data array consisting of the values
[12,8,19,3,10,5] and you want to display them as a bar plot. This is
the simplest way to do this:

If you compare this to the previous line examples you can see that
the only change necessary was that instead of creating a new line plot
(via the new LinePlot(...) call) we used the statement new
BarPplot().

The other change we should do is to make sure the X-axis have an
text-scale (it is perfectly fine to use a linear X-scale but in most
cases this is not the effect you want when you use a bar graph, see
more below). With this two simple change we will now get a bar graph as
displayed in the following image
You can of course modify the
appearance of the bar graph. So for example to change the fill color
you would use the
BarPlot::SetFillColor() method. Making this small change to the
previous example would give the expected effect as can be seen in the
next example.
Sidebar: You should note from the
previous two graphs that slight change in appearance for the X-scale.
The bar graphs gets automatically centered between the tick marks when
using as text x-scale. If you were to use a linear scale they would
instead start at the left edge of the X-axis and the X-axis would be
labeled with a linear scale. As is illustrated in the (small) example
below

Figure 29: A small example with a bar graph using
a linear X-scale [src]

JpGraph allows you to easy customize the appearance of the bar graph,
for example to change the width of each bar. The width of each bar can
be specified either as a fraction of the width between each major tick
or as an absolute width (in pixels).

You cane see a small nuisance in this graph. The auto scaling
algorithm chooses quite tight limits for the scale so that the bars
just fit. Adding the value on top of the bar makes it collide with the
top of the graph. To remedy this we tell the auto scaling algorithm to
allow for more "grace" space at the top of the scale by using the
method
SetGrace() which is used to tell the scale to add a percentage (of
the total scale span) more space to either one end or both ends of the
scale. In this case we add 20% more space at the top to make more room
for the values with the line

You can also adjust the general position of the value in respect to
the bar by using the
BarPlot::SetValuePos() method. You can set the position to either
'top' (the default) , 'center' or 'bottom'. The graph below shows the
value being positioned in the center. In this example we have also
adjusted the format to just display the value as an integer without any
decimals.

It is also possible to specify a more fine grained control on how
you want the values presented. You can for example, rotate them, change
font, change color. It is also possible to adjust the actual value
displayed by either using a printf()-type format string or with the
more advanced technique of a format callback routine.

To show what you can do we just give another example for you to
examine without much further explanations. Just remember that to have
text at an angle other than 0 or 90 degrees we have to use TTF fonts.
Even though we haven't explained the SetFont() method it should be
fairly obvious.

These types of bar graph is used to easy group two or more bars
together around each tick (X-value). The bars will be placed
immediately beside each other and as a group centered on each tick
mark. A grouped bar is created by aggregating two or more ordinary bar
graphs and creating a
GroupBarPlot() From two ordinary bar graphs along the lines of

If you use the SetWidth() method on the GroupBarPlot() this will
affect the total width used by all the added plots. Each individual bar
width will be the same for all added bars. The default width for
grouped bar is 70%.

The final variety of group bars you can have are accumulated bars. They
work in much the same way as accumulated line plots described above.
Each plot is stacked on top of each other.

You create accumulated bar plots in the same way as grouped bar
plots by first creating a number of ordinary bar plots that are then
aggregated with a call to
AccBarPlot();

An example makes this clear. Let's use the same data as in the two
examples above but instead of grouping the bars we accumulate (or
stack) them. The code would be very similar (actually only one line has
to change)

It is perfectly possible to combine the previous bar types to have
grouped accumulated bar plots. This is done by just adding the
different accumulated plots to a group bar plot, for example the
following code would do that.

It can often come in handy to have horizontal bar graphs especially if
you have a large number of values to display. Even though JpGraph
doesn't directly support horizontal bar graphs this is easy achieved by
constructing a normal vertical bar graph which is then rotated 90
degrees.

The example below shows a simple example of this

Figure 40: A typical horizontal bar graph with the
Y-axis at the bottom [src]

In order to achieve this effect you should study the above example
carefully and you might notice two things

We don't simply rotate the graph we also specify that we want the
rotation center to be the middle of the entire image. The reason for
this is that by default (See the section on rotating plots) the pivot
point for rotation is the center of the plot area.
Since the center of the plot area is not necessary the center of the
entire image the rotation might be a little bit difficult to predict
since it will depend on the margins specified. <

The size of the plot area is determined from the original width and
height of the image taking the specified margin into account. When the
the plot area is rotated 90 degrees clockwise what was the left margin
now in effect become the upper margin and so on. This is a small nuance
since we conceptually want to specify the margins directly in the
rotated plot.
I have chosen not to add any special margin method specifically for
a 90 degree rotated plot. Since to compensate for this since is fairly
easy once you understood this problem.For this reason the example code
let's you specify the perceived margins and they are then backwards
converted to their horizontal equivalent. If the width and height
differs we must also take that into account.
The code below extracts the lines that makes this simple conversion

// Since we swap width for height (since
we rotate it 90 degrees)
// we have to adjust the margin to take into account for that
$top = 50;
$bottom = 30;
$left = 50;
$right = 20;
$adj = ($height-$width)/2;
$graph->SetMargin($top-$adj,$bottom-$adj,$right+$adj,$left+$adj);

We finally show three more examples of horizontal bar plots. In the
first plot we have hidden the Y-axus and in the second we have
positioned the Y - axis at top as opposed to the bottom as the first
example shows.

It is possible to use color gradient fill for the individual bars in
the bar graph.

Color gradient fill fills a rectangle with a smooth transition
between two colors. In what direction the transition goes (from left to
right, down and up, from the middle and out etc) is determined by the
style of the gradient fill. JpGraph currently supports 7 different
styles. All supported styles are displayed in the figure below.

To specify a gradient fill for the bar plots you make use of the method
BarPlot::SetFillGradient() . See the class reference for details of
this function.

When using gradient fills there are a couple of caveats you should
be aware of:

gradient filling is computational expensive. Large plots with
gradient fill will take in the order of 6 times longer to fill then for
a normal one-color fill. This might to some extent be helped by making
use of the cache feature of JpGraph so that the graph is only generated
a few times.

gradient filling will make use of much more colors (by definition)
this will make the color palette for the image bigger and hence make
the overall image larger. It might also have some severe effect on
using anti-aliased line in the same image as color gradient filling
since anti-aliased lines also have the possibility to make use of many
colors. Hence the color palette might not be big enough for all the
colors you need. So if you use gradient fills you should also be using
a true-color image since you otherwise run out of colors.
This problem is often seen as that for no apparent reason some
color you have specified in the image does appear as another color.
(This is not a bug in JpGraph!) This is something to especially watch
out for when enabling anti-aliasing since that also uses a lot of
colors. Since the numbers of colors used with anti-aliasing depends on
the angle on the lines it is impossible to foresee the number of colors
used for this.

Semi filled bar graphs are in principle the same as normal filled bar
graphs but with the additional feature that you can choose to only fill
a specified range (or ranges) of X-coordinates. The figure below
illustrates this

Error plots are used to visually indicate uncertainty in data points.
This is done by for each X value by giving both a minimum and a maximum
Y-value.

Before you can use error plots you must remember to include the file
"jpgraph_error.php" in your script.

The following example illustrates a simple error bar. We will have 5
points, so we need 10 Y-values. We also would like the error bars to be
red and 2 pixels wide. All this is accomplished by creating an
ErrorPlot() in much the same way as, for example, a normal line
plot. Doing this would now give the example shown below.

You might notice that there is one displeasing esthetic quality of
this graph. The X-scale is just wide enough to just accompany the
number of error bars and hence the first bar is drawn on the Y-axis and
the and last bar just at the edge of the plot area. To adjust this you
might call the SetCenter()
method which will adjust the X-scale so it does not use the full width
of the X-axis.

The following example illustrates the use of this feature by
applying this technique to the previous example

Figure 54: Adjusting the X-scale not to use the
full width of the X-axis. [src]

A line error plot is an error plot with the addition that a line is
drawn between the average value of each error pair. You use this type
of plot the exact same way you would use an error plot. The only change
is that you must instantiated an
ErrorLinePlot() instead and make sure you have included the
"jpgraph_line.php" since the line error plot makes use of the line plot
class to stroke the line.

To control the various properties of the line drawn the "line"
property of the error line plot may be accessed. So, for example, if
you want the line to be 2 pixels wide and blue you would have to add
the following two lines

You may of course add legends to none, one or both of the line types
in the above graph. So for example if we wanted the legend "Min/Max"
for the red error bars and a legend "Average" for the blue line you
would have to add the lines

$errplot->SetLegend("Min/Max");
$errplot->line->SetLegend("Average");

The resulting graph will now look like (note that we are using the
default placement of the legend box)

Scatter plots are very simple; they plot a number of points specified
by their X- and Y-coordinate. Each point is stroked on the image with a
mark as with line plots. The stroked marks can also be connected with
an optional line.

Sidenote: Even though it is only scatter
plot that was designed to be used with X,Y plots it is perfectly
possible to use use both X,Y coordinates for bar and line plots as
well.

Even though you would normally supply X-coordinates it is still
perfectly possible to use a text-scale for X-coordinates to just
enumerate the points. This is especially useful when using the
"Impulse" type of scatter plot as is shown below.

Scatter pots are created by including the jpgraph extension
"jpgraph_scatter.php" and then creating an instance of plot type of
ScatterPlot(). To specify the mark you want to use you access the mark
with the instance variable "mark" in the scatter plot. The default is
to use an unfilled small circle.

Another possible variant of scatter plot is impulse-scatter plots.
This is a variant of normal scatter plot where each mark have a line
from the mark to the Y=0 base line. To change a scatter plot into an
impulse scatter plot you have to call the method
SetImpuls() on the scatter plot.

This type of plots are often used to illustrate signals in
conjunction with digital signal processing. The following two examples
illustrates simple use of impulse plots.

Sidebar: You may draw impulse graphs
without any mark by specifying the mark type as (-1) . That way only
the impulse lines will be drawn. As a final touch we show two more advanced impulse graphs . In
these graphs we have used more advanced formatting for the Y-axis
labels as well as adjusted the position of the axis position.

Figure 61: In this imuplsplot we have adjusted the
position of the X-axis to the bottom and also added more decimals to
the labels on the Y-axis [src]

Figure 62: In this impuls plot we have also added
a lineplot with a dotted line style.
[src]

A variant of scatter plot is the so called Field Plots this is
basically a scatter plot where each scatter point is an arrow with a
direction between 0 to 359 degrees. This effectively allows the
visualization of 3 parameters at each point (x,y,angle). As an
additional bonus there is also possible to define a callback for each
scatter plot to also define the color for each point.

To create a field plot you create an instance of
FieldPlot in the same way as you created a normal scatter plot. The
arguments to this method are Y-coordinate, X-coordinate and angle. To
specify a callback you use
FieldPlot::SetCallback()

The following example (and code) illustrates the usage of the field
plot type.

In addition to the parameters mentioned above you can also adjust
both the general size of the arrow and also the specific size of the
arrowhead. The arrow size is specified in pixels and the arrow head is
specified as an integers between 0 and 10. These sizes are specified
with a call to
FieldPlot::arrow::SetSize()

Stock charts is used to display data values where one is interested in
4 different values for each data point. This could for example be used
to display a stock's open,close, min and max value during a specific
day. Hence the name Stock chart (or Stock plot).

For this type of plot the Y-data array must be consist of a number
of quadruples of data where each quadruple consists of
(open,close,min,max). The open and close values determine the min max
for the middle bar and the min,max determine the end points of the
"error-lines" at the top and bottom of of each bar.

Note that the data follows the following rules

min < max

min < min(open.close)

max > max(open,close)

To separate the two cases where "open > close" or "open < close "
different colors are used. These colors are specified with the
SetColor() method. By default a positive bar (close > open) have a
fill color of white and for the negative case where (close < open) the
bars have a red color.

You can specify the width of the bar by setting the width (in
pixels) with a call to the method
SetWidth()

The final variation of stock plots you can have is to determine
whether or not the end point for the min,max lines should have the
horizontal line marking the end of the line or not. This can be
adjusted with a call to method
HideEndLine().

A minor variation of stock charts is the "BoxPlot()" this is almost the
same as StockPlot() but with the very small difference that in addition
to the open,close,min, max values you also specify a median value . The
median lies between the open and close value and is illustrated as a
horizontal line within the bar.

In the same way as for other plots you may associate an image map with
these plots. The "hot" area for each plot is the mid "bar" section. In
the same way as other plot types you use the
SetCSIMTargets() to set the URL's you want to use.

Note: These plot types, though normally used without explicit
X-values, can of course handle a supplied X-coordinate array without
any problem.

It is perfectly legal to add several different plot types to the same
graph. It is therefore possible to mix line plots with (for example)
filled bar graphs. What you should keep in mind doing this is the order
in which these plots are stroked to the image since a later stroke will
overwrite a previous one. All plots are stroked in the order you add
them, i.e. the first plot added will be stroked first. You can
therefore control which plot is placed in the background and which one
is placed in the foreground by the order you add them to the plot.

To start simple we just mix a filled line plot with a non-filled
line plot as the following example shows.

Figure 66: Mixing filled and non-filled line plots
in the same graph [src]

Let's now go to something a little bit more complicated. How to mix
bar and line graphs. Let's just take one of our previous bar graphs and
add a line plot to it and see what happens.

Normally the automatic scaling should be doing an adequate job in most
circumstances but there might be cases where you like to manually set
the scale. For example if you have several graphs where you like to be
able to easily compare them and therefore want them all to have the
same scale.

To specify a manual scale you have to add arguments to the standard Graph::SetScale() method.
So to specify that you want an Y-scale between 0 and 100 you need to
write

$graph->SetScale("textlin",0,100);

When you specify a scale manually there is one additional thing you
need to decide. How the tick marks should be positioned. You have three
choices

Let JpGraph decide suitable tick marks honoring the exact scale you
specified. This is the default behavior if you don't do anything
else.

Allow JpGraph to slightly adjust your specified min and max values.
With the default method, depending on the min and max values, the end
and start of the scale might not fall on an exact tick mark. For
esthetic reasons you might still want the last/first tick mark to fall
on the edges of the scale. By calling
LinearScale::SetAutoTicks() you tell JpGraph to make the smallest
necessary adjustment of the end/start points so that they fall on an
exact tick mark.

A common plot type is to have a date/time scale on the X-axis. Even
though there is not special support for a time scale this is easy to
accomplish.

In the following we will assume that all data points are specified
by a tuple where the date/time is specified as a timestamp in second in
the same format as is returned by the PHP function time().

The trick here is to use a label formatting callback routine which
gets called to format each label on the scale.

What we do is that we specify that the X-scale should be an ordinary
"int" scale (remember that the data values are timestamps which are
integers). We then install our custom label callback (with a call to
SetLabelFormatCallback()) which given a timestamp formats it to a
suitable human readable form. In our example we will use the PHP
function Date() for this purpose.

In the following section we will work through an number of examples on
how to manipulate labels on a text scale. Primarily we will investigate
how to best handle the case where you have a large number of values.

As a remainder; Text scale is meant to be used on the X-axis when
the X-axis doesn't have a numeric value, i.e you are only interested in
linear ordering of the data. If you don't specify the labels manually
they will be set automatically starting from 1 as the example below
shows.

To specify the labels on the X-axis as suitable text strings you
call the method
Axis::SetTickLabels() with an array containing the text-labels. If
there are more data points than labels the non-specified labels will be
given their ordinal number. If we augment the previous example with the
name of the month we get the following new example

Tip: To get hold of localized version of
the month names (or weekdays) you can use the
DateLocal class available in the global variable $gDateLocale If no
locale has been specified the default locale for the installation will
be used.

What happen now if we have a larger number of bars? Let's try with
25 bars and see what result we get.

Not all to impressive. The labels are to close and they overlap.
Hence it is not a good idea to display every label. To adjust what
labels are to be displayed you use the
SetTextLabelInterval() method. The argument to this method is the
interval between text labels. So to display only every 3 month you
would add the line

If we have an even larger data set it might not longer be meaningful
to display all the tick marks since they would simple become to close.
In JpGraph there is a possibility to specify that you only would like
every n:th tick mark to be visible (
SetTextTickIntervall() ). For bar graphs using text scale however,
that might not be such a good idea since the tick marks are between the
bars and the labels centered under the bars. If we only were to
display, say, every 3 tick mark it wouldn't look to good. Not that we
can't do it, as the example below shows, but it just doesn't look very
good.

To add clarification or other information text strings to the graph you
can add arbitrary lines of text anywhere you like onto the graph. The
text might have multiple lines and you can choose the paragraph
alignment.

To add text you have to create one or more instances of the
Text() object and then add the text object to the graph with the
AddText() method.

The position of these text boxes are given as fraction of the width
and height of the graph. When you are positioning these text boxes you
might also choose what part of the text box should be considered the
anchor point for the position you specify.

By default the anchor point is the upper left corner of the bounding
box for the text.

To show some ways of positioning the text we use a very simple bar
graph not to distract from the text. We first just add a single text
line with most of the settings their default value by adding the
following lines to the graph

Not too exiting. Let's make it more interesting by having a
background color, using larger fonts and framing the text box and
adding a drop shadow to the text box by using the methods
SetBox() and SetBox()

That's better. Now we get some attention. If you want to add a text
with several lines you just need to separate the lines with a newline
('\n' character). The default paragraph alignment is left edge but you
can also use right and center alignment.

As an illustration let's add a couple of more lines to the previous
text, center the text box in the middle of the graph and also use
centered paragraph alignment for the text. To adjust the paragraph
alignment of the text you have to use the
Text::ParagraphAlign()

Of course there is no limit to the number of text string you can add
to the graph.

From version 1.12 it is also possible to add text strings to a graph
using the scale coordinates instead. This is accomplished by using the Text::SetScalePos() Which
is completely analog to SetPos() with the only difference that the
positions given are interpretated as scale values instead of fractions
of the width and height.

Each graph can have up to three different titles accessed by the three
properties

title

subtitle

subsubtitle

All of these three properties is a standard text object which means
that you can have individual font, colors, margins and sizes of these
tree titles.

The only thing you need to think of is that you probably want to add
some extra margin to make room for the titles (using
Graph::SetMargin() )

The individual positioning of these titles are done automatically
and will adjust to the font size being used.

If you for, esthetic reasons, would like increase the distance from
the top where the title is positioned (or the intra distance between
title and sub title) you can use the
Text::SetMargin() method. For example the line

$graph->title->SetMargin(20);

will set the distance between the top of the title string and the
top of the graph to 20 pixels. If you instead call the SetMargin()
method for the subtitle it will adjust the distance between the top of
the subtitle and the bottom of the title.

The titles will be positioned at the top and be centered in the
graph. Each of these titles may have multiple lines each separated by a
"\n" (newline) character. By default the paragraph alignment for each
title is centered but may of course be changed (using the
ParagraphAlign()) method.

Each graph can also have a footer. This footer is actually three
footers. Left, center and right. The 'left' footer is aligned to the
left, the 'center' at the bottom center and the right to the right.

Each of these three positions is a standard Text object which means
you can change color, font and size as you please individually on each
of these footer positions.

You access the footer through the Graph::footer property as the
following example shows

Instead of having a single color background you can easily have an
arbitrary image as the background. The image may be in either PNG, JPG
or GIF format depending on what your installation supports.

A note on GD: If you are using GD 2.xx you
must make sure that the define USE_TRUECOLOR is set to true. This is
also the default. Failure to do so in combination with GD 2.xx will
make the background image just look like a solid black square.

To use a specific image as the background you just have to use the
method
Graph::SetBackgroundImage() The arguments specify file-name, how
the image should be positioned in the graph and finally the format of
the image (if it is in JPG, PNG or GIF) format. If the format is
specified as "auto" (the default) then the appropriate image format
will be determined from the extension of the image file.

The file name is of course obvious but the second argument might not
be. This arguments determine how the image should be copied onto the
graph image. You can specify three different variants here

BGIMG_ COPY This will just copy the image unchanged onto the graph
from the top left corner.

BGIMG_CENTER This will just copy the image unchanged onto the graph
but it will center the image in the graph.

BGIMG_FILLFRAME This will scale the image to exactly fit the whole
graph image.

BGIMG_FILLPLOT This will scale the image to exactly fit just the
plot area of the graph.

The following section only applies to palette based images.
True color images can NOT be manipulated this way. Applying the
following sections to true-color images will have no affect.

You might often find yourself wanting to use a background image as a
"waterstamp". This usually means taking the original image, import it
to some image editing program and then "bleaching" the color
saturation, reducing the contrast and so on. Finally you save the
modified image which you then use as a background image.

This whole process can be automatically accomplished in JpGraph by
using the method
Graph::AdjBackgroundImage() which allow you to adjust color
saturation, brightness and contrast of the background image.

For example, in the image below I have used the settings

$graph->AdjBackgroundImage(...)

to achieve the "watercolor" effect to avoid the image being too
intrusive in the graph.

Sidenote: The background image used above
is my primary means of summer transportation. A 1998 Triumph Tiger.
This bike is a nice 900cc quarter-of-a-metric-ton on/off-road bike.
This is one of the few bikes I found which I can ride comfortable in
despite me being 6' 4''.

In addition to the background image you can also add a background color
gradient. This gradient can be covering the entire graph, just the plot
area or just the margins. This flexibility allows you to combine a
background image with a background color gradient. You can for example
use a background image in the plot area and a color gradient out in the
margins.

You specify a color gradient background by calling the
Graph::SetBackgroundGradient() method. All details are available in
the class reference (follow the link above). We finally give a quick
example on what kind of effect you can achieve using this feature.

Figure 88: Using a background color gradient with
the SetBackgroundGradient() method
[src]

Finally we like to mention that in the "/utils/misc/" directory you
will find a small utility script called "mkgrad.php". Running this
script presents you with a UI that makes it a breeze to create a
gradient image on it's own.

The UI for the utility is so obvious that we won't discuss it
further, we just show it below. The UI for the mkgrad.php utility

In the example below I have used this utility to get a more
interesting plot area.

An interesting enhancement when using Plotmarks is the possibility to
add a callback function to control the size and color of the plotmarks.

This callback function will get called with the current Y-value (for
the plotmark) as it's argument. As return value the callback function
must return an array containing three (possible null) values. The
values returned must be

Plot mark Weight

Plot mark Color

Plot mark Fill color

The exact meaning of the parameters will of course depend on the type
of plot marks being used.

As you can see in the above example we have left some of the return
values blank. Doing this will just ignore any change of these value and
use the global settings for the plotmarks.

If you also let the (Y) value affect the size of the plot marks you
can get what is sometimes known as a "balloon plot". The example below
is basically a scatter plot that uses filled circles to mark the
points. A format callback is then used to change the color and size
depending on the Y-value for each plot.

In section 10.2 you can read about
arbitrary rotation of the graphs. For most practical purposes rotation
of 90 degrees is most useful. This could for example be used to plot
horizontal bar graphs.

The slight complication with general rotation is that the margins
also rotates, this means that if you rotate a graph 90 degrees the left
margin in the image was originally the bottom margin. In additional by
default the center of the rotation is the center of the plot area and
not the entire image (if all the margins are symmetrical then they will
of course coincide). This means that depending on your margin the
center of the rotation will move. You can read more about this and how
to manually set the center for rotation in the section about rotation, 10.2

This is just a slight inconvenience which you have to take into
account when you need to set an explicit margin with a call to
Graph::SetMargin()

However, in order to make a rotation of 90 degrees much easier you
can easily rotate a graph 90 degrees and set the correct margin with a
call to
Graph::Set90AndMargin() The parameter to this method lets you
specify the margins as you will see them in the image without having to
think of what becomes what after the rotation.

So, the only thing you need to do is call this method and then the
graph will have been rotated 90 degrees.

Assuming we start with the traditional two axis graph, one X and one Y
axis. You may then change the position of each axis by calling
Axis::SetPos($aPosition) You have to remember that you need to
specify the position on the other axis. SO you need to specify the
world-coordinate for the position. By default the axis are each
positioned at the 0-point on the other axis, i.e. the axis will cross
at the 0,0 point in the graph.

In addition to the standard positioning you may also use the two
special position markers "min" and "max". This will position the axis
at the minimum (or maximum) position of the other axis.

For example, to make sure that the X-axis is always at the bottom of
the graph (at lowest possible Y-value) you would have to add the line

Invisible axis Even though JpGraph (1.7)
doesn't directly support "hidden" axis where the labels are still drawn
it is very easy to achieve this effect by setting the colors of the
axis to be the same as the background. See the example barintex2.php in
the Example directory. To completely hide an axis you can make use of
the Hide()

You might also want to add titles to the axis. This is done through
the Axis::SetTitle()
method. This is actually just a shortcut for accessing the title
property direct. Axis::title::Set() which also allow you to set the
alignment in one call.

By default the position of the title is to the far right for the
X-axis and in the middle (and 90 degrees rotated) for the Y-axis.

You can adjust the position of the title with the help of the second
argument to the
Axis::SetTitle() method.

The possible positions are "high","middle" and "low" which refers to
the scale values on the axis.

One common modification you might want to do to the title is to
increase the margin between the axis and the actual title. This is
often necessary to do for the Y-axis if the values displayed are large.
You may adjust the distance (in pixels) between the axis and the title
by using the method
Axis::SetTitleMargin()

So for example to increase the margin on the Y-axis you might add
the line

$graph->yaxis->SetTitleMargin(40);

to your code.

Finally we mention something about the positioning of tick marks and
labels on the axis. You have the possibility to choose what side of the
axis the tick marks and the labels should be at. For the X-axis this
can be specified as either on the the top (inside the plot area) or at
bottom (outside of the plotarea). In the same way you can specify for
the Y-axis if the labels ( or ticks) should be on the left or right
side.

How to adjust the actual labels are discussed elsewhere in this manual
(see ???,???). However we like to mention here that you can adjust the
label margin (distance between the axis and the labels) with the method Axis::SetLabelMargin()

to adjust the actual label format (like font, color, angle) you need
to access the Axis::SetFont()
and the Axis::SetColor()
methods. If you investigate the Axis
class you will discover more methods to adjust the many aspects of the
axis layout.

As a final note we also mention the methods
Axis::SetLabelAlign() and
Axis::SetLabelAngle() This first method is really only mentioned
here for completeness since it is mostly used for internal purposes.
However on some occasion you might want to adjust the alignment of the
labels. By default they are centered in respect to the tick mark. By
using the method you might override this positioning should you choose
to do so.

The second of these methods adjusts the angle of the label in
regards to the axis. This is very useful for X-axis that have long
labels.

In order to have full control over the way that the labels are
displayed it is possible to define a callback function that will be
applied to all labels. The callback function will be called with the
label as the only argument and should return the value that will be
displayed in the graph. This could for example be used to turn seconds
(used to position data points) into hour and minutes on the scale. For
further reference see the two methods:
Graph::SetLabelFormatCallback(); and
Graph::SetLabelFormat();

By default the auto-scaling algorithm tries to make best possible use
of screen estate by making the scale as large as possible, i.e. the
extreme values (min/max) will be on the top and bottom of the scale if
they happen to fall on a scale-tick. So for example doing a simple line
plot could look like the plot shown in the below.

However you might sometime want to add some extra to the minimum and
maximum values so that there is some "air" in the graph between the end
of the scale values and the extreme points in the graphs. This can be
done by adding a "grace" percentage to the scale. So for example adding
10% to the y-scale in the image above is done by calling the
SetGrace() method on the yscale as in

$graph->yaxis->scale->SetGrace(10,10);

These lines add a minimum of 10% to the top and bottom values of the
scale. Note that we say "minimum" since depending on the specific tick
values choose this might be a little bit more to make the end of the
scale fall on an even tick mark.

Adding this line to the previous graph will result in the following
example

Figure 95: Adding 10% grace value to top and
bottom of the Y-scale [src]

Since we haven't adjusted the position of the X-axis it will remain
at Y=0 which might not necessary be what we would like so we therefor
also add the line

$graph->xaxis->SetPos("min");

So that the X-axis always will remain at the lowest possible
Y-value. Doing this will then result in the example below

Figure 96: Using grace but also adjusting the
position of the X-axis [src]

As an additional way of emphasizing certain areas of the graph it is
possible to add bands (either vertical or horizontal) to any one of the
standard X-Y coordinate system based graphs. A band is a rectangular
area that stretches one entire axis. This means that if you define a
band between X-coordinates 3 and 5 the band area will occupy an area
between the X-coordinates and the entire Y-range.

In order to access this functionality you must first make sure that
you include the additional library file jpgraph_plotband.php

At the time of this writing (current as of JpGraph 1.8) the table
below illustrates the 8 basic types of patterns available. We will
shortly show you how you can customize these patterns, To keep these
examples clear we have only used one pattern in each figure.

To add a one of these patterns to your graph you need to call the
method
PlotBand::PlotBand() The arguments is fairly easy to understand.
The pattern you would like to use is specified by using the correct
constant. You can see the name of the correct constants in the figures
above. You also need to specify if the band should stretch along the
vertical or horizontal axis as well as the min and max coordinates for
the band. As coordinates you may also use the special values "min" and
"max" which automatically sets the value to the minimum/maximum value
of the scale. The specified numeric value will be automatically
truncated to fit within the plot area.

We don't discuss the other arguments further here, instead we refer
you to the class reference.

... altering the density of the patterns using the method
PlotBand::SetDensity() The density is specified as an integer in
range 1 to 100 where a higher number means a higher density (smaller
distance between the lines). For example setting the density of the 3D
plane above to 60 gives the result

Sidenote. 3D planes actually carry another
possible modification. You can specify the vanish point to change the
perspective used. You can't access the method to change the horizon
directly but you can access it through

$band->prect->SetHorizon($aHorizon)

assuming that the band is a 3D plane.

To finish this section we give one final, more creative, example on
how to use the bands.

In addition to the bands you can also add static lines to the graph. An
example of that is actually shown in figure 11 above. You create a line
as an instance of class
PlotLine . So for example the lines

The fundamental difference is that these classes makes use of an
extended version of the basic Graph class. Therefor you can not mix X,Y
plots with non-X,Y plots. For example it is not possible to mix a line
graph with a Polar graph.

Spider plots are most often used to display how a number of results
compare to some set targets. They make good use of the human ability to
spot symmetry (or rather un-symmetry) . the figure below show an
example of a spider (sometimes called a web-plot). Spiderplots are not
suitable if you want very accurate readings from the graph since, by
it's nature, it can be difficult to read out very detailed values.

We normally would like something more meaningful as description of each
axis than it's number. Specifying the titles are accomplished through
the use of the method SetTitles() of the graph. Let's say that each
axis corresponds to a month. We could then use the code

$titles = $gDateLocale->GetShortMonth();
$graph->SetTitles($titles);

As you can see the way radar plot is constructed will assign the
titles (and plot points) in a counter-clockwise direction. If you want
them in clock-wise order you will have to inverse your input data array
as well as the title array.

To specify a legend you (as with the other plot) make use of the
SetLegend(); method on each radar plot.

Each major tick mark can also be connected together to create a grid.
The grid is accessed through the 'grid' property of the graph. To
enable the grid and set the line style to "dotted" you would have to
add the lines

You can easily create several radar plot which are added to the same
radar graph. The thing to remember is that if you use filled radar
plots and they overlap each other that the order which they are added
will be the order they are drawn.

So far we have just show plots based on an X-Y coordinate system. This
is not the only types of graphs you can create with JpGraph. Another
common type is Pie plots. JpGraph supports both 2D and 3D pie plots.
For 2D pie plots there are also 2 versions, but more on that later.

The main difference as compared to the X-Y plots is that to all pie
plots are added to the
PieGraph() instead of the Graph() object we used for the X-Y graphs
we have drawn so far. For this you must first include the
"jpgraph_pie.php" in your script (or "jpgraph_pie3d.php" if you want to
use 3-dimensional pies).

Below you cane see the code needed to create the simplest possible
pie graph just using the default settings.

Adjust the labels for the slice (color, font, format, position ) by
accessing the value
property of pie plots, for example (
PiePlot::value::SetFont(), You can read more about label formatting
and how to change what is displayed as a value further down in this
chapter.

The next simplest addition we can do is to add a legend to the pie
graph. We do this by using the
SetLegends(); method. By adding the legends to the previous example
we get the following image

(In the figure above we also moved the center of the pie slightly to
the left to make more room for the legend box.)

The text for the legends can also contain printf() style format
strings to format a number. This number passed on into this string is
either the absolute value of the slice or the percentage value. How to
switch between the is describe further down in this chapter.

The next change you might want to change is the size and position of
the Pie plot. You can change the size with a call to
SetSize(); and the position of the center of the pie plot with a
call to SetCenter();
The size can be specified as either an absolute size in pixels or as a
fraction of width/height (whatever is the smallest). The position of
the pie plot is specified as a fraction of the width and height.

To put the size and positioning API to use we will show how to put
several pie plots on the same pie graph. In the following example we
have also adjusted the legends of the slice values to use a smaller
font.

What we do in this example is quite simple, create 4 pie plots, make
them smaller and put them in the four corner of the graph. This will
give the result as shown in the following example.

So far we have only made use of 2D pie plots, creating 3D pie plots is
no more difficult. Instead of creating the plots with a call to
PiePlot() you create the plots with a call to
PiePlot3D() If we just take the first simple pie plot and replace
the call to PiePlot() with a call to PiePlot3D() we get the following
result.

3D Pie plots have the same possibilities as the normal pie plots
with the added twist of a 3:rd dimension. You can adjust the
perspective angle with the method
SetAngle() So for example to make the pie more "flat" you just set
it to a smaller angle. Setting the perspective angle to 20 degrees in
the previous example will give the following result.

One way to attract attention to some specific piece of information in a
pie chart is to "explode" one or more slices. Both 2D and 3D pies
support exploding one or several slices.

Exploding slices is accomplished by the methods
Explode() and
ExplodeSlice() The first method is used if you want to explode more
than one slices and the second is a shorthand to make it easy to just
explode one slice.

For example to explode one slice the default "explode" radius you
would just have to say

$pieplot->ExplodeSlice(1)

The above line would explode the second slice (slices are numbered
from 0 and upwards) the default amount. Doing this to the two previous
example would result in

By default the values shown just outside the pie for each slice are the
percentage value for each slice. If you instead wanted the absolute
value you would just have to use the
SetLabelType() method. So to use the absolute value you would call

$pieplot->SetLabelType("PIE_VALUE_ABS");

Furthermore you could enhance the formatting of the value by either
using a printf() style format string (using
SetFormat() ) or by providing a formatting function callback (using
SetFormatCallback() ) for doing more advanced formatting.

You can also adjust the position of the labels by means of the
PiePlot::SetLabelPos() method. The argument to this method is
either the fraction of the radius or the string 'auto'. In the latter
case JpGraph automatically determines the best position and the the
first case The following example illustrates this

Figure 121: Example of adjusting the position of
the labels for the slices [src]

If this formatting is not enough you can also "manually" specify the
labels for each slice individually. You do this by using the
PiePLot::SetLabels() method. This will let you specify individual
text strings for each label. In each specification you can also add a
printf() formatting specification for a number. The number passed on
will be either the absolute value for the slice or the percentage value
depending on what was specified in the call to
SetLabelType()

The SetLabels() method can also take a second parameter, the label
position parameter. This is just a shortcut to the SetLabelPos() as
described above. By default the position will be set to 'auto' if not
explicitely specified.

Note: The alignment of the labels will be
different depending on whether they are inside or outside the pie. When
inside the center of the strings will be aligned with the center of the
slice at the specified fraction of the radius. When positioned outside
the alignment will depend on the angle to avoid that the labels
inadvertely writes over the pie.

Another typical change would be to change the colors of the slices.
There are two fundamental ways of doing this. You either manually
specify the colors for the slices as an array using the method
SetSliceColors() If you specify fewer colors than the number of
slices they will just wrap around.

Another way is to use one of the pre-defined color "themes". This is
just a predefined set of colors that will be used for the slices. You
choose what "theme" you like to use with the method (
SetTheme() ) At the time of this writing the available themes are

"earth"

"pastel"

"sand"

"water"

The following example shows the same pie using the different "themes"
in order.

An additional visual enhancements can be made by adding a drop shadow
to the individual slices. This is accomplished by means of the
PiePlot::SetShadow() method. Adding a drop shadow is often more
affective if the pie has one or more slices exploded as the following
example shows

Each data point in a polar plot is represented by a tuple consisting of
a radius and an angle. The polar plot itself can be either outlined or
filled. In addition each point may have a standard marker (the same as
for line and scatter plots).

The scale for the radius can be either linear or logarithmic.

A polar graph is created by creating an instance of
PolarGraph::PolarGraph(). The polar graph type inherits all the
capabilities of ordinary X-Y graphs, i.e they can have background
images, background gradients, tabbed titles and so on.

Polar graphs comes in two basic types, they can either show a full
360 degree graph or a half 180 degree graph. The two examples below
show these two basic types of graphs.

The radius axis can be shown in either a linear or logarithmic scale.
This is controlled, as usual, by a call to
PolarGraph::SetScale() The two examples below show the same plot in
either linear or logarithmic scale

By default the scale will be auto scaled depending on the data. You
can also specify a manual scale by supplying an extra argument to the
SetScale() value. The only difference from the manual scaling with the
other X-Y-graphs is that for polar graph you only specify a manual
maximum. The minimum will always be 0 for the linear scale and a scaled
value of 10 (i.e 1, 0.1, 0.001 and so on) for the logarithmic scale.

The plot is clipped to the plot area so if you specify a smaller
scale then the maximum value that part of the plot that are outside the
plot area will be clipped.

As usual you have full freedom to select what grid lines you like to
show (and what colors they should have). There are three different
types of grid lines you may adjust. The radius minor and major grid
lines and the angle grid lines.

You select what grid lines to show with a call to
PolarAxis::ShowGrid() The two example below shows a logarithmic
plot with either just major grid lines or both minor and major grid
lines.

For the angle grid lines it is possible to specify the angle
division between each grid line with the method
PolarAxis::SetAngleStep() You specify the step distance in degrees.
By default the step size is 15 degrees.

You can individually specify different fonts and colors for the angle
and the radius labels. The radius font is specified with
PolarAxis::SetFont() and the angle font is specified with a call to
PolarAxis::SetAngleFont()

The following example specifies different color for the labels. it
also shows that you can add both a radial axis title as well as a
tabbed title. In this example we have also chosen not to show the frame
around the edge of the plot.

Figure 135: Different colors for labels,
specifying both a tabbed title as well as a axis title
[src]

As can be seen from the previous examples the angle labels have a small
superscripted "o" after each label. You can select if you like to show
this degree mark or not with a call to the
PolarAxis::SetANgleDegreeMark() method by which you can enable or
disable that mark after the angels.

For the radius labels all standard formatting that can be done to
the X-Y axis such as format string or format callbacks are supported.

A common modification for polar plots is probably to disable the
display the last label when using a 360 degree plot since the last
label will "collide" with the plot box around the plot area. It is
possible to disable the last label with a call to
Axis::HideLastTickLabel() As you can see this has been used in some
of the examples in this chapter.

If you have specified markers for the polar plot (by setting the mark
property of the plot) each marker can be a hot spot in a client side
image map. The target URL are as usual specified with the
SetCSIMTargets() as the following short code excerpt shows

Time to show you an example of a Gantt chart and how easy it is to make
one. Lets make it the simplest possible Gantt chart. One activity,
named "Project", which lasts from "2001-11-01" to "2002-02-20".

All it takes to do this (using default values for everything) is the
following code.

Figure 138: Making the Gantt chart a little bit
more interesting with title and more colors.
[src]

From the above example you might note a few things

The margins adjust automatically to the added title and subtitle

The height of the scale headers adjust automatically when you
change the font.

You have great flexibility in choosing what format the scale labels
will have. If you for example wanted the full 4 digit year in the month
header all you have to change is use the constant
MONTHSTYLE_SHORTNAMEYEAR2 in the code above to
MONTHSTYLE_SHORTNAMEYEAR4

You have full freedom of manipulating headers in terms of font,
color, background and size.

To show that this is really simple let's show the full year in the
month, and set the header style to be white text on a dark blue
background by adding the lines

// Use the short name of the month
together with a 4 digit year
// on the month scale
$graph->scale->month->SetStyle(MONTHSTYLE_SHORTNAMEYEAR4);
$graph->scale->month->SetTextColor("white");
$graph->scale->month->SetBackgroundColor("blue");

On the top there is the scale headers (up to four headers may be
displayed)

The actual plot area where all the Gantt bars and markers go

The margin area, where for example the titles are shown

Since a Gantt chart inherits all the usual properties of a JpGraph
Graph() you have the access to the same method to formatting the image
as before. For example to have a shadow around the image you call
Graph::SetShadow() and to set the margin color you can use
Graph::SetMarginColor(). Please refer to the reference documentation
for a full list of supported features.

To create a Gantt chart you add objects to it. As
of this writing you may add the following object by the use of the
GanttChart::Add() method

Gantt bars (indicates the length of an activity)

Milestones, a single mark at a specific date

Vertical line, might be use to mark phases in projects

All these objects may be extensively modified in terms of formatting.
You can specify color (both fill- and frame color), size, titles, style
and patterns and so on. All these objects comes with (in my mind)
sensible default so you don't have to specify a lot of parameters. But
if you need a fine grain control or if you disagree with my taste you
can.

You create a new Gantt Chart with a call to GanttChart(). The signature
for GanttGraph is the same as for ordinary JpGraph graphs, i.e

function
GanttGraph($aWidth,$aHeight,$aCachedName,$aTimeOut,$aInline)

The only real difference is that for GanttCharts you can specify one
or both of the dimension parameters (width and height) as -1 in which
case that dimension will be automatically sized determined by scale and
fonts chosen. The following examples shows some possible ways of
creating a new graph

$graph=new GanttGraph()
The size of the graph will be determined automatically, no caching
will be used and the graph will be generated in-line.

$graph=new GanttGraph(-1,-1,"auto")
The size of the graph will be determined automatically, caching
will be used (the name will be based on the script name), no timeout
will be used and the graph will be generated in-line

$graph=new GanttGraph(450,-1,"auto",5)
Same as the previous entry but the width is fixed to 450 points and
the cached image will have a timeout of 5 min.

$graph=new GanttGraph(-1,-1,"auto",5,false)
The image will not be generated in-line, only the cache will be
updated if it has timed out, otherwise nothing will happen.

Since GanttGraph() inherits all the methods (that make sense for
GanttGraph) from Graph you can specify shadow, color etc of the general
frame.

Bars and Milestones need both a vertical position and a horizontal
position. The horizontal start position is specified as a date, e.g.
"2001-06-23", and the vertical positions are specified as a number
[0,1,2,3,...]. This vertical number indicates the position from the top
where the object should be placed. To understand this you might imagine
a number of "invisible" horizontal bands with a certain height. If you
specify 0 as the vertical position the bar will be placed in the first
band, specify 3 and the bar will be placed in the fourth band and so
on.

It is perfectly legal, and perhaps even desirable to leave "gaps"
when laying out bands to group related activities. So, for example you
could have three activities/bars at positions 1,2,3 and then another 2
bars at position 6,7 leaving band 0,4,5 empty.

All these "invisible bands" have the same height (equ-spaced). The
height of each band is automatically determined and depends on both the
method of layout ( as specified by (GanttChart::SetLayout()) and the
individual heights of the individual bars and titles. The rules are
quite simple:

If you use layout=GANTT_FROMTOP (the default and most common) the
height will equal the height (+ a margin) of the highest gantt bar. The
height calculation of each bar takes into account both the actual bar,
the title, and any left- right-marks (more about that later) that may
be present. The name "fromtop" refers to that when you have explicitly
specified a height the bars will usually be added from band 0 and
onwards and hence being added from the top. (This might leave empty
space at the bottom of the plot area in the graph if the height of the
graph has been explicitly specified).

If you use layout=GANTT_EVEN the bars are evenly (hence the name)
spread out over the available height in the gantt chart and no
consideration is taken of the individual bars heights. Note that if you
use automatic sizing you cant use even layout. It just doesn't make
sense. Even layout is for those cases when you deliberately specify a
very large image and want the bars evenly distributed using the full
height.

The most common of all object in a Gantt chart is of course the
activity bar (GanttBar()). In terms of formatting this object has a
very large flexibility. The full signature for the GanttBar constructor
is

function
GanttBar($aVPos,$aTitle,$aStart,$aEnd,$aCaption,$aHeight)

<?php $aVPos

The
vertical position for the bar, [0..n]

<?php $aTitle

Title
for the activity

<?php $aStart

Start
date for the activity given as string, e.g "2001-09-22"

<?php $aEnd

End
date for activity given as either a date (a string) or as the
duration (in days) of the activity, e.g both "2001-10-15" and 20.5 are
valid inputs

<?php $aCaption

Text string (caption) to appear at the end (right side) of the bar

<?php $aHeight

Height of bar given as either a value in range [0,1] in which
case this is interpretated as what fraction of the vertical position
should the bar occupy. The height can also be given in absolute pixels
[1..200]

Start of bars are given as a date string. The format depends on the
current locale. Examples of valid date strings are

"2001-10-22"

"22 October 2001"

"22 Oct 2001"

Even if several format are supported it is recommended to use all
numeric dates, i.e in the form "2001-10-22".

Specifying the end position may be done in two different ways,
either by the end date in the same way as for the start date. The other
way is to specify the length of the activity in number of days
(and fractions thereof). Examples of valid end dates are:

By default milestones are rendered as a filled "Diamond" shape. This
may be optionally modified. The actual shape is specified by the 'mark'
property of milestone which is an instance of the PlotMark() class
(same class responsible for the marks in line graphs).

To change the shape of a milestone to, say a triangle, you use the
SetType() method as in

$milestone->mark->SetType(MARK_DTRIANGLE)

Let's put this into practice and add a milestone to our previous
example by adding the following two lines of code which result in
Figure 141 shown below.

Figure 141: Illustration of how to add a milestone
to a gantt chart [src]

You may note that by default the title color is red for milestones.
If you like to change this to be instead, say bold black, you would
invoke the SetColor() and SetFont() methods on the title property of
milestones as in

The final object you may add to a Gantt chart is simple, but quite
useful, a straight vertical line extending over the whole plot height.
This could for example be used to illustrate different phases in a
project. You create a line object by a call to GanttVLine()

The full signature for GanttVLine() is

function
GanttVLine($aDate,$aTitle,$aColor,$aWeight,$aStyle)

<?php $aDate

Date
for the milestone

<?php $aTitle

Title
for the line. The title is displayed at the bottom of the line

<?php $aColor

Color
for the line

<?php $aWeight

Line
width

<?php $aStyle

Line
style,"dashed", "dotted" and so on

Valid creations of lines are for example

$vline = new GanttVLine("2001-12-24");

$vline = new GanttVLine("2001-12-24","Phase 1");

$vline = new GanttVLine("2001-12-24","Phase
1","darkred");

$vline = new GanttVLine("2001-12-24","Phase
1","darkred",5);

$vline = new GanttVLine("2001-12-24","Phase
1","darkred",5,"dotted");

To add the line to the graph you just have to call GanttGraph::Add() as
with milestones and bars. Let's illustrate the use of vertical lines by
adding a line to the previous example.

$vline = new
GanttVLine("2001-12-24","Phase 1");
$graph->Add($vline);

and the example (See 143) now becomes

Figure 143: Adding a vertical line with a title to
the Gantt chart [src]

From the above figure you can see that by default the line is drawn
at the beginning of the day of the specified date and in a 'dashed'
style. This can (of course!) be modified so that the line is
drawn/aligned anywhere in the specified day. You modify this by
invoking the method SetDayOffset() with an argument specifying the
fraction of the day where you want the line positioned.

If you, for example, want to display the line in the middle of the
day just add the line

You can easily add a variety of markers both to the start and end of
the gantt bar. They could for example be used as an alternate way to
illustrate important milestones or anticipated deliveries.

The left and right markers are accessed through the two properties
'leftMark' and 'rightMark'. They are both instances of the general
'PlotMark' class which is also used for the milestones (and in line
graphs). The 'PlotMark' class supports several different styles, for
example, diamond (the default for milestones), filled and unfilled
circles, squares, stares, and so on. Please refer to the reference
section for a complete listing.

Let's illustrate this by adding a right marker to the previous
example. We will use a style of a filled (red) circle with a white
title, say, "M5". In order to accomplish this we must augment the
previous example with the following lines:

This might seem like a lot of lines but this is as complicated as it
possible can get. As an illustration I have changed more or less
everything that is changeable. I changed the default font, font-color,
fill-color, frame-color and width of marker. The two lines only really
necessary are the first two, showing the mark and setting a title. You
could get away with using default values for the rest of the
properties.

I have deliberately introduced a "strangeness" here. If you compare
the two previous examples you can see that the last example is larger
than the previous one. Why?

The explanation is simple if you remember that the height of bars
are sized relative to the horizontal spacing. The horizontal spacing
are based on the highest single bar including title size and, here come
the explanation, marker size. The horizontal spacing has grown since
the minimum height is now based on 10 points(=the height of the mark).
The bar still occupy the same percentage of the height so it seems to
have grown.

If this behavior is unwanted it is always possible to specify an
absolute size for the bar heigh, say 8 pixels, with a call

$activity->SetHeight(8);

and achieve the result in Figure 146 below.

Figure 146: Specifying an absolute size for the
height of the bar. [src]

It is worth noting that the height reserved for each bar is still
the same since we haven't changed the height of the marker and the
reserved space is the maximum height used by any bar.

Let's see what happens if we set the height of each bar to be 100% of
the reserved height by adding another activity/bar below the first one
and set the height of each bar to 100% by adding the lines (I omit the
added lines to add another bar since they are just a copy of the first
bar)

$activity->SetHeight(1.0);
$activity2->SetHeight(1.0);

to the previous example. (Note that a value in the range [0..1] is
interpretated as the fraction of the reserved height while a value > 1
is interpretated as the absolute size in pixels.)

Aha.. What we are trying to do doesn't really make sense. Since we
have specified that the bar will always occupy 100% of the available
reserved with there will be no distance between the bars. So what if we
specify the bar as 10 pixel absolute by changing the lines to

So what can we actually do? Well if you remember the reserved height
for each bar is the maximum height of all bars including titles. This
guarantees that no two bars will ever overlap. To guarantee that titles
don't end up too close together there is a Vertical Label Margin
which basically specifies some extra "air" in between the titles. The
amount of air is specified in percent of the title height. To set the
margin you use

GanttGraph::SetLabelVMarginFactor($aMargin)

As an example let's set that margin in the previous example to 0 and
see what happens.

The scale headers allow you to view up to four different scales at the
same time. The four basic scales are:

Day scale

Week scale

Month scale

Year scale

You can choose what scale to include and exclude by using the
SetScale() method. For example, for a detailed gantt you might choose
to display days and weeks by specifying

$graph->ShowHeaders( GANTT_HWEEK |
GANTT_DAY );

If you instead wanted "the big picture" it might be enough to show
year and months by specifying

$graph->ShowHeaders( GANTT_YEAR |
GANTT_MONTH );

You can choose freely the combination of scales that you want, but a
chart must at least have one scale of course.

Once you have decided what level of details you need you can then
fine tune the exact layout/formatting of each of the enabled scales as
described below.

These scale header are all accessed through the graph instance
variables 'scale' as in

$graph->scale->week

or

$graph->scale->day

. All these headers share the following properties.

Show()

Determine if the scale should be shown or not

SetFont()

Font for text in header

SetFontColor()

Specify the color of the header text

SetStyle()

Specify what date format should be used, for example in the week
scale it is possible to show either week number, the start date of the
week and so on.

SetBackgroundColor()

As it says, the background color for the header

SetFrameWeight()

The line weight of the box around the scale

SetFrameColor()

The line color for the frame

SetTitleVertMargin()

The margin, in percent, below and above the title text

In addition to these methods each scale also has the property 'grid'
which determines the appearance of grid lines for that specific scale.
You may modify the appearance of grid lines by the "normal" line
methods, i.e. SetColor(),SetWeight() SetStyle() and Show(). So for
example to set the week grid line red you would use

$graph->scale->week->grid->SetColor("red");

Each of the scales also have some specific formatting possibilities
as described below.

Minute scale is the lowest resolution you can use. It is often
convenient to use Minute scale with "GanttScale::SetINtervall()" since
by default the increment will be 1 minute. The style of minute scale
can be further adjusted by the use style/i> parameters which can be
one of

"MINUTESTYLE_MM", This will display minutes as a two digit number
with a leading zero if necessary

"MINUTESTYLE_CUSTOM", This will let you specify you own custom
minute style by making a call to HeaderProperty:: SetFormatString()

Minute scale is enabled by adding the GANTT_HMIN in the
GanttGraph::ShowHeaders() call. For example as in

$graph->ShowHeaders(GANTT_HDAY |
GANTT_HHOUR | GANTT_HMIN);

The code snippet below shows how to set up a minute scale with 30
min interval and some custom colors.

The hour scale has more builtin formatting possibilities. The following
formatting options are available

"HOURSTYLE_HM24", Will display the only the hour in military time
0-24 , for example 13:00

"HOURSTYLE_H24", Will display the hour with both hour and minute in
military time 0-24, for example 13

"HOURSTYLE_HMAMPM", Will display the hour and minutes with a
suitable am/pm postfix, for example 1:30pm

"HOURSTYLE_HAMPM", Will display only the hour with a suitable am/pm
postfix, for example 1pm

"HOURSTYLE_CUSTOM", Custom defined format as specified with a call
to HeaderProperty::SetFormatString()

For hours it is possible to specify the interval in either of two ways.
With an integer, e.g. 6, or as time interval, e.g. "1:30" which makes
the interval one and a half hour. The only restriction is that the
interval must be even dividable for 24 hours since one day is the
smallest possible interval to show. This means that it is allowed to
use, for example 2,4,6,"1:30" or "0:45" as intervals but not 7, "2:45".

The code snippet below shows hot to set up a hour scale to with 45
minutes interval and some custom colors

Days are shown as "one letter boxes". The extra formatting
possibilities you have for days is the possibility to specify a
different color for the weekend background and for the Sunday.

SetWeekendColor()

Set the background color for weekends. (Defaults to light gray)

SetSundayFontColor()

The Sunday font color. (Defaults to red)

In addition to this there is also a possibility to choose whether or
not the weekend background should be extended vertically down over the
plot area. By default it is. Since that is a property more of the whole
plot you modify this behavior with a call to the method

Week scales, if enabled, by default shows the week number in range 1 to
53 (as defined by ISO-8601, see the reference section).

It might be worth pointing out here that the week number calculation
is carried out within JpGraph and does not rely on the underlying OS
date libraries. This makes the behavior consistent over several OS:s
(at least M$ Windows does not comply to ISO-8601 or supply any
way of doing this through the normal libraries, e.g. strftime())

You may modify the week behavior in three ways. You can specify
(with SetStyle()) a different date format using the constants

WEEKSTYLE_WNBR

Show week number To further modify the formatting of the actual week
number you can optionally supply a format string with a call to

SetLabelFormatString()

The format of the string should be a standard sprintf() syntax
expecting an integer (the week number). By default a 'W' is prefixed to
the number.

Year scale has no extra formatting possibilities. (Simply because I
couldn't come up with any useful modification of a simple year. If you
have any suggestion of fancy formatting you think could be useful
please drop me a note and I have something to do for the next version)

are both ways of specifying the caption "[BS,ER]" for the activity.
Since activity is a standard JpGraph text object you can easily modify
font, color and size with calls to SetFont() and SetColor(), (e.g.

To indicate the progress of a specific activity it is also possible to
add a progress indicator to each bar. This progress indicator consists
of a smaller bar within the bar. By default this progress bar is black
and 70% of the height of the bar. These parameter can (of course) all
be changed.

The properties for the progress indicator are accessed through the
'progress' property and it's methods.

To set the progress for a specific activity you only specify the
percent as a fraction. As in

$activity->progress->Set(0.4)

In Figure 152 the previous example is modified to indicate the
progress of each activity by the default progress indicator. A solid
bar. To make it clearer I have also modified the caption to reflect the
displayed progress. (At the same time I slightly modified the scale
headers just for fun).

It is common to group activities. We have used this feature in the
examples of constrains. There is no special type for activity bars that
are used to illustrate grouping. The common way of illustrating this
(as have been used above) is to add "half" a triangle marker at both
ends of the bar. The special provision that JpGraph does is that if you
add a left or right marker of type MARK_LEFTTRIANGLE or
MARK_RIGHTTRIANGLE those triangles will be drawn under the bars to give
the effect as show in the examples above. In the example above we also
have made the grouping bars have slightly less heigh since the end
triangles will visually "grow" the bar.

So to get the effect we want for a group bar we have to use the two
lines:

As of the current version There is not yet any formatting support to
accomplish the effect of indentation for the titles so this is
accomplished by using a fixed width font and adding spaces in front of
the title.

It is often of interest not only to show one title for a gantt bar but
often one wants to show, title, start date, end date, duration or
effort and so on. Up until now we have, to keep things simple only
shown a single title for each activity. We will now show you how you
can specify an arbitrary number of columns as titles for a Gantt chart
as well as adding icons in the graph columns.

You will notice two things. We fist specify the titles using an
array. We have also specified a second array with the numbers 30 and
100. This is an optional array that specifies the minimum width of, in
this case, the first two columns. By default the columns will be wide
enough to hold the widesat text string in the column. However for
esthetic reasons you might sometimes want to increase the minium width.
This is what we have done here for the first two columns.

Furthermore you can also adjust the background colors and the style
and colors of the vertical dividing grid lines. In the previous image
we used the lines

The style for the grid lines can also be "dashed", "dotted" or
"longdashed" as in other line formatting contexts within the library.
You can also adjust if you would like the small "3D" effect in the
titles. By default this is enabled. You can easily turn this of with a
call to

$graph->scale->actinfo->SetStyle(ACTINFO_2D);

To adjust the colors of the vertical dividing lines in the title the
method SetColor() is used as in
"$graph->scale->actinfo->SetColor('navy');".

The second thins is to actually populate the columns. This is done
(of course) as you add the activity bars to the graph. Previous we just
used a string as the title when we wasn't using columns. By simply
replacing this string with an array we specify the content of the
columns.

For example to specify two column titles we just create a
hypothetical Gantt bar as In the full example above we put all this in
arrays to make for better coding practice since we create several bars.

In addition to ordinary text you can also add an image or any of the
predefined icons available. In order to add that in a column you first
create an instance of IconImage() and then specify that instance
instead of the text. So in the previous code snippet if we wanted a
"open folder" image in the first column we would change the lines to

Precisely as before you can also have a title spanning all the columns.
This title is specified with the property tableTitle of the
scale. Specifying a table title will automatically adjust the height of
the column titles to fit the table title. The small code snippet below
shows how to add a title.

In exactly the same way as for a single title it is possible to specify
individual CSIM targets for each of the title columns. This is
accomplished by specifying an array for both the target and the alt
text instead of a single string as arguments for SetCSIMTarget()
The following code snippet shows how to specify that.

The (default) white area in the top left of the gantt table may have a
title. This is accessed by the 'tableTitle' property of the gantt
scale. Using this is straightforward as the following lines show.

The vertical and horizontal lines between the titles and the bars can
be modified by accessing the 'divider' and 'dividerh' properties of the
scale. Again, this is straightforward as the following example shows:

Note: You might notice the slight discrepancy in
design that here you use a method and in the previous cases accessed a
property which you modified. This is the unfortunate affect of over a
years development of JpGraph. My own design preference has simply
changed over time. For revision 2.x I plan on taking the opportunity to
make things like this more conform since I have now convinced myself
that this is a better design.

As we have shown in the previous examples constructing a Gantt chart
consists of a number of repetitive tasks; Create the individual
activity bars and add them to the graph.

Now when you have a basic understanding of how this works you are
ready to appreciate a small helper method.
GanttGraph::CreateSimple(). This method takes a few arrays of data
which specifies you Gantt chart and then constructs this chart. By
using this method you sacrifices a few adjustment possibilities for
simplicity. This method is nothing magical it just takes the data for
the activities,(start and end date, titles, progress, any constrains
and so on) and constructs the activities and adds them to the graph.

The activities are specified in data array which for each activity
have the following fields

What row the activity should be on

Activity type, controls the appearance. Can be one of

ACTYPE_NORMAL, A standard activty bar

ACTYPE_GROUP, A Grouping bar

ACTYPE_MILESTONE, A milestone

Title text

Start date

End date (NOT FOR Milestones!)

Caption

So for example to create a Gantt chart consisting of two activities
which are grouped and a milestone one would have to use something
similar to the following code

You may (slightly) modify the appearance of the simple Gantt charts
by means of the methods GanttGraph::SetSimpleFont() and GanttGraph::SetSimpleStyle() But not anything else,
remember that the purpose with this way of constructing graphs is to be
simple. If you need full advanced control you have to construct all the
activities in the "normal" way.

You can also specify constrains and progress for each bar by
supplying additional data arrays to GanttGraph::CreateSimple().

In a similar way you set the target and Alt texts for the activity
title as the following code extract shows.

$bar->SetCSIMTarget("http://localhost/abc/");
$bar->SetCSIMAlt("Alt Text for the bar");
$bar->title->SetCSIMTarget("http://localhost/abc");
$bar->title->SetCSIMAlt("Alt Text for the title");

The above code assumes that your activity is available in the
variable 'bar'. In the example directory there is a complete example of
how to use CSIM together with Gantt charts in the "ganttcsimex1.php"
file. (Please note that this example makes use of the simplified Gantt
chart specification using the CreateSimple() method.

With Gantt charts there is often the need to illustrate constrains
between one or several activities. One of the most common constrain is
that on activity can't start before an other activity finish.

JpGraph support visualizing the following types of constrains

Start to End

Start to Start

End to Start

End to End

An example will clarify how to specify a constrain between two
activities.

Assume that we start with the Gantt schema as illustrated below

Figure 160: The original Gantt schema we wich to
add constrains to [src]

We would now like to add the constrains that the activity "Label 3"
cant start before activity "Label 2" has finished and that the
milestone "Phase 1 done" is depending on when activity "Label 3" is
done.

The principle of adding constrains is that you for each activity you
want to have a constrain you have to tell to what other activity this
constrain should be to. That other activity is specified by telling on
what row that activity lies. Depending on what type of constrain, e.g.
Start-to-End, an arrow will now connect the two activities in correct
way.

The way to do this is to call the
SetConstrain() method on the activity. In this method you specify
the type of constrain as well as to what other activity this constrain
should be to. If you read the class reference you can also see that you
can specify the type and size of arrow used. For now we will just use
the default sizes and type.

So for example to add an End-To-Start constrain between "Label 2"
and "Label 3" you could write

$bar2->SetConstrain(2,CONSTRAIN_ENDSTART)

The first parameter in the call above "2" is the row of the target
activity (i.e. the row where "Label 3") activity is. In the example
below we have added the constrains we wanted.

A note: The actual path followed by the arrow is controlled by some
heuristics to make it clear what the constrain is. It has been a design
decision that in order to keep the API simple the user has no further
detailed controlled on the actual path followed. However, in future
version the heuristics may be extended and provide some
user-controllable parameters.

You can choose to only display a vertical slice of the overall Gantt
chart by explicitly specifying a date range with the method
GanttGraph::SetDateRange(). This will cap any bars to only be displayed
in between the start and end date given as parameters. For example
specifying

$graph->SetDateRange("2001-12-20","2002-01-20");

will show the part of the Gantt chart between the 20 Dec 2001 and 20
of January 2002. Please note that the format depends on the locale
setting.

You can set the week start day with a call to
GanttScale::SetWeekStart(). This method takes an integer [0,6] as input
which represents the start day of the week, 0 means Sunday, 1 Monday, 2
Tuesday and so on. The default is to start the week on Monday.

Depending on your installation of PHP you might have support for
several locales. By default the locale is set up to use the default
locale on the server.

To specifically set a locale you specify the wanted locale with a
locale string (ala standard PHP), for example American English is
specified with the string 'EN_US', British English with 'EN_UK' 'nl_NL'
for Dutch and so on. If your current installation does not support the
specified locale an error message will be given.

$graph->scale->SetDateLocale("se_SE");

The result is displayed below.

Figure 162: Using swedish locale. (Can you spot
the difference from English?)
[src]

Image maps, or client side image which are used in JpGraph, 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 I will make the assumption that the reader is
familiar with the basic concepts of client side image map in HTML. If
you are not familiar you can a) read some book that explains this or b)
pay me lots of money to explain it to you :-)

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 "wrapper" script?

In JpGraph there is actually two ways of solving this.

Use the preferred "builtin" way using the modified Stroke() method
Graph::StrokeCSIM() instead of the standard Graph::Stroke() method.

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 a HTML page containing both the image map
specification and the correct <IMG> tag.

This of course means that you have 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.

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 you can't use the script directly in an
image-tags src-property.

You can create an CSIM in two ways

Use the CSIM image script as the target in a standard anchor
reference, for example

<a href="mycsimscript.html">

This has the drawback that your image page will only contain the
image and nothing else.

The other way let's you include the image in an arbitrary HTML page
by just including the image script at the wanted place in your HTML
page using a standard "include" php statement. For example

<h2> This is an CSIM image </h2>
<?php
include "mycsimscript.php"
?>

Note: If you have several CSIM images on
the same page you must use 'include_once' in the scripts when you
include "jpgraph.php" and the other jpgraph library files since you
will otherwise in effect try to include these libraries multiple times
on the same page and get a "Already defined error" The process to replace Stroke() with StrokeCSIM() is simple. You
just need to make the replacement and supply some arguments to
StrokeCSIM(). The only required argument is the first which must be the
name of the actual image script file including the extension. So for
example if your image script is called "mycsimscript.php" you must make
the call

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

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

$graph->StrokeCSIM(basename(__FILE__))

This is a better way since you can now rename the file without
having to change any code in the file which you otherwise would have
to.

Sidebar: Why do I need to supply the image
script name? 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
not 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 that 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 you are using several CSIM images in the same HTML page you also
need to specify the image map name as the second parameter since all
image maps must be unique since they are used to bind one image to one
image map. Please see the class reference
StrokeCSIM() for details.

The examples below shows how different plot types uses image maps.
Please note that none of the URLs in the image points to any valid
page. SO you will get an "404 Page not found" if you click on the
images. A nice feature in most browsers is that if you hold the pointer
on a CSIM point in the image you will see the alt-tag as a small popup.
In these examples that popup is used to display the value for the
particular part of the graph.

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.

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.

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"

The anti-aliasing for lines works by "smoothing" out the edges on
the line by using a progressive scale of colors interpolated between
the background color and the line color.

Sidenote: The algorithm used for
anti-aliasing of lines is quite simple. It would be possible to achieve
even better result by doing some real 2D signal processing. However,
doing real time 2D signal processing on a HTTP server would be madness
so I deliberately kept it simple. To achieve best visual result always
use a dark line color on a light background.

An example will show that this, quite simple algorithm, gives a
reasonable good result. The figures below shows a radar plot with and
without anti-aliasing.

One thing you need to keep in mind when deciding to use
anti-aliasing is that it could have potentially a dramatic effect on
the time it takes to generate the image. Line drawing with
anti-aliasing turned on is roughly 8 times slower than the normal line
drawing so treat this feature wisely.

Furthermore there are a couple of "gotchas" you should be aware of
when using anti-aliasing.

Anti-aliased lines uses up more of the available color-palette. The
exact number of colors used is dependent on the line-angle, a near
horizontal or near vertical line uses more colors (number of lines with
different angles uses more colors). Hence it might not be possible to
use anti-aliasing with color-gradient fill since the number of
available colors in the palette might not be enough. A normal palette
can keep around 256 colors. This means that you are advised to use a
true-color image when using anti-aliasing.

Anti-aliasing does not work very well together with background
images since it assumes a the same solid color on each side of the
line. Doing a more advanced anti-aliasing algorithm would simple take
to much processing power.

Anti-aliased lines will ignore the line width specified. They will
always have a width of roughly 1.

JpGraph provide the possibility for you to rotate the generated graph
an arbitrary angle. This will only affect the actual graph (axis, axis
titles, labels and so on) and not fixed elements on the graph like
title or footer.

Rotation is probably most used to rotate a graph 90 degrees, for
example a bar graph to get the effect of horizontal bars.

Performance note: Adding a rotation
transformation will make the graph generation slightly slower since
each point of the graph as to go through a transformation step before
being stroked on to the image. JpGraph optimizes this by using a
pre-calculated transformation matric and also optimizes the special
case 90 degrees.

By default the center of the rotation will be the center of the plot
area, which may or may not coincide with the center of the entire
image.

There is actually a third method that you could use, adding a
translation to the graph after the rotation. Since
this probably a very little used method we don't discuss it further but
refer the reader to the class reference instead
Graph:image::SetTranslation()

When you rotate an image you should be aware of that the individual
labels on the axis are not rotated. The design decision behind this is
a) Bit mapped font can't be rotated
b) Maintain readability

Since the anchor point for labels is by default the optimum for
graph at 0 degree you might want to adjust the anchor point and
alignment for the labels on the axis to get a better visual appearance
on you rotated graph. This is accomplished by the method
Axis::SetLabelAlign() For a detailed discussion on how to do this
please see the section on horizontal bar graphs, (
Working with bar plots )

The table below shows some examples on different kinds of rotation
to give you an idea of how changing the angle and rotation center may
be used to generate different effects. The top left graph is the
original image. The point of rotation has been marked with a red-cross
in each of the images.

The following section only applies to palette images. This
means it wont work on true-color images. It is often desirable
to have a background image look a little bit "washed" out so it doesn't
take the concentration away from the actual graph. There are basically
two ways of accomplish this

Prepare the image with an external images editor to adjust the
level of brightness and contrasty to a desirable level

Use JpGraph:s built in adjustment for contrast, brightness and
color saturation.

To adjust the background image call The levels for both brightness and
contrast are real numbers in the range [-1, 1] You can choose to adjust
for example just the background image or you might also choose to
adjust the whole image. To change the background image just use the
method
Graph::AdjBackgroundImage() to specify a suitable value. Let's show
some example on what we can do with this. The following example have
been generated by using the small utility "adjimg.php" which you can
find in the "utils/" directory.

You can either set the global define BRAND_TIMING (in jpgraph.php)
to true. This will add the timing string to all graphs generated.

.. or you can enable it for a specific graph by setting the global
variable $gJpgBrandTiming as in

$gJpgBrandTiming=true;

in the beginning of the script.

If you like you might also change the way the timing is formatted by
setting the string defined by BRAND_TIMING_FORMAT (in jpgraph.php).
This string represents a standard printf() format string.
Sidenote: JpGraph contains a utility class
called JpgTimer which you can use yourself should you need ms timing of
part of your own code. The API is really simple. The class supports
multiple running timers and you start a timer simply by calling the
Push() method. This will start a new timer and put it on the top of the
timer stack. To stop the timer, pop it from the stack and return the
timing value simply call Pop().

JpGraph has built-in support for over 200 country flags, i.e. they are
available to be used in graphs without any external image definitions.

Country flags can be used in primarily two settings

As image markers in line and scatter graphs

As background images for graphs

As a special type of icons (using the IconPlot()) which can be
added to the graph in any arbitrary position. See next section

In order to make it easy to find the appropriate country flags they can
be specified with either full or partial name or as an numeric index.
The routines in JpGraph are "smart" enough to figure out which way you
are trying to specify a particular flag.

To specify a country flag as a marker you have to specify the
special mark type as one of MARK_FLAG1,MARK_FLAG2,MARK_FLAG3 or
MARK_FLAG4

Flags are internally stored in 4 different sizes which is indicated
by the number in the mark types. Flags may also be arbitrary scaled
when displayed. Since this is partially overlapping functionality you
might very well ask why the flags are stored in four different basic
sizes. The reason is of course performance. It you only want a very
small flag it takes processing time to scale down a large image to,
say, a small icon size. At the same time for large flags to be used as
background a small original flag might not have enough details to be
scaled up to a large size. Hence the reason for storing the flags in 4
different sizes.

To use country flags as background one has to use the method
Graph::SetBackgroundCountryFlag(). With this method you can specify
both how much of the image should be filled as well as how much of the
flag should be mixed into the background.

To see a list of all supported country flags you can run the script
"listallcountryflags.php" in the Example directory. This will show you
a table with all flags.

In addition to the standard background image you can also add an
arbitrary number of icons onto the background of the graph. These icons
are created with a call to the special Plot class IconPlot.

The image from icons are taken from a file or as one of the builtin
country flags.

You may control how much of the icon should be blended into the
background by specifying a percentage (1-100). The example below shows
how to mix in the picture of "Tux" into the background of a filled line
graph. Note: This example uses alpha blending and will therefore
require GD2.

To specify any of the roughly 200 country flags as an icon you first
create an empty Icon and then call the IconPlot::SetCountryFlag() with
the appropriate parameters. (See the class reference). This is
illustrated below by adding the Icelandic flag into the background as
an icon

Canvas graphing is an advanced feature that comes in handy where you
need to draw some more arbitrary graphics. To give you a flavor of what
you can do the following example shows an architecture overview of
JpGraph which was drawn using a canvas.

Canvas graph is really not a graph. It a blank sheet of paper which you
can use to draw arbitrary shapes and still have access to some of the
convenient features of JpGraph.

You can work with a canvas in different levels of complexity. You
can for example work directly with the Image class which provides a
large number of primitives for drawing but requires that you use
absolute pixel coordinates.

You can also make life a little bit easier by using a canvas scale.
This lets you define your own scale on the canvas which often makes it
easier by letting you work on a grid you have specified yourself. It
also makes it very easy to re-scale you image automatically by just
changing your scale. For example to half the size of you drawing you
just make the scale twice as large.

To give you some help in working with different canvas you should
include the "jpgraph_canvtools.php" file when working on canvases. This
is not strictly necessary but it will give you some nice abstraction to
help you create your masterpieces.

As another (concrete) example on the use of a canvas the figure
below is a listing of font styles available with JpGraph.

Figure 176: Another example of using a canvas to
draw a number of text boxes
[src]

In order to create a canvas graph you need to include the file
"jpgraph_canvas.php" in addition to the standard "jpgraph.php" file.
You might also want to include the "jpgraph_canvtools.php" to get
access to some supporting classes that may (or not) come in handy.

Creating a canvas gives you the opportunity draw arbitrary shapes on
a "white" piece of paper. Let's first show a simple example were we
just draw a text box. We first show you the code which we will walk
through

The example above starts by creating a
(400x200) sized image. We set the margins to get a nice frame around
the image. For canvases the margins has no effect in the way you enter
coordinates. Top left is (0,0) and bottom right (including any
potential margin and shadow) is the maximum. In this case the
coordinates are X:0-399, and Y:0-199

We then call the
InitFrame() method which actually strokes the margin and plotarea
to the graph. Since everything is stroked in the order you issue the
commands you must make sure that the graphical objects you want on top
is stroked last. This is different from the way you normally work with
JpGraph since it queues up all you addition and then makes sure they
are stroked in the correct order.

We then create a Text object,
setup it's properties, including the absolute screen position where we
want the text, and then stroke it. Her it might be a need for a closer
explanation of the, perhaps misnamed, method
Text::Align() This method states how the text coordinates
should be interpreted , i.e when we specify (200,10) as the
coordinates for the text paragraph should that be interpreted as the
top left corner, bottom-left corner or something else (of the bounding
box)? In the code above we have chosen to interpret the X-coordinate as
being the center of the bounding box and the Y-coordinate as the top.
Hence the text will be aligned so that the (200,100) point in the graph
is aligned with the middle of the top line of the paragraphs bounding
box.

We also specify that the lines within the paragraph should be
centered with a call to
Text::ParagraphAlign() Since we also choose to have a box around
the text we have to make use of the method
Text::SetBox() which is used to specify the fill color, the border
color and the shadow color (if you leave out shadow color or set it to
'', no shadow will be used).

Now we are ready to stroke the text onto the canvas. In order to do
so we must specify the basic Image drawing class we want to use.
Without discussing this further we just state that a suitable image
class can always be found as the img property of the
Graph class.

Finally we are ready to stroke the entire graph, which in effect
sends the canvas back to the browser. Below you can see the effect of
all this code

Figure 177: A simple canvas drawing with a text
box in the middle [src]

A canvas also makes a good background for using standard graphic
primitives, for example circles and lines. What you first have to
remember is that you are (so far) working with absolute screen
coordinates and secondly all drawing primitives are found in the
Image Class accessible as a property of the Graph class. So for
example to draw a line between coordinate (0,0) and (100,100) you would
have to add the line

$graph->img->Line(0,0,100,100);

To your code. The following example shows some of the graphic
primitives you have access to in the Image class

A note on GD For those of you using GD
1.xx you might notice that the large "filled circle" isn't completely
filled. This is because in GD 1.xx there are no low level primitives to
fill an ellipse or circle so JpGraph tries to make the best out of a
bad situation and manually fake a filled circle. For interest of speed
JpGraph does not contain a complete (for example) Bresenham-circle fill
but cheats by using some existing GD routines. This is not a perfect
solution and for large filled circles like this you get some
moire-patterns in the circle. If you upgrade to GD 2.x JpGraph will be
able to make full use of those new existing methods and the fill will
be perfect.

We refer you to the class reference to find out what other graphic
primitives are available for use.

The previous method using absolute coordinates works. But nothing more.
It doesn't give you any chance to easily scale the image (unless you
manually recalculate all used coordinates) , it gets tedious to work
with pixel level resolution. Especially if you just like to draw a few
basic shapes.

To help with this you can use a scale for the canvas. This lets you
define a "work-space" of your choice. You can for example set the
coordinates to be between X:0-10, Y:0-10. This makes it easier to
position objects on the canvas. This also has two additional
advantages:

If you increase the size of the canvas all objects will be
automatically scale to keep their proportions without any changes.

You can shrink/enlarge your drawing (not the image) by just using
another scale. For example if you originally draw the image using a
(0:10, 0:10) scale and then change the scale to (0:20, 0:20) then the
effect will be that you drawings will "shrink" to half their size.

To use this type of scaling you must make sure you include the file
"jpgraph_canvtools.php" . In addition to the scaling class their are
also a couple of other utility classes that may come in handy,
especially the Shape class.

Using the scale is quite simple. You first instantiate a scale
object passing the graph as a parameter and then specify the scale you
want to use. This means you need to add the lines

$scale = new CanvasScale($g);
$scale->Set(0,$xmax,0,$ymax);

to your code. You can then use one of the translation methods (for
example
CanvasScale::Translate()) in the canvas scale class to translate
between your world coordinates and the absolute screen coordinates.
This means you could take the code in the example above and just add
the lines, for example,

Since this pattern has to be repeated for every object that has to
be drawn it makes good sense to encapsulate this in a separate class.
This is exactly why the canvas tools file also have a utility class
called Shape This class is
mainly a wrapper around the most commonly used methods in the basic
Image class (with one important exception) and does all these the
translation for you. Please see the class reference for a complete list
of the available methods To set up the Shape class you instantiate it
with the graphic context and the scale you want to use as argument as
in

$shape = new Shape($g,$scale);

You are then ready to use all the methods in the shape class. Using
a scale and imitating the previous example we would get the source
shown below.

If we like to make a smaller image we could just change the image
size and everything will be rescaled without any further code changes.
SO for example making the image half the size would give the result

Figure 180: Shrinking the image to half the size
is easy since the scaling will maintain the relative position of the
objects [src]

If we instead wanted to keep the image size but shrink the shapes we
could just make the scale twice as large which would result in

Figure 181: Shrinking hte graphic object by making
the scale twice as large [src]

We previously mentioned that the Shape class was a wrapper around
the image class with one exception. So what is the exception? Well,
glad you asked. The exception is that it contain an additional method
which draws an "indented rectangle". An indented rectangle is a
rectangle where one of it's four corners have been moved into the
rectangle. You create an indented rectangle by calling either
Shape::IndentedRectangle() or A few examples illustrates what this
shape looks like.

As a final note we mention the class
CanvasRectangleText Which can be used to add a text with a rounded
rectangle (possibly filled) onto the canvas. The previous example where
all the available fonts were drawn were using this class. We don't
describe it further but refer the interested reader to the class
reference and the 'listfontsex1.php' example file.

As a final example we shortly discuss how the canvas type of graph was
used to generate the DB schema for the DDDA architecture.

The library php file "utils/misc/imgdbschema.php" included in the
distribution contains some utility classes to make the drawing of table
schemes easier. It contains two basic classes, Class ImgDBTable and
Class ImgDBSchema. The first class understand how to draw an image
illustrating a single table. The second class is responsible for
automatically extract all the relevant information from a DB to draw a
complete DB Schema.

Before going into this a little bit more we show what an example of
this might look like.

Figure 183: Example of using the canvas graph
style together with the imgdbschema.php library to semi-automatically
generate a DB schema [src]

Before going on it should be noted that the ImgDBSchema assumes that
the DB can be accessed through a DB abstraction layer modeled after the
abstraction layer available in the 'jpdb.php' file in the DDDA
architecture. This abstraction layer assumes a MySQL database in the
bottom. This specific dependency of this particular abstraction layer
is the reason I have not included these classes in the generic canvas
tools file.

The second thing you should note that this library does not contain
a complete automatic-layout engine but rather a very simple automatic
system which, if nothing else is specified, just puts the table in a
rectangular grid. A complete graph layout engine would simple be to
much to write in this context. This is also a very difficult
optimization problem and sofar not even any of the professional
programs I have seen that tries this can achieve a satisfactory layout
without manual intervention.

The rest of the code in the file is just to setup the canvas, add an
indented rectangle to group some tables and generate a footer with the
date and time this image was generated.

The first line instantiates a new ImgDBSCheme layout engine asking
it to draw an image for the database 'jpgraph_doc'. The following two
arguments specify two callback functions for formatting the text for
header and each field in a table.

The next line specify the top left margin where the drawing of the
tables should be started.

The third line specify the width of a single table. The final lines
starts the engine and draws all tables in the database to the canvas.
The final argument requires some further explanation. This is an offset
(x,y) from the top left corner how each individual table should be
positioned. If the value is -1 indicates that the default value should
be used. If this array is not specified then the tables will simple
arranged line by line.

The full source code for drawing this DB schema example is shown
below.

Various settings in JpGraph are controlled by overall DEFINEs at the
top of jpgraph.php. Most of these defines should not have to be changed
by the regular user but left at their default values. Below is a
complete table of all defines and their meaning.

Define, default value

Comment

"CACHE_DIR","/tmp/jpgraph_cache/"

The full
absolute name of directory to be used as a cache. This directory
must be readable and writable for PHP. Must end with '/'

"TTF_DIR","/usr/local/fonts/ttf/"

Directory
for JpGraph TTF fonts. Must end with '/' Note: The fonts must follow
the naming conventions as used by the supplied TTF fonts in JpGraph.

"USE_LIBRARY_GD2",false

Specify if we
should use GD 2.x or GD 1.x If you have GD 2.x installed it is
recommended that you use it since it will give a slightly, slightly
better visual appearance for arcs. If you don't have GD2 installed this
must be set to false!

'USE_TRUECOLOR',true

Should the image be a
truecolor image? Note 1: Can only be used with GD 2.0.2 and above. Note
2: GD 2.0.1 + PHP 4.0.6 on Win32 crashes when trying to use truecolor.
Truecolor support is to be considered alpha since GD 2.x is still not
considered stable (especially on Win32). Note 3: MUST be enabled to get
background images working with GD2 Note 4: If enabled then truetype
fonts will look very ugly => You can't have both background images and
truetype fonts in the same image until these bugs has been fixed in GD
2.01

"USE_CACHE",false

Should the cache be used
at all? By setting this to false no files will be generated in the
cache directory. The difference from READ_CACHE being that setting
READ_CACHE to false will still create the image in the cache directory
just not use it. By setting USE_CACHE=false no files will even be
generated in the cache directory.

"READ_CACHE",true

Should we try to find an
image in the cache before generating it? Set this define to false to
bypass the reading of the cache and always regenerate the image. Note
that even if reading the cache is disabled the cached will still be
updated with the newly generated image. Set also "USE_CACHE" below.

"DEFAULT_GFORMAT","auto"

Default graphic
format set to "auto" which will automatically choose the best available
format in the order png,gif,jpg (The supported format depends on what
your PHP installation supports)

"USE_IMAGE_ERROR_HANDLER",true

Determine
if the error handler should be image based or purely text based. Image
based makes it easier since the script will always return an image even
in case of errors.

"USE_APPROX_COLORS",true

If the color
palette is full should JpGraph try to allocate the closest match? If
you plan on using background image or gradient fills it might be a good
idea to enable this. If not you will otherwise get an error saying that
the color palette is exhausted. The drawback of using approximations is
that the colors might not be exactly what you specified. Note1: This
does only apply to a palette image, not true color images since they
don't have the limitations of maximum number of colors.

"LANGUAGE_CYRILLIC",false

Special unicode
language support

"ERR_DEPRECATED",false

Should usage of
deprecated functions and parameters give a fatal error? (Useful to
check if code is future proof.)

"BRAND_TIMING",false

Should the time taken
to generate each picture be branded to the lower left in corner in each
generated image? Useful for performance measurements generating graphs

"BRAND_TIME_FORMAT","Generated in: %01.3fs"

What format should be used for the timing string?

The following defines should very rarely need to be changed

Define, default value

Comment

"CACHE_FILE_GROUP","wwwadmin"

What group
should the cached file belong to (Set to "" will give the default group
for the "PHP-user") Please note that the Apache user must be a member
of the specified group since otherwise it is impossible for Apache to
set the specified group.

"CACHE_FILE_MOD",0664

What permissions
should the cached file have (Set to "" will give the default
permissions for the "PHP-user")

"USE_BRESENHAM",false

Decide if we should
use the Bresenham circle algorithm or the built in Arc(). Bresenham
gives better visual appearance of circles but is more CPU intensive and
slower then the built in Arc() function in GD. Turned off by default
for speed

"JPG_DEBUG",false

Enable some extra
internal debug information to be shown. (Should only be changed if your
first name is Johan and you happen to know what you are doing. You have
been warned.)

"_CSIM_SPECIALFILE","_csim_special_"

Special file name to indicate that we only want to calc the image map in
the call to Graph::Stroke() used internally from the GetHTMLCSIM()
method.

"_CSIM_DISPLAY","_jpg_csimd"

HTTP GET
argument that is used with image map to indicate to the script to just
generate the image and not the full CSIM HTML page.