Jasper Reports - Gantt Chart

Jasper Reports framework uses JFreeChart, to dynamically generate charts in a Java application. In this post, I'm gonna use the Java beans as data holders and pass a collection of these beans, to the Jasper reporting engine, to dynamically generate these reports. Below is the code for the Java bean:

package com.chetty.reporting.beans;

import java.util.Date;

public class GanttChartBean {
private String series;
private String task;
private Date startDate;
private Date endDate;

public void setSeries(String series) {
this.series = series;
}

public String getSeries() {
return series;
}

public void setTask(String task) {
this.task = task;
}

public String getTask() {
return task;
}

public void setStartDate(Date startDate) {
this.startDate = startDate;
}

public Date getStartDate() {
return startDate;
}

public void setEndDate(Date endDate) {
this.endDate = endDate;
}

public Date getEndDate() {
return endDate;
}
}


And below is the code for the Java class, that holds the business logic for creating these beans:

package com.chetty.reporting.business;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;

import com.chetty.reporting.beans.GanttChartBean;

public class GanttChartBeanMaker {
public ArrayList getGanttChartData() {
ArrayList ganttChartDataList = new ArrayList();

Calendar calendar = Calendar.getInstance();

for(int i=1;i<8;i++) {
calendar.set(Calendar.HOUR_OF_DAY, i*1);

Date startDate = calendar.getTime();

calendar.set(Calendar.HOUR_OF_DAY, i*3);

Date endDate = calendar.getTime();

String series = (i % 2 == 0) ? "High Priority" : "Normal";

ganttChartDataList.add(create(series, "Meeting" + i, startDate, endDate));
}

return ganttChartDataList;
}

private GanttChartBean create(String series, String task, Date startDate, Date endDate) {
GanttChartBean ganttChartBean = new GanttChartBean();

ganttChartBean.setSeries(series);
ganttChartBean.setTask(task);
ganttChartBean.setStartDate(startDate);
ganttChartBean.setEndDate(endDate);

return ganttChartBean;
}
}
And below is the main class, which passes the collection of beans, to the Jasper reporting engine, to dynamically generate the Gantt Chart:
package com.chetty.reporting.engine;

import java.io.FileInputStream;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

import com.chetty.reporting.beans.GanttChartBean;
import com.chetty.reporting.beans.PieChartBean;
import com.chetty.reporting.business.GanttChartBeanMaker;
import com.chetty.reporting.business.PieChartBeanMaker;

import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperExportManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.engine.data.JRBeanCollectionDataSource;
import net.sf.jasperreports.engine.design.JasperDesign;
import net.sf.jasperreports.engine.xml.JRXmlLoader;

public class Reporter {
@SuppressWarnings("unchecked")
public static void main(String[] args) throws Exception {
InputStream inputStream = new FileInputStream ("reports/ganttchart.jrxml");

GanttChartBeanMaker ganttChartBeanMaker = new GanttChartBeanMaker();
ArrayList ganttChartBeanList = ganttChartBeanMaker.getGanttChartData();

JRBeanCollectionDataSource beanColDataSource = new JRBeanCollectionDataSource(ganttChartBeanList);

Map parameters = new HashMap();

JasperDesign jasperDesign = JRXmlLoader.load(inputStream);
JasperReport jasperReport = JasperCompileManager.compileReport(jasperDesign);
JasperPrint jasperPrint = JasperFillManager.fillReport(jasperReport, parameters, beanColDataSource);
JasperExportManager.exportReportToPdfFile(jasperPrint, "c:/reports/ganttchart.pdf"); 
}
}
When you run the code, the following report is generated: Gantt Chart The above report uses a different theme, which is not present in the jasperreports.jar file. To use that theme, you would have to include the 'jasperreports-chart-themes.jar' file. You can find the report design file, for the above report, here: ganttchart.jrxml

