1 Advanced features of JpGraph
1.1 Using grace percentage on scales
By default the autoscaling algorithm tries to make best possible use of screen estate by making the scale as large as possible, i.e. the extreme values (min/max) will be on the top and bottom of the scale if they happen to fall on a scale-tick. So for example doing a simple line plot could look like the plot shown in Figure 1 below.
Figure 1. Example of graph with grace=0 (default values).
However you might sometime want to add some extra to the minimum and maximum values so that there is some “air” in the graph between the end of the scale values and the extreme points in the graphs. This can be done by adding a “grace” percentage to the scale. So for example adding 10% to the y-scale in the image above is done by calling the SetGrace() method on the yscale as
$graph->yscale->SetGrace(10); // Set 10% grace.
After this the graph will look like shown in figure below
Figure 2. Example of using grace for the Y-scale.
As you can see the dynamic range has been reduced by roughly 10% . The exact value will depend on the endpoints chosen by the autoscaling algorithm. The grace simply works by adding the percentage grace value of the dynamic range (maximum-minimum) and using those values as the min and max values sent into the autoscaling algorithm.
Note: As you can see the above graph also
makes use of SetCenter() for the lineplot so thet the numbering on the x-axis
is placed in the center of each tick-“slot”.
As an example the complete code for the last graph in Figure 2 above is:
<?php
include ("jpgraph.php");
include ("jpgraph_line.php");
$datay = array(0.2980,0.3039,0.3020,0.3027,0.3015);
$graph = new Graph(300,200);
$graph->img->SetMargin(40,40,40,40);
$graph->img->SetAntiAliasing();
$graph->SetScale("textlin");
$graph->SetShadow();
$graph->title->Set("Example of 10% grace in line plot");
$graph->title->SetFont(FF_FONT1,FS_BOLD);
$graph->yscale->SetGrace(10);
$p1 = new LinePlot($datay);
$p1->mark->SetType(MARK_FILLEDCIRCLE);
$p1->mark->SetFillColor("red");
$p1->mark->SetWidth(4);
$p1->SetColor("blue");
$p1->SetCenter();
$graph->Add($p1);
$graph->Stroke();
?>
Figure 3. The code that generated Figure 2 above.
1.2 Timing the generation of graphs
When evaluating the performance (or suitability for on-line graph genertation) for graphs there must be a simple way to get a knowledge on the time it takes to generate a specific image. In JpGraph this works by the possibility to brand each generated picture by the time in s (and ms) it took PHP to generate that image.
This is controlled by the definition (in jpgraph.php)
. . .
DEFINE("BRAND_TIMING",TRUE);
. . .
By specifying this constant true or false you can determine wheter or not you would like to have the image branded by the time. The actual string that gets formatted is specified by the definition
. . .
DEFINE("BRAND_TIME_FORMAT","Generated in: %01.3fs");
. . .
This let’s you easy customize the actual string that gets printed on the image. This string will always be printed in the lower left corner of the graph. The image below show an example of a graph with the time branded into it.
Figure 4Graph with
timing information. (on my very slow old server…)
1.3 Using color gradient fill
From version 1.2 it is possible to use color gradient fill for certain graphs. As of this writing only bar graphs supports color gradient fill at the moment. In future releases of JpGraph there will be added functionality to use gradient fill for backgrounds and possible area-graphs (filled line-plots).
Color gradient fill fills the image with a smooth transition between to 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.
Before explaining how this feature is used you must be aware of two caveats with gradient filling:
The seven different styles are specified by using the specific PHP constants defined in jpgraph.php. Currently the following styles are available:
Style |
Description |
Example |
GRAD_VER |
The gradient moves from left to right |
|
GRAD_HOR |
The gradient moves from top to bottom |
|
GRAD_MIDVER |
The gradient goes from the middle and vertically up/down |
|
GRAD_MIDHOR |
The gradient goes from the middle and horizontally left/right |
|
GRAD_CENTER |
The gradient radiates from the center and outwards. |
|
GRAD_WIDE_MIDVER |
Similar to GRAD_MIDVER but with the middle color taking up a wider area |
|
GRAD_WIDE_MIDHOR |
Similar to GRAD_MIDHOR but with the middle color taking up a wider area |
|
Table 1. Different styles of color gradient filling
You only need to create the barplot as usual and then call method SetFillGradient() where you need to specify two colors and a gradient style. So for example to specify the GRAD_WIDE_MIDHOR style as in the last example in Table 1
$barplot->SetFillGradient("navy","lightsteelblue",GRAD_WIDE_MIDHOR);
1.4 Specifying fonts
JpGraph supports both a set of built in bit-mapped font as well as True Type Fonts. For scale values on axis it is strongly recommended that you just use the built in bitmap fonts for the simple reason that they are, for most people, easier to read (they are also quicker to render). Try to use TTF only for headlines and perhaps the title for a graph and it’s axis. By default the TTF will be drawn with anti-aliasing turned on.
Fonts are generally specified with three parameters
1. Font family
2. Font style
3. Font size
In the call to method SetFont(). If no specified style is dsupplied then the style will default to normal style (FS_STYLE) , size has default value of 12pt.
Built in fonts are chosen by using one of the font families
· FF_FONT0 (small size, does not support bold style)
· FF_FONT1 (normal size)
· FF_FONT2 (large size)
Built in fonts only supports style FS_NORMAL and FS_BOLD (and in the case of FF_FONT0 only FS_NORMAL) trying to specify an unsupported combination for built in fonts will not give an error but will have no effect.
Note: To support backward compatibility with pre-1.2 bitmap fonts might also be specified with FONT0, FONT1, FONT2 (note the missing prefix FF_). However these specifications are deprecated as of 1.2. And usage of these will be a critical error in the next major release. It is strongly suggested that you use the new naming conventions since that is designed to harmonise with the TTF support.
The size parameter has no meaning for built in fonts and will be ignored. The size is implicitly set by choosing the corresponding font family .
Some examples of how to specify the built in fonts
SetFont(FF_FONT1,FS_BOLD);
SetFont(FF_FONT1,FS_BOLD,12); // Size 12 is ignored
SetFont(FONT1); // Deprecated!
SetFont(FF_FONT2); // Use built in FONT1 using default
style.
SetFont(FF_FONT0,FS_BOLD); // FONT0 does not support bold style, will be
ignored
Before you can start using True Type Fonts you need to make sure that
1. You have downloaded the TTF files. Due to it’s size they are in a separate package from the JpGraph script code.
2. The TTF_DIR constant in jpgraph.php points to the directory where the font files may be found.
3. You installation of PHP supports TTF (most should do)
By default JpGraph will look for fonts in directory “./TTF/”
In JpGraph 1.2 the font families and styles supported are listed in Table 2.
Font family |
Font style |
||||
PHP Constant |
Real name |
FS_NORMAL |
FS_BOLD |
FS_BOLDITALIC |
FS_ITALIC |
FF_COURIER |
Courier
new |
ü |
ü |
|
ü |
FF_VERDANA |
Verdana |
ü |
ü |
|
ü |
FF_TIMES |
Times New Roman |
ü |
ü |
ü |
|
FF_HADWRT |
Lucida Handwriting |
ü |
|
|
|
FF_COMIC |
Comic Sans |
ü |
ü |
|
|
FF_ARIAL |
Arial |
ü |
ü |
|
ü |
FF_BOOK |
Book Antiqua |
ü |
ü |
ü |
ü |
Table 2 Available combination of TTF font families and styles
The use of a an illegal combination will give a runtime error indicating the type of problem, e.g. “Style not supported for font family”. On additional thing to keep in mind when designing graphs is that even though TTF may look more appealing from an aesthetic point of view they are much more time consuming to render and also involves one additional disk access.
Some examples:
SetFont(FF_COURIER); // Courier normal 12 points
SetFont(FF_COURIER,FS_BOLD);
// Courier bold 12 points
SetFont(FF_COMIC,FS_BOLD,16);
// Comic Sans Serif, bold, 16 points
If you have a particular favourite font which doesn’t come as default it is quite easy to add that font to JpGraph as an extension. There are basically 3 things you need to do:
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 font file =
<basefilename>
Bold font file =
<basefilename>”bd”
Bold italic file =
<basefilename>”bi”
Italic file =
<basefilename>”i”
2.
Define a new constant FF_xxxxx in jpgraph.php which names your
font (at the top of the file)
3. Update Class TTF constructor in jpgraph.php with the mapping between your new constant and the <basefilename>
That’s it!
1.5 Using Anti-Aliasing
From version 1.2 JpGraph supports drawing of anti-aliased lines. There are a few caveats in order to use this which is discussed in this section.
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, so for example you would normally make the call
$graph->img->SetAntiAliasing()
to enable this feature. 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.
Note: The algorithm used is quite simple. It would be possible to achieve even better result by doing some real 2D signal processing. However it is my view that doing real time 2D signal processing on a WEB 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. Figure 3 shows a spider graph with ant without anti-aliasing. One thing to keep in mind when deciding to use anti-aliasing is that it could have a potentially dramatic effect on the time it takes to generate the image (compare 0.2s with 2.0, a factor of ten!) (the code for this particular spider graph might be found as spiderex6.php in the Examples directory, (you might want to see how much faster your machine is to my old server, but hey it’s a seven year old machine sitting in my basement and doubling as a firewall as well)
There are also a couple of potential limitations (or gotchas) you probably would like to keep in mind when using anti-aliased lines
1.
Anti-aliases lines are much slower then the normal lines,
roughly 5 times slower per line. Remember that the whole line-drawing algorithm
is implemented in PHP since the underlying graph library (GD) doesn’t support
anti-aliased lines.
2.
Anti-aliased lines uses up more of the available color-palette.
The exact number of colors used is dependent on the line-angle, a near
horizontal or near vertical line uses more colors (number of lines with
different angles uses more colors). Hence it might not be possible to use
anti-aliasing with color-gradient fill since the number of available colors in
the palette might not be enough. A normal palette can keep around 256 colors
(I’m not 100% sure of the exact format used in the JPG, PNG, or GIF standards)
3. Anti-aliased lines will ignore the line width specified. They will always have a width of roughly 1.
1.6
Specifying
timeouts for the cached images
Using the cache can greatly improve performance. However for certain type of graphs the data may be short lived and might have to be updated once in a while. A way to combine this with the effeciancy of a cache is to have a time limit on the cached image. As of ver 1.3 this is now supported.
The timeout is specified as the fourth argument to the Graph::Graph() method and is given in minutes. As long as the cached image is newer then the timeout the cached image is used. If the cached image is older a new image will be generated.
To specify a 5min timeout you would call (for example)
$graph = new
Graph(300,300,"mygraph_01",5);
The same syntax is used for Spider and Pie graphs
$graph = new
SpiderGraph(300,300,"myspidergraph",5);
$graph = new PieGraph(300,300,"mypiegraph",5);
There are two “special” values you can use as a timeout
- 0 Infinite large timeout (the default), the cached image will never be re-generated
- -1 Infinite small timeout, the cached image will always be generated
1.7
Generating images
only to file
As of ver 1.3 it is now possible to just generate the image to the cache and not stream it back to the browser. This is for example useful for batch-processing (using PHP as a script language) and necessary for working with client side image maps, see below. To specify that you don’t wont the image streamed back to the browser you must set the fifth argument to Graph::Graph() to false.
$graph = new Graph(300,300,"mygraph_01",5,false);
When the $graph->Stroke() method is called this will only generate the file “mygraph_01” in the cache directory.
Pleae note that depending on your particular Apache setup you may or may not be able to read from that cache directory directly from a “normal” HTML page. Please check with you local WEB-server guru how your setup works.
1.8
Automatic
generation of client side image maps
Aa a precursor to making client side image map you must make sure that a normal HTML page has access rights to your cache directory. That would normally imply that your cache directory is visible somewhere within the HTTP_ROOT. If you setup allows Apache to follow symbolic links an easy way might be to add a symbolic link to your cache directory (e-g /tmp/jpgraph_cache) or you might be able to persuade your Apache administrator to add an “alias” which points to the jpgraph_cache directory.
It is up to you to figure out how to work with this!
PLEASE make sure that all this is sorted before reading on !
PLEASE also note that this is not anintroduction to HTML client side image maps but assumes you know what this is.
As of ver 1.3 client side image maps are only supported for all types of bar graphs and for pie graphs. Future versions will add support for marks in lineplots as well.
There are basically 3 steps involved in generating the image with the map.
An simple example will make this clear. In this example I
assume that the cache directory is accessible as an alias “/jpgcache/” from the
Apache server.
$datay=array(12,26,9,17,31);
// Create the graph. These
two calls are always required
$graph = new
Graph(310,200,"barcsimex1.png",1,0);
$graph->SetScale("textlin");
$graph->img->SetMargin(60,30,20,40);
// Move the Y-axis title a bit away from the Y-axis
$graph->yaxis->SetTitleMargin(45);
// Have a shadow arounf the image
$graph->SetShadow();
// Create a bar pot
$bplot = new
BarPlot($datay);
// Create targets for the
image maps. One for each column
$targ=array("bar_clsmex1.php","bar_clsmex1.php","bar_clsmex1.php","bar_clsmex1.php","bar_clsmex1.php","bar_clsmex1.php");
// Create alt texts for each target
$alts=array("val=%v","val=%v","val=%v","val=%v","val=%v","val=%v");
// Set the targets and alt texts
$bplot->SetCSIMTargets($targ,$alts);
// Fill color for bars
$bplot->SetFillColor("orange");
// Use a shadow on the bar
graphs (just use the default settings)
$bplot->SetShadow();
// Display the actual value on top of each bar
$bplot->SetValueFormat("%2.1f");
$bplot->ShowValue();
$graph->Add($bplot);
$graph->title->Set("Image
maps barex1");
$graph->xaxis->title->Set("X-title");
$graph->yaxis->title->Set("Y-title");
$graph->title->SetFont(FONT1,FS_BOLD);
$graph->yaxis->title->SetFont(FONT1,FS_BOLD);
$graph->xaxis->title->SetFont(FONT1,FS_BOLD);
// Write the file to the
cache
$graph->Stroke();
// Send backthe image map to the browser
echo
$graph->GetHTMLImageMap("myimagemap");
// … and an image tag
echo "<img
src=\"/jpgcache/barcsimex1.png\" ISMAP
USEMAP=\"#myimagemap\" border=0>";
Some comments:
- In this example we also make use of the possibility to have the actual value of each bar displayed on top of the bar
The resulting image will now look like
Figure 5. Example of image map
1.9
Adjusting
brightness and contrast for images and backgrounds
It is often desirable to have a background image look a little bit “washed” out so it doesn’t take the concentration away from the actual graph. There are basically two ways of accomplish this
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($bright,$contr) to specify a desirable value. Letts show somw examples.
First the original image
Figure 6.
Original image
Using a value of $contrast=-0.8, and brightness=0.4 gives the image
Figure 7. Washed out effect by setting contrast = -0.7 and brightness=0.4
To adjust the overall image you need to use the method Graph:: AdjImage($bright,$contr) . This will affect not only the background image but the whole graph.
Note: The eye’s sensitive is logarithmic and the arguments in the method above are linear. For tht reason there might not be a big visual difference between, say, 0.2 and 0.4.
1.10 JpGraph global defines
In order to control certain behaviours of the library there are a number of DEFINE’s at the top of the file ‘jpgraph.php’. Their purposes are briefly discussed below. The default values for all these constants should be fine for most users of the library. However, “power-users” might want to tweak these, hence this description.
Constant |
Default
value |
Description |
ERR_DEPRECATED |
False |
Should the use if deprecated functions and values give a fatal runtime error? |
BRAND_TIMING |
False |
Should the time taken to generate an image be “branded” in the lower left corner of the image? |
BRAND_TIME_FORMAT |
“Generated
in: 01.3fs” |
The actual format string for the time branding. |
READ_CACHE |
True |
Should JpGraph first look in the cache to see if the image has already been generated? |
CACHE_DIR |
“tmp/jpgraph_cache” |
Location of cache directory. Note this directory must be writable for PHP. |
USE_BRESENHAM |
False |
Should a PHP implementation of the Bresenhams’s circle algorithm be used instead of the built in GD Arc() drawing routine? (Makes circles look aesthetically better in some few cases – the drawback being that do circles in PHP are slower then native GD) |
TTF_DIR |
“/usr/local/fonts/ttf” |
Location for TTF fonts |
DEFAULT_GFORMAT |
“auto” |
Which graphic format should be used (auto, jpg, gif, png) If this value is set to “auto” then the best available format will automatically be chosen. The preferred order is “png,gif,jpg”. |
1.11 Drawing arbitrary graphic shapes using dummy
graphs
Disclaimer: This is an unsupported part of JpGraph.
To make it easy to try out arbitrary graphic drawings with all the normal support of JpGraph (like caching, anti-aliasing etc) you can crate a dummy graph. This will in affect give you a canvas where you can use all the drawing primitives in the Image class.
As usual you need to include both jpgraph.php and also the “dummy” extension “jpgraph_dummy.php”
An example to draw a simple line would be
#include
<jpgraph.php>
#include
<jpgraph_dummy.php>
$graph = new
DummyGraph(300,200);
$graph->img->SetColor(“red”);
$graph->img->Line(10,10,100,100);
$graph->Stroke();
1.12 Utility scripts
Disclaimer: This is an unsupported part of JpGraph.
JpGraph 1.2 comes with two utility script to help with color selection and to automatically generate a test page of images. Please note that this is only tools I use myself which I thought might be useful for someone else. They are not supported in any shape or form!
Automatic generation of
all test images (test-suit)
Running the script “testsuit_jpgraph.php” will generate an index list of all *.php files in the current directory. This is useful if you run this script from the “Examples” directory. It will then generate an index list with a link to all the example images. This is the tool used to manage all regression tests internally in the development of JpGraph.
This script may also be called with a parameter “style” as in
“testsuit_jpgraph.php?style=1”
or
“testsuit_jpgraph.php?style=2”
In the latter case (style=2) the links will be replaced by the actual images. You may then visually inspect all the generated images.
Running the script “gencolorchart.php” will generate (by default in the cache directory) a number of images with color samples and also a theme page. Running the script should generate the following output:
JpGraph color chart
Generating color chart images ...
1. ./jpgraph_cache/color_chart01.gif
2. ./jpgraph_cache/color_chart02.gif
3. ./jpgraph_cache/color_chart03.gif
4. ./jpgraph_cache/color_chart04.gif
Generating color chart index page.
Generating themes...
1. ./jpgraph_cache/theme01.gif [24 colors in theme 'earth']
2. ./jpgraph_cache/theme02.gif [19 colors in theme 'pastel']
3. ./jpgraph_cache/theme03.gif [15 colors in theme 'water']
4. ./jpgraph_cache/theme04.gif [11 colors in theme 'sand']
Generating theme index
page.
Work done in: 3.64 seconds.
See Colorchart
See Index of themes
Figure 8. Output after running gencolorchart.php
The “Colorchart” is simple a page with all the named colors
available in JpGraph. You can see all the colors by following the link
“Colorchart” at the bottom of the page. The reason for braking up the colors in
separate images is just the fact that the maximum number of colors in one image
is limited by the palette size.
Note: This is a good example of the inefficiency of the GIF format as compared to PNG. Each of the above generated GIF images for the color charts are roughly 100K while the corresponding images generated as PNG are only around 13K in size.
The “themes” index is just a collection of colors that make up a certain theme, i.e. “earth”, “pastel” etc. Themes are an upcoming feature in JpGraph 1.3. This utility was just intended to help me to easily view and pick what colors are/should be present in a certain theme. By using a certain theme your graph will automatically draw colors from that theme, so for example all the default colors for the pie slices in a pie graph will be taken from the theme. Please note that the selection of colors in a specific theme is based on my personal judgement and may not agree with you. If you have additional themes you would like to use please send me a note on jpgraph@aditus.nu
As an example the “earth” (a “professional” looking color theme) have the following tentatively composition:
Figure 9. The colors in the "earth" theme (subject to change for 1.3!).
As opposed to the more colorful “pastel”-theme shown below
Figure 10.
The colors in the "pastel" theme (subject to change fror 1.3!)