<?xml version="1.0" encoding="UTF-8"?>

<sample>

  <name>chartthemes</name>
  <title>Chart Themes Sample</title>
  <description>Shows how the chart themes could be used to change the look and feel of all chart types.</description>

  <mainFeature ref="chartthemes"/>
  <secondaryFeature name="charts" sample="charts" title="Charts"/>
  <secondaryFeature name="chartcustomizers" sample="charts" title="Altering Charts (Chart Customizers)"/>
  
  <!-- chartthemes -->
  
  <feature name="chartthemes" title="Enhancing Charts Look and Feel (Chart Themes)">
    <description>
Customizing the appearance of all charts created using the chart element, across an entire application. 
    </description>
    <since>3.1.0</since>
    <documentedBy>
      <author>
    	<name>Sanda Zaharia</name>
    	<email>shertage@users.sourceforge.net</email>
      </author>
    </documentedBy>
    <content>
    <b>Why are chart themes necessary</b>
    <br/>
    <br/>
<ul>
	<li>Chart theme
		<ul>
			<li>A chart theme represents a set of chart properties that are modified together on the target chart component in order to significantly alter its overall look and feel. 
		The chart settings that make up a chart theme are usually not part of the chart settings of JFreeChart that are exposed in JRXML.</li>
		</ul>
	</li>
</ul>
<ul>
	<li>Chart customizer
		<ul>
			<li>A chart customizer is similar to a chart theme in the sense that it too alters a chart look and feel and makes use of chart settings that are not exposed in JRXML. 
		But unlike chart themes, a chart customizer only affects the current chart it is attached to, while a chart theme affects all types of charts supported by JR.</li>
		</ul>
	</li>
