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 :-)
The basic structure of an image map script
The standard structure for a HTML page using client
side image maps would be something along the lines of
// Image map specification with name "mapname"
<MAP NAME=...>
... specification ...
</MAP>
// Image tag
<img src="..." ISMAP USEMAP="mapname">
This poses some interesting questions.
Since we normally call the
graphing script directly in the <img> tag how do
we get hold of the image map (which is available only
in the image script> in this "wrapper" script?
In JpGraph there is actually two ways of solving
this.
- Use the preferred "builtin" way using the modified Stroke()
method Graph::StrokeCSIM() instead of the standard Graph::Stroke()
method.
- Directly use the Graph::GetHTMLImageMap() which gives you
fine control at the expense of more complex coding.
The first (and preferred) way modifies the stroke
method so that instead
of returning an image (like the standard Stroke() method)
StrokeCSIM() 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 use it directly
as the target dor the "src" attribute of the
<IMG> tag.
Specifying targets for image map plots
To turn a standard image script into a CSIM
script the first thing you need to do is to supply
the appropriate URL targets for the hotspots
in the image.
What the hotspots represent depends on the type of plot
you are doing. The following plot types support image
maps.
- 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.
The two arguments to this method are
- $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.
Using StrokeCSIM()
The simplest way of creating a creating a CSIM image
is with the StrokeCSIM() method. As mentioned before
this method actually returns a (small) HTML page
containing both the image-tag as well as the image
map specification. Hence you can't use the script
directly in an image-tags src-property.
You can create an CSIM in two ways
- Use the CSIM image script as the target in a standard
anchor reference, for example
<a href="mycsimscript.html">
This has the drawback that your image page will only contain
the image and nothing else.
- The other way let's you include the image in an
arbitrary HTML page by just including the image script
at the wanted place in your HTML page using a standard
"include" php statement. For example
<h2> This is an CSIM image </h2>
<?php
include "mycsimscript.php"
?>
Note:
If you have several CSIM images on the same page you must use
'include_once' in the scripts when you include "jpgraph.php" and the
other jpgraph library files since you will otherwise in effect try to
include these libraries multiple times on the same page and get a
"Already defined error"
The process to replace Stroke() with StrokeCSIM()
is simple. You
just need to make the replacement and supply some
arguments to StrokeCSIM(). The only required
argument is the first which must be the name
of the actual image script file including the
extension. So for example if your image script is
called "mycsimscript.php" you must make the call
$graph->StrokeCSIM('mycsimscript.php')
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.
Examples of Image maps
The examples below shows how different plot types uses
image maps. Please note that none of the URLs in the image
points to any valid page. SO you will get an "404 Page not found" if
you click on the images. A nice feature in most browsers is that if
you hold the pointer on a CSIM point in the image you will see the
alt-tag as a small popup. In these examples that popup is used to
display the value for the particular part of the graph.
Client maps with Bar graphs
Client maps with Pie graphs
Client maps with Scatter graphs
How does StrokeCSIM() work?
Knowledge of the exact technical details of the
way StrokeCSIM() works is probably not needed
by many people but for completeness we outline
those details in this short section.
The fundamental issue we have to solve is that we
must be able to call the image script in two modes.
When the user includes the image script the StrokeCSIM()
method should return the HTML page but when the
image script is later called directly in the image
tag it must not return an HTML page but rather the
actual image.
The way this is solved is by using one HTTP argument
which is passed on automatically when we
use the image script name in the image-tag.
If you look at the generated HTML you will see that
the argument to the src-property of the image tag
is not simply the script name but the script name with a
additional argument.
In the JpGraph internal code this pre-defined argument
is checked for and if it exists the image is send back
and not the HTML page.
The name of this argument is defined by a DEFINE() statement
in JpGraph. The define is _CSIM_DISPLAY.
Getting hold of the image map
In the case where you want to store the image on disk and later use it
in an img-tag you need to get hold of the image map. For this you will have to
use the function
Graph::GetHTMLImageMap()
An example of the use of this is shown below. With these lines the
image will be written to a file. The script then returns a HTML
page which contains the Client side image map and an img-tag which
will retrieve the previously stored file.
$graph->Stroke("/usr/local/httpd/htdocs/img/image001.png");
echo $graph->GetHTMLImageMap("myimagemap001");
echo "<img src=\"img/image001.png\" ISMAP USEMAP=\"#myimagemap001\" border=0>";
Image maps and the cache system
Unfortunately you can't use the automatic Jpgraph cache system together
with client side image maps. The reason for this is that the cache
system would have to be extended to also cache the actual HTML
maps. Without doing this we could not make use of the cached image.
However, as was shown in the previous example you can still manually
store the image in a file and get hod 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.