Search code examples
javajasper-reportsbar-chartjfreechart

How to show time (HH:mm) in bar chart value expression?


I have designed a bar chart with String value in categorie CRANE_NUMBER and value expression REMAINING_TIME is java.util.Date.

Data

When I run the report, I got error below.

Grave:   java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.Number
    at net.sf.jasperreports.charts.fill.JRFillCategorySeries.evaluate(JRFillCategorySeries.java:141)
    at net.sf.jasperreports.charts.fill.JRFillCategoryDataset.customEvaluate(JRFillCategoryDataset.java:110)
    at net.sf.jasperreports.engine.fill.JRFillElementDataset.evaluate(JRFillElementDataset.java:172)
    at net.sf.jasperreports.engine.fill.JRCalculator.calculateVariables(JRCalculator.java:187)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:735)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:255)
    at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:115)
    at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:582)
    at net.sf.jasperreports.engine.fill.BaseReportFiller.fill(BaseReportFiller.java:414)
    at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:121)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:667)
    at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:648)
    at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:970)

Is it possibile to show remaining time HH:mm in a barchart on the y-axis?


Solution

  • To create a bar chart with HH:mm on range axis, I would use a JRChartCustomizer

    I will show a full example of how this can be achieved using the chart customizer, the library to renderer charts used by jasper-reports is .

    The JRChartCustomizer

    public class ChartHHmmCustomizer implements JRChartCustomizer {
    
        @Override
        public void customize(JFreeChart jfchart, JRChart jrchart) {
    
            //Get the category plot
            CategoryPlot plot = (CategoryPlot) jfchart.getPlot();
    
            //Crete a date axis
            DateAxis yAxis = new DateAxis();
            //Override the date format
            yAxis.setDateFormatOverride(new SimpleDateFormat("HH:mm"));
            //Customize tick unit
            yAxis.setTickUnit(new DateTickUnit(DateTickUnitType.HOUR, 1));
            //Set it to the range axis
            plot.setRangeAxis(yAxis);
    
            //adding a customize item label renderer to view the valus on the barchart
            CategoryItemRenderer renderer = ((CategoryPlot) jfchart.getPlot()).getRenderer();
            renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator("{2}",new SimpleDateFormat("HH:mm")));
            renderer.setBaseItemLabelsVisible(true);
            ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.TOP_CENTER);
            renderer.setBasePositiveItemLabelPosition(position);
        }
    }
    

    The jrxml

    <?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="timeBarChart" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="f71aa6b8-70ce-4de9-9e62-f8bd196e40f8">
        <queryString>
            <![CDATA[]]>
        </queryString>
        <field name="CraneNumber" class="java.lang.String"/>
        <field name="RemaningTime" class="java.util.Date"/>
        <columnHeader>
            <band height="20">
                <staticText>
                    <reportElement x="0" y="0" width="100" height="20" uuid="af39006a-cd21-46c1-b74f-69fd3c570031"/>
                    <textElement verticalAlignment="Middle">
                        <font isBold="true"/>
                    </textElement>
                    <text><![CDATA[CraneNumber]]></text>
                </staticText>
                <staticText>
                    <reportElement x="100" y="0" width="100" height="20" uuid="83918a9e-3cd4-4581-8304-35246f8db5a9"/>
                    <textElement verticalAlignment="Middle">
                        <font isBold="true"/>
                    </textElement>
                    <text><![CDATA[RemaningTime]]></text>
                </staticText>
            </band>
        </columnHeader>
        <detail>
            <band height="20" splitType="Stretch">
                <textField pattern="HH:mm">
                    <reportElement x="100" y="0" width="100" height="20" uuid="a699d0ea-03fa-4232-8bc3-7b6c72c8e13c"/>
                    <textElement verticalAlignment="Middle"/>
                    <textFieldExpression><![CDATA[$F{RemaningTime}]]></textFieldExpression>
                </textField>
                <textField>
                    <reportElement x="0" y="0" width="100" height="20" uuid="bbb040e5-4958-435a-90eb-b52f231ed5cd"/>
                    <textElement verticalAlignment="Middle"/>
                    <textFieldExpression><![CDATA[$F{CraneNumber}]]></textFieldExpression>
                </textField>
            </band>
        </detail>
        <summary>
            <band height="185" splitType="Stretch">
                <barChart>
                    <chart isShowLegend="false" customizerClass="my.package.ChartHHmmCustomizer">
                        <reportElement x="66" y="29" width="356" height="141" uuid="60bdb0d1-8c39-4fdc-98b9-d1c5458cb665"/>
                        <chartTitle/>
                        <chartSubtitle/>
                        <chartLegend/>
                    </chart>
                    <categoryDataset>
                        <categorySeries>
                            <seriesExpression><![CDATA["My cranes"]]></seriesExpression>
                            <categoryExpression><![CDATA[$F{CraneNumber}]]></categoryExpression>
                            <valueExpression><![CDATA[$F{RemaningTime}.getTime()]]></valueExpression>
                        </categorySeries>
                    </categoryDataset>
                    <barPlot>
                        <plot/>
                        <itemLabel/>
                        <categoryAxisFormat>
                            <axisFormat/>
                        </categoryAxisFormat>
                        <valueAxisLabelExpression/>
                        <valueAxisFormat>
                            <axisFormat/>
                        </valueAxisFormat>
                    </barPlot>
                </barChart>
            </band>
        </summary>
    </jasperReport>
    

    Note: That I add the customizerClass="my.package.ChartHHmmCustomizer"to chart component and as valueExpression I set $F{RemaningTime}.getTime(), hence the time in milliseconds (a number)

    Some data

    +-------------+--------------+
    | CraneNumber | RemaningTime |
    +-------------+--------------+
    | Crane1      | 04:20        |
    | Crane2      | 02:13        |
    | Crane3      | 06:31        |
    +-------------+--------------+
    

    Output

    barchart