Mark Lorenz on Technology

Wednesday, February 22, 2006

BIRT Tips for Java Developers


As I've used BIRT (Business Intelligence and Reporting Tools) over the last few months, I've collected some lessons learned. I'm hoping these can save some future newbies the pain of learning the hard way.

Background
BIRT is an open source (free) framework for designing and generating HTML and PDF reports from the Java Eclipse platform. BIRT 2.0 was released in January 2006.

Highlights:
  1. WYSIWYG drag and drop design layout tools and templates
  2. Control of attributes such as font, alignment, and color via settings as well as JavaScript
  3. Sorting, grouping, subtotals
  4. POJO (via scripting), XML, JDBC, JDO, and Hibernate data sources, also with DnD
  5. Bar, pie, line, scatter charts in 2D and 3D
  6. Multi-page PDF and HTML output with headers and footers
  7. Fully integrated with Eclipse
  8. Very active development community
Prerequisites:
  1. Eclipse 3.1+
  2. Open source Eclipse plugins:
  • Graphic Editor Framework (GEF)
  • Eclipse Modeling Framework (EMF)
  • iText (PDF framework built on top of FOP)
  • Apache Axis (SOAP support)
Strengths:
  1. Easy to use, fast report development (approx. 20 common LOC + 10-15 LOC per report type + design file for each report)
  2. Powerful components with wide range of settings and customization via scripting
  3. Free while still offering paid support for those that want it
  4. Virtually any input is supported, including business object state data and DB query results
  5. Good, responsive support (bugzilla, newsgroup, tutorials, example code, online help)
  • Actuate offers a commercial version with service level agreements for those projects that need better support
Weaknesses:
  1. Installation is not automated (will be resolved in the 2.1 release in summer of 2006)
Tips

Logging
  • BIRT is using the 1.4 logging package. To change the logging level, you need to edit the logging.properties file in the /lib directory that you are running off of.
     Change the line:
    .level= INFO
    to something else, like:
    .level= WARNING
     
Dates
  • To output the current date, you can use a text element (specified as HTML/Dynamic type) and type the following expression:
     <value-of format="MM/dd/yyyy hh:mm:ss">new Date()</value-of>
     
Threads
  • BIRT supports multi-threaded application. ReportEngine is the primary entry point for most applications to integrate with BIRT. It is designed to be thread-safe. When you work with BIRT engine, there are a few key concepts needed to be aware of:

    1. engineConfig, which holds the engine configurations for the current report engine instance. It is not thread safe. So the application should have the engineConfig set for the report engine object before launching any worker threads to execute engine tasks.

    2. engineTask, which represents the report generation/rendering operation. In a standalone application, each engine task should be assigned to a worker thread to execute. In case of BIRT viewer, the viewer servlet thread is the worker thread. So there is no thread safety issue for engineTask itself.

    3. IReportRunnable, represents the report design. It's thread safe. You should be able reuse a cached report design for different engine tasks.

    BIRT report viewer itself is multi-threaded application. You can look to BIRT viewer code for details on how to use BIRT engine API.
Master Page footer
  • You can insert only one top-level element in the header or footer. Because
    there's already a date element in the footer, you can't insert the page
    element.

    If you want only the page element, delete the date element first, then
    insert the page element.

    If you want to insert multiple elements, delete the date element first,
    insert a grid, then insert as many elements as you want in the grid
    No data set fields on the master page.
Here's how to put a page number on all pages: have the following line as the only script on the Master Page footer:
                       - <value-of>pageNumber</value-of> -
Browser
  • If you are using Firefox, artwork files should be referenced with relative paths - absolute paths will work in IE but not in Firefox:
               E.g.: "./images/filename.jpg"

Conditional Coloring on Charts
  • Here's the script I associated with my chart to conditionally color a bar based on a marker value:
    function beforeDrawDataPoint(
    dataPointHints, fill, scriptContext ){

    val = dataPointHints.getOrthogonalValue();
    chart = scriptContext.getChartInstance();
    marker = chart.getAxes().get(0).getAssociatedAxes().get(0).getMarkerLines().get(0).getValue().getValue();
    if (val > marker) //crosses marker?
    fill.set(255, 0, 0); //yes - display in red
    else
    fill.set(0, 0, 255); //no - display in blue

    }
