Tuesday, September 27, 2016

Multiple charts using same report template in a Report Book using JRBeanCollectiondatasource as a Datasource

I had to create multiple XY-line chart in jasper reports using same report template. And that too using JRBeanCollectionDatasource. And I am creating a Report book, latest feature of Jasper Reports.
Report book feature is used when you want to generate a document as in with table of content, book cover, chapters etc. In my case, I had also to create a document and this challenge was a part of it. With a single chart it is quite easy to generate, but it becomes complicated when you have to use the same report template to create same chart but multiple times. It took me a bit of time to solve this problem and that’s the reason I am writing this blog.

 Requirements:
       1) Create multiple XY-line chart using same report template.
       2) JRBeanCollectionDatasource should be used as a Datasource.
     3) Number of data series in a chart is not fixed and multiple charts needs to be generated of same kind.
      4) Multiple charts belong to the same Report Book ( Single Document ).


 Solution:


Coordinates.java

private Number series; 
private Number xCoordinate;
private Number yCoordinate;

//Getters & Setters

GenerateReport.java
List<List<Coordinates>> allchartData = new ArrayList<>();

List<Coordinates> chartData = null;
// dataseries for chart 1
chartData = new ArrayList<>();
chartData.add(new Coordinates(series1-1, xCoordinate, yCoordinate));
chartData.add(new Coordinates(series1-2, xCoordinate, yCoordinate));
chartData.add(new Coordinates(series1-3, xCoordinate, yCoordinate));
.
.
.
allchartData.add(chartData);
// dataseries for chart 2
chartData = new ArrayList<>();
chartData.add(new Coordinates(series2-1, xCoordinate, yCoordinate));
chartData.add(new Coordinates(series2-2, xCoordinate, yCoordinate));
chartData.add(new Coordinates(series2-3, xCoordinate, yCoordinate));
.
.
.
allchartData.add(chartData);
  
reportParameters.put("XYChartDataSource", allchartData);


How to structure report_book?

As we want to iterate the same report multiple times, then that report should be act as a subreport in a detail band of a report.

It’s the property of detail band which makes it possible to iterate or run something for multiple times. Hence, if we put the report with chart, which we want to print multiple time in a detail band than that report will also be repeated multiple times.

But, Report book doesn’t have a detail band. Hence we will create a “new book part”(sub_charts.jrxml) in a report book and  in the detail band of sub_charts.jrxml we will create one subreport (sub_chart.jrxml), which would contain the XY-linechart.

Note: Open this image in a new tab and carefully notice all the tiny important details.


How to pass parameters from main_report_book to chart?

This above image is ultimate answer for all your question regarding parameter passing and report structure, you just need to keep in mind the tiny but very important details in it.
I will point out what parameters and fields I have created.

main_report_book.jrxml

Parameters:
<parameter name="XYChartDataSource" class="java.util.List"/>

Data Source Expression for sub_charts.jrxml
Datasource expression: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($P{XYDatasource})
that means List<List<Coordiantes>>  is passed to sub_charts.jrxml

sub_charts.jrxml

Field:
<field name="_THIS" class="java.util.List">

Data Source Expression for sub_chart.jrxml (in detail band)
Datasource expression: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{_THIS})
 _THIS is List<Coordinates> inside List<List<Coordiantes>>. it will iterate through the list.Hence here we are passing indivdiual chart data to sub_chart.jrxml



sub_chart.jrxml

Field:
<field name="xCoordinate" class="java.lang.Double"/>
<field name="yCoordinate" class="java.lang.Double"/>
<field name="series" class="java.lang.Double"/>

XY-Line Chart : [use Main Data Set]

<seriesExpression><![CDATA[$F{series}]]></seriesExpression>
<xValueExpression><![CDATA[$F{xCoordinate}]]></xValueExpression>
<yValueExpression><![CDATA[$F{yCoordinate}]]></yValueExpression>

No comments:

Post a Comment