Friday, May 11, 2012

Add Values to a BIRT Chart

When building reports that contain Charts, the BIRT data engine is responsible for creating the chart series data points. These data points are generally tied to BIRT data sets or cubes. While these mechanisms handle a lot of the grouping an aggregation of the data to be charted it may be desirable to add some manual data points to the chart. Fortunately this can be done with a fairly simple chart script event handler. If you have not done any chart scripting before, you may want to read over this post on scripting.

Chart event handlers are fired on the server and can be written in Java or JavaScript. The event order is listed in the post described earlier. The before and after DatasetFilled events are fired first. These events are fired for every runtime series that will be plotted. For example if you have one bar series, these events will be fired once for the category series values and once for the bar series values. If you use optional grouping, these events will be fired for every optional group the data engine encounters. The afterDataSetFilled event handler is passed a reference to the current series and the data set that will be used by the chart engine. This is an ideal location to change values, check for nulls or add values to the chart.
Lets assume we have the following Chart:

Generic Chart
This chart contains one bar series with four data points. In this example the afterDataSetFilled event will be fired twice, once for the category values and once for the bar series values. We can then use the following script to add a value to the beginning and the end of the series.
function afterDataSetFilled(series, dataSet, icsc)
{
	importPackage( Packages.java.util );
	importPackage(Packages.java.lang);	
	importPackage( Packages.org.eclipse.birt.chart.model.type.impl );
	importPackage( Packages.org.eclipse.birt.chart.model.data.impl);
      var list = dataSet.getValues();
	var narray1 = new ArrayList( );

//Check Series Type
//SeriesImpl used for category series
//AreaSeriesImpl
//BarSeriesImpl
//BubbleSeriesImpl
//DialSeriesImpl
//DifferenceSeriesImpl
//GanntSeriesImpl
//LineSeriesImpl
//PieSeriesImpl
//ScatterSeriesImpl
//StockSeriesImpl

	
	if( series.getClass() == BarSeriesImpl ){
		narray1.add(new Double(40.6));
	}else{
		narray1.add("AddBefore");
	}	
	
	var llen =list.length;
    for ( i=0; i < llen; i++)
    {
		narray1.add(list[i]);
    }
//Chart Data Set Types
//BubbleDataSetImpl
//DateTimeDataSetImpl
//DifferenceDataSetImpl
//GanttDataSetImpl
//NumberDataSetImpl
//StockDataSetImpl
//TextDataSetImpl
    
	if( series.getClass() == BarSeriesImpl ){
		narray1.add(new Double(25.6));
		series.setDataSet(NumberDataSetImpl.create( narray1 ));
	}else{
		narray1.add("AddAfter");
		series.setDataSet(TextDataSetImpl.create( narray1 ));
	}	
   
}
The first thing this script does is to get the current values for the given series and creates a new ArrayList. Next it checks to see which series triggered this event. It does this by checking the series class. You could also check the series identifier. Once the series type is determined we add an initial value to the ArrayList, followed by adding all existing values to the ArrayList. Finally a last value is added to the ArrayList and a new chart data set is created. The type of chart data set that is created will depend on how you configured the chart and what type of chart you are using. The comments show additional options. In this example we are using a Text data set for the categories and a number data set for the bar series values. The output of the chart should now look like:
Chart After Script
This example is available for download at Birt-Exchange. For an example on adding a whole new series to a chart, see this post.