JasperReports logo version 7.0.0 Home - Samples - Configuration - Functions - FAQ - API (Javadoc)

JasperReports - Chart Themes Sample

Shows how the chart themes could be used to change the look and feel of all chart types.

Main Features in This Sample

Enhancing Charts Look and Feel (Chart Themes)

Secondary Features

Charts
Altering Charts (Chart Customizers)

Enhancing Charts Look and Feel (Chart Themes)

Documented by Sanda Zaharia

Description / Goal
Customizing the appearance of all charts created using the chart element, across an entire application.

Since: 3.1.0

IMPORTANT NOTIFICATION:

As explained in this [Migration note](https://github.com/jfree/jfreechart?tab=readme-ov-file#migration), since JFreeChart v.1.5.0 all (pseudo) 3D charts have been removed. As a consequence, the (pseudo) 3D effect is no longer visible for 3D charts used in JasperReports Library v.7.0.0 and newer. The affected charts are the following:

3D charts are now marked for deprecation and will be removed.

Why are chart themes necessary?

The purpose of this feature is to provide a way for users to change the overall appearance of the charts generated using the JasperReports built-in chart component, without having to write chart customizers or to use an extensive set of chart properties. Using a single chart property or a global configuration property, it will be possible to change the look and feel of all chart types supported by the built-in JasperReports chart component and give those graphics a more professional appearance.

Creating and registering chart themes

Chart themes make use of the new extension support introduced in JasperReports v.3.1.0. The extension support allows users to add chart themes to a JasperReports deployment without the need to change any configuration file. Simply dropping a JAR into the classpath will make the chart themes it comes with, automatically available to the JasperReports engine.

In order to create a single chart theme or several chart themes available as an extension to JasperReports, one must first implement the net.sf.jasperreports.charts.ChartTheme interface. This interface represents an implementation of a chart theme and has only one method:

public JFreeChart createChart(ChartContext charContext) throws JRException;

Basically, the whole purpose of a chart theme implementation is to create JFreeChart objects out of the incoming net.sf.jasperreports.charts.ChartContext object that is passed as parameter.
The chart context contains all the runtime information needed including the original chart element definition from the report template, the ability to evaluate expressions at runtime, the chart dataset, a label generator and the locale. In the future, more runtime information could be added to the chart context interface, if needed, without affecting the already existing chart theme implementations.
Secondly, the user must implement the net.sf.jasperreports.charts.ChartThemeBundle interface in order to make the chart themes available by giving them names and putting them together in a bundle. A chart theme bundle can contain one or more chart themes that are found by name. The chart theme bundle interface has only two methods:

public String[] getChartThemeNames();
public ChartTheme getChartTheme(String themeName);

Once the chart theme bundle was created, it has to be added as an extension to JR. In order to do this, the net.sf.jasperreports.extensions.ExtensionsRegistryFactory interface must be implemented. This factory implementation will be responsible for creating an net.sf.jasperreports.extensions.ExtensionsRegistry object, which in turn will provide a list of chart theme bundles, including the one the user has just created above. JasperReports will be able to automatically detect the presence of the custom chart theme bundle through its built-in extension support, if all the above mentioned classes (chart themes, chart bundle and extension registry factory) are put in a single JAR file and inside the root folder of this JAR file, a file named jasperreports_extension.properties is present. This properties file placed in the root of the JAR, has to have a property in the form net.sf.jasperreports.extension.registry.factory.<arbitrary_suffix> that would be the name of a class that implements the net.sf.jasperreports.extensions.ExtensionsRegistryFactory interface, mentioned above.

Chart themes implementations in JasperReports

In order to customize a chart, a sum of specific settings should be configured in a given chart theme. Then, when a chart gets created, if its own settings are not present, they are read from the related chart theme. For example, if chart's own title position is not set, then the title position will be set using the chart theme's title position attribute. Chart settings are grouped in 4 main categories:

In order to eliminate the need of hard-coding these settings in a chart theme class, it is recommended to use an XML approach instead. In JasperReports there are 2 different XML-based chart themes implementations.

XML Spring-based chart theme implementation

This implementation is based on the Spring Framework platform, and uses Spring beans for binding the chart theme bundle class and the 4 above chart settings categories. All related java classes and XML beans are found in the /ext/jasperreports-chart-themes/src/main/java/net/sf/jasperreports/chartthemes/spring directory. The implementation comes with 4 different sample chart themes, identified by their names: generic, default.spring, eye.candy.sixties, aegean. The generic chart theme is the parent implementation, and all Spring-based chart themes should extend it. In the chartThemesBeans.xml file found in /ext/jasperreports-chart-themes/src/main/java/net/sf/jasperreports/chartthemes/spring/beans directory are mapped both the chart theme bundle class, and the parent chart theme named generic. The other Spring-based themes are mapped each one in a separate xml file (see the aegeanChartPropertiesBean.xml file, for example), which are referred in the chartThemesBeans.xml by their resource name. Below is the theme bundle bean:

  <bean id="themeBundle" class="net.sf.jasperreports.chartthemes.ChartThemeMapBundle">
    <property name="themes">
      <map>
        <entry key="generic">
          <ref bean="genericChartTheme"/>
        </entry>
        <entry key="default.spring">
          <ref bean="defaultChartTheme"/>
        </entry>
        <entry key="eye.candy.sixties">
          <ref bean="eyeCandySixtiesChartTheme"/>
        </entry>
        <entry key="aegean">
          <ref bean="aegeanChartTheme"/>
        </entry>
      </map>
    </property>
  </bean>

The generic chart theme bean is referenced by id="genericChartTheme" and contains 4 bean elements related to the 4 chart settings categories:

Any newly created chart theme should be saved in a new xml file. This file should be added to chartThemesBeans.xml resource imports, and the chart theme's name has to be added to the theme bundle bean. After that, the new theme will be available. In order to make available Spring-based chart themes, in the jasperreports_extension.properties file the following lines should be uncommented:

net.sf.jasperreports.extension.registry.factory.chart.theme=net.sf.jasperreports.extensions.SpringExtensionsRegistryFactory
net.sf.jasperreports.extension.chart.theme.spring.beans.resource=net/sf/jasperreports/chartthemes/spring/beans/chartThemesBeans.xml

All other lines in the file have to be commented.

Castor XML Mapping-based chart theme implementation

This implementation based on Castor XML Mapping provides both marshalling and unmarshalling features available on the Castor platform. This is a good reason to write and use Castor XML Mapping-based implementations. All related java classes and XML files are found in the /ext/jasperreports-chart-themes/src/main/java/net/sf/jasperreports/chartthemes/simple directory.

Let's take a look into the chart.theme.mapping.xml file, where is stored all the mapping configuration needed for this implementation.
First we'll see the net.sf.jasperreports.chartthemes.simple.ChartThemeSettings class definition. It contains all necessary settings for a chart theme. Because title, subtitles and legend are chart subelements, their specific settings were grouped in specific fields. Also, settings for domain and range axis were separated in related fields:

  <class name="net.sf.jasperreports.chartthemes.simple.ChartThemeSettings">
    <map-to xml="chart-theme"/>
    <field name="chartSettings" type="net.sf.jasperreports.chartthemes.simple.ChartSettings">
      <bind-xml node="element"/>
    </field>
    <field name="titleSettings" type="net.sf.jasperreports.chartthemes.simple.TitleSettings">
      <bind-xml node="element"/>
    </field>
    <field name="subtitleSettings" type="net.sf.jasperreports.chartthemes.simple.TitleSettings">
      <bind-xml node="element"/>
    </field>
    <field name="legendSettings" type="net.sf.jasperreports.chartthemes.simple.LegendSettings">
      <bind-xml node="element"/>
    </field>
    <field name="plotSettings" type="net.sf.jasperreports.chartthemes.simple.PlotSettings">
      <bind-xml node="element"/>
    </field>
    <field name="domainAxisSettings" type="net.sf.jasperreports.chartthemes.simple.AxisSettings">
      <bind-xml node="element"/>
    </field>
    <field name="rangeAxisSettings" type="net.sf.jasperreports.chartthemes.simple.AxisSettings" >
      <bind-xml node="element"/>
    </field>
  </class>

Then each field above is described in its own class. For example, the LegendSettings:

  <class name="net.sf.jasperreports.chartthemes.simple.LegendSettings">
    <map-to xml="legend"/>
    <field name="showLegend" type="java.lang.Boolean">
      <bind-xml node="attribute"/>
    </field>
    <field name="position" type="net.sf.jasperreports.charts.type.EdgeEnum" handler="net.sf.jasperreports.chartthemes.simple.handlers.EdgeFieldHandler">
      <bind-xml node="attribute"/>
    </field>
    <field name="foregroundPaint" type="net.sf.jasperreports.chartthemes.simple.PaintProvider">
      <bind-xml auto-naming="deriveByField" node="element"/>
    </field>
    <field name="backgroundPaint" type="net.sf.jasperreports.chartthemes.simple.PaintProvider">
      <bind-xml auto-naming="deriveByField" node="element"/>
    </field>
    <field name="font" type="net.sf.jasperreports.engine.JRFont">
      <bind-xml auto-naming="deriveByClass" node="element"/>
    </field>
    <field name="horizontalAlignment" type="org.jfree.chart.ui.HorizontalAlignment" handler="net.sf.jasperreports.chartthemes.simple.handlers.HorizontalAlignmentFieldHandler">
      <bind-xml node="attribute"/>
    </field>
    <field name="verticalAlignment" type="org.jfree.chart.ui.VerticalAlignment" handler="net.sf.jasperreports.chartthemes.simple.handlers.VerticalAlignmentFieldHandler">
      <bind-xml node="attribute"/>
    </field>
    <field name="padding" type="org.jfree.chart.ui.RectangleInsets">
      <bind-xml node="element"/>
    </field>
  </class>

And finally, any object type involved in the class definitions above is also mapped in this xml file:

  <class name="net.sf.jasperreports.chartthemes.simple.ColorProvider">
    <map-to xml="color"/>
    <field name="color" type="java.awt.Color" handler="net.sf.jasperreports.chartthemes.simple.handlers.ColorFieldHandler">
      <bind-xml node="attribute"/>
    </field>
  </class>

All classes mapped above correspond to a related java implementation. You can see them in the net.sf.jasperreports.chartthemes.simple package.

Now, in order to create a new XML Mapping-based chart theme, one have to write an xml file with the .jrctx extension which is handled by Castor via marshalling/unmarshalling processes. In this sample was implemented the net.sf.jasperreports.chartthemes.simple.SimpleSettingsFactory class which produces the simple theme's specific settings. These settings are related to the net.sf.jasperreports.chartthemes.simple.SimpleChartTheme class.
The simple.jrctx file is produced when the ant themes task is called, and this file will be used further when a new JFreeChart object gets created.

In order to make available Castor XML Mapping-based chart themes, in the jasperreports_extension.properties file the following lines should be uncommented:

net.sf.jasperreports.extension.registry.factory.xml.chart.themes=net.sf.jasperreports.chartthemes.simple.XmlChartThemeExtensionsRegistryFactory
net.sf.jasperreports.xml.chart.theme.simple=net/sf/jasperreports/chartthemes/simple/simple.jrctx

All other lines in the file have to be commented.

Using chart themes

Themes can be associated globally with all charts by using the following configuration property in the jasperreports.properties file:

net.sf.jasperreports.chart.theme=<theme_name>

This configuration property can be used at report level too, in order to override the chart theme to be used for the current report:

<property name="net.sf.jasperreports.chart.theme" value="theme_name"/>

Changing the chart theme is also possible at chart element level using the theme attribute:

<chart theme="theme_name">
...
</chart>

Running the Sample

Running the sample requires the Apache Maven library. Make sure that maven is already installed on your system (version 3.6 or later).
In a command prompt/terminal window set the current folder to demo/samples/chartthemes within the JasperReports source project and run the following command:

> mvn clean compile exec:exec@all

It will generate all supported document types containing the sample report in the demo/samples/chartthemes/target/reports directory.




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