Right Outer Join

17 April 2011

Useful Chart Customizers in JasperReports, iReport, and JasperReports Server

Useful Chart Customizers in JasperReports, iReport, and JasperReports Server

In a previous article I described some reasons that chart customizers are useful and gave some links to useful resources. (I’ll call that article “Chart Customizers 1″.) If you are not already familiar with chart customizers, then please read Chart Customizers 1 before reading this one. If you are already familiar with them, then please skim Chart Customizers 1 before reading this one.

Overview

“Chart Customizers 1″ explained what chart customizers are and provided some code. It was useful for Java developers. It made all changes as hard-coded settings, so the samples were not immediately useful for anyone without further coding.

“Chart Customizers 2″ (this article) provides a useful chart customizer and describes why it’s useful. You can immediately use it to solve some common problems (no coding required!).

If you just want to grab the chart customizer (binary and source) scroll all the way to the bottom.

Using Additional Properties

The concept of “properties” is a key idea that was missing in “Chart Customizers 1″. Using properties lets you set values in the report (in the .jrxml file) rather than hard-coding them as I did in my earlier sample. As one would hope (expect?) it’s simple. The chart customizer extends JRAbstractChartCustomizer. Therefore we can get the chart properties like this:

JRPropertiesMap pm = jasperChart.getPropertiesMap();

Then we can get a particular property like this:

double upperMargin = (pm.getProperty("UpperMargin") == null) ? -1 : Double.parseDouble(pm.getProperty("UpperMargin"));

This is the addition that made it possible for me to extend my chart customizers from being purely proof of concept samples to being useful chart customizers.

Bar Chart Improvements

Integer Tick Marks

Let’s start with some common requests for bar charts. Perhaps the most common request that I have seen is to prevent charts from showing non-integer values on value axis. Here’s an example. The number of times that a person shopped on a particular day is necessarily an integer. I don’t want to see “2.5″ on the chart axis.

The bars are completely accurate. Yet it's annoying to have the non-decimal value displayed.

How easy is it to tell JFreeChart to only use integers? Really easy! Hooray! It has a method called “createIntegerTickUnits()”. By the way, if you’re doing any significant work with JFreeChart then you should buy their Developer Guide. It’s well done.

How easy is it tell iReport and JasperReports to use only this method? Impossible. That’s a big bummer.

Fortunately, we can amend that somewhat pessimistic answer like this:

How easy is it tell iReport and JasperReports to use only integers? Really easy if we use a chart customizer! Hooray! It’s a single line. Since we might not always want this applied, we can surround it by an if statement:

if (useIntegerTickUnits) {
	valueAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
}

Now if I add the property “IntegerTickUnits” with the value “true” to my bar chart I’ll only get integers.

On the chart "Shopping Days" I set this property

If I set the value to “false” (or to anything besides “true”) or if I don’t set the property at all, then I get the standard behavior. If you’re new to JasperReports Server then refer to the Detailed Steps at the end of this article to exactly exactly what you need to do to apply this chart customizer.

The bars look much better when aligned with tick marks (or exactly half way between them)

Category Labels on multiple lines

By default there is no way to tell the chart to use multiple lines to display a category label. Again it’s easy in JFreeChart, so it’s easy in a chart customizer. Now I just have to add the property “MaximumCategoryLabelLines” with the value “2″ to my chart to get what I want.

Who is it that drank more ţuică?

Now its clear that I ate more hot dogs.

Using more space for category labels

JFreeChart is nice enough to truncate long labels for me. But it’s quite restrictive about how large it lets the labels be. A call to setMaximumCategoryLabelWidthRatio let’s me allot more space for the labels. Here’s an alternative solution to the previous problem where labels are cut off.

Who is it that ate more hot dogs?

Alternative solution increases the width allowed for the labels

Space between bars

The default amount of space put between the bars within each category is pretty generous. That can be reduced as a percentage of the available space. I added this to the .jrxml (well, iReport adds this to the .jrxml) to completely eliminate the space between bars:

<property name="ItemMargin" value="0.0f"/>

In some charts its more effective to remove the space between bars

Upper Margin

I will not bother showing this property since it’s covered in “Chart Customizers 1″. The only difference now is that in that case I hard-coded the margin to .40. Now I can set that percentage as a property in the chart.

Pie Chart Improvements

My most common annoyance with pie charts was when I put several pie charts onto the same page to show a trend. There is no easy way to specify a color for a named section. It’s easy to specify a color for the first section and a color for the second section. This is often sufficient. But this has the potential to be extremely confusing when two different charts have different items or when they have the same items returned in a different order. The following sample report shows the idea clearly.

Passing in the colors for the sections in a pie chart is the most complex piece in all of my chart customizers. I give a special thank you to Teodor Danciu for the idea and to Luke Shannon for help with some implementation details.

You must create a property on the chart called “Predefined Colors”. The property value is a String containing key:value pairs separated from each other by semi-colons. For example, for a report that I run which shows the databases that JasperReports Server instances use for their repository database I pass this string:

MySQL:#015A84;Oracle:red;PostgreSQL:#0085B0;Microsoft SQL Server:#F8EB33

For most databases I choose a color using RGB values. For Oracle I use the shorthand syntax “red”. These values get converted into colors using a utility class that is built-in to JasperReports: http://jasperreports.sourceforge.net/api/net/sf/jasperreports/engine/type/ColorEnum.html

To see exactly how it’s done, refer to the sample report (Pie_Specified_Series_Colors.jrxml) and to the comments in the chart customizer (PieLabels.java).

These are some of the most common chart tweaks that I have seen. Some are ones that I have needed myself, and others are ones that I have seen requested on JasperForge. Please let me know if you find the chart customer useful, and let me know what other properties you would find useful in a chart customizer.

Detailed Steps to update a report

Here are the steps I followed to apply my new chart customizer to an existing report. This is the report “Customer Overview” that ships with Jaspersoft BI evaluation version. So you can easily apply this chart customizer to that sample before trying it on your own charts.

  1. Upload ChartCustomizers2.jar into JasperReports Server. (Use either the web UI or iReport’s JasperReports Server plug-in.)
  2. Edit the report to add a link to the resource ChartCustomizers2.jar. (Use either the web UI or iReport’s JasperReports Server plug-in.)
  3. Edit the report in iReport to make two changes:
    1. Find the property “Customizer Class” and set it to “com.jaspersoft.bizdev.BetterBarLabels” (without the quotes).
    2. Find the property “Properties expressions” and add a new property called “IntegerTickUnits” with the value “true” (without the quotes in both cases).
  4. Save the report back to JasperReports Server. Run the report.

Sample reports and the Chart Customizer

WordPress seems to lose my attachments with some regularity. So instead of using that I’ll try GoogleDocs for sharing my samples.

  • Chart Customizer 2 – This is a .jar file. Just add it to your classpath and you can use it. The .jar also includes the source .java files.
  • Pie Chart sample report JRXML
  • Pie Chart sample report PDF
Advertisement

18 Comments »

  1. Romanian by any chance ? :)
    “tuica” got my attention

    Comment by John — 4 May 2011 @ 03:39

  2. I’m glad you noticed the reference. I’m not Romanian, but I chose that example as a reference to the founder of JasperReports, Teodor Danciu, who is.

    Comment by mdahlman — 12 May 2011 @ 15:41

  3. Matt, your jar file attachment seems to have gone missing – I’m getting an IE error when I try to download it. The jrxml and pdf are ok.

    Comment by Christine — 19 May 2011 @ 22:29

    • Strange. It’s still working well for me using Chrome and Firefox. Try with this link to the .jar file:

      Comment by mdahlman — 20 May 2011 @ 10:41

  4. Im having a pie chart and a stacked 3d bar chart in the same page with values for same category. I used Pie_Specified_Series_Colors.jrxml) example to fix the issue in pie chart. how to fix the same in stacked 3d bar char. Can you help?

    Comment by Anand — 2 September 2011 @ 12:30

    • I’m relatively sure that it should be possible to the same thing for stacked bar charts. Sorry, I have never tried that, so I don’t have any specific advice. I would begin by taking a look at the JFreeCharts API to see how to control series colors in stacked bar charts.

      Comment by mdahlman — 2 September 2011 @ 13:55

      • Thanks dahlman

        I found the answer
        i did it this way
        categoryPlot.getRenderer().setSeriesPaint(i, (Paint)colorMap.get(rowKey));

        where the colorMap is something like your piesections in yor example.
        i runs through – dataset.getRowCount()

        Comment by Anand — 13 September 2011 @ 13:27

      • Would you mind sharing your jar file that includes the customization for your stacked bar chart color control?

        Comment by Christine — 23 November 2011 @ 15:01

  5. Thanks so much for this code! Definitely saved me some time.

    For anyone else that wants a pie chart with colors that stay the same:

    On the chart itself set the Customizer Class property to com.jaspersoft.bizdev.PieLabels

    Set the property named “PredefinedColors” without a space in the name.

    Comment by sjbotha — 12 September 2011 @ 11:20

  6. I have been trying to resolve this issue with my charting for months (where the pie chart color ties to the specific slice). I think this is exactly what I need, but I am not successful getting the ChartCustomizer2 to apply the property PreDefinedColors to my report. I added the report to the Jasper Report as a resource, then added the property to the chart.

    This is the first time I’ve tried applying a chart customizer, so is there something you think I am missing?

    Thanks in advance,
    Christine

    Comment by Christine — 23 November 2011 @ 11:01

  7. Will the integer tick units property work on a time series chart?

    Comment by kathy — 30 December 2011 @ 14:54

    • Never mind.. now it’s working. Thanks for the tool it’s awesome! Now, how do I go about building my own? I studied java a long time ago, I downloaded Eclipse, what would be my next step?

      Comment by kathy — 30 December 2011 @ 16:01

  8. Hello,

    I want to extend your great customizers. How is it possible to debug in the customizers?

    Thanks.

    Comment by stefansta — 12 January 2012 @ 10:35

    • I’m really glad you’re finding them useful. The source is all there, so you should be able to open it in the IDE of your choice and work with it.

      Comment by mdahlman — 12 January 2012 @ 11:04

  9. Hallo,

    I am not sure which debugger to use and how to configure that the ireport is startet out of my IDE. Which IDE do you use?

    Thanks.

    Comment by stefansta — 12 January 2012 @ 11:17

  10. Hi there,

    I am using ireport and have added the jar to my classpath. I think added “com.jaspersoft.bizdev.BetterBarLabels” to customizer class and added the property for “IntegerTickUnits” and set True however when I try to run my report I get a java.lang.NullPointerException  at com.jaspersoft.bizdev.BetterBarLabels.customize(BetterBarLabels.java:49

    Do you have ideas what I may be doing wrong?

    Thanks,

    Scott

    Comment by Scott Crawford — 9 February 2012 @ 03:27

    • This is line 49:
      double upperMargin = (pm.getProperty(“UpperMargin”) == null) ? -1 : Double.parseDouble(pm.getProperty(“UpperMargin”));

      It’s not supposed to be possible to get a Null Pointer Exception there. I guess that you have not set the property “UpperMargin”. That should be OK. Try adding the property UpperMargin and setting it to .05 (which is 5%), and see what happens. If that solves it… then my chart customizer seems to have a bug, but at least you have a simple workaround.

      If you still have a problem, please open a thread on the JasperReports forum on jasperforge.org. Include the full stack trace. Post here to let me know that the thread is started, and I’ll take a look.

      Comment by mdahlman — 9 February 2012 @ 09:14

      • I found a way that my chart customizer throws a Null Pointer Exception. If you have not set any properties at all on the chart, then the JRPropertiesMap is not just empty but null. So subsequent attempts to retrieve properties yield NPEs rather than the intended result of retrieving the value or retrieving nothing for unset values. It’s a simple fix. I’ll post it someday.

        Comment by mdahlman — 21 February 2012 @ 22:39


RSS feed for comments on this post. TrackBack URI

Go on... leave a reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Theme: Silver is the New Black. Blog at WordPress.com.

Follow

Get every new post delivered to your Inbox.