Академический Документы
Профессиональный Документы
Культура Документы
2 Introduction......................................................................................................................................................2
2.1 Version...............................................................................................................................................2
2.2 Software License................................................................................................................................2
2.3 JpGraph Features...............................................................................................................................2
2.4 Getting the latest version..................................................................................................................3
2.5 Planned future addition......................................................................................................................3
2.6 Known bugs and omissions...............................................................................................................4
2.7 Acknowledgements...........................................................................................................................4
2.8 A note on Implementing an OO library in PHP4...............................................................................4
2.9 Reporting bugs and suggesting improvements..................................................................................5
3 Installation........................................................................................................................................................6
3.1 Preparation.........................................................................................................................................6
3.2 Customizing the installation..............................................................................................................6
3.3 Required files....................................................................................................................................7
3.3.1 Plot extension modules......................................................................................................7
3.4 Graphic libraries requirements for PHP 4.02 and above...................................................................7
3.5 Detailed steps to install JpGraph........................................................................................................8
3.6 Troubleshooting your installation......................................................................................................8
9 Gantt charts..................................................................................................................................................102
9.1 Purpose of this tutorial...................................................................................................................102
9.2 Some notes on format and files used in this tutorial......................................................................102
9.3 Why use Gantt charts?...................................................................................................................102
9.4 Capabilities in JpGraph Gantt module...........................................................................................103
9.5 A simple Gantt chart......................................................................................................................103
9.6 The structure of a Gantt chart.......................................................................................................106
9.7 Creating a GanttChart....................................................................................................................107
9.8 Positioning objects in the Gantt plot..............................................................................................107
9.9 Gantt bars.......................................................................................................................................108
9.9.1 Specifying vertical position...........................................................................................108
9.9.2 Specifying start and end position for a bar....................................................................109
9.9.3 Milestones......................................................................................................................110
9.9.4 Vertical line....................................................................................................................112
9.9.5 Adding markers to a gantt bar........................................................................................114
9.9.6 Adjusting the minimum distance between bars.............................................................115
9.10 Formatting the scale headers........................................................................................................117
9.10.1 Day scale......................................................................................................................119
9.10.2 Week scale...................................................................................................................119
9.10.3 Month scale..................................................................................................................120
9.10.4 Year scale.....................................................................................................................121
9.11 More formatting for bars..............................................................................................................121
9.11.1 Adding caption to bars.................................................................................................121
9.11.2 Adding progress indicators to bars..............................................................................122
9.12 More general Gantt formatting....................................................................................................123
9.12.1 Adding a table title.......................................................................................................123
9.12.2 Modifying the divider lines..........................................................................................124
9.12.3 Modifying the box around the plot..............................................................................125
9.13 Advanced formatting...................................................................................................................125
9.13.1 Showing only part of the graph....................................................................................125
9.13.2 Specifying start day of week........................................................................................126
9.14 Localizing....................................................................................................................................126
JpGraph Manual
10 Miscellanies features..................................................................................................................................127
10.1 Anti−aliasing in JpGraph.............................................................................................................127
10.1.1 Enabling anti−aliased lines..........................................................................................127
10.2 Rotating the graphs......................................................................................................................128
10.3 Adjusting brightness and contrast for images and backgrounds..................................................129
10.4 Timing the generation of graphs..................................................................................................131
12 Utilities in JpGraph..................................................................................................................................148
12.1 Under the utils/misc directory.....................................................................................................148
12.2 Under the utils/jpdcgen...............................................................................................................148
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 sript then uses the text based HTML browser 'links' to render the PHP
image script non−interactively and then store them in the 'img' directory.
To finally generate all pure HTML pages from the PHP sources again 'links' was used together with a custom
Makefile.
The final set of HTML files was then processes by HTMLDOC to construct table of contents and chapter
links.
The result of this process is what you are reading at the moment.
10/07/2002 01:19:24 AM 1
2 Introduction
2.1 Version
This manual covers version 1.8 of JpGraph. A 2D graph plotting library for PHP 4.02 and above.
Note that this library will not work with versions prior to PHP 4.02 due to extension in the object model that
is used in this library.
JpGraph is free software as in free speech but not as in free beer. Every hour I spend working on this library
means one less hour spend on my consultancy work needed to pay silly things like rent and food. If you are a
large company making use of the library in a commercial context you are both morally and legally bound to
get the Professional JpGraph License.
The license fee corresponds to the cost for roughly 35 min of work for a professional IT consultant (average
according to IDG for 2002)
The professional version also contains additional features not available in the free version
• Flexible scales, supports text−lin, text−log, lin−lin, lin−log, log−lin and log−log and integer scales.
• Supports both PNG, GIF and JPG graphic formats. Note that the available formats are dependent on
the specific PHP installation where the library is used.
• Supports caching of generated graphs to lessen burden of a HTTP server.
• Supports batch mode to only generate images to a file
• Supports client side image maps which makes it easy to produce drill down images.
10/07/2002 01:19:24 AM 2
• Intelligent autoscaling which gravitates towards esthetical values, i.e. multiples of 2:s and 5:s
• Fully supports manual scaling, with fine grain control of position of ticks.
• Supports background images with different formatting options
• Supports color and brightness adjustments of images directly in PHP.
• User specified grace for autoscaling
• Supports up to two different y−scale, it is possible to have different left and right y−scale and add
plots to both
• Supports, line−plots, filled line−plots, accumulated line−plots, bar plots, accumulated bar plots,
grouped bar plots, error plots, line error plots, scatter plots, gantt−charts, radar plots, 2D and 3D pie
charts.
• 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−alising of lines
• Supports rotation of linear graphs
• More then 400 named colors
• Designed modularly − you don't have to include code which isn't used
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 straitforward version scheme to avoid the version number inflation. This means
10/07/2002 01:19:24 AM 3
No time frames have been determined for version 2.x and above. If you like these timeframes to move
forward either get involved in the development yourself or conside make a donation. Changes, bugfixes and
additions are always welcome. For the latest upate on planned future version see the web−site for JpGraph at
http://www.aditus.nu/jpgraph/
2.7 Acknowledgements
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
my 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.
10/07/2002 01:19:24 AM 4
2.9 Reporting bugs and suggesting improvements
Bug reports and suggestions are always welcome. I 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. I will unfortunately not be able to answer standard OO or PHP4 questions. Neither do I
have the time to give PHP/GD/TTF/Apache installation support. Please see the corresponding documentation
and relevant FAQ. I simply don't have the bandwith to help with these kinds of installations. Please note that
this library will not work with versions prior to PHP4.02. Bug reports and suggestions should be sent to
jpgraph@aditus.nu
10/07/2002 01:19:24 AM 5
3 Installation
3.1 Preparation
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 verion 4.02 or above of PHP since JpGraph will not work with versions
prior to PHP 4.02 that. Ideally you should use at least PHP 4.1.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.
In order to make sure that you have GD installed you could try by running the following example which
creates a very simple image using just pure GD calls and outputs an image in PNG format.
The above script must work before you will have any chance of getting JpGraph working.
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 genereate a graph. You can read more about
how to use the cache in the chapter Making sense of caching system in JpGraph
10/07/2002 01:19:24 AM 6
3.3 Required files
This is the base library files, which you must have
To add plots to the graph you will need one or more of the following files plot extension files dependiong on
what kind of graph you need to create.
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".
Note: The reason that my site (www.aditus.nu) only displays GIF images is that my Web hotell doesn't support a newer version of GD which allows PNG
format. One of lifes small pains. This is the reason that I in most places just displays the PNG images directly in the img tag on my site without going through
Jpgraph since the GIF format gives much bigger files and would make my site slower.
Sidenote 2: To get background images working with GD 2.0.1 you MUST enable Truecolor images by setting the constant USE_TRUECOLOR to true. If you
don't do this the background images will just be a black rectangle. The bad thing with this is that the antialias for Truetypes is broken using truecolor images in
GD 2.0.1. This means you can't have background and TTF fonts in the same image.
You can find a bug fix for GD 2.01 and the TTF problem together with Truecolor images at
10/07/2002 01:19:24 AM 7
http://www.coupin.net/gd−freetype/
NOTE: This bug fix has _nothing_ to do with JpGraph and I can't guarantee anything nor answer any questions regarding this specific fix.
−−−−<QUOTE >−−−−
−−with−gd=/home//gd−2.0.1
−−with−freetype−dir=/use
−−enable−gd−native−ttf
−−enable−gd−imgstrttf
−−with−jpeg−dir=/usr
−−with−png−dir=/usr
10/07/2002 01:19:24 AM 8
−−with−xpm−dir=/usr/X11R6
The above assumes you have freetype2 installed along with the
libjpeg and libpng libs under /usr
10/07/2002 01:19:24 AM 9
4 Working with jpGraph
4.1 What you will learn in this chapter
1. How to generate images in PHP with JpGraph
2. How to choose the image encoding
3. Various ways of using the generated image, streaming it back to the browser, sending it to a file or
getting hold of the image handle for further post processing
4. How to specify fonts (both bit−mapped and TTF) in JpGraph
5. How to extend JpGraph with your own fonts
6. How to work with Cyrillic fonts
7. How to specify colors in JpGraph
8. List all available named colors in JpGraph
9. How to effectively use the built in cache schema in JpGraph
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
Observere 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 comming back from this script is normal
ASCII. When then the image headers get send back to the browser to forwarn the browser of the
forthcomming 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:
10/07/2002 01:19:24 AM 10
<?php
include ('jpgraph.php');
include ('jpgraph_line.php');
...
// Code that uses the jpgraph library
...
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
excuted. While require() will always be replaced by the file specified. See PHP documentation for further explanation. For most practical purposes they are
identical.
1. Create a script that constructs the image, type, colors size and so on.
2. A wrapper script which contains one or more <IMG> tags to position the graphs on the proper HTML
page.
Of course it is of perfectly possible to call the image script directly in the browser to just display the generated
image in the browser.
You shopuld 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 apperance 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
When it comes to the structure of your imaging script they will generally have the structure
$graph−>Stroke();
10/07/2002 01:19:24 AM 11
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
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 begiven 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.
DEFINE("DEFAULT_GFORMAT","auto");
2. Set the graphic format in your script by calling the method SetImgFormat() For example, to force your script to use JPEG in one specific image
use
$graph−>img−>SetImgFormat("jpeg")
$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.
10/07/2002 01:19:24 AM 12
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 usefull 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:
$handle = $graph−>Strokg(_IMG_HANDLER);
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 defione (in jpgraph.php). 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
10/07/2002 01:19:24 AM 13
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.
10/07/2002 01:19:24 AM 14
We finally show some example of valid font specifications
$graph−>title−>SetFont(FF_FONT2);
$graph−>title−>SetFont(FF_FONT2,FS_BOLD);
$graph−>title−>SetFont(FF_ARIAL);
$graph−>title−>SetFont(FF_ARIAL,FS_BOLD,24);
Note: This information is only given here for very advanced users. No free support will ge 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 favourite fonts there are three steps you need to follow :
1. 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. These different files uses the following naming conventions:
♦ Normal fonts file = [basename].ttf
♦ Bold font file = [basename]"bd".ttf
♦ Italic font file = [basename]"i".ttf
♦ Bold Italic font file = [basename]"bi".ttf
2. Define a new "FF_" constant naming your font family
3. Update the Class TTF constructor in jpgraph.php with the mapping between your new constant and
the [basefilename]
SetColor("khaki");
A named color can also be modified by adding a adjustment factor. An adjustment factor, 0 < f < 1, a
smaller value will give a darker version and a value of 0 or 1 will return the original color. A value >
1 will make the color brighter. A few examples
SetColor(array(65,100,176));
10/07/2002 01:19:24 AM 15
3. By specifying the color as a hex string value
SetColor("#A16BFF");
10/07/2002 01:19:24 AM 16
10/07/2002 01:19:24 AM 17
10/07/2002 01:19:24 AM 18
10/07/2002 01:19:24 AM 19
10/07/2002 01:19:24 AM 20
4.7.2 Theme colors for pie:s
For more on how to use the different themes see Working with 2D 3D pie plots
Theme 1: Earth
Theme 2: Pastel
10/07/2002 01:19:24 AM 21
Theme 3: Water
Theme 4: Sand
10/07/2002 01:19:24 AM 22
5 Understanding the JpGraph caching system
To reduce load on the web server JpGraph implements an advanced caching system which avoids the burden
of always having to run the full image script.
Depending on the complexity of the image script (for example if it is doing several DB lookups) this could
significantly improve performance.
The rationale behind this is of course performance, and the observation that very few graphs are really
real−time, i.e. needs to be updated absolutely every time the graphing script is called.
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 woudl 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.
10/07/2002 01:19:24 AM 23
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 above code will use the automatic filename and a make the cache valid for 60 minutes.
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.
10/07/2002 01:19:24 AM 24
6 Introducing X−Y plot type
6.1 Common feature for all graphs
This is a summary of the available feature for all Graph based charts.
1. Each graph can have three titles accessed through the properties 'Graph::title', ''Graph::subtitle' and
''Graph::subsubtitle'
2. Each graph have a legend accessed through the 'Graph::legend' property
3. Each graph can have a left, center and right footer accessed through
'Graph::footer::left','Graph::footer::center' and 'Graph::footer::right'
4. You access the axis through 'Graph::xaxis', 'Graph::yaxis' and 'Graph::y2axis'
5. You access the grids through 'Graph::xgrid', 'Graph::ygrid' and 'Graph::y2grid'
1. You add plot objects (barplots, pieplots, texts, bands, lines etc) with the 'Graph::Add() method.
2. Each graph can have a specified margin set by 'Graph::SetMargin()'
3. Each graph can have a fill color in the plot area 'Graph::SetColor()'
4. The plot areas may have a box around it 'Graph::SetBox()'
5. Each graph can have a specified margin color 'Graph::SetMarginColor()'
6. Each graph can have a frame or not 'Graph::SetFrame()'
7. Each graph can have a specified drop shadow 'Graph::SetShadow()'
8. The grid lines can be either behind or in front of the plots 'Graph::SetGridDepth()'
9. The plot can be rotated an arbitrary angle with 'Graph::SetAngle()'
10. You can add a background image with 'Graph::SetBackgroundImage'
11. You can change the overall apperance of the axis with 'Graph::SetAxisStyle'
(File: example0.php)
<?php
include ("../jpgraph.php");
include ("../jpgraph_line.php");
// Some data
$ydata = array(11,3,8,12,5,1,9,13,5,7);
10/07/2002 01:19:24 AM 25
$graph = new Graph(350,250,"auto");
$graph−>SetScale("textlin");
• Both the X and Y axis have been automatically scaled. We will later on show how you might control
the autoscaling 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 littel bit "sparse". To make it more interesting we might want to add a
few things like
From looking at the previous example you can see that you access all properties of JpGraph through the
objects you create. Graph(), LinePlot() and so on. In general all objects you can see in the graph is accessed
10/07/2002 01:19:24 AM 26
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 2: 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
looka t the full source just click the [src] link in the caption. )
A nice change would now be to have all the titles in a bold font and the line plot a little bit thicker and in blue
color. Let's do that by adding the lines
10/07/2002 01:19:24 AM 27
$graph−>title−>SetFont(FF_FONT1,FS_BOLD);
$graph−>yaxis−>title−>SetFont(FF_FONT1,FS_BOLD);
$graph−>xaxis−>title−>SetFont(FF_FONT1,FS_BOLD);
$lineplot−>SetColor("blue");
$lineplot−>SetWeight(2); // Two pixel wide
Again please note the consistent interface. To change font you just have to invoke the SetFont() method on the
appropriate object. This principle is true for most methods you will learn. The methods may be applied to a
variety of objects in JpGraph. So for example it might not come as a big surprise that to have the Y−axis in
red you have to say:
$graph−>yaxis−>SetColor("red")
$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()
Figure 3: 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
10/07/2002 01:19:24 AM 28
For now let's just add a triangle shape marker to our previous graph by adding the line
$lineplot−>mark−>SetType(MARK_UTRIANGLE);
If you like you can ofd course both change the size, fill−color and frame color of the choosen 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.
10/07/2002 01:19:24 AM 29
Figure 5: Displaying the value for each data point [src]
We can of course change both color, font and format of the displyed value. So for example if we wanted the
display values to be dark red, use a bold font and have a '$' in front we need to add the lines
$lineplot−>value−>SetColor("darkred");
$lineplot−>value−>SetFont(FF_FONT1,FS_BOLD);
$lineplot−>value−>SetFormat("$ %0.1f");
Figure 6: 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 spearte thousends.
What if we want to add a second plot to the graph we just produced? Well, this is quite straightforward and
just requires two simple step:
10/07/2002 01:19:24 AM 30
To create the second plot we need some data (we could of course use the same data as for the first plot but
then we wouldn't be able to see the new plot!)
The following lines show how to create the new plot and add it to the graph (we only show the new lines − not
the full script)
$ydata2 = array(1,19,15,7,22,14,5,9,21,13);
$lineplot2=new LinePlot($ydata2);
$lineplot2−>SetColor("orange");
$lineplot2−>SetWeight(2);
$graph−>Add($lineplot2);
Making these changes to the previous graph script would generate a new graph as illustrated below.
• 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.
10/07/2002 01:19:24 AM 31
First we need to create a new data array with large values and secondly we need to specify a scale for the Y2
axis. This is done by the lines
$y2data = array(354,200,265,99,111,91,198,225,293,251);
$graph−>SetY2Scale("lin");
and finally we create a new line plot and add that to the second Y−axis. Note that we here use a new method,
AddY2(), since we want this plot to be added to the second Y−axis. Note that JpGraph will only support two
different Y−axis. This is not considered a limitation since using more than two scales in the same graph would
make it very difficult to interpret the meaning of the graph.
To make the graph a little bit more aesthetical 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
noramlly 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");
10/07/2002 01:19:24 AM 32
Figure 9: Adding a legend to the graph [src]
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 centred. 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
$graph−>legend−>Pos(0.05,0.5,"right","center");
Doing this small modification will give the result shown below
Figure 10: 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
10/07/2002 01:19:24 AM 33
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 hte 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 discontinuties) 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.
10/07/2002 01:19:24 AM 34
Figure 12: Handling null values in line graphs [src]
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 segements. 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 ber rendered with this style by calling the method SetStepStyle() on the
lineplot.
Figure 13: Rendering a line plot with the step style [src]
Using a logarithmic scale requires you to include the logarithmic add on module in "jpgraph_log.php". So you
must have the line
10/07/2002 01:19:24 AM 35
include("jpgraph_log.php");
on the top of your code. To Illustrate how to use a logarithmic scale let's make the right Y scale in the
previous example a logarithmic scale. This is done by the line
$graph−>SetY2Scale("log");
Figure 14: Using a logarithmic scale for both the Y2 axis [src]
You can of course also use a logarithmic X−scale as well. The following example shows this.
Figure 15: 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.
10/07/2002 01:19:24 AM 36
Figure 16: Example of using logarithmic scale togther with bar plots [src]
As you saw in the previous example it is possible to use different types of scales. In JpGraph you can use the
following scales
Any combination of these may be used. Linear and logarithmic scales are pretty straightforward. The text
scale might deserve some explanation. The easiest way to think of the text scale is as a linear scale consisting
of only natural numbers, i.e. 0,1,2,3,4,... . This scale is used when you just have a number of Y−values you
want to plot in a consecutive order and don't care about the X−values. For the above example it will also work
fine to use a linear X−scale (try it!). However, the scale is now treated as consisting or real numbers so the
autoscaling, 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.
10/07/2002 01:19:24 AM 37
• "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
$graph−>SetY2Scale("log");
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 disply 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 gridlines 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 gridlines since the resulting image becomes
difficult to read for a viewer.
$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 gridlines for both Y and X axis enabled.
10/07/2002 01:19:24 AM 38
Figure 17: 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() )
You might want to have specific labels you want to use for the X−axis when this has been specified as a "text"
scale. In the previous example each Y−point might represent a specific measurement for each of the first 10
month. We might then want to display the name of the months as X−scale.
To specify the labels on the scale you make use of the SetTickLabels() method.
To get a localized version of the name of the month you can use a nice feature in JpGraph, the global
'$gDateLocal' object which is an instance of the DateLocale
This class has a number of methods to get localized versions of relevant names for dates, (months and
weekdays).
So to specify the X−axis with the short form of the month names we use the construction
$a = $gDateLocale−>GetShortMonth();
$graph−>xaxis−>SetTickLabels($a);
10/07/2002 01:19:24 AM 39
Figure 18: Specifying text labels for the X−axis [src]
Note: It is also perfectly legal to override the default labels for the Y (and Y2) axis in the same way, however
there is seldom need for that. Please note that the supplied labels will be applied to each major tick label. If
there are insufficient number of supplied labels the non−existent positions will have empty labels.
As can be seen in the previous example the X−axis is slightly cluttered with the labels very close to each
other. We might rectify this by either enlarging the image or just displaying fewer tick label on the x−axis.
Specifying that we only want, for example, to print every second label on the axis is done by a call to the
method SetTextLabelInterval() Which would result in the graph
Figure 19: Just printing every second label on the X−axis [src]
If the text labels are long (for example full dates) then another way might bne 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()
10/07/2002 01:19:24 AM 40
Figure 20: Rotating the X−labels 90 degrees [src]
Note: The internal fonts which we have been using so only supports 0 or 90 degrees rotation. To use arbitrary
angles you must specify TTF fonts. More on fonts later.
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 apperance you expect.
10/07/2002 01:19:24 AM 41
As you can see from the graph above the gridlines are below the filled line graph. If you want the gridlines 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
You might of course also fill each line plot by adding the lines
$p1−>SetFillColor("red");
$p2−>SetFillColor("blue");
10/07/2002 01:19:24 AM 42
$p3−>SetFillColor("green");
Using some appropriate data this might then give a graph perhaps like the one showed in the figure below
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:
$datay=array(12,8,19,3,10,5);
$bplot = new BarPlot($datay);
$graph−>Add($bplot);
If you comapre this to the previous line examples you can see that the only change necessary was that instead
of createing 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
10/07/2002 01:19:24 AM 43
Figure 1: A very simple bar graph [src]
You can of course modify the apperance 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.
Figure 2: A very simple bar graph with changed fill color [src]
Sidebar: You should note from the previous two graphs that slight change in apperance 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 3: A small example with a bar graph using a linear X−scale [src]
JpGraph allows you to easy customize the apperance 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
10/07/2002 01:19:24 AM 44
an absolute width (in pixels).
To set the width in fraction you use the method SetWidth() and to set the width in pixels you use the
SetAbsWidth()
As an example let's take the previous example and set the width to 100% of the distance between the ticks.
The example will now become
Figure 4: Setting the width of the bars to 100% of the tick width [src]
You can easily choose to display the value (and it's format) on top of each bar by accessing the bar's 'value'
property. So for example by just adding the line
$barplot−>value−>Show();
Will enable the values in it's simplest form and will give the result
You cane see a small nuiance in this graph. The autoscaling 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
10/07/2002 01:19:24 AM 45
remedy this we tell the autoscaling 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
$graph−>yaxis−>scale−>SetGrace(20);
Figure 6: Adding some grace space to the top of the Y−scale [src]
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
10/07/2002 01:19:24 AM 46
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.
One simple way of making the bar graph more attracting is to add a drop shadow to each bar. This is done by
calling the SetShadow() method. An example will clarify this.
As you have seen from the previous examples bar graphs are normally centered between the trick marks on a
text scale. However, you can modify this behavious by calling the method BarPlot::SetAlign()
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 centred 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
10/07/2002 01:19:24 AM 47
// Create the bar plots
$b1plot = new BarPlot($data1y);
$b1plot−>SetFillColor("orange");
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%.
Setting the grouped with to 0.9 would result in the image below.
10/07/2002 01:19:24 AM 48
Figure 11: Adjusting the width for a gropued bar plot. [src]
The final varietys 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.
10/07/2002 01:19:24 AM 49
// Create the grouped bar plot
$gbplot = new GroupBarPlot(array($ab1plot,$ab2plot));
Putting this together in an example would then produce the graph as whown below
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 achived by
constructing a normal vertical bar graph which is then rotated 90 degrees.
10/07/2002 01:19:24 AM 50
Figure 14: 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 dont 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 plotarea. Since the center of the plotarea 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 plotarea is determined from the original width and height of the image taking the
specified margin into account. When the the plotartea is rotated 90 degrees clockwise what was the
left margin now in effect becomw 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 choosen 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 percived 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
10/07/2002 01:19:24 AM 51
$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.
10/07/2002 01:19:24 AM 52
Figure 16: Horizontal bar graph with Y axis at the top [src]
In the final example which is almost similair to the two first we illustrate the use of labels with more than one
line.
10/07/2002 01:19:24 AM 53
Figure 17: Horizontal bar graph with manual integer scale as well as multiple line labels [src]
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, fomr 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.
10/07/2002 01:19:24 AM 54
Figure 18: [src] Figure 19: [src] Figure 20: [src]
When using gadient 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 gadient 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 apperant 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−alising since that also uses a lot of colors. Since the numbers of colors
used with anti−alising 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
10/07/2002 01:19:24 AM 55
Figure 25: Semi−filled line graph [src]
I this example we defined two areas along the X−axis to be filled. You can add filled areas by using the
method AddArea() and specifying range and color for the filled area.
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 aesthetical quality of this graph. The X−scale is just wide
10/07/2002 01:19:24 AM 56
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 2: 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
$elplot−>line−>SetWeight(2);
$elplot−>line−>SetColor("blue");
10/07/2002 01:19:24 AM 57
Figure 3: Linear error plot [src]
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)
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 usefull when using the "Impuls" type of scatter
10/07/2002 01:19:24 AM 58
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.
We can easily adjust the size and colors fo the markers to get another effect as shown below
Figure 2: The simplest possible scatter plot with adjusted marks [src]
Another possible vaiant of scatter plot is impuls−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 impuls 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 impuls plots.
10/07/2002 01:19:24 AM 59
Figure 3: A simple impuls plot [src]
The next example shows how to modify the color and width of the impuls plot
Sidebar: You may draw impuls graphs without any mark by specifying the mark type as (−1) . That way only the impuls lines will be drawn.
As a final touch we show two more advanced impuls 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 5: 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]
10/07/2002 01:19:24 AM 60
Figure 6: In this impuls plot we have also added a lineplot with a dotted line style. [src]
To start simple we just mix a filled line plot with a non−filled line plot as the following example shows.
Figure 1: 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.
10/07/2002 01:19:24 AM 61
Figure 2: Adding a line to a bar graph [src]
Not too bad. But we can't see the line so we change the order in which we add the lines to the graph and sees
what happens.
If you want the line points to be aligned in the center of the bars you can accomplish this is two ways.
If you use a text scale then you need to call the LinePlot::SetBarCenter()
Figure 4: Centering the line point in the middle of the bars using LinePlot::SetBarCenter() [src]
10/07/2002 01:19:24 AM 62
You can also use an integer scale. This places both the bar and the line points centered at the tick marks. As
the following example will show
Note: In this example we also have illustrated the fact that you can add text labels to a linear (or integer)
scales as well.
As a final example we show how you can combine a scatter plot and a line plot which could be used to
illustrate a regression line fitting.
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);
10/07/2002 01:19:24 AM 63
When you specify a scale manually there is one additional thing you need to decide. How the tick marks
should be positioned. You have two choices
1. Manually specify the tick marks with a call to LinearTicks::Set() This is the default behavious. Hence
every manually specified scale must be followed by a call that sets the tick marks. For example
$graph−>SetScale("textlin",0,100);
$graph−>yscale−>ticks−>Set(10,5);
Will set the major tick marks every at 0,10,20,.. And every minor tick mark in between
(0,5,10,15,20,25,...).
2. Let JpGraph decide the best tick marks. You have to tell JpGraph that you want the tick marks to be
set automatically by calling LinearScale::SetAutoTicks() What you need to be aware of here is that
this might slightly chance the min and max values you have specified. This is done so that the scale
will start and end on a major tick mark.
The two images below illustrates this. They both have a manual scale, the left a manual ticks and the right
automatic ticks.
Figure 1: Manual scale, manual ticks [src] Figure 2: Manual scale, automatic ticks using SetAutoTicks() [src]
Taking the previous example with the manual scale but automatic ticks and using a denser ticks setting gives
the following result
10/07/2002 01:19:24 AM 64
Figure 3: Manual scale with automatic ticks but with a denser tick settings. [src]
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 ineterested in linear ordering of the data. If you don't specify the labels manually they will be
set automtically 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
gioven their ordinal number. If we augument the previous example with the name of the month we get the
following new example
10/07/2002 01:19:24 AM 65
Figure 5: Manually specifying the text scale labels [src]
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 sisplay every
label. To adjust what labels are to be displayed you use the SetTextLabelInterval() method. The argument to
this method is the itervall between text labels. So to display only every 3 month you would add the line
10/07/2002 01:19:24 AM 66
Figure 7: Displaying only every third label [src]
If we have an even larger data setit might not longer be meaningfull 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 disply, 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.
A better way to handle large data set is simply to hide the tick marks all together. Tick marks may be hidden
by calling the method Axis::HideTicks(); If we hide all the ticks on the X−axis we will get the result shown
below
10/07/2002 01:19:24 AM 67
Figure 9: Hiding all tick mark. [src]
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 migt 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 distact 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
10/07/2002 01:19:24 AM 68
Figure 1: Adding a single text string in the upper left corner [src]
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 paragarph alignemtn of the text
you have to use the Text::ParagraphAlign()
10/07/2002 01:19:24 AM 69
Figure 3: Text with multiple lines and centered paragraph alignment [src]
Of course there is no limit to the number of text string you can add to the graph.
1. title
2. subtitle
3. 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 beeing used.
If you for, aesthetic 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.
10/07/2002 01:19:24 AM 70
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
Note: If you enable the brand timing argument you should leave the left footer empty.
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
1. BGIMG_ COPY This will just copy the image unchanged onto the graph from the top left corner.
2. BGIMG_CENTER This will just copy the image unchanged onto the graph but it will center the
image in the graph.
3. BGIMG_FILLFRAME This will scale the image to exactly fit the whole graph image.
4. BGIMG_FILLPLOT This will scale the image to exactly fit just the plot area of the graph.
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 "bleeching" the color saturation,
reducing the contrast and so on. Finally you save the modified image which you then use as a bacvkground
image.
This whole process can be automatically accomplished in JpGraph by using the method
10/07/2002 01:19:24 AM 71
Graph::AdjBackgroundImage() which allow you to adjust color saturation, brightness and contrast of the
background image.
$graph−>AdjBackgroundImage(...)
to achive the "watercolor" effect to avoid the image being too intrusive in the graph.
Sidenote: The background image 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''.
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
which then can be used as a background image (after you saved it of course).
The UI for the utility is so obvious that we won't discuss it further, we just show it below.
10/07/2002 01:19:24 AM 72
The UI for the mkgrad.php utility
In the example below I have used this utility to get a more interesting plot area.
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
10/07/2002 01:19:24 AM 73
2. Plot mark Color
3. Plot mark Fill color
The exact meaning of the parameters will of course depend on the type of plot marks being used.
The callback must be a global function and is installed with a call to PlotMark::SetCallback()
So for example to install a callback that changes the fill color for all marks with a (Y) value higher than 90
you could add the lines
function MarkCallback($aVal) {
if( $aVal > 90)
$fcolor="red"
else
$fcolor="";
return array("","",$fcolor);
}
...
$plot−>mark−>SetCallback("MarkCallback");
...
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.
10/07/2002 01:19:24 AM 74
Figure 6: Creating a balloon plot by using plot mark callback function [src]
Assuming we start with the traditonal 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 positoined at the 0−point on the other axis, i.e. the axis will cross at the 0,0 point in the graph.
In additio 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
$graph−>xaxis−>SetPos("min");
To change the color and width of the axis you have to make use of the Axis::SetColor() and Axis::SetWeight()
methods.
Invisible axis Even though JpGraph (1.7) doesn't directly support "hidden" axis wher the labels are still drawn it is very easy to achive 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()
10/07/2002 01:19:24 AM 75
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 proeprty 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 plotarera) 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.
To adjust the label positioning you have to use the method Axis::SetTitleSide() and to adjust the position of
the tick mark you have to use the method SetTickSide()
Note: There is also an alias for this method, SetTickDirection() which is deprecated from version 1.7 but kept for backwards compatibility.
• SIDE_UP
• SIDE_DOWN
• SIDE_LEFT
• SIDE_RIGHT
For example, the following lines added to a script would change side of the labels and tickmarks for the
X−axis.
10/07/2002 01:19:24 AM 76
$graph−>xaxis−>SetLabelPos(SIDE_UP);
$graph−>xaxis−>SetTickSide(SIDE_DOWN);
This technique is for example used if you position the X−axis at the top of the graph as the following example
shows.
Figure 1: Example of both how to adjust the position of the X−axis as well as adjusting the side for the tick and axis title [src]
In scientific style plots it is often common to duplicate each axis so that all sides of the graph have a labeled
axis. This is of course also fully supported by JpGraph.
10/07/2002 01:19:24 AM 77
The example above shows the basic configuration. There are now several modifications you may do to these
axis like
The style of axis is determined by the method Graph::SetAxisStyle() The available type of axis are
How to adjust the actual labels are discussed elsewhere in this manual (see ???,???). Howver we like to
mention here that you can adjust the label margin (distance betweeen 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 completenesss since it is mostly used for internal purposes. However
on som occasion you might want to adjust the alignment of the labels. By default they are centered in respect
to the tickmark. 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 usefull for
X−axis that have long labels.
One good way of illutrsate the usefullness of label callbacks in a slightly different context is to show how we
can achieve the effect of an inverted Y−scale.
An inverted Y−scale has the lowest number at the top and the scale values increases downwards.
Even though JpGraph doesn't directly support this feature it is wuite easy to achieve with just a few extra lines
of code in your image script.
10/07/2002 01:19:24 AM 78
Figure 3: Inverted Y−axis [src]
Two achieve this effect there are two simple steps to take:
And that's it! We refeer you to the code in the example above for the details.
However you might sometime want to add some extra to the minimum and maximum values so that there is
10/07/2002 01:19:24 AM 79
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 5: Adding 10% grace value to top and bottom of the Y−scale [src]
Since we haven't adjusted the positoin of the X−axis it will remain at Y=0 which might not necessary be waht
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
10/07/2002 01:19:24 AM 80
Figure 6: Using grace but also adjusting the position of the X−axis [src]
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.
10/07/2002 01:19:24 AM 81
Figure 5: [src] Figure 6: [src]
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 desnity 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
10/07/2002 01:19:24 AM 82
Figure 9: Increasing the desnity in a pattern [src]
• ... enabling or disabling a frame around the pattern by using the method PlotBand::ShowFrame() The
band will ge given the same color as the band.
• ... finally you can change whether the band should be drawn on top of the plots or beneath, (by default
the bands are under the plots), using the PlotBand::SetOrder() as the following example show
Sidenote. 3D planes actually carry another possible modification. You can specify the vanish point to change the perspective used. You can't acces the
method to change the horizon directly but you can access it through
$band−>prect−>SetHorizon($aHorizon)
To finish this section we give one final, more creative, example on how to use the bands.
10/07/2002 01:19:24 AM 83
Figure 11: Combining 3D plane, solid band and a sttaic line [src]
10/07/2002 01:19:24 AM 84
7 Working with non X,Y−plots
Non X,Y plots includes
The fundamental difference is that these classes that each one makes use of an extended version of the basic
Graph class.
10/07/2002 01:19:24 AM 85
In the following section we show how to draw both simple and complex radar graph. As we will show all the
settings will follow the same pattern as for the more standard linear graphs.
Let's start by creating a very simple radar plot based on 5 data points using mostly default values.
As the first thing you must remember to include the extension module that contains the radar plot.
"jpgraph_radar.php".
(File: radarex1.php)
<?php
include ("../jpgraph.php");
include ("../jpgraph_radar.php");
Figure 2: A first very simple radar plot using default settings [src]
To change the size and position of the radar graph is similair to the pie plot and you do it by using the
methods SetSize() and SetCenter()
10/07/2002 01:19:24 AM 86
If you want a filled radar plot you need to specify the fill color with the method SetFillColor() The following
example shows these methods in action
Figure 3: Changing size, position and adding fill color to the radar plot. [src]
7.1.2 Specifying titles for the axis and legends for the plots
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 ticvk mark can also be connected togehter 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
$graph−>grid−>Show();
$graph−>grid−>SetLineStyle("dotted");
10/07/2002 01:19:24 AM 87
Figure 4: Adding dotted gridlines to the graph [src]
By design the plot is above the gridline but beneath the axis in image depth, hence some part of the gridlines
are hidden.
To have the gridlines more "visible" just change their color, say to, dark red by invoking the SetColor()
method on the gridlines which would give the following result
Another simple change we could do would be to just change the background color of the radargraph. This is
(not surprisingly) done by a call to the method SetColor() invoked on the graph object.
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.
10/07/2002 01:19:24 AM 88
Figure 6: Several radar plots in one radar graph [src]
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.
include ("../jpgraph.php");
include ("../jpgraph_pie.php");
$data = array(40,60,21,33);
10/07/2002 01:19:24 AM 89
Figure 1: The simplest possible pie graph [src]
• By default all pie slices have the percentage shown just outside the slice.
• The colors are automatically assigned to the slices.
• The pie have the edges marked by default
• The fisr slice start at 0 degrees (3 a'clock)
You can change allmost all aspects of apperance of the pie graphs. For example you could change :
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
10/07/2002 01:19:24 AM 90
(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.
10/07/2002 01:19:24 AM 91
Figure 4: A first example of a 3D pie plot [src]
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.
Explding 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
10/07/2002 01:19:24 AM 92
Figure 6: Exploding one slice [src] Figure 7: Exploding one 3D slice [src]
To explode all slices at once you can use the PiePlot::ExplodeAll() method. If you want to explode several
slices you can use the PiePlot::Explode() method and supply a suitable array argument.
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 8: Example of adjusting the position of the labels for the slices [src]
10/07/2002 01:19:24 AM 93
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 sert to 'auto' if not explicetely
specified.
Note: The alignment of the labels will be different depending on wheter 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
inadvertedly 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.
Figure 9: [src] Figure 10: [src] Figure 11: [src] Figure 12: [src]
A complete color chart of all available colors in the different themese can be found here
Another simple change is to remove the border ( or change it's colors ) that separates each slice. This can be
done by a call to ShowBorder()
10/07/2002 01:19:24 AM 94
7.2.5 Adding drop shadows to the slices
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
As mentioned in the beginning there are two versions of the 2D pie plots. The normal pie plot created as an
instance of class PiePlot and a variant created as an instance of class PiePlotC
This variant is an extension of the standard PiePlot in the sense that it also have a filled circle in the center.
The following example illustrates this
Figure 14: Example of the variant of pie plot with a filled center circle [src]
10/07/2002 01:19:24 AM 95
Since the PiePlotC is an extension to the basic pie plot all the normal formatting you can do for pie plots you
can also do for the PiePlotC .
The additional formatting only concerns the filled middle circle. You have the option of adjusting size, fill
color and all font properties. You perform these operations with the methods
The next example shows an example with some more innovative formatting. In this example we have :
Figure 15: PiePlotC with some more innovative formatting to make it more interesting. [src]
10/07/2002 01:19:24 AM 96
8 Using image maps with JpGraph
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 :−)
// Image tag
<img src="..." ISMAP USEMAP="mapname">
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?
1. Use the preferred "builtin" way using the modified Stroke() method Graph::StrokeCSIM() instead of
the standard Graph::Stroke() method.
2. Directly use the Graph::GetHTMLImageMap() which gives you fine control at the expense of more
complex coding.
The first (and preferred) way modifies the stroke method so that instead of returning an image (like the
standard Stroke() method) StrokeCSIM() actuallty returns a HTML page containing both the image map
specifiaction and the correct <IMG> tag.
This of course means that you have to treat an image map returning image script diffrently 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.
What the hotspots represent depends on the type of plot you are doing. The following plot types support
image maps.
10/07/2002 01:19:24 AM 97
• Line plots. Markers are hotspots.
• Scatter plot. Markers are hotspots.
• Pie Plots and 3D Pie plots. Each slice is a hotspot
• All types of Bar graphs. Each bar is a hotspot
To specify a link for each hotspot you have to use the SetCSIMTargets() method for each plot in the graph
you want to have hotspots.
• $aTargets, an array of valid URL targts. One URL per hotspot, for example if you have a 10 values
bar plot you need 10 URLs
• $aAlts, an array of valid alt−texts. Usually showed by most browsers if you hold you pointer over a
hotspot.
1. Use the CSIM image script as the target in a standard anchor reference, for example
<a href="mycsimscript.html">
This has the drawback that your image page will only contain the image and nothing else.
2. 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
<?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')
10/07/2002 01:19:24 AM 98
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.
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.
10/07/2002 01:19:24 AM 99
8.4.3 Client maps with Scatter graphs
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.
An example of the use of this is shown below. With these lines the image will be written to a file. The script
then returns a HTML page which contains the Client side image map and an img−tag which will retrieve the
previously stored file.
$graph−>Stroke("/usr/local/httpd/htdocs/img/image001.png");
echo $graph−>GetHTMLImageMap("myimagemap001");
echo "<img src=\"img/image001.png\" ISMAP USEMAP=\"#myimagemap001\"
border=0>";
However, as was shown in the previous example you can still manually store the image in a file and get hold
of the HTML image map manually. Using this method you could yourself store away the HTML page
containing the img−tag together with the map so you don't have to re−generate the image each time. This
could come in handy if you work a lot with 3D pie graphs since they are computational expensive.
This tutorial specifically will not teach you how to install PHP, Apache, TTF fonts, the GD library or any
other infrastructure that you need to make JpGraph work.
You should have obtained a copy of JpGraph together with its associated documentation and have access to a
WEB server on which you have tried (and succeeded!) to run a few of the example graphs supplied. If you
have successfully completed that you are all set to start reading this tutorial.
This tutorial will therefore only focus on and go to some great length to introduce you to all features of the
JpGraph Gantt module. Enjoy!
Sometimes (to save space) I don't include the full source if the example is just a very minor modification to a
previous example. In that case I just show the difference. For all images in this tutorial the full source can
always be seen by clicking on the "[src]" tag at the end of the caption for that image.
My hope is that these convention will make it easier to follow the tutorial and will give a balanced mix of full
source versus space and ease of reading.
The pragmatic view: To keep management of our back and know what we have forgotten
The common view: As a tool to help identify project issues and highlight problem areas.
Basically, Gantt charts are used to show the state of a number of activites (possible grouped) against time.
All it takes to do this (using default values for everything) is the following code.
(File: ganttex00.php)
<?php
include ("../jpgraph.php");
include ("../jpgraph_gantt.php");
Let's note a few things with the above image and code:
So, lets start making this graph a little bit more interesting. First we are going to add a title, then we will add a
month scale and finally we will change the color of the bar.
(File: ganttex01.php)
<?php
include ("../jpgraph.php");
include ("../jpgraph_gantt.php");
// Use the short name of the month together with a 2 digit year
// on the month scale
$graph−>scale−>month−>SetStyle(MONTHSTYLE_SHORTNAMEYEAR2);
Figure 2: Making the Gantt chart a little bit more interesting with title and more colors. [src]
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");
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
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 choosen. The following examples shows some possible ways of creating a new graph
• $graph=new GanttGraph()
The size of the graph will be determined automtically, no caching will be used and the graph will be
generated inline.
• $graph=new GanttGraph(−1,−1,"auto")
The size of the graph will be determined automtically, caching will be used (the name will be based
on the script name), no timeout will be used and the graph will be generated inline
• $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 inline, 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.
It is perfectly legal, and perhaps even desirable to leave "gaps" when laying out bands to group related
activiies. 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.
• 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 accout 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 explicetly specified a height the bars will usually be
added from band 0 and onwards and hence beeing 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 explicetly 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 automtic sizing you cant use even layout. It just doesn't make sence. Even layout is for those cases
when you deliberately specify a very large image and whant the bars evenly distributed using the full
height.
function GanttBar($aVPos,$aTitle,$aStart,$aEnd,$aCaption,$aHeight)
As described above vertical positions are specified as a numeric value [0..n] where 'n' is an arbitrary constant.
(For practical purposes n is most likely < 100)
Using our previous example we will illustrate this parametger by changing the position of our 'Project' activity
to position 7. Therefor we change the call to GanttBar() to
Note that the height of each position (vertical position) will depend on the actual height of the bar.
Start of bars are given as a date string. The formar 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:
• "2001−11−15"
• "15 Nov 2001"
• 22, (specifies duration of 22 days)
• 22.7, (specifies duration of 22.7 days)
Milestones are similair to bars but have no end date since milestones just apply to one single date. Milestones
are created much the same way as activities but using method MileStone() instead.
function MileStone($aVPos,$aTitle,$aDate,$aCaption)
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 followinf two lines of
code which result in Figure 5 shown below.
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
$milestone−>title−>SetFont(FF_FONT1,FF_BOLD);
$milestone−>title−>SetColor("black");
To modify the caption you do exactly the same but act on property 'caption' instead of 'title', i.e.
$milestone−>caption−>SetFont(FF_FONT1,FF_BOLD);
$milestone−>caption−>SetColor("black");
It is worth noting that you modify the bar title and caption the exact same way by acting on the 'title' and
'caption' property for the bars.
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()
function GanttVLine($aDate,$aTitle,$aColor,$aWeight,$aStyle)
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.
Figure 7: 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
$vline−>SetDayOffset(0.5);
Figure 8: Modifying the position of the line within the day [src]
As usual you may modify the font, size and color by invoking the appropriate method (SetFont(), SetColor())
on the 'title' property of lines.
You can easily add a variety of masrkers 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 augument the previous example with the
following lines:
$activity−>rightMark−>Show();
$activity−>rightMark−>title−>Set("M5");
$activity−>rightMark−>SetType(MARK_FILLEDCIRCLE);
$activity−>rightMark−>SetWidth(10);
$activity−>rightMark−>SetColor("red");
$activity−>rightMark−>SetFillColor("red");
$activity−>rightMark−>title−>SetFont(FF_ARIAL,FS_BOLD,12);
$activity−>rightMark−>title−>SetColor("white");
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 defult 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.
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 behaviour is unwanted it is always possible to specify an absolute size for the bar heigh, say 8 pixels,
with a call
$activity−>SetHeight(8);
Figure 10: 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
Figure 11: Setting the height for each bar to 100% [src]
Aha.. What we are trying to do doesn't really make sence. 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
$activity−>SetHeight(10);
$activity2−>SetHeight(10);
we instead get
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
GanttGraph::SetLabelVMarginFactor($aMargin)
As an example let's set that margin in the previous example to 0 and see what happens.
As you would perhaps expect the two bars just barely touches now since there are no extra margin added. If
the two bars hadn't had the extra right marker it would have looked very compressed.
• Day scale
• Week scale
• Month scale
• Year scale
These scale header are all accessed through the graph instance variables 'scale' as in
$graph−>scale−>week
or
$graph−>scale−>day
Show()
SetFont()
SetFontColor()
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()
SetFrameWeight()
SetFrameColor()
In addition to these methods each scale also has the property 'grid' which determines the appearance of
gridlines for that specific scale. You may modify the appearance of gridliens by the "normal" line methods,
i.e. SetColor(),SetWeight() SetStyle() and Show(). So for example to set the week gridline red you would use
$graph−>scale−>week−>grid−>SetColor("red");
Each of the scales also have some specific formatting possibilities as described below.
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()
SetSundayFontColor()
In addition to this there is also a possibility to choose whether or not the weekend background should be
extended vertically down over the plotare. By default it is. Since that is a property more of the whole plot you
modify this behaviour with a call to the method
UseWeekendBackground()
$graph−>scale−>UseWeekendBackground(false);
Week scales, if enabled, by default shows the week number in range 1 to 53 (as defined by ISO−8601, see the
reference section).
You may modify the week behaviour in three ways. You can specify (with SetStyle()) a different date format
using the constants
WEEKSTYLE_WNBR
Show weeknumber To further modify the formatting of the actual week number you can optionally
supply a format string witha call to
SetLabelFormatString()
The format of the string should be a standard sprintf() syntax expecting an integer (the weeknumber).
By default a 'W' is prefixed to the number.
WEEKSTYLE_FIRSTDAY
For month scale you can use the SetStyle() method to choose between a variety of formats.
MONTHSTYLE_SHORTNAME
Display the month name in its locale specific short form, i.e Jan, Feb etc
MONTHSTYLE_SHORTNAMEYEAR2
Display the month name in its locale specific short form together with a 2 digit year , i.e Jan '01, Feb
'01 etc
MONTHSTYLE_SHORTNAMEYEAR4
MONTHSTYLE_LONGNAME
Display the month name in its locale specific long name, i.e. January, February
MONTHSTYLE_LONGNAMEYEAR2
Display the month name in its locale specific long name together with a 2 digit year , i.e January '01,
February '01 etc
MONTHSTYLE_LONGNAMEYEAR4
Display the month name in its locale specific long name together with a 4 digit year , i.e January
2001, February 2001 etc
Year scale has no extra formatting possibilities. (Simply because I couldn't come up with any usefull
modification of a simple year. If you have any suggestion of fancy formatting you think could be usefull
please drop me a note and I have something to do for the next version)
Caption for bars are placed at the far right side of the bars. They can for example be used to indicate the
resources assigned to a task, the duration of the task or the progress of the activity.
Caption text for a bar is specified either when creating a bar or later by accessing the 'caption' property of
bars. So the two lines
and
are both ways of specifying the caption "[BS,ER]" for the activity. Since activity is a standard JpGraph text
object you can easiliy modify font, color and size with calls to SetFont() and SetColor(), (e.g.
$activity−>caption−>SetFont(FF_ARIAL,FF_BOLD,9);
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 15 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).
To specify a different format for the progress you use the SetPattern() method as in
$activity−>progress−>SetPattern(BAND_RDIAG,"blue");
In the reference section you can see the exact parameters and all available methods.
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 example lines above also changes the default white background to silver. Adding these lines to the
previous example gives the following result:
From the above example you might notice that the width of the left column (which holds all the titles) have
automtically adjusted itself to make the table title fit.
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:
$graph−>scale−>divider−>SetWeight(3);
$graph−>scale−>divider−>SetColor("navy");
$graph−>scale−>dividerh−>SetWeight(3);
$graph−>scale−>dividerh−>SetColor("navy");
In a similair manner to the other plots in JpGraph you modify the Box round the plot with the standard graph
method 'SetBox()' as in
$graph−>SetBox(true,"navy",3)
which will result in a thicker plot box around the area as shown below
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.
You can choose to only display a vertical slice of the overall Gantt chart by explicetly sepcifying a date range
with the method GanttGraph::SetDateRange(). This will cap any bars to only be displayed in between the start
$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 startday of the week, 0 means Sunday, 1 Monday, 2 Tuesday and so on. The
default is to start the week on Monday.
9.14 Localizing
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 exampel
american english is pecified with the string 'EN_US', brittish 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");
Figure 20: Using swedish locale. (Can you spot the difference from English?) [src]
Sidebar Note that anti−alising will not be used for either horizontal, vertical or 45 degree lines since they are by their nature are sampled at adequate rate.
Anti−aliased lines are enabled by calling the method SetAntiAliasing() in the Image class in the script where
you want to use anti−aliasing.
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.
Figure 1: Spiderplot without anti−aliasing [src] Figure 2: Spiderplot with anti−aliasing [src]
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.
1. 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
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 optimises this by using a pre−calculated transformation matrice and also optimises 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.
For example
$graph−>image−>SetAngle(45);
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
Please remember that you may still rotate the labels by calling the Axis::SetLabelAngle() method.
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 )
Figure 3: Original image [src] Figure 4: Rotated 45 degrees around center of plot area [src]
Figure 5: Rotated 90 degrees around center of plot area [src] Figure 6: Rotated 45 degrees around center of the image [src]
Figure 7: Rotated 90 degrees around center of the image [src] Figure 8: Rotated −30 degrees around the lower left point of the plot area [src]
As you can see from the images above if you rotate about any other point than the center of the plot area the
plot can be placed outside the image after rotation.
Since the rotation, by design, only affects the plot area it is often most effective to use when the color of the
margin is the same as the background color.
1. Prepare the image with an external images editor to adjust the level of brightnes and contrasty to a
desirable level
2. Use JpGraph:s built int adjustment for contrast, brightness and color saturation.
To adjust the background image call The levels for both brightness and constrast 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.
1. You can either set the global define BRAND_TIMIING (in jpgraph.php) to true. This will add the
timing string to all graphs generated.
2. .. or you can enable it for a specific graph by setting the global variable $gJpgBrandTiming as in
$gJpgBrandTiming=true;
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
Working with canvas requires more understanding of JpGraph as well as more programming and fine tuning.
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 automtically 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 2: Another example of using a canvas to draw a number of text boxes [src]
Creating a canvas gives you the opportunity draw arbitrary shapes on a "white" piece of paper. Let's first show
a simple exmaple were we just draw a text box. We first show you the code which we will walk through
(File: canvasex01.php)
<?php
// $Id: canvasex01.php,v 1.2 2002/08/27 20:09:31 aditus Exp $
include "../jpgraph.php";
include "../jpgraph_canvas.php";
// Add a box around the text, white fill, black border and gray shadow
$t−>SetBox("white","black","gray");
?>
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
upp all you addition and then makes sure thay are stroked in the correct order.
We then create a Text object, setup it's properties, inculding 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 somthing else (of the bounding box)? In the code above we have choosen to interpet the
X−coordinate as beeing 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 iun 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 discussin 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 3: A simple canvas drawing with a text box in the middle [src]
$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
(File: canvasex02.php)
<?php
// $Id: canvasex02.php,v 1.1 2002/08/27 20:08:57 aditus Exp $
include "../jpgraph.php";
include "../jpgraph_canvas.php";
// .. add a rectangle
$g−>img−>SetColor('green');
$g−>img−>FilledRectangle(10,10,50,50);
?>
Pleas note the way to access these routines through the img property of the Graph class. Please alos keep in
mind that the coordinates are absolute.
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 ontain 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 refernce to find out what other graphic primitives are available for use.
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 additinal advantages:
• If you increase the size of the canvas all objects will be automtically 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
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 utiity 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
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,
list($x1,$y1) = $this−>scale−>Translate($x1,$y1);
list($x2,$y2) = $this−>scale−>Translate($x2,$y2);
$g−>img−>Line($x1,$y1,$x2,$y2);
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 methodsTo set up the Shape class you instantiate it with the graphic context and the scale
you want to use as argument as in
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.
(File: canvasex03.php)
<?php
// $Id: canvasex03.php,v 1.1 2002/08/27 20:08:57 aditus Exp $
include "../jpgraph.php";
include "../jpgraph_canvas.php";
include "../jpgraph_canvtools.php";
// The shape class is wrapper around the Imgae class which translates
// the coordinates for us
$shape = new Shape($g,$scale);
$shape−>SetColor('black');
// .. add a rectangle
$shape−>SetColor('green');
$shape−>FilledRectangle(15,8,19,14);
If we like to make a smaller image we could just change the image size and everyting will be rescaled without
any further code changes. SO for example making the image half the size would give the result
Figure 6: 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 7: 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
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 refeer the interested reader to the class reference and the
'listfontsex1.php' example file.
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 automaticially 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.
Before going on it should be noted that the ImgDBSchema assumes that the DB can be accessed through a DB
abstraction layer modelled 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 critical lines int the code to generate the above graph is
$tblposadj=array($tlo,0,$tblwidth+$tlo+2,0,2*$tblwidth+$tlo+4,0,−1,16,−1,16);
$dbschema = new ImgDBSchema("jpgraph_doc","FormatTblName","FormatFldName");
$dbschema−>SetMargin($leftm,$topm);
$dbschema−>SetTableWidth($tblwidth);
$dbschema−>Stroke($this−>img,$this−>iscale,$tblposadj);
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 imge 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 speicfy 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.
(File: dbschemaex1.php)
<?php
/*=======================================================================
// File: DBSCHEMAEX1.PHP
// Description: Draw a DB schema of the DDDA architecture
// Created: 2002−08−25
// Author: Johan Persson (johanp@aditus.nu)
// Ver: $Id: dbschemaex1.php,v 1.1 2002/08/27 20:08:57 aditus Exp
$
//
// License: This code is released under QPL
// Copyright (C) 2001,2002 Johan Persson
// Note: The actual drawing of the tables are semi−automatically
// but you can easily adjust the individual tables position
// with the 'tblposadj' array.
//
class Driver {
function Driver() {
function Run() {
// Stroke the tables (series of x,y offsets, If =−1 then use the
// automtic positioning
$tblposadj=array($tlo,0,$tblwidth+$tlo+2,0,2*$tblwidth+$tlo+4,
0,−1,16,−1,16);
$dbschema = new ImgDBSchema('jpgraph_doc','FormatTblName','FormatFldName');
$dbschema−>SetMargin($leftm,$topm);
$dbschema−>SetTableWidth($tblwidth);
$dbschema−>Stroke($this−>img,$this−>iscale,$tblposadj);
// Add explanation
$tt−>SetFont(FF_ARIAL,FS_NORMAL,12);
$tt−>Set('Project specific tables',$tblwidth+$leftm+3,16,15);
$tt−>Stroke($this−>img,$this−>iscale);
// Add title
$tt−>SetColor('');
$tt−>SetFont(FF_VERDANA,FS_BOLD,26);
$tt−>Set('DDDA − DB Schema',9,0.5,30);
$tt−>Stroke($this−>img,$this−>iscale);
$this−>ig−>Stroke();
}
}
?>