JFreeChart-integratie in SEAM
SEAM is een applicatieframework van JBoss dat gebruik maakt van bestaande standaarden. Als componentmodel wordt bijvoorbeeld EJB3 gebruikt, JPA of Hibernate dient voor de persistence en als presentatietechnologie wordt JSF toegepast.
SEAM integreert verder nog een aantal andere technologieën, maar in deze blog wil ik me richten op een integratie met JFreeChart.
Er bestaat al een JSF-component om JFreeChart aan te spreken: ChartCreator. In een webapplicatie is voor een afbeelding een tweede HTTP request noodzakelijk. ChartCreator werkt door in de request voor de page de benodigde data op de session te zetten. In de request voor de afbeelding wordt deze data weer van de session gehaald en gebruikt om het plaatje te maken. Persoonlijk vind ik dit niet zo heel fraai, ’session scope’ is bedoeld voor data die wat langer bewaard moet blijven en er bestaat het risico dat de data niet correct wordt opgeruimd (bv. omdat de gebruiker een request afbreekt).
Een ander nadeel van de manier waarop ChartCreator werkt, is dat je in de applicatiecode gebruik moet maken van de JFreeChart classes om de data voor een grafiek aan te leveren. Hiermee wordt de code direct aan JFreeChart gekoppeld. Het genereren van een grafiek is onderdeel van de presentatielaag en het is goed gebruik om de koppeling hiermee zo los mogelijk te houden.
Eisenpakket
Aan mijn eigen component heb ik de volgende eisen gesteld:
- geen API van JFreeChart vanuit de business logic
- alleen ondersteuning voor Facelets, geen JSP-ondersteuning
- geen gebruik van de HTTP session
Waarom geen JSP-ondersteuning? De belangrijkste reden is dat ik het zelf niet gebruik. JSP is eigenlijk niet zo’n goede keus voor JSF (ook al denken veel mensen ten onrechte dat JSF alleen met JSP’s gebruikt kan worden). Als iemand er zin in heeft, kan de code redelijk eenvoudig worden uitgebreid met ondersteuning voor JSP’s. Een goed verhaal over facelets staat op de IBM-website.
Om aan te geven wat ik ongeveer wil bereiken, eerst een fragment uit de source waarmee een ‘barchart’ wordt beschreven:
<g:barChart type="bar3D" width="600" height="320" title="Bar 3D" categoryAxis="Month" valueAxis="Margin" background="255,255,255,128"> <g:categoryDataset value="#{graphBean.data}" var="d" val="#{d.profit}" colKey="#{d.month}" rowKey="Netherlands" color="10,10,10"/> <g:categoryDataset value="#{graphBean.data2}" var="d" val="#{d.profit}" colKey="#{d.month}" rowKey="China" /> </g:barChart>
Hiermee wordt de volgende grafiek beschreven:

In het template worden twee datasets benaderd door middel van de Unified Expression Language. Het eerder genoemde ChartCreator-component wil als dataset graag een implementatie van een JFreeChart-interface hebben. In dit voorbeeld worden echter normale Java-classes gebruikt (POJO’s).
De Java-code ziet er als volgt uit:
@Name("chartBean") public class ChartBean { public List<ProfitData> getData() { List<ProfitData> ret = new ArrayList<ProfitData>(); ret.add(new ProfitData("jan",BigDecimal.valueOf(30))); ret.add(new ProfitData("feb",BigDecimal.valueOf(40))); ret.add(new ProfitData("mar",BigDecimal.valueOf(35))); ret.add(new ProfitData("apr",BigDecimal.valueOf(33))); return ret; } ....
De @Name annotation is om aan geven dat deze class een SEAM-component is. Verder wordt er geen SEAM-functionaliteit gebruikt in dit voorbeeld. De ProfitData class is een eenvoudige class met een getter voor ‘month’ en ‘profit’. Omdat er alleen maar standaard POJO’s gebruikt worden, zou de data ook het resultaat kunnen zijn van een JPA-/HQL-query.
Nu is nog de vraag hoe de data zonder gebruik van de HTTP-sessie gebruikt kan worden bij het genereren van de afbeelding. De oplossing is alle benodigde data in de URL te verpakken. Deze techniek wordt ook gebruikt door Google Chart. Het is zelfs redelijk eenvoudig om Google Chart in plaats van JFreeChart te gebruiken, dit zou voor de applicatiecode geen verschil maken!
Om de afbeeldingen te genereren heb ik een servlet geschreven die alle benodigde data weer uit de URL haalt en er een PNG-afbeelding van maakt. Aangezien alles in de URL staat, is het wel noodzakelijk om teksten te coderen en decoderen met een URLEncoder/URLDecoder, zodat de URL’s geldig blijven als er bijvoorbeeld een ‘&’ in de tekst voorkomt.
Gebruik van de source & voorbeelden
Het bestand jsfchart.zip bevat de sourcecode van de servlet en de JSF componenten.
Om te builden moeten in de lib folder de volgende jars geplaatst worden (deze zitten niet in de download, maar wel allemaal in de Seamdistributie):
- el-api.jar
- jcommon.jar
- jfreechart.jar
- jsf-api.jar
- servlet-api.jar
- jsp-api.jar
Een voorbeeld voor het gebruik staat in ‘examples’. De view-directory bevat een facelet-template en de java-directory de sources om de data beschikbaar te stellen.
Het eenvoudigste is een nieuw project maken met ’seam-gen’ en dan deze bestanden toe te voegen aan het project. De build moet aangepast worden zodat jfreechart.jar, jcommon.jar en jsfcharts.jar in de WEB-INF/lib komen te staan.
Tot slot moet in web.xml het volgende worden toegevoegd:
<servlet> <servlet-name>Chart Servlet</servlet-name> <servlet-class>com.finalist.charts.servlet.ChartServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Chart Servlet</servlet-name> <url-pattern>*.chart</url-pattern> </servlet-mapping>
Conclusie
Met het gepresenteerde component is het eenvoudig om grafieken te gebruiken vanuit Seam of JSF applicaties. JFreeChart biedt echter veel meer mogelijkheden die nu nog niet gebruikt worden. Er kan dan ook zeker nog veel worden verbeterd en worden uitgebreid.
Verdere ontwikkelingen?
- Momenteel worden alleen BarChart en PieChart ondersteund. JFreeChart kent nog veel meer type grafieken, dus hier valt nog wat werk te verzetten.
- Ook biedt JFreeChart veel mogelijkheden om de layout van een grafiek aan te passen. Al deze gegevens aan de URL van de afbeelding toevoegen wordt wel rommelig. Een mogelijke oplossing is een soort stylesheet voor grafieken. Dan kan er in de URL eenvoudig verwezen worden naar een uitgebreide layoutdefinitie.
- JSP-ondersteuning (alleen als het echt nodig is)
- Google Chart-ondersteuning



Ik liep trouwens net tegen http://www.jfree.org/eastwood/ aan.
Levi Hoogenberg - maart 8, 2008 12:41
Dat ziet er goed uit. Dit zou een vervanging kunnen zijn voor de servlet die ik nu gebruik.
Toen ik de blog schreef (december) had ik dat component nog niet gevonden.
Edwin van der Elst - maart 10, 2008 9:50