Flash Charts in JSF

This is the first entry of a series “PrimeFaces Diary” demonstrating the features included in PrimeFaces library. Thanks to my friend Matthias Wessendorf for suggesting the name of the series. This entry is about JSF charting and the solutions provided by PrimeFaces UI component suite.

I’ve done a lot of work about integrating charts and JSF in the past, maybe you’ve heard of “JSF ChartCreator” which uses JFreechart as the underlying engine. Although there’re various types of charts supported, chartcreator lacked interactivity since a chart is displayed as an image.
On the other hand I believe flash really fits well to data visualization requirements since they look cool and allow better user interaction..

In PrimeFaces currently there’re 6 chart components based on flash based YUI charts.

* Pie
* Line
* Column
* Bar
* Stacked Column
* Stacked Bar

Pie Chart

Let’s begin with PieChart, for a fictional data I’ll be displaying the sales of 4 brands last year. Starting point would be to create the Sale class to represent the each section in a pie.

public class Sale {

	private String brand;
	private int amount;

	public Sale() {}

	public Sale(String brand, int amount) {
		this.brand = brand;
		this.amount = amount;
	}

	public String getBrand() {
		return brand;
	}
	public void setBrand(String brand) {
		this.brand = brand;
	}

	public int getAmount() {
		return amount;
	}
	public void setAmount(int amount) {
		this.amount = amount;
	}
}

Next thing to do is to create the actual data in a JSF backing bean.

public class SalesDisplay {

	private List<Sale> sales;

	public SalesDisplay() {
		sales = new ArrayList<Sale>();
		sales.add(new Sale("Brand 1", 540));
		sales.add(new Sale("Brand 2", 325));
		sales.add(new Sale("Brand 3", 702));
		sales.add(new Sale("Brand 4", 421));
	}

	public List<Sale> getSales() {
		return sales;
	}
}

Data is ready now, so let’s add the chart to the page.

<p:pieChart value="#{salesDisplay.sales}" var="sale" categoryField="#{sale.brand}" dataField="#{sale.amount}" />

Output of this example would be;

pie1

Line Chart

Second example is about linecharts and multiple series support. For the line chart example, I’ll be using another fictional data
the number of girl-body births last years. Like the pie chart example, a Birth class is needed to represent the model.

public class Birth {

private int year;
 private int boys;
 private int girls;

public Birth() {}

public Birth(int year, int boys, int girls) {
 this.year = year;
 this.boys = boys;
 this.girls = girls;
 }

public int getYear() {
 return year;
 }

public void setYear(int year) {
 this.year = year;
 }

public int getBoys() {
 return boys;
 }

public void setBoys(int boys) {
 this.boys = boys;
 }

public int getGirls() {
 return girls;
 }

public void setGirls(int girls) {
 this.girls = girls;
 }
 }

Now the Birth class is ready, let’s create the data.

public class BirthsDisplay {

private List births;

public BirthsDisplay() {}

public BirthsDisplay() {
 births = new ArrayList();
 births.add(new Birth(2004, 120, 52));
 births.add(new Birth(2005, 100, 60));
 births.add(new Birth(2006, 44, 110));
 births.add(new Birth(2007, 150, 135));
 births.add(new Birth(2008, 125, 120));
 }

public List getBirths() {
 return births;
 }
 }

LineChart supports multiple series and each series is nested with the p:series component.

<p:lineChart value="#{chartBean.births}" var="birth" xfield="#{birth.year}">
<p:chartSeries label="Boys" value="#{birth.boys}" />
<p:chartSeries label="Girls" value="#{birth.girls}" />
</p:lineChart>

You can add as many series as you want, out of this line chart is;

line1

Extreme Makeover

It’s very likely that we need to customize the chart look and feel that our client would like:) For that there’re a couple of powerfull style attributes.
Since charts are flash based CSS styling doesn’t play well, so we’ll be using a javascript object created with the object notation. If you heard of the tv show Extreme Makeover, we’ll doing something similar here:) Our candidate is column chart displaying the births used in linechart example;

<p:columnChart value="#{chartBean.births}" var="birth" xfield="#{birth.year}">
<p:chartSeries label="Boys" value="#{birth.boys}" />
<p:chartSeries label="Girls" value="#{birth.girls}" />
</p:columnChart>

column3

Above is plain column chart, the makeover material is as follows;

var chartStyle = {
				padding : 20,
				border: {color: 0x96acb4, size: 8},
				background: {
					image : "../design/bg.jpg"
				},
				font: {name: "Arial Black", size: 14, color: 0x586b71},
				dataTip:
				{
					border: {color: 0x2e434d, size: 2},
					font: {name: "Arial Black", size: 13, color: 0x586b71}
				},
				xAxis:
				{
					color: 0x2e434d
				},
				yAxis:
				{
					color: 0x2e434d,
					majorTicks: {color: 0x2e434d, length: 4},
					minorTicks: {color: 0x2e434d, length: 2},
					majorGridLines: {size: 0}
				},
				legend: {
					display: "right"
				}
			};

			var boysSeriesStyle =
				{
					image: "../design/column.png",
					mode: "no-repeat",
					color: 0x3399FF,
					size: 35
				};

			var girlsSeriesStyle =
			{
				image: "../design/column.png",
				mode: "no-repeat",
				color: 0xFF66CC,
				size: 35
			};

Apply this style;

<p:columnChart value="#{chartBean.births}" var="birth" xfield="#{birth.year}"  style="chartStyle">
<p:chartSeries label="Boys" value="#{birth.boys}" style="boysSeriesStyle"/>
<p:chartSeries label="Girls" value="#{birth.girls}" style="girlsSeriesStyle"/>
</p:columnChart>

The good looking column chart after extreme makeover;

skinnedcolumn1

Upcoming Features
There’re two features I’m planning to add to PrimeFaces chart components soon, one is interactivity so when users
click on a series, we can be notified of these actions via ajax, second feature is polling, suppose you’ve a chart displaying the stock market
and chart data is refreshed in 10 seconds interval.

Live Demo
The examples I’ve given can be reached at the online demo PrimeFaces.

One Response to Flash Charts in JSF

  1. Pingback: Interactive JSF Charts « Cagatay Civici’s Weblog

%d bloggers like this: