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:

 

  1. 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 once or a few times.

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

    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.

 

 

 

Different styles of 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

 

Using color gradient bar graphs

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 bitmapped fonts

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

 

True Type Fonts

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

 

Adding new TTF fonts

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.

 

Enabling anti-aliased lines

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)

Anti-aliased “gotchas”

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.

 

  1. Specify the targets and ALT:s text for the map with calls to

    BarPlot:: SetCSIMTargets($targ,$alts);

    The alt text may be specified to disply the actual value of the graph by using a printf() format string. So for example the string “val=%d” will be replace by, for example “val=23” if the value for the bar is 23. You may use any legal printf() format string.

  2. Generate the image as usual but make sure it is generated in batch (off-line) mode so that the image is only written to disk and not streamed back to the browser.

  3. Get the tags or the client side image back with a call to
    Graph:: GetHTMLImageMap($mapname);
    This will return a string starting with “<MAP NAME=$mapname>” and followed by the appropriate areas according to the graph.

  4. Send the image map back to the browser together with a suitable <img> tag to let the browser generate the image. Normally the <img> tag would follow the pattern
    <img src="cache_file_name" ISMAP USEMAP=\"#$mapname\" border=0>

 

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

 

  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 adjsutmnst for contrast and brightness

 

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.

 

Color selection and upcoming support for color themes

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