Monday, February 4, 2013

Creating BIP Gantt Charts using JFreeChart (cont.)

In my previous post I showed the majors steps for creating a simple Gantt Chart in BI-Publisher using the JFreeCharts API. The purpose of this post is to provide the technical details of the implementation. 
We first need to download the following JAR files:
· jfreechart-1.0.4.jar
· jcommon-1.0.8.jar
· Commons-code-1.5.jar
 
Extension code:
Create a Jdeveloper generic application
Application Name: GanttChart
 
g1


















Click Next to create a project:
Project Name: bip
 
g2

Add a new Java class to the bip project 

g3

I’ve created a Java class that will be packaged as a jar file and copied to the Weblogic folder. The purpose of this file is to:
1) Read in the XML from the BI-Publisher data model:
2) Organize XML data in the format expected by the JFreeChart API
3) Plot the Gantt Chart using the API
4) Return the generated image
5) BI-Publisher renders the image on the report
Update the code in Jdeveloper with the following is the code listing: this is a very crude code intended for testing only
 
/* ======================================
* JFreeChart : a free Java chart library
* ======================================
*
* Project Info: http://www.jfree.org/jfreechart/index.html
* Project Lead: David Gilbert (david.gilbert@object-refinery.com);
*
* (C) Copyright 2000-2003, by Object Refinery Limited and Contributors.
*
* This library is free software; you can redistribute it and/or modify it under the terms
* of the GNU Lesser General Public License as published by the Free Software Foundation;
* either version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330,
* Boston, MA 02111-1307, USA.
package oracle.bip.extensions;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.commons.codec.binary.Base64;
import javax.sql.rowset.serial.SerialException;
import javax.xml.parsers.ParserConfigurationException;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
public class bipExt {
public static String createGantt(NodeList bipXML, String taskName,
String taskStartDate,
String taskEndDate, String title) throws IOException,
SerialException,
ParserConfigurationException, SQLException, SAXException,
ParseException, NullPointerException {
final TaskSeries s1 = new TaskSeries("GANTT");
//Read in the start dates, end dates, task names as lists
ArrayList<String> startDate = new ArrayList<String>();
ArrayList<String> endDate = new ArrayList<String>();
ArrayList<String> taskname = new ArrayList<String>();
// First parameter list is the list of task start dates
for (int i = 0; i < bipXML.getLength(); i++) {
Node node = bipXML.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
NodeList nodelist = element.getElementsByTagName(taskStartDate);
Element element1 = (Element)nodelist.item(0);
NodeList startDateNode = element1.getChildNodes();
String c1=startDateNode.item(0).getNodeValue().toString();
// Extract the canonical dates
startDate.add( c1.substring(0, 9));
}
}
// Second parameter list is the list of task end dates
for (int i = 0; i < bipXML.getLength(); i++) {
Node node = bipXML.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
NodeList nodelist = element.getElementsByTagName(taskEndDate);
Element element1 = (Element)nodelist.item(0);
NodeList endDateNode = element1.getChildNodes();
String c2=endDateNode.item(0).getNodeValue().toString();
// Extract the canonical dates
endDate.add(c2.substring(0, 9));
}
}
// First parameter list is the list of task labels
for (int i = 0; i < bipXML.getLength(); i++) {
Node node = bipXML.item(i);
if (node.getNodeType() == Node.ELEMENT_NODE) {
Element element = (Element)node;
NodeList nodelist = element.getElementsByTagName(taskName);
Element element1 = (Element)nodelist.item(0);
NodeList labelNode = element1.getChildNodes();
String label = labelNode.item(0).getNodeValue();
taskname.add(label);
}
}
BufferedImage chartImage;
bipExt gantt = new bipExt();
// Create the dataset expected by JFreeChart for the Gantt Chart Type
IntervalCategoryDataset dataset =
gantt.createDataset(startDate, endDate, taskname);
// Create the JFreeChart
final JFreeChart chart = ChartFactory.createGanttChart(
title,
"Task",
"Date",
dataset,
true,
true,
false
);
chart.setBackgroundPaint(new GradientPaint(0, 0, Color.white, 1000, 0, Color.blue));
// Render the Chart as an image
final ChartPanel chartPanel = new ChartPanel(chart);
int width=450;
int height=270;
chartPanel.setPreferredSize(new java.awt.Dimension(width, height));
ChartRenderingInfo info = null;
info = new ChartRenderingInfo(new StandardEntityCollection());
chartImage = chart.createBufferedImage(550, 350, info);
byte[] buffered_image = ChartUtilities.encodeAsPNG(chartImage);
String image = new String(Base64.encodeBase64Chunked(buffered_image));
return image;
}
public bipExt() {
}
public static IntervalCategoryDataset createDataset(List sdate,
List edate,
List taskName) throws ParseException {
Iterator iterator = sdate.iterator();
final TaskSeries s1 = new TaskSeries("Schedule");
for (int i = 0; i < sdate.size(); i++) {
String c1;
String c2;
c1=sdate.get(i).toString();
c2=edate.get(i).toString();
s1.add(new Task(taskName.get(i).toString(), new SimpleDateFormat("yyyy-MM-dd").parse(c1),
new SimpleDateFormat("yyyy-MM-dd").parse(c2)));
}
final TaskSeriesCollection collection = new TaskSeriesCollection();
collection.add(s1);
return collection;
}
}

Add the previous 3 jar files to the project 



g5

And create the JAR Deployment file

g6

Once the JAR File is generated, copy it to the place where Weblogic  server expects it 

g8

Log into to BI Publisher and “Change the Disable external references” flag to “False”, it is “True” by default. 

BI Publisher Report:
Create the BI-Publisher data model. For this example, download the ACTIVITIES table from the amis site and create a simple BIP SQL query:
select label,start_date,end_date from activities with the respective XML tag names: LABEL, START_DATE, END_DATE
 
g9

Following is a sample XML data set from the data model 

g10


Create an RTF template using BIP template builder with the following 3 form fields:
1) Namespace:
 
g11

2) Create Gantt:
Call to the Java extension to pass in the XML data from BIP, the XML tag names and title, the result from the call is stored in a parameter called GanttIMG 

g15

3) Display Gantt:
Display the image on the report 

g13

Create a new BIP report using this RTF template and the previous data model.
Run your report, if all goes well: ta-da! 

g16
 
a+
Fiston