More tips coming soon...

Resources


8 Comments:

  • I have found BIRT very helpful for designing reports. I have one problem though. I need to get the record count in the data set using a jdbc Data Source. Is that possible in BIRT? I am unable to locate any help forum for BIRT. Any help would be appreciated.

    By Blogger Sabya, at March 09, 2006 1:56 AM  

  • Hi Sabya. BIRT supports basically any SQL queries. You can post questions about BIRT at the BIRT Newsgroup.

    See you on the web!
    Mark

    By Blogger Mark, at March 09, 2006 8:01 AM  

  • Nested datasets

    This is a workaround for the 2.0.1 release. It should be handled and documented better in a future release.

    If you use nested datasets and are having problems with the values not being correct, here is what to try:

    In the inner dataset's "open" or "fetch" scripts (depending on your design), use a reference to rows[n] where "n" is 0 for datasets nested one level or 1 for two levels of nesting or ...

    Here's an "open" script for a dataset that is two levels down (i.e. third set used to populate a List or Table inside another List or Table which is in turn inside another List or Table (whew):

    iActivities = rows[1].activities.iterator();

    By Blogger Mark, at March 14, 2006 1:03 PM  

  • I found your tip on dynamically setting colors useful, and I am doing a similar thing:

    function beforeDrawDataPoint( dph, fill, context ){

    if (dph.getSeriesDisplayValue() == 'Ok')
    {
    fill.set(255, 0, 0);
    }

    etc.

    The only problem is that now the colors in my legend don't match the colors in my chart. Do you have any idea to take care of that?

    I suspect it's within the beforeDrawLegendEntry function, but I don't know how to get a handle on the boxes holding the legend colors.

    Thanks!

    By Blogger Dan, at May 31, 2007 7:54 PM  

  • Hi Dan. I would have thought BIRT would handle this for you.

    The only suggestion that comes to mind is to call chart.getLegend() and work with the Legend object. See:

    org.eclipse.birt.chart.model.layout.Legend
    http://help.eclipse.org/help31/index.jsp?topic=/org.eclipse.birt.doc/chart/api/org/eclipse/birt/chart/model/Chart.html

    Best of luck!
    Mark

    By Blogger Mark, at June 01, 2007 2:17 PM  

  • Thanks for your reply.

    I think BIRT will take care of it for you if you actually change the colors associated with the Series object, but it seems like beforeDrawDataPoint is very specific to the actual rendering.

    I tried looking at the Legend object per your suggestion, but I don't see any handle to the actual box that contains the color in the legend. I guess I don't know what that legend box is called in BIRT terminology.

    By Blogger Dan, at June 04, 2007 4:29 PM  

  • Try this code, it should work:

    function beforeDrawLegendItem(lerh, bounds, icsc)
    {
    lerh.getFill().set(255, 0, 0);
    }

    The reason the legend doesn't automatically change the color is that in some case, you just want to highlight one point, but the remaining of the series stays with the same color.

    David

    By Blogger David Michonneau, at August 01, 2007 11:39 AM  

  • Hi,

    I am actually working with BIRT and kinda just starter.

    My project requirement is use BIRT reports and present the same to end user. I have prepared various BIRT reports as expected by the End User, and are made using Eclipse IDE. Now I want to deploy at client side and I am stuck up. I don't know where/how BIRT reports will fetch the Database connection string and database related information. I am looking to generalize that Database connection issue, rather hard code any where in report. !!!

    Secondly, I need to understand how to deploy them into the web application. I am thinking to give a link, will it be wise to just give a link for the BIRT reports in .jsp pages ?

    I would appreciate if you could tell me how that could be possible.

    Thanks,
    Pranav

    By Blogger Cool Space..., at November 03, 2007 11:47 AM  

Post a Comment

Links to this post:

Create a Link

<< Home