In order to start running the examples given in this article, you need JDK 1.2 or higher ( http://java.sun.com ). You will also need a web server that supports JSP. I tested this example on Tomcat, where I used the com.sun.image.codec.jpeg class (released in the Sun Java 2 SDK) to encode the graphics data.
Since you want to have reusable backgrounds, you should create a Java class to manage the layout, including the title area and outer borders. As shown in Figure A.
Figure A
As you can see, I've shadowed both the title area and the outer border. The title has a white, one-pixel wide border, and the graphics area has a thin black border. These borders add definition to the shadows.
Boundaries are easy to create. Use the Fill() method of the Graphics2D object to fill a blue title rectangle, and then use the draw() method to draw the border with another color.
Creating a shadow effect is also very simple. First, use the fill() method to draw a shadow. Then, draw the title at an offset of seven pixels. This offset creates a three-dimensional effect, which results in the shadow effect.
Suppose there is a company that sells agricultural products and it needs a histogram to show sales. In a practical application, we would need to obtain this data from a database or XML file, but for simplicity, let's assume that the sales data is stored in the following two arrays:
String datanames[] = {"apple", "orange", "peach", "lemon", "grapefruit"};
int datavalues[] = {11, 62, 33, 102, 50};
The first array holds items for various agricultural products sold by the company. The second array is the sales volume corresponding to each agricultural product.
The histogram will be displayed and saved in JPEG format, so we need to set the MIME, the content type, correctly. Browsers use MIME types to decide how to react. The following code sets the MIME type:
response.setContentType("image/jpeg");
Next, we need an object that represents the image. The Java 2D API supports the BufferedImage class, which provides a way to save and manage pixel data in memory. We want the graphics to be in color, so we use the TYPE_INT_RGB graphics type. The two integer data WIDTH and HEIGHT are used to specify the width and height of the image in pixels:
BufferedImage bi = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
Now that we have a BufferedImage object, we can set the contents of Graphics2D by calling the object's createGraphics() method:
Graphics2D biContext = bi.createGraphics();
The programmer who created the graph needs to set the WIDTH parameter based on the importance of the graph and the overall layout of the page. Graphic elements automatically resize themselves according to changes in graphic width.
The width and bounding area of the title, as well as the longest straight square of the graphic, need to be calculated based on the WIDTH parameter. The purpose of this is to ensure that all graphic elements do not exceed the width of the graphic and cross the right border of the graphic.
The number of data items that need to be displayed determines the HEIGHT parameter of the graph. If new elements are added to the datavalues[] and datanames[] arrays, the height of the graphic should grow accordingly to accommodate the required display area size.
The maximum parameter is used for the longest straight square. Then, the widths of other rectangular blocks are calculated relative to the maximum :
int barWidth = (innerWIDTH * currentValue) / maximum;
The above algorithm uses the two values of maximum and the innerWIDTH (graphic area) of the graphic to ensure that the rectangle will automatically expand and contract as the WIDTH value changes.
In order to display the graphic, we need to create a background image and then add the graphic data. First, create a graphBG object and call its draw() method:
graphBG gr = new graphBG();
gr.draw(biContext, WIDTH, HEIGHT, "Farm Produce", "Overall Average: " + average);
The parameters of the draw() method include graphic content, biContext , WIDTH and HEIGHT , which the graphBG class uses to determine the width and height of the title and graphic area. Finally, the average data value is calculated and added to the text displayed in the title.
The vertical coordinate (y-axis) position of each rectangular block is calculated according to the following formula: y_pos = i * displayHeight + headerOffset . The displayHeight is equal to the height of the text on the straight square plus the height of the straight square, and headerOffset represents the vertical distance from the top of the graphic, including the height of the title area and shadow.
I created these rectangles and their borders using the same technique I used to create the title borders earlier. I subtracted one pixel from the width and height of the rectangle borders so that each rectangle appears to have a red border, and made the subtraction effect easy by drawing the inner borders on a white background. .
We have created the image in memory, now we encode it and display it to the user. We cannot use the default JSP output stream to process JPEG, so we need to use response.getOutputStream() to get the stream from the response object. We can use the output stream to create a JPEGImageEncoder object and call its encode() , passing the BufferedImage object we created earlier:
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(output);
encoder.encode(bi);
The resulting image is relatively small, occupying only 13.7 kilobytes of capacity. Figure B gives the final effect:
Figure B
In either case, the output of index.jsp is a JPEG image. You can save it to your desktop or press the PrintScreen key to take a screenshot. If you need to display multiple graphics on the same page or introduce graphics into other content, you can use the HTML img tag (< img src = ”index.jsp"> ), and then place the graphics when needed, such as Use a form.
Perhaps one of the oldest Internet technologies for dynamically generated graphics can perform tasks other than displaying an image. Imagine that you need to record the number of viewers of this image (similar to recording the number of clicks on an advertisement), then you need to implement tasks such as click counting, database or file access in index.jsp , and you can process these tasks in the background. There is no need to use buffered page switching to the user.
In this paper we examined a method that produces neat, pleasant-looking histograms. We skillfully handled changing the size of the graphics and encoding them into JPEG format, and discussed modifying the HTML code to place the resulting images in different locations on the page.