Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to populate chart data with JavaBeans collection dataSet?

I have already created a working jrxml report presenting a table populated by a dataset of a collection (List) of Java beans.

Now I would like to use that same dataset to create Chart (basic bar chart for starters). Each bean contains 4 values that I would like to show on bar chart: month, normal hours, travel hours, and overtime hours. I was hoping that each bean would generate a group of 3-bars for each month so in the end the chart would contain 12x3 bars growing from bottom to up and the name of the month would act as a label under the 3-bar groups, each group positioned next to another starting from left to right.

Unfortunately creating this chart seems much harder than I thought. At least it seems to be totally different compared to creating the table. I'm not sure if the Jasper Studio's Chart wizard is even working. At least it doesn't allow me to add any series in the chart data series dialog: if I press Add absolutely nothing happens - no dialog opens, no error message, nothing, nothing to hint me what is wrong.

Main problem is that I don't see a way to connect the dataset data to the Chart.

After trying embedding chart to my main report, I tried to add it also to a new subreport created only for to act as chart container. I passed the main report dataset as a datasource to subreport and tried to use it as main data set in subreport's chart. Still no luck with the dataset/chart connection, f.e. Still nothing happens if I press the Add-button.

Below you can see the simple beans I'm using. First one, the WorkingHoursReport is the bean I'm passing to report as JRBeanCollectionDataSource. I believe the most interesting field of that bean is the list of WorkingHours-beans. There will be always 12 items on that list: one for each month. That is the list I'm currently passing to my table element using datasource expression: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{workingHours}).

WorkingHoursReport.java:

public class WorkingHoursReport extends CommonReport {
    private int year;
    private List<WorkingHours> workingHours;
}

WorkingHours.java:

public class WorkingHours {

    private int month = 0;
    private double hoursNormal = 0;
    private double hoursTravel = 0;
    private double hoursOvertime = 0;
    private double hoursTotal = 0;
    private double hoursTotalCumulative = 0;
 }

While trying to create my first chart ever, I was naturally trying to populate the data to chart using the very same command for defining the datasource as I was already using successfully with my table:

new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{workingHours}).

Unfortunately it seemed that at least the jasper studio chart creation wizard did not get any connection to the data (no dialog was opening where, according to the docs, I should have been able to select data fields to chart ).

like image 422
Vka Avatar asked Mar 04 '16 15:03

Vka


1 Answers

This is how I would solve your problem considering that you are using java beans, need to sum up data and then have both series (hours) and categories (months). Don't connect it to your table datasource but create a specific datasource for it.

Create a specific chart bean

public class ChartData {
    private String serie;
    private String category;
    private double value;

    public ChartData(String serie, String category, double value) {
        super();
        this.serie = serie;
        this.category = category;
        this.value = value;
    }
    .... getter and setters         
}

Fill the chart bean's with data

Loop your dataset (List) and fill the ChartData list, you will probably need a map to find same month and add to the hours. I will not show you this but create them statically to show an example

List<ChartData> cList = new ArrayList<ChartData>();
cList.add(new ChartData("hoursNormal","month1", 12.3)); //The use of resources or static text is beyond this example
cList.add(new ChartData("hoursTravel","month1", 3.2));
cList.add(new ChartData("hoursOvertime","month1", 1.3));
cList.add(new ChartData("hoursNormal","month2", 16.4));
cList.add(new ChartData("hoursTravel","month2", 5.2));
cList.add(new ChartData("hoursOvertime","month2", 4.1));

Pass the List as a datasource through the parameter map

Map<String, Object> paramMap = new HashMap<String, Object>();
paramMap.put("CHART_DATASET", new JRBeanCollectionDataSource(cList));

Display the chart

Now we can display the chart in the title or summary band using a subDataset passed on the parameter $P{CHART_DATASET}

<?xml version="1.0" encoding="UTF-8"?>
<jasperReport xmlns="http://jasperreports.sourceforge.net/jasperreports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://jasperreports.sourceforge.net/jasperreports http://jasperreports.sourceforge.net/xsd/jasperreport.xsd" name="working_hours" pageWidth="595" pageHeight="842" whenNoDataType="AllSectionsNoDetail" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="1a12c021-57e2-4482-a273-56cbd3f78a17">
    <subDataset name="chartDataSet" uuid="119b7f0e-01ef-4e2b-b628-d76f51e83768">
        <field name="serie" class="java.lang.String"/>
        <field name="category" class="java.lang.String"/>
        <field name="value" class="java.lang.Double"/>
    </subDataset>
    <parameter name="CHART_DATASET" class="net.sf.jasperreports.engine.data.JRBeanCollectionDataSource" isForPrompting="false"/>
    <summary>
        <band height="142" splitType="Stretch">
            <barChart>
                <chart>
                    <reportElement x="80" y="0" width="337" height="142" uuid="c8f4dc5d-47e7-489b-b27e-09976d90994a"/>
                    <chartTitle/>
                    <chartSubtitle/>
                    <chartLegend/>
                </chart>
                <categoryDataset>
                    <dataset>
                        <datasetRun subDataset="chartDataSet" uuid="abec2dce-b670-4e84-b71f-469d954dbcb5">
                            <dataSourceExpression><![CDATA[$P{CHART_DATASET}]]></dataSourceExpression>
                        </datasetRun>
                    </dataset>
                    <categorySeries>
                        <seriesExpression><![CDATA[$F{serie}]]></seriesExpression>
                        <categoryExpression><![CDATA[$F{category}]]></categoryExpression>
                        <valueExpression><![CDATA[$F{value}]]></valueExpression>
                    </categorySeries>
                </categoryDataset>
                <barPlot>
                    <plot/>
                    <itemLabel/>
                    <categoryAxisFormat>
                        <axisFormat/>
                    </categoryAxisFormat>
                    <valueAxisFormat>
                        <axisFormat/>
                    </valueAxisFormat>
                </barPlot>
            </barChart>
        </band>
    </summary>
</jasperReport>

Settings in JasperSoft Studio

Studio

Enjoy the result

Result

like image 164
Petter Friberg Avatar answered Jan 02 '23 08:01

Petter Friberg