I want to make a jasper report with vertical separation on series in line chart.
I checked all report elements but I didn't find any matching element. I attach sample image what I want
The chart is generated by the jfreechart library and AFIK there is no setting that will allow you to achieve this automatically.
The solution would be generating multiple charts (one on top of the other) on each series and applying a customizer to the chart so that each chart can be adapted in base of its position.
csv data example
+----------+--------+--------+
| Category | Serie1 | Serie2 |
+----------+--------+--------+
| A | 1 | 0.3 |
| B | 0.5 | 0.2 |
| C | 0.7 | 0.6 |
+----------+--------+--------+
jrxml example with two charts (1 for series1 and the other for series2)
<?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="chartTest" pageWidth="595" pageHeight="842" whenNoDataType="BlankPage" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="597c0716-df6b-42ec-a7c8-863eb1b7174a">
<queryString>
<![CDATA[]]>
</queryString>
<field name="Category" class="java.lang.String"/>
<field name="Serie1" class="java.lang.Double"/>
<field name="Serie2" class="java.lang.Double"/>
<summary>
<band height="205" splitType="Stretch">
<lineChart>
<chart customizerClass="ChartCustomizer">
<reportElement x="171" y="0" width="200" height="100" uuid="245c4678-0cad-4342-8e54-6355c23a3c72"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend position="Right"/>
</chart>
<categoryDataset>
<categorySeries>
<seriesExpression><![CDATA["Serie 1"]]></seriesExpression>
<categoryExpression><![CDATA[$F{Category}]]></categoryExpression>
<valueExpression><![CDATA[$F{Serie1}]]></valueExpression>
</categorySeries>
</categoryDataset>
<linePlot isShowShapes="false">
<plot/>
<categoryAxisFormat>
<axisFormat verticalTickLabels="false"/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat tickLabelColor="#FF0033"/>
</valueAxisFormat>
</linePlot>
</lineChart>
<lineChart>
<chart>
<reportElement x="171" y="93" width="200" height="111" uuid="b53cb5dc-09cd-448d-93ea-0719c239eafe"/>
<chartTitle/>
<chartSubtitle/>
<chartLegend position="Right"/>
</chart>
<categoryDataset>
<categorySeries>
<seriesExpression><![CDATA["Serie 2"]]></seriesExpression>
<categoryExpression><![CDATA[$F{Category}]]></categoryExpression>
<valueExpression><![CDATA[$F{Serie2}]]></valueExpression>
</categorySeries>
</categoryDataset>
<linePlot isShowShapes="false">
<plot>
<seriesColor seriesOrder="0" color="#000000"/>
</plot>
<categoryAxisFormat>
<axisFormat verticalTickLabels="true"/>
</categoryAxisFormat>
<valueAxisFormat>
<axisFormat/>
</valueAxisFormat>
<rangeAxisMinValueExpression><![CDATA[0]]></rangeAxisMinValueExpression>
<rangeAxisMaxValueExpression><![CDATA[2]]></rangeAxisMaxValueExpression>
</linePlot>
</lineChart>
</band>
</summary>
</jasperReport>
java class including the ChartCustomizer
for chart 1 and main
method to run report
public class ChartCustomizer implements JRChartCustomizer {
@Override
public void customize(JFreeChart jfchart, JRChart jrchart) {
CategoryPlot plot = (CategoryPlot) jfchart.getPlot();
CategoryAxis range = plot.getDomainAxis();
//Don't show the range axis
range.setVisible(false);
//Lets remove the 0, in your case you can do a customizer to remove the 2 on the other chart
NumberAxis rangeAxis = new NumberAxis() {
private static final long serialVersionUID = 3744076016723532336L;
@SuppressWarnings({ "rawtypes", "unchecked" })
@Override
public List refreshTicks(Graphics2D g2, AxisState state, Rectangle2D dataArea, RectangleEdge edge) {
List allTicks = super.refreshTicks(g2, state, dataArea, edge);
NumberTick t0 = new NumberTick(TickType.MAJOR, 0, "", TextAnchor.CENTER_RIGHT, TextAnchor.CENTER_RIGHT, 0);
allTicks.set(0, t0);
return allTicks;
}
};
//Set range and paint, since we replace the rangeAxis
rangeAxis.setRange(0, 2);
rangeAxis.setTickLabelPaint(Color.RED);
plot.setRangeAxis(rangeAxis);
}
public static void main(String[] args) throws Exception {
JasperReport report = JasperCompileManager.compileReport("ChartTest.jrxml");
JRCsvDataSource ds = new JRCsvDataSource(new File("ChartData.csv"));
ds.setNumberFormat(NumberFormat.getInstance(Locale.US)); //. as decimal separator
ds.setFieldDelimiter(';');
ds.setUseFirstRowAsHeader(true);
Map<String, Object> paramMap = new HashMap<String, Object>();
JasperPrint jasperPrint = JasperFillManager.fillReport(report, paramMap, ds);
JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput("ChartTest.pdf"));
SimplePdfExporterConfiguration configuration = new SimplePdfExporterConfiguration();
configuration.setCreatingBatchModeBookmarks(true);
configuration.setMetadataAuthor("Petter");
exporter.setConfiguration(configuration);
exporter.exportReport();
}
}
Result
As you can see it not yet perfect, for the legend you can remove it from the chart and create it directly in jasper report, furthermore you can remove the 2.0 on second chart instead of the 0 in first chart, but further implementation I will leave to you.