Integrating JFreeChart to ZK Framework, Part II

From Documentation
DocumentationSmall Talks2006JuneIntegrating JFreeChart to ZK Framework, Part II
Integrating JFreeChart to ZK Framework, Part II

Author
Henri Chen, Principal Engineer, Potix Corporation
Date
June 22, 2006
Version


This article is the second part of the series regarding how to provide charting capability to ZK. I would suggest reading the previous smalltalk Integrating JFreeChart to ZK Framework, Part I first so you have a much more complete understanding.

In the previous smalltalk, we have illustrate how to show a chart on the ZK. This article would then focus on how to make the chart a more responsive one. For example, in some application, the end user would generally read the analysis chart first. Then when he/she found something interesting on the chart, he/she can drill down that specific point by simply clicking on that part of chart. And the application should then responds the request and provides more detail information to the end user.

OK, then how to do that?


Getting start

If you have read the previous smalltalk, you probably have known how to make JFreeChart works with ZK. However, I would repeat the procedures here again to make it a complete set. For those already known how to get started, you can skip this section.

To make JFreeChart works with ZK, you have to go to JFreeChart download page. Download the latest version and unzip it to a directory. In the $JFREECHART$/lib subdirectory, find jcommon*.jar and jfreechart*.jar. Copy them to shared/lib of your Tomcat (The same place with other ZK jars). Or you can copy those two files to your project's WEB-INF/lib along with other ZK jar files.

The < imagemap> and < area> components

In previous smalltalk, we use the < image> to show the chart image. However, to make the chart a responsive one, we would now need the < imagemap> and < area> components. These two components are in fact the ZK's counter parts to the HTML's map and area tags. In a traditional HTML page, map and area tags are used to mark an image into several hotspots. Each hotspot is associated with a hyperlink address. When an end user clicks on a hotspot of the image, the browser would jump to the HTML page of the specified hyperlink. The ZK's imagemap and area components almost do the same thing. The only difference is that ZK does it the Ajax way. When the end user click on the hotspot of the image, an onClick mouse event would be fired to the imagemap, telling that which area (identified by the area's id) has been clicked on and then the imagemap onClick event listener does what the application developers told it to do.

In ZK, the function of the < imagemap> component is almost the same as the < image> component. The only difference is that the < imagemap> component allows < area> components as its children. That is, what you can do to the image that you can do to the imagemap. So you still can setContent() of an image stream to an imagemap component as you can setContent() to an image component. There is no problem with the imagemap component.

The < area> component is where you really mark a hotspot of an image. You can mark a rectangle area, a circle area, or a polygon area. In a chart, the hotspots that are interesting are apparently the bar in a bar chart, the slice in a pie chart, and the xy point in a line chart, etc. Then, how to mark those hotspots?


The key question: How to mark a hotspot?

Since we are using a charting engine to draw a chart, all these hotspot information is therefore embedded in that charting engine. The JFreeChart does a very good job on this. It will export these information in a class named ChartRenderingInfo. A developer simply provides the API a ChartRenderInfo object and the JFreeChart engine would fill out the hotspots information for you automatically.


The example

We still use the previous PieChart3D chart as our example. All the code is almost the same as the previous one. The different part is when the chart is really drawn on the BufferedImage. Here we provide the API a ChartRenderingInfo object.

  ChartRenderingInfo info = new ChartRenderingInfo();
  BufferedImage bi = chart.createBufferedImage(500, 300, BufferedImage.TRANSLUCENT, info);


And now we need to generate <area> component based on the retrieved ChartRenderingInfo. Each entity in the EntityCollection represents a slice of the pie. The coordinates and the shape type are already prepared by the JFreeChart engine. We just have to copy it over to ZK's area component. And then we set the area's id as the combination of imagemap's id plus an index number so when the onClick event is fired, we know which area is clicked on. Finally, we set area's tooltiptext the dataset's key name.

  for(Iterator it=info.getEntityCollection().getEntities().iterator();it.hasNext();) {
    ChartEntity ce = ( ChartEntity ) it.next();
    if (ce instanceof PieSectionEntity) {
      Area area = new Area();
      area.setParent(myimage);
      area.setCoords(ce.getShapeCoords());
      area.setShape(ce.getShapeType());
      area.setId(myimage.getId()+'_'+((PieSectionEntity)ce).getSectionIndex());
      area.setTooltiptext(ce.getSectionKey().toString());
    }
  }


After areas are created and appended onto imagemap, the hotspots are marked. As in the previous smalltalk, we encode the BufferedImage into png image stream byte array, wrap it as an AImage, and show the image onto the browser.

  byte[] bytes = EncoderUtil.encode(bi, ImageFormat.PNG, true);

  AImage image = new AImage("Pie Chart", bytes);
  myimage.setContent(image);


Testing

Move over the mouse pointer on each slice of the pie chart, you should see the tooltiptext popup. Click on a slice, a message window would popup telling which slice is clicked on. A real application implementation might draw another chart showing the trends of that language over time or something else useful. Here we just show the concept.

  <imagemap id="myimage">
    <attribute name="onClick"><![CDATA[
      if (event.getArea() != null) {
        alert(self.getFellow(event.getArea()).getTooltiptext());
      }
    ]]></attribute>
  </imagemap>

Jfreechart2.gif


Summary

Making a responsive chart add only 10 more lines of code to the previous one. The ZK's imagemap and area components provide the vehicles to mark the chart's hotspots; while the JFreeChart provides excellent APIs to simplify that process. All that added is one more step only:

  • Prepare the dataset.
  • Use chart engine to create the chart per the prepared dataset.
  • Draw the chart on a BufferedImage providing a ChartRenderingInfo.
  • Generate area to mark chart hotspot per the retrieved ChartRenderingInfo.
  • Use encode engine to encode the BufferImage into image stream byte array(png format in our example).
  • Wrap the stream as an AImage and setContent() of the ZK's < imagemap> component.


The whole example source code can be copied to the demo Source pane and press "try me" button to view the result. Remember to copy those two JFreeChart jars into the Tomcat's shared/lib directory first and reboot Tomcat.

We use the PieChart3D as our example, but the same procedures can be apply to other types of chart as well. The ZK team will finally integrate all charting capabilities into charting components that developer can use seamlessly just like using other ZK components.




Copyright © Potix Corporation. This article is licensed under GNU Free Documentation License.