9/21/2011

Simple JSF Chart Component

Save to PDF

My last project was a conversion project, standalone Swing application to JSF application. Swing renders lot of charts and graphs. To render charts in JSF pages, we need to use some third party components like PrimeFaces. But in our case if we use primefaces, then we need to reiterate the charting usecase from the scratch. Existing swing application used JFreeCharts API to generate charts. I googled a lot to find any JFreeChart based JSF component. But I couldn't find one. Then I decided to create one.

My first and main priority in mind was to develop a JSF component to which I can wrap a JFreeChart. So that I can reuse the same charts which is generated by the swing application in my JSF pages.

Finally I got it working as I desired. So I thought of sharing with you friends.

If you are familiar with JFreeChart API, there is a method called createBufferedImage in JFreeChart class which is the vital method used in this component.

Let me explain how I approached the problem:
  • Generate Charts using JFreeChart API
  • Create a BufferedImage from the generated chart
  • Use javax.imageio.ImageIO class to write this BufferedIamge to ServletOutputStream

First I created a custom JSF custom component called ChatComponent which will collect data needed to generate the chart.

In the above code ChartProcessorFactory is a Factory class to generate different processors whcih can process different type of Charts like Area, Bar, Line etc. I need to develop this a reusable and extensible component. That is why lot of Fatory and generic abstraction layers.

Here is my ChartProcessor interface:

In this blog I will explain how I generated an Area Chart. Now will create a concrete CharProcessor called AreaChartProcessor.


AreaChartProcessor class will collect all the data required to generate an area chart from JSF page using a custom tag.

Once AreaChartProcessor collects all the data, it will generate an appropriate ChartData object (line #24 of AreaCharProcessor) and store it in session. Key for storing this session is generated using component's id attribute. This is for rendering multiple charts on same page.

That is all we are doing in the encodeEnd method of UIComponent. But we have not generated chart yet. We need some process to generate chart from this data before the page is rendered. Here come JSF PhaseListeners handy. I created a PhaseListener to hook BEFORE RESTORE_VIEW event.

Not done yet! Now somebody have to fire a faces request to kick in the PhaseListener. This is done by generating an image component with source pointing to FacesServlet.

Our PhaseListener will retrieve all the ChartData stored in session and will generate charts. To retrieve ChartData, listener needs the key used to store ChartData into session. So I stuffed these keys as URL parameters to the above discussed image (line #45 of AreaChartProcessor).

Once ChartData is retrieved from session, phaselistener will create an appropriate ChartGenerator from ChartGeneratorFactory. ChartGenerator will generate chart from ChartData. From this chart a BufferedImage is created and which will be written to ServletOutputStream.






For source code and library, visit: Google Project Hosting

No comments:

Post a Comment