Search code examples
javajasper-reportsjfreecharttimeserieschart

How to create a line chart with date's on both axis?


I need to implement a two date type axis with jasper-reports.

The time series chart allows a date on x-axis and a number value on y-axis, is there a way to implements two date type axis where both y-axis and x-axis is of date type?


Solution

  • To set y-axis as a Date axis you need to.

    1. Convert the Date in the valueExpression to a java.lang.Number, since valueExpression does only allow this class (or a sub class)

    Instead of passing a java.util.Date in the valueExpression pass the time in milliseconds java.lang.Long by calling Date.getTime()

    <valueExpression><![CDATA[$F{myDateOnYAxis}.getTime()]]></valueExpression>
    

    2. Add a JRChartCustomizer that changes the number axis to a date axis with relative formatter

    public class MyChartCustomizer implements JRChartCustomizer {
    
        @Override
        public void customize(JFreeChart jfchart, JRChart jrchart) {
            XYPlot plot = (XYPlot) jfchart.getPlot(); //get the plot
    
            //Create the new date axis for y
            DateAxis yDateAxis = new DateAxis();
            //Set desired time format
            DateFormat dateFormat = new SimpleDateFormat("MMM - yyyy"); 
            yDateAxis.setDateFormatOverride(dateFormat); 
            //Add your own Tickunit if you like (you can do with out also, comment out the below line and let JFreeChart decided)
            yDateAxis.setTickUnit(new DateTickUnit(DateTickUnitType.MONTH,3));
    
            //Set the new y-axis to the plot
            plot.setRangeAxis(yDateAxis);
        }
    }
    

    For how to add JRChartCustomizer to your design (jrxml) see Sample reference

    Result

    Resultl

    *Some random dates formatted in Italian

    Example jrxml used to generate graph with a csv datasource

    <?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="Test2DateGraph" pageWidth="595" pageHeight="842" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="2347c131-1884-430a-b77f-59f08f896c8a">
    	<property name="com.jaspersoft.studio.data.defaultdataadapter" value="Dates"/>
    	<queryString language="csv">
    		<![CDATA[]]>
    	</queryString>
    	<field name="Date1" class="java.util.Date"/>
    	<field name="Date2" class="java.util.Date"/>
    	<summary>
    		<band height="353">
    			<timeSeriesChart>
    				<chart evaluationTime="Report" customizerClass="MyChartCustomizer">
    					<reportElement x="10" y="50" width="530" height="256" uuid="4a93e72e-251b-4026-bb11-edc26ecd6599"/>
    					<chartTitle/>
    					<chartSubtitle/>
    					<chartLegend/>
    				</chart>
    				<timeSeriesDataset>
    					<timeSeries>
    						<seriesExpression><![CDATA["SERIES 1"]]></seriesExpression>
    						<timePeriodExpression><![CDATA[$F{Date2}]]></timePeriodExpression>
    						<valueExpression><![CDATA[$F{Date2}.getTime()]]></valueExpression>
    					</timeSeries>
    				</timeSeriesDataset>
    				<timeSeriesPlot>
    					<plot/>
    					<timeAxisFormat>
    						<axisFormat/>
    					</timeAxisFormat>
    					<valueAxisFormat>
    						<axisFormat/>
    					</valueAxisFormat>
    				</timeSeriesPlot>
    			</timeSeriesChart>
    		</band>
    	</summary>
    </jasperReport>

    Note: If your not using a timeSeriesChart, the same needs to be done with x-axis.