Inserting Images Into WebFOCUS Graphs

How often have you wanted to give your graphs just a little bit more style, even something as mundane as a company logo or a watermark?
This example of how to do it works for server-side graphics when outputting a graphics format of gif, jpeg, or png, although there do appear to be some issues with SVG. (I have not been able to get it to work with the applet.)
The sample above uses standard API calls from the graph engine and allows you to incorporate gif and jpeg images for any component that you can apply a texture to.
The problem is that the documentation gives you very little help, and as documented in both the 5.3 and 7.1 API manual, it does not appear to work. (I must remember to raise hottracks at some point.)
So How Do We Do It?
The thing to remember when dealing with images is to think of them instead as textures. You will find no mention in the documentation about including images within the graph image.
The reason is that in API terms, an external graphics file is a texture. When you realize that the textures used by WebFOCUS for its texture displays are in fact gif files, the logical conclusion is: if I can use an Information Builders gif, then I can use any gif.
With that starting assumption we can do really stylish things.
The principle API calls that control the display of images (sorry – textures) are:
- setFillType
- setTextureURL
- setTextureDisplayMode
The setFillType API call sets the fill type for an object (all graph components are objects). Possible values as documented are:
- (color) the default
- (gradient)
- (texture)
We need to use texture fill type 3 to be able to insert a gif or jpeg.
So, for example, if we want to set a background image for a graph we need to apply a texture to that object.
For the chart background, the object that we need to modify is ChartBackground using the get method. So the API call that we use is setFillType(getChartBackground(),3);
Once we have set the fill type we can apply our texture.
A texture file is applied in the API by calling setTextureURL and supplying it with the object that you want to apply the texture to and the location/name of your texture file.
Here we hit both a bug and either a second bug and/or a documentation omission.
The documentation tells you to apply the texture file using an example like setTextureURL(object id,"file:/full path to the file");
This does not work. (Nor any of the variants documented for the setTextureURL call).
The only way it works (and this is the possible second bug and/or document omission) is for the file to exist in the javaassist directory of WebFOCUS or a subdirectory of javaassist. So as I use a subdirectory to javaassist called /images/custom the API call then becomes setTextureURL(object id,"/images/custom/ file");
The same method works for all objects and allows you to have a different image for each one. So as in the example, each bar shows a different cartoon cat, it could just as easily be different products, brand logos or anything else.
The only objects that require extra work are annotation objects because you must create these first and place them where you want them. Also for an annotation object you must supply some text even if it's a space as I do (if you do supply text it will appear over your image perhaps a date or version number might be a use for the feature).
The most difficult thing with annotation boxes – and with any repositioned/resized object, in fact – is setting the coordinates correctly. But the documentation on that is almost understandable. Also there have been several posts on the forum giving sound advice.
Basically, two points centered on the center of the graph (when connected by perpendicular lines) give you your box. The main thing to remember, the system is 32k by 32k even if your height is 400 and your width is 600. It's always 32k on each axis for the virtual coordinate system; 0 to -16000 and 0 to +16000.
The final API call setTextureDisplayMode(getSeries(0),0); controls the tiling of the images According to the documentation :
- 0 is stretched
- 1 is tiled
For bars, as an example, it controls whether you have stacked images or whether the images are stretched to fill the bar. (In perhaps another issue, however, I had to reverse the options to get the correct effect.)
That's basically it, and the code sample below shows the full code used to create the example. (Thanks to Google for the base images.)
However, there some more items that you must also attend to.
Your images need to be sized and modified to fit the available space. And/or the graph objects need to be resized. (I would recommend using setPlace(false) as it makes things much easier) In the case of bars for example, explicitly set the bar width using the setRiserWidth(nn); API call and size your images to fit that width wise. When resizing the images (I just use paint) I also edited them to add a bar to the right of them to make them look even better.
Alas, we cannot at the moment use transparent images, which would look really good (especially with the added bar).
The reason, I have been assured, is a cross-platform compatibility issue. Information Builders is working on this, so it may come in the future.
Happy graphing!
The Code
GRAPH FILE CAR
SUM DEALER_COST
ACROSS COUNTRY
ON GRAPH SET LOOKGRAPH VBAR
ON GRAPH SET GRAPHEDIT SERVER
ON GRAPH SET BARNUMB OFF
ON GRAPH SET 3D OFF
ON GRAPH SET VZERO ON
ON GRAPH SET GRID ON
ON GRAPH PCHOLD FORMAT PNG
ON GRAPH SET GRAPHSTYLE *
setFrameDisplay(false);
setRiserWidth(55);
setDataTextDisplay(true);
-*
-* Create the annotation box and
-*
setDisplay(getAnnotationBox(0), true);
setDisplay(getAnnotation(0), true);
setFontSize(getAnnotation(0),6);
setFontStyle(getAnnotation(0), 0);
setTextString(getAnnotation(0), " ");
setTransparentBorderColor(getAnnotationBox(0), false);
setRect(getAnnotation(0), new Rectangle (9000, 5000, 4800,10000));
-*
-* Set the fill type for objects that you want to contain images
to texture
-*
setFillType(getSeries(0),3);
setFillType(getSeries(1),3);
setFillType(getSeries(2),3);
setFillType(getSeries(3),3);
setFillType(getSeries(4),3);
setFillType(getAnnotationBox(0),3);
setFillType(getChartBackground(),3);
-*
-* Set the display mode of you objects to either stretched or tiled
-*
setTextureDisplayMode(getSeries(0),0);
setTextureDisplayMode(getSeries(1),1);
setTextureDisplayMode(getSeries(2),1);
setTextureDisplayMode(getSeries(3),1);
setTextureDisplayMode(getSeries(4),0);
-*
-* Assign your images (textures) to the objects
-*
setTextureURL(getAnnotationBox(0),"/images/custom/garfieldcs.jpg");
setTextureURL(getChartBackground(),"/images/custom/sunset.jpg");
setTextureURL(getSeries(0),"/images/custom/cat32.jpg");
setTextureURL(getSeries(1),"/images/custom/cat4.jpg");
setTextureURL(getSeries(2),"/images/custom/cat2.jpg");
setTextureURL(getSeries(3),"/images/custom/cat1.jpg");
setTextureURL(getSeries(4),"/images/custom/garfield.jpg");
setPlace(false);
ENDSTYLE
ON GRAPH SET STYLE *
PAGESIZE='Letter',
LEFTMARGIN=0.250000,
RIGHTMARGIN=0.250000,
TOPMARGIN=0.250000,
BOTTOMMARGIN=0.250000,
SQUEEZE=ON,
ORIENTATION=PORTRAIT,
TITLETEXT='And Garfield wins by a head',$
TYPE=REPORT,
GRID=OFF,
FONT='TIMES NEW ROMAN',
SIZE=10,
BACKCOLOR='NONE',
STYLE=NORMAL,$
ENDSTYLE
END