</ul>
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.
<br/>
<br/>
<b>Creating and registering chart themes</b>
<br/>
<br/>
Chart themes make use of the new extension support introduced in JR 3.1.0.
<br/>
The extension support allows users to add chart themes to a JR 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 JR.
<br/>
In order to create a single chart theme or several chart themes available as an extension to JR, one must first implement the <code>net.sf.jasperreports.charts.ChartTheme</code> interface. 
This interface represents an implementation of a chart theme and has only one method:
<br/>
<br/>
<code>public JFreeChart createChart(ChartContext charContext) throws JRException;</code>
<br/>
<br/>
Basically, the whole purpose of a chart theme implementation is to create JFreeChart objects out of the incoming <code>net.sf.jasperreports.charts.ChartContext</code> object that is passed as parameter.
<br/>
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.
<br/>
Secondly, the user must implement the <code>net.sf.jasperreports.charts.ChartThemeBundle</code> 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.
<br/>
The chart theme bundle interface has only two methods: 
<br/>
<br/>
<code>
public String[] getChartThemeNames();
<br/>
public ChartTheme getChartTheme(String themeName);
</code>
<br/>
<br/>
Once the chart theme bundle was created, it has to be added as an extension to JR. In order to do this, the <code>net.sf.jasperreports.extensions.ExtensionsRegistryFactory</code> interface must be implemented. This factory implementation will be responsible for creating an <code>net.sf.jasperreports.extensions.ExtensionsRegistry</code> object, which in turn will provide a list of chart theme bundles, including the one the user has just created above.
<br/>
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.
<br/>
This properties file placed in the root of the JAR, has to have a property in the form <code>net.sf.jasperreports.extension.registry.factory.&lt;arbitrary_suffix&gt;</code> that would be the name of a class that implements the <code>net.sf.jasperreports.extensions.ExtensionsRegistryFactory</code> interface, mentioned above.
<br/>
<br/>
<b>Chart themes implementations in JasperReports</b>
<br/>
<br/>
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.
<br/>
Chart settings are grouped in 4 main categories:
<ul>
<li>general chart settings: available to all chart types. For example, the title color, the legend position, the chart border, etc.</li>
<li>general plot settings: referring to the chart's plot, like: plot background color, orientation, gridlines, etc.</li>
<li>general axis settings: referring to the chart's axis: axis color, label angle, tick marks count, etc.</li>
<li>specific chart type settings: available only for a particular chart type. For example, only a pie chart can have a circular shape, only a meter chart can have a display value, only line charts can show or hide lines, etc. </li>
</ul>
<br/>
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.
<br/>
In JasperReports there are 2 different XML-based chart themes implementations. 
<br/>
<br/>
<b>XML Spring-based chart theme implementation</b>
<br/>
<br/>
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 /src/net/sf/jasperreports/chartthemes/spring directory.
<br/>
The implementation comes with 4 different sample chart themes, identified by their names: <code>generic</code>, <code>default.spring</code>, <code>eye.candy.sixties</code>, <code>aegean</code>. The <code>generic</code> chart theme is the parent implementation, and all Spring-based chart themes should extend it.
<br/>
In the chartThemesBeans.xml file found in /src/net/sf/jasperreports/chartthemes/spring/beans directory are mapped both the chart theme bundle class, and the parent chart theme named <code>generic</code>. 
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.
<br/>
Below is the theme bundle bean:
<pre><![CDATA[
  <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>
]]></pre>
The generic chart theme bean is referenced by <code>id="genericChartTheme"</code> and contains 4 bean elements related to the 4 chart settings categories: 
<ul>
<li>defaultChartPropertiesMap - contains general chart settings</li>
<li>defaultPlotPropertiesMap - contains general plot settings</li>
<li>defaultAxisPropertiesMap - contains axis settings</li>
<li>defaultChartTypePropertiesMap - contains settings available only for specific chart types.</li>
</ul>
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.
<br/>
In order to make available Spring-based chart themes, in the jasperreports_extension.properties file the following lines should be uncommented:
<br/>
<br/>
<code>
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
</code>
<br/>
<br/>
All other lines in the file have to be commented.
<br/>
<br/>
<b>Castor XML Mapping-based chart theme implementation</b>
<br/>
<br/>
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.
<br/>
All related java classes and XML files are found in the /src/net/sf/jasperreports/chartthemes/simple directory.
<br/>
<br/>
Let's take a look into the chart.theme.mapping.xml file, where is stored all the mapping configuration needed for this implementation.
<br/>
First we'll see the <code>net.sf.jasperreports.chartthemes.simple.ChartThemeSettings</code> 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:
<pre><![CDATA[
  <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>
]]></pre>
Then each field above is described in its own class. For example, the LegendSettings:
<pre><![CDATA[
  <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="positionValue" 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.ui.HorizontalAlignment" handler="net.sf.jasperreports.chartthemes.simple.handlers.HorizontalAlignmentFieldHandler">
      <bind-xml node="attribute"/>
    </field>
    <field name="verticalAlignment" type="org.jfree.ui.VerticalAlignment" handler="net.sf.jasperreports.chartthemes.simple.handlers.VerticalAlignmentFieldHandler">
      <bind-xml node="attribute"/>
    </field>
    <field name="padding" type="org.jfree.ui.RectangleInsets">
      <bind-xml node="element"/>
    </field>
  </class>
]]></pre>
And finally, any object type involved in the class definitions above is also mapped in this xml file: 
<pre><![CDATA[
  <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>
]]></pre>
All classes mapped above correspond to a related java implementation. You can see them in the <code>net.sf.jasperreports.chartthemes.simple</code> package.
<br/>
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.
<br/>
In this sample was implemented the <code>net.sf.jasperreports.chartthemes.simple.SimpleSettingsFactory</code> class which produces the <code>simple</code> theme's specific settings. 
These settings are related to the <code>net.sf.jasperreports.chartthemes.simple.SimpleChartTheme</code> class.
<br/>
The simple.jrctx file is produced when the ant <code>themes</code> task is called, and this file will be used further when a new <code>JFreeChart</code> object gets created. 
<br/>
In order to make available Castor XML Mapping-based chart themes, in the jasperreports_extension.properties file the following lines should be uncommented:
<br/>
<br/>
<code>
net.sf.jasperreports.extension.registry.factory.xml.chart.themes=net.sf.jasperreports.chartthemes.simple.XmlChartThemeExtensionsRegistryFactory
<br/>
net.sf.jasperreports.xml.chart.theme.simple=net/sf/jasperreports/chartthemes/simple/simple.jrctx
</code>
<br/>
<br/>
All other lines in the file have to be commented.
<br/>
<br/>

<b>Using chart themes</b>
<br/>
<br/>
Themes can be associated globally with all charts by using the following configuration property in the jasperreports.properties file:
<br/>
<br/>
<code>net.sf.jasperreports.chart.theme=theme_name</code>
<br/>
<br/>
This configuration property can be used at report level too, in order to override the chart theme to be used for the current report:
<br/>
<br/>
<code>&lt;property name="net.sf.jasperreports.chart.theme" value="theme_name"/&gt;</code>
<br/>
<br/>
Changing the chart theme is also possible at chart element level using the <code>theme</code> attribute:
<br/>
<br/>
<code>&lt;chart theme="theme_name"&gt;
<br/>
...
<br/>
&lt;/chart&gt;
</code>
<br/>
<br/>
<b>Running the Sample</b>
<br/>
<br/>
Running the sample requires the <a href="http://ant.apache.org/">Apache Ant</a> library. Make sure that <code>ant</code> is already installed on your system (version 1.5 or later).
<br/>
In a command prompt/terminal window set the current folder to <code>demo/samples/chartthemes</code> within the JasperReports source project and run the <code>&gt; ant test view</code> command.
<br/>
It will generate all supported document types containing the sample report in the <code>demo/samples/chartthemes/build/reports</code> directory. 
<br/>
Then the report will open in the JasperReports internal viewer.
    </content>
  </feature>

</sample>
