JasperReports Ultimate Guide - Samples - Schema - Configuration - Functions - FAQ - API (Javadoc)

JasperReports - JFreeChart Sample (version 6.21.0)


Shows how third-party charting APIs could be used for rendering charts as images.

Download All Sample Source Files
Browse Sample Source Files on Git


Main Features in This Sample

Rendering Images Using Third Party APIs (JFreeChart Library)


top

Rendering Images Using Third Party APIs (JFreeChart Library)Documented by Sanda Zaharia


Description / Goal
How to render images using the JFreeChart library.

Since
0.6.0

Other Samples
/demo/samples/xchart


Rendering Graphic Objects

Usually, the mechanism of producing complex images, charts and other graphic objects is part of some more specialized Java libraries, and does not represent one of the JasperReports goals. However, one of its important goals is to easily integrate within a generated report charts, barcodes and other graphics produced by third party libraries.
This integration is based on the fact that great majority of graphic objects produced by these libraries can output to image files or in-memory Java image objects. Then all these generated image objects can be handled by the JasperReports engine using a normal image element, as described in the Images sample.
One problem is that the content of an image element can come either directly from an image file like a JPG, GIF, PNG, or can be a Scalable Vector Graphics (SVG) file that is rendered using some business logic or a dedicated graphics API related to a specific charting or a barcode library. In this case, JasperReports treats all kind of images in a very transparent way because it relies on a special interface called JRRenderable to offer a common way to render images.
The JRRenderable interface has a method called render(Graphics2D grx, Rectangle2D r), which gets called by the engine each time it needs to draw the image on a given device or graphic context. This approach provides the best quality for the SVG images when they must be drawn on unknown devices or zoomed into without losing sharpness.
Other methods specified in this interface can be used to obtain the native size of the actual image that the renderer wraps or the binary data for an image that must be stored in a separate file during export.
The JasperReports library comes with a default implementation for the JRRenderable interface that wraps images that come from files or binary image data in JPG, GIF, or PNG format. The JRImageRenderer class is actually a container for this binary image data, which it uses to load a java.awt.Image object from it, which it then draws on the supplied java.awt.Graphics2D context when the engine requires it.
Image renderers are serializable because inside the generated document for each image is a renderer object kept as reference, which is serialized along with the whole JasperPrint object.
When a JRImageRenderer instance is serialized, so is the binary image data it contains. However, if the image element must be lazy loaded (see the isLazy attribute in the Images sample), then the engine will not load the binary image data at report-filling time. Rather, it stores inside the renderer only the java.lang.String location of the image. The actual image data is loaded only when needed for rendering at report-export or view time.
To simplify the implementation of SVG image renderers, JasperReports ships with an abstract renderer: JRAbstractSvgRenderer. This implementation contains the code to produce binary image data from the SVG graphic in JPG format. This is needed when the image must be stored in separate files on disk or delivered in binary format to a consumer (like a web browser).
Specific image renderers are called when the class of the <imageExpression/> element is net.sf.jasperreports.engine.JRRenderable. In this case the image expression value should point to a JRRenderable object which is designated to render the image.

Rendering a JFreeChart Object Example

This sample shows how to integrate a JFreeChart pie chart into a report, letting the JFreeChart engine to draw itself the chart.
In order to put together both the JFreeChart chart and the JRRenderable renderer, the JFreeChartReport.jrxml template provides a scriptlet class atribute: scriptletClass="JFreeChartScriptlet". The scriptlet class source is available as JFreeChartScriptlet.java file in the src directory.
In the afterReportInit() method, a chart object is created, with all necessary information to be represented:
  DefaultPieDataset dataset = new DefaultPieDataset();
  dataset.setValue("Java", 43.2d);
  dataset.setValue("Visual Basic", 10.0d);
  dataset.setValue("C/C++", 17.5d);
  dataset.setValue("PHP", 32.5d);
  dataset.setValue("Perl", 1.0d);
	
  JFreeChart chart = 
    ChartFactory.createPieChart3D(
      "Pie Chart 3D Demo 1",
      dataset,
      true,
      true,
      false
      );
	
  PiePlot3D plot = (PiePlot3D) chart.getPlot();
  plot.setStartAngle(290);
  plot.setDirection(Rotation.CLOCKWISE);
  plot.setForegroundAlpha(0.5f);
  plot.setNoDataMessage("No data to display");
The resulting chart is passed to a JCommonDrawableRenderer class constructor. The JCommonDrawableRenderer extends the JRAbstractSvgRenderer class nominated above, and its constructor needs an org.jfree.ui.Drawable object, characterized by its draw() method. A JFreeChart chart represents such a Drawable object.
The render() method in the JCommonDrawableRenderer class just calls the Drawable object's draw() method, and all the rendering stuff will be done by this dedicated API:
  public JCommonDrawableRenderer(Drawable drawable) 
  {
    this.drawable = drawable;
  }

  public void render(Graphics2D grx, Rectangle2D rectangle) 
  {
    if (drawable != null) 
    {
      drawable.draw(grx, rectangle);
    }
  }
Once the renderer gets available, one have to instruct the JasperReports engine to use it. The new renderer is passed to the engine in the Chart report variable:
  this.setVariableValue("Chart", new JCommonDrawableRenderer(chart));
This variable is referred to in the reports/JFreeChartReport.jrxml file:

  <variable name="Chart" class="net.sf.jasperreports.engine.JRRenderable" calculation="System">

Now, let's take a look at the <image/> element itself:

  <image scaleImage="Clip" hAlign="Center" hyperlinkType="Reference">
    <reportElement x="0" y="110" width="515" height="300"/>
    <graphicElement/>
    <imageExpression class="net.sf.jasperreports.engine.JRRenderable"><![CDATA[$V{Chart}]]></imageExpression>
    <hyperlinkReferenceExpression><![CDATA["http://www.jfree.org/jfreechart"]]></hyperlinkReferenceExpression>
  </image>


The image expression class is net.sf.jasperreports.engine.JRRenderable, and its value points to the Chart report variable prepared in the report scriptlet.

Running the Sample

Running the sample requires the Apache Ant library. Make sure that ant is already installed on your system (version 1.5 or later).
In a command prompt/terminal window set the current folder to demo/samples/jfreechart within the JasperReports source project and run the > ant test view command.
It will generate all supported document types containing the sample report in the demo/samples/jfreechart/build/reports directory.
Then the report will open in the JasperReports internal viewer.



© 2001- Cloud Software Group, Inc. www.jaspersoft.com