Skip to content

Commit

Permalink
chart customization example (#139)
Browse files Browse the repository at this point in the history
* added the charting dependencies
* index the transitive dependencies for the above
* a little refactor to the database report service to make it usable by multiple endpoints
* added an example report with a chart customizer to add a green box to the bottom half of the chart
* added an endpoint to expose the chart report as a PDF document
* added unit and integration tests for the chart endpoint

Signed-off-by:Nathan Erwin <[email protected]>
  • Loading branch information
nderwin authored Oct 21, 2024
1 parent bdc8bf1 commit f6a2fc6
Show file tree
Hide file tree
Showing 10 changed files with 192 additions and 9 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,9 @@ UberJarMergedResourceBuildItem mergeResource() {
@BuildStep
void indexTransitiveDependencies(BuildProducer<IndexDependencyBuildItem> index) {
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-charts"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-chart-customizers"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-chart-themes"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-data-adapters"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-excel-poi"));
index.produce(new IndexDependencyBuildItem("net.sf.jasperreports", "jasperreports-jdt"));
Expand Down Expand Up @@ -245,7 +248,9 @@ void runtimeInitializedClasses(CombinedIndexBuildItem combinedIndex,
BuildProducer<RuntimeInitializedPackageBuildItem> runtimeInitializedPackages) {
//@formatter:off
List<String> classes = collectImplementors(combinedIndex, net.sf.jasperreports.extensions.ExtensionsRegistryFactory.class.getName());
classes.addAll(Stream.of("javax.swing",
classes.addAll(Stream.of(
"java.awt",
"javax.swing",
"javax.swing.plaf.metal",
"javax.swing.text.html",
"javax.swing.text.rtf",
Expand Down
38 changes: 38 additions & 0 deletions integration-tests/src/main/jasperreports/CustomChart.jrxml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<!-- Created with Jaspersoft Studio version 7.0.0.final using JasperReports Library version 7.0.0 -->
<jasperReport name="CustomChart" language="java" pageWidth="612" pageHeight="792" columnWidth="555" leftMargin="20" rightMargin="20" topMargin="20" bottomMargin="20" uuid="cc707d51-bcf7-44bb-bb94-744598a3d011">
<query language="sql"><![CDATA[SELECT
nums.item, nums.num, nums.item * nums.num AS mult
FROM (
SELECT
data.item, row_number() over (ORDER BY data.item) AS num
FROM (
SELECT X AS item FROM SYSTEM_RANGE(0, 20)
) AS data
ORDER BY data.item
) AS nums
]]></query>
<field name="item" class="java.lang.Integer"/>
<field name="num" class="java.lang.Integer"/>
<field name="mult" class="java.lang.Integer"/>
<detail>
<band height="30" splitType="Stretch">
<printWhenExpression><![CDATA[false]]></printWhenExpression>
<element kind="textField" uuid="85928695-87b1-436a-888f-5a98ac899dc4" x="0" y="0" width="100" height="30">
<expression><![CDATA[$F{mult}]]></expression>
</element>
</band>
</detail>
<summary height="245" splitType="Stretch">
<element kind="chart" chartType="xyLine" uuid="d7d5b5fb-e919-4980-9c63-3687941c2d6e" x="0" y="0" width="572" height="245" evaluationTime="Report" linkTarget="Self" customizerClass="io.quarkiverse.jasperreports.it.ChartCustomizer">
<dataset kind="xy">
<series>
<seriesExpression><![CDATA["SERIES 1"]]></seriesExpression>
<itemHyperlink linkType="None" linkTarget="Self"/>
<xvalueExpression><![CDATA[$F{item}]]></xvalueExpression>
<yvalueExpression><![CDATA[$F{mult}]]></yvalueExpression>
</series>
</dataset>
<plot categoryAxisLabelColor="#000000" categoryAxisTickLabelColor="#000000" categoryAxisLineColor="#000000" valueAxisLabelColor="#000000" valueAxisTickLabelColor="#000000" valueAxisLineColor="#000000"/>
</element>
</summary>
</jasperReport>
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.quarkiverse.jasperreports.it;

import java.awt.BasicStroke;
import java.awt.Color;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.annotations.XYBoxAnnotation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.data.Range;

import net.sf.jasperreports.charts.JRAbstractChartCustomizer;
import net.sf.jasperreports.charts.JRChart;

public class ChartCustomizer extends JRAbstractChartCustomizer {

@Override
public void customize(final JFreeChart freeChart, final JRChart jasperChart) {
final XYPlot plot = freeChart.getXYPlot();
final XYItemRenderer renderer = plot.getRenderer();
final Range range = renderer.findDomainBounds(plot.getDataset());
final Range yRange = plot.getDataRange(plot.getRangeAxis());

final double startX = range.getLowerBound() - 1.0d;
final double endX = range.getUpperBound() + 1.0d;

final Color green = new Color(0, 192, 0, 64);

renderer.addAnnotation(
new XYBoxAnnotation(startX, 0.0d, endX, yRange.getUpperBound() / 2.0d, new BasicStroke(), green, green));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -22,23 +22,22 @@
import net.sf.jasperreports.engine.SimpleReportContext;
import net.sf.jasperreports.engine.export.JRTextExporter;
import net.sf.jasperreports.export.SimpleExporterInput;
import net.sf.jasperreports.export.SimpleOutputStreamExporterOutput;
import net.sf.jasperreports.export.SimpleWriterExporterOutput;
import net.sf.jasperreports.pdf.JRPdfExporter;

@ApplicationScoped
@Transactional(Transactional.TxType.NEVER)
public class DatabaseReportService extends AbstractJasperResource {

private static final String TEST_REPORT_NAME = "DbDatasourceMain.jasper";

@Inject
ReadOnlyStreamingService repo;

@Inject
DataSource datasource;

@Transactional(Transactional.TxType.NEVER)
public byte[] text() throws JRException, SQLException {
final JasperPrint jasperPrint = fill();
public byte[] text(final String reportName) throws JRException, SQLException {
final JasperPrint jasperPrint = fill(reportName);
final JRTextExporter exporter = new JRTextExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
Expand All @@ -47,15 +46,25 @@ public byte[] text() throws JRException, SQLException {
return outputStream.toByteArray();
}

private JasperPrint fill() throws JRException, SQLException {
public byte[] pdf(final String reportName) throws JRException, SQLException {
final JasperPrint jasperPrint = fill(reportName);
final ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
final JRPdfExporter exporter = new JRPdfExporter();
exporter.setExporterInput(new SimpleExporterInput(jasperPrint));
exporter.setExporterOutput(new SimpleOutputStreamExporterOutput(outputStream));
exporter.exportReport();
return outputStream.toByteArray();
}

private JasperPrint fill(final String reportName) throws JRException, SQLException {
final ReportContext reportContext = new SimpleReportContext();

final Map<String, Object> params = new HashMap<>();
params.put(JRParameter.REPORT_LOCALE, Locale.US);
params.put(JRParameter.REPORT_CONTEXT, reportContext);

try (final Connection connection = datasource.getConnection()) {
return JasperFillManager.getInstance(repo.getContext()).fillFromRepo(TEST_REPORT_NAME, params, connection);
return JasperFillManager.getInstance(repo.getContext()).fillFromRepo(reportName, params, connection);
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package io.quarkiverse.jasperreports.it;

import java.sql.SQLException;

import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.ServerErrorException;
import jakarta.ws.rs.core.Response;

import io.quarkus.logging.Log;
import net.sf.jasperreports.engine.JRException;

@Path("jasper/chart")
@ApplicationScoped
public class JasperReportChartResource {

@Inject
DatabaseReportService databaseReportService;

@GET
@Path("")
@Produces(ExtendedMediaType.APPLICATION_PDF)
public byte[] pdf() {
try {
return databaseReportService.pdf("CustomChart.jasper");
} catch (final JRException | SQLException ex) {
Log.error("Unexpected DB Error", ex);
throw new ServerErrorException(Response.Status.INTERNAL_SERVER_ERROR, ex);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@
@ApplicationScoped
public class JasperReportsDatabaseResource extends AbstractJasperResource {

private static final String TEST_REPORT_NAME = "DbDatasourceMain.jasper";

@Inject
DatabaseReportService databaseReportService;

Expand All @@ -48,7 +50,7 @@ public String entities() {
@Produces(MediaType.TEXT_PLAIN)
public String text() {
try {
return new String(databaseReportService.text());
return new String(databaseReportService.text(TEST_REPORT_NAME));
} catch (final JRException | SQLException ex) {
Log.error("Unexpected DB Error", ex);
throw new ServerErrorException(Response.Status.INTERNAL_SERVER_ERROR, ex);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.quarkiverse.jasperreports.it;

import io.quarkus.test.junit.QuarkusIntegrationTest;

@QuarkusIntegrationTest
public class JasperReportChartResourceIT {
// Execute the same tests but in packaged mode.
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package io.quarkiverse.jasperreports.it;

import static io.restassured.RestAssured.given;
import static org.hamcrest.Matchers.greaterThan;
import static org.hamcrest.Matchers.notNullValue;

import jakarta.ws.rs.core.HttpHeaders;

import org.junit.jupiter.api.Test;

import io.quarkus.test.junit.QuarkusTest;

@QuarkusTest
public class JasperReportChartResourceTest {

@Test
public void testPdfExport() {
given()
.when().get("/jasper/chart")
.then()
.statusCode(200)
.header(HttpHeaders.CONTENT_LENGTH, Integer::parseInt, greaterThan(0))
.body(notNullValue());
}

}
15 changes: 15 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,21 @@
<artifactId>jasperreports</artifactId>
<version>${version.jasperreports}</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-chart-customizers</artifactId>
<version>${version.jasperreports}</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-chart-themes</artifactId>
<version>${version.jasperreports}</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-charts</artifactId>
<version>${version.jasperreports}</version>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-jdt</artifactId>
Expand Down
12 changes: 12 additions & 0 deletions runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-chart-customizers</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-chart-themes</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-charts</artifactId>
</dependency>
<dependency>
<groupId>net.sf.jasperreports</groupId>
<artifactId>jasperreports-fonts</artifactId>
Expand Down

0 comments on commit f6a2fc6

Please sign in to comment.