Tuesday, August 25, 2009

JFreeChart - Easy way to include Graphics






I have used JFreeChart to setup some charts on my Web application . The app was built using J2EE framework . Example from my Project shown above, the code sample below shows the Aggregate image that's generated on the fly based on the input
Green - if percent is less than 33
Orange - if percent is less than 66
red - if percent is over 66


1 . Setting up , is fairly simple . Download the required files from http://www.jfree.org/jfreechart/download.html and include in the WEB-INF/lib directory . I have used 1.0.1 version.

2. Setup your utility class that generates the image on the fly ( Bar chart in this case ) . You have to go through the api's and do a lot of tries to get the image that works as per your specifications.
Here is the example code for the 3D graph , as shown in picture above

import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import org.jfree.chart.ChartPanel;


/**
* Creates a 3D Graph bar based on the percent
*/
public class Treepercent extends ChartPanel {



public Treepercent(JFreeChart chart)
{
super(chart);
}


public static Treepercent createChart(String title,double dPercent,String sTree,String sFrac)
{
CategoryDataset dataset = createDataset(dPercent,sTree);
JFreeChart chart1 = createChart(dataset,sTree,dPercent,sFrac);
ChartPanel chartPanel = new ChartPanel(chart1, false);
chartPanel.setSize(new Dimension(50, 27));
chartPanel.setBounds(10,10,15,100);
//setContentPane(chartPanel);
Treepercent tp = new Treepercent(chart1);
return tp;
}


public static CategoryDataset createDataset(double dPercent,String sTree) {

// row keys...
String series1 = "First";

// column keys...
// String category1 = sTree;
String category1 = "";
// create the dataset...

DefaultCategoryDataset dataset = new DefaultCategoryDataset();
dataset.addValue(dPercent, series1, category1);
return dataset;

}

/**
* Creates a sample chart.
*
* @param dataset the dataset.
*
* @return The chart.
*/
public static JFreeChart createChart(CategoryDataset dataset, String sTree,double dPercent,String sFrac) {

// create the chart...
JFreeChart chart = ChartFactory.createBarChart3D(
"", // chart title
"", // domain axis label
"Aggregate "+String.valueOf(dPercent)+" Percent ("+ sFrac+")", // range axis label
dataset, // data
PlotOrientation.HORIZONTAL, // orientation
false, // include legend
true, // tooltips?
false // URLs?
);
// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...

// set the background color for the chart...
chart.setBackgroundPaint(Color.white);

// get a reference to the plot for further customisation...
CategoryPlot plot = chart.getCategoryPlot();
plot.setBackgroundPaint(Color.lightGray);
plot.setDomainGridlinePaint(Color.white);
plot.setDomainGridlinesVisible(true);
plot.setRangeGridlinePaint(Color.white);

// set the range axis to display integers only...
final NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setRange( 0.0D, 100D );
rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());

// disable bar outlines...
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setDrawBarOutline(true);

//renderer.setLegendItemToolTipGenerator( new StandardCategorySeriesLabelGenerator( "Tooltip: {0}" ) );
// renderer.setBaseItemLabelsVisible(false);
// set up gradient paints for series...

GradientPaint gpGreen = new GradientPaint(
0.0f, 0.0f, new Color(0, 64, 0),
0.0f, 0.0f, new Color(0, 64, 0)
);

GradientPaint gpOrange = new GradientPaint(
0.0f, 0.0f, new Color(220, 124, 9),
0.0f, 0.0f, new Color(220, 124, 9)
);
GradientPaint gpRed= new GradientPaint(
0.0f, 0.0f, Color.red,
0.0f, 0.0f, Color.red
);

if (dPercent <= 33) renderer.setSeriesPaint(0, gpGreen); else if(dPercent <= 66) renderer.setSeriesPaint(0, gpOrange); else renderer.setSeriesPaint(0, gpRed); CategoryAxis domainAxis = plot.getDomainAxis(); domainAxis.setLabel(""); domainAxis.setCategoryLabelPositions( CategoryLabelPositions.STANDARD ); // OPTIONAL CUSTOMISATION COMPLETED. return chart;
}

}


3. Next is to setup a servlet or a screen class that would generate the image . Remember the servlet the image itself as bytes .

import org.jfree.chart.ChartUtilities;
....

public class generatechart extends ... {

screenmethod (....)
{
ChartUtilities.writeChartAsJPEG( os, 100, Treepercent.createChart("Aggregate",dPer,"",sFrac).getChart(), 300, 75 );
// this create a chart based on the numbers sFranc
}
}


4. Setup a template a JSP or Velocity template , It will be a empty file .

5. Test if the image is generated