Have you ever needed to present data to a user with a chart on a browser? If so, then there was a choice you had to make: Do you use a servlet and embed it in an HTML page, or do you do the work on the server and present the ready-made chart to the browser as an image?
This article will show how to add graphical images that are dynamically created on your application server -- and that do not rely on the capabilities of the user's Web browser -- to a Web page. Creating images on the server and streaming them to the Web browser eliminates many potential problems that might be encountered when trying to accommodate multiple browsers running on different operating systems.
A typical use of dynamic chart data could be to show stock price movements; stock prices change frequently and trying to display stock movements to a user for a selected time period could mean processing very large amounts of data. The process for consolidating data for large time periods can be performed by the server, and the relevant data could then be used to produce a dynamic chart for inclusion on a Web page.
The sample code included with this article contains code you can use to create the bar graph shown in Figure 1. This code, along with the process of creating the chart itself (which is detailed inside the code), can be used as the basis for creating other types of images as well.
This article covers the process of setting up, creating, and displaying an image, as opposed to the specifics of how to create a bar chart. Basic knowledge of Java™ and Web applications is assumed.
Figure 1. Browser displaying a bar chart
Servlets seem to be the easiest and most popular choice for performing the task at hand, possibly because they are relatively straightforward to use and easy to get ahold of -- plus, you can download ready-made servlets free from the Internet. However, there are a few problems with the servlet approach:
- You are stuck with the style of the chart that you downloaded.
- You have a potential problem with versions of Java runtimes in which the servlet will run.
- You are relying on the target computer to perform the number crunching necessary to display the chart.
- You have to download the servlet to the target computer, and there may be environmental or other restrictions that prevent this.
The worst case when attempting to use a servlet is that your servlet does not work and you end up with a blank box on your browser.
An alternative to using a servlet is to create the chart on the application server and send it to the browser as an image. This eliminates the concerns with Java runtimes and machine capabilities, and enables you to control the look of your chart.
Creating a chart on the server is a relatively straightforward process:
- Create a BufferedImage object to hold your chart.
- Use the Java AWT libraries to build a chart in the BufferedImage.
- Use the Java JPEG libraries to convert the chart from a BufferedImage to a JPEG image.
- Stream the image back to the browser.
JPEG images are used here because there is built-in support for the generation of JPEG images in the standard Java runtime. It is possible to use other image types, provided you have the supported imaging libraries for the type of image that you want to create.
Before starting the creation of your chart, you will need to set up the values of various parameters that affect the chart, such as the title, values for the axis, the data, and so on. In the sample code, the setting of these parameters is performed using the JavaServer Pages™ Standard Tag Library (JSTL, used for creating dynamic Web content). (See Resources for more information on JSTL.)
To enable the graph to be streamed back to the browser, a simple HTTP servlet needs to be written. The code for the servlet is shown in Listing 1.
Listing 1. HTTP handling servlet
package samp.barchart;
/*
* BargraphServlet
*/
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Simple servlet to handle the HTTP request
*/
public class BarchartServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException {
try {
//Create the producer
BarchartProducer producer = new BarchartProducer();
//Set the content type.
//This needs to be done before calling the producer
response.setContentType("image/jpg");
//Create and return the image
String type = producer.createImage(response.getOutputStream());
} catch (Exception e) {
throw new ServletException(e);
}
}
|
As you can see in Listing 1, the work of creating the chart image is performed in the BarchartProducer code (available in the download file.) This code contains a public method, createImage, which is responsible for generating the chart image and converting it into a .jpg image. The code for createImage is shown in Listing 2.
Listing 2. createImage method
public String createImage(OutputStream stream) throws IOException {
//Initialise the chart variables
initialize();
//Create a BufferedImage to hold the chart and set the parameters
BufferedImage bi = new BufferedImage(
imageWidth + 10,
imageHeight,
BufferedImage.TYPE_BYTE_INDEXED);
chart = bi.createGraphics();
chart.setColor(Color.white);
chart.fillRect(0, 0, bi.getWidth(), bi.getHeight());
//Now draw our chart in the BufferedImage
drawFramework(); //Draw the framework
drawBars(); //Draw the bars
drawTitleAndKey(); //Draw the title and the key
//Finally encode the image to a jpg
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(stream);
encoder.encode(bi);
return "image/jpg";
}
|
The remainder of the BarchartProducer code is responsible for setting the chart parameters and drawing the chart in the BufferedImage object. The parameters for the chart need to be set prior to making the createImage call. The parameters are all set using JSTL calls into BarchartProducer to set the required values and style of the chart (see Resources).
Setting up and displaying the image
The sample ChartView.jsp JSP is used to set up the chart and display it on the browser. All custom properties for the chart are set using calls to the JSTL <c:set .../> method. (The <c:set...> tag is used to set a property on a Java bean that is used in a JSP, and maps one-to-one to properties in the Java bean.)
Using a JSP for server side graphics is not mandatory, but provides a convenient mechanism for setting up data in the chart. The JSP in the sample is used to set values in the client session prior to the creation of the bar chart. (Although not shown in this sample, an alternative would be to directly pass values on an HTTP post to a different HTTP handling servlet using a URL string such as http://.../barchart?bar1=10,bar2=15,bar3=0.)
The data for the sample bar graph is obtained from a random number generator in the GetChartData class. Using JSTL <c:set...> calls, the values from the GetChartData class are read by the JSP and used to set parameters in BarchartProducer before the bar chart is generated. Of course, you can add your own mechanism for obtaining data to display using the GetChartData class.
Listing 3. ChartView.jsp
<%--
This is where we set the custom values of the chart using JSTL
--%>
<%-- Set the size of the chart --%>
<c:set target="${BAR}" property="imageWidth" value="550"/>
<c:set target="${BAR}" property="imageHeight" value="280"/>
<%-- Set the values fot the appearance of the chart --%>
<%-- numberOfValues MUST be set BEFORE any data is set --%>
<c:set target="${BAR}" property="numberOfValues" value="5"/>
<c:set target="${BAR}" property="columnSets" value="1"/>
<c:set target="${BAR}" property="borderFrame" value="0"/>
<c:set target="${BAR}" property="border" value="50"/>
<c:set target="${BAR}" property="yborder" value="18"/>
<c:set target="${BAR}" property="colMargin" value="6"/>
<c:set target="${BAR}" property="grid" value="0"/>
<%-- Set the main title for this chart --%>
<c:set target="${BAR}" property="title">
<fmt:message key="TITLE.CHART.OVERVIEW"/>
</c:set>
<%-- Get the data for this chart --%>
<c:set var="ONE" value="${DATA.dataOne}"/>
<c:set var="TWO" value="${DATA.dataTwo}"/>
.
.
<%-- Set the data values to be displayed for this chart (calls setStrValue(String strValue) method)--%>
<c:set target="${BAR}" property="strValue" value="${ONE}"/>
<c:set target="${BAR}" property="strValue" value="${TWO}"/>
<c:set target="${BAR}" property="strValue" value="${THREE}"/>
<c:set target="${BAR}" property="strValue" value="${FOUR}"/>
<c:set target="${BAR}" property="strValue" value="${FIVE}"/> |
In the JSP, you will see that successive calls are made to <c:set...> to set the values that are being displayed. This maps to the setStrValue(String strValue) method in the BarchartProducer, in which the values are stored in an array.
To enable access to the BarchartServlet class from the JSP, it is necessary to add the BarchartServlet to the list of servlets and JSPs, and an entry to the URL Mappings section of the Web Deployment Descriptor, as shown in Figure 2.
Figure 2. URL Mappings
Finally, when the values have been set, the image is streamed to the browser in the <img /> HTML tag:
<img border='0' src='barchart' ......
You can experiment with the sample bar chart by changing the values of the properties in the JSP. Most of the properties are self-explanatory, and change the properties of the chart as expected.
Other uses for server side graphics
The principle described above is not limited to the production of charts. It can be used to create graphical images of any description on an application server and then convert them to a streamed image for browser presentation. This can be very useful when the graphic being produced is complex and not static, as it allows the server to produce the image dynamically as required, without the need to stream data to a browser-resident servlet.
There are alternatives to using server-side-generated graphics. In addition to using a servlet, the pitfalls of which are described above, there are also several commercially available packages that can produce similar results at a cost. General Public License (GPL) packages are also available, but for simple chart or graphic production, this option may be unnecessarily complex, plus your use of the package would also be subject to the GPL licensing restrictions.
You can also generate browser-side charts in JavaScript™; however, this can be extremely complex when dealing with the multiple browser types and versions, and again relies on the support of JavaScript on the browser.
The sample code supplied with this article contains the source code for displaying the graph shown in Figure 1. The code is contained in an EAR file that can be easily imported into IBM WebSphere Studio Application Developer, or you can unzip the EAR and WAR files to recover the source.
When compiled and run on Websphere Application Server, the code will display a bar chart similar to Figure 1. To run the sample on Websphere Application Server from within WebSphere Studio Application Developer, right-click on ChartView.jsp from the Project Explorer, then select Run on Server and Finish.
Figure 3. Run sample code
When running the sample code in WebSphere Studio Application Developer, you can view the chart by opening a browser at the address http://localhost:9080/WASChart.
This article explained how to use an application server to create a graphical image from dynamic data for streaming to a Web browser. The code required to run on the application server to produce an image was provided, with suggestions on how the image can be customized from a JSP prior to being displayed.
| Name | Size | Download method |
|---|---|---|
| serversidegraphs.ZIP | 475 KB | FTP |
Information about download methods
- A JSTL primer, Part 3: Presentation is everything
- Best Practice: Developing Internationalized Applications for WebSphere V5 using JSTL
- JavaServer Pages Standard Tag Library
- Java Advanced Imaging API documentation
Nigel Morton is a Software Engineer working at Hursley Park in the UK. He has worked for IBM since September 2000 on Business Integration and Web Services projects. Before joining IBM, he worked in both the banking and telecommunications industries, developing integrated solutions and messaging software.
Comments (Undergoing maintenance)