13 comments:

  1. Hi, I have a question. I follow your logic, but I am new to reporting and usint Ireport. Where do I put the code for the beans, main class, and data class? Is the data class code for sub reports?

    ReplyDelete
    Replies
    1. iReport is used for designing the reports. You can create a Java/Groovy project and create beans and other classes in some packages. You can then run the project and dynamically create reports. Check the linked report design file to this post and browse the project linked to that.

      Delete
  2. Are you able to add labels to the bars in the GanttChart? If so how?

    ReplyDelete
    Replies
    1. Download the jrxml file, open it in iReport, right-click the chart and check the 'Chart Data' tab.

      Delete
    2. Hi, I tried your tip, but without any result. For the bar label, in the properties I set the visibility to True, set the fg and bgcolor, but the labels for the bars doesn't appear. Do you have maybe any idea? Thanks!

      Delete
  3. I have a problem with bar charts and time series charts. When I fill those with my javabean arraylist I'll get as many charts as I have beans. And they all look the same. I tried reset type Group and reset group "dummy" but doesn't seem to work.

    ReplyDelete
    Replies
    1. It depends on your report design and how you are grouping the data. If you can post your jrxml file, I can try to diagnose the problem.

      Delete
    2. http://pastebin.com/xXZTuJe8

      I tried without groups when Ill get only 1 bean information to all barcharts and if i put reset to report ill get all information to bar charts but multiple same charts..

      Delete
    3. I just checked your report design, which looks like a simple test chart. The chart data is filled, but the "Range Axis" values are not set. Check the "properties" for the chart and set the range axis values accordingly. 'Range axis' is something like the duration (start time - end time) for the chart. Depending on what you want, you can set the properties you need. Check my sample "jrxml" file and the source code for Gantt Chart in the above post and compare it with yours.

      Also, you need to understand how 'Grouping' works. "Reset Type" is something different. If you are passing 10 objects to the Jasper Engine and if there's no grouping or if there's nothing in common, there will be 10 records.

      Delete
    4. But I do have groups and still get as many records as I have objects?

      Delete
    5. Are the objects that are sent to the Jasper Engine, sorted by 'deliveryType' and 'date'?

      Delete
  4. This comment has been removed by a blog administrator.

    ReplyDelete
  5. Hi,
    While running the given code , I am getting below error.

    Exception in thread "main" java.lang.NoSuchMethodError: net.sf.jasperreports.engine.JRChart.getOwnMode()Ljava/lang/Byte;
    at net.sf.jasperreports.chartthemes.spring.GenericChartTheme.setChartBackground(GenericChartTheme.java:1955)
    at net.sf.jasperreports.chartthemes.spring.GenericChartTheme.configureChart(GenericChartTheme.java:335)
    at net.sf.jasperreports.chartthemes.spring.AegeanChartTheme.configureChart(AegeanChartTheme.java:103)
    at net.sf.jasperreports.chartthemes.spring.GenericChartTheme.createGanttChart(GenericChartTheme.java:1438)
    at net.sf.jasperreports.chartthemes.spring.AegeanChartTheme.createGanttChart(AegeanChartTheme.java:301)
    at net.sf.jasperreports.chartthemes.spring.GenericChartTheme.createChart(GenericChartTheme.java:319)
    at net.sf.jasperreports.engine.fill.JRFillChart.evaluateChart(JRFillChart.java:843)
    at net.sf.jasperreports.engine.fill.JRFillChart.evaluateRenderer(JRFillChart.java:808)
    at net.sf.jasperreports.engine.fill.JRFillChart.resolveElement(JRFillChart.java:1384)
    at net.sf.jasperreports.engine.fill.JRFillElement.performDelayedEvaluation(JRFillElement.java:968)
    at net.sf.jasperreports.engine.fill.JRFillElement.resolveElement(JRFillElement.java:1070)
    at net.sf.jasperreports.engine.fill.ElementEvaluationAction.execute(JRBaseFiller.java:2423)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.resolveBoundElements(JRBaseFiller.java:1609)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.resolveGroupBoundElements(JRBaseFiller.java:1680)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillSummary(JRVerticalFiller.java:1074)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportEnd(JRVerticalFiller.java:319)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:158)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:932)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:864)
    at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:88)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:653)
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:969)
    at com.learn.business.ReporterGantt.main(ReporterGantt.java:37)

    can any body help??

    ReplyDelete

Note: Only a member of this blog may post a comment.