Changing the colors of a bar chart in JFreeChart – Does it really have to be this much work?

9
Share this on .. Tweet about this on Twitter0Share on LinkedIn0Share on Facebook0Share on Google+0Email this to someoneShare on TumblrBuffer this page

The default colors of the first two bars in a bar chart are red and blue. We created a chart for a customer, but he wanted red and green bars. Changing that color takes about five minutes, I thought. But when I tried it, it took me way more time.

First of all I think that JFreeChart should rename itself to JNotSoFreeChart, when I look for documentation I only see this : “> Click here to BUY the JFreeChart Developer Guide <“. Of course it’s great that we can use JFreeChart for free, but at least provide a little bit of documentation and write a book that people can buy in a store. AMIS wil definitely buy that book.

I hooked up the debugger to our chart drawing class and found out that the colors come from an object that implements the DrawingSupplier interface. I can’t find a way to create such an object, so I had to create one myself.
As we can see in the javadoc of DrawingSupplier we have to implement 5 methods. For a simple bar chart the outline, outline stroke, shape and stroke will always be the same, so we can use static fields for these objects.

My implementation of DrawingSupplier:

<code>
<span style="color: #7f0055;"><strong>public class </strong></span><span style="color: #000000;">AmisDrawingSupplier </span><span style="color: #7f0055;"><strong>implements </strong></span><span style="color: #000000;">DrawingSupplier </span><span style="color: #000000;">{</span>


<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>private static </strong></span><span style="color: #000000;">Stroke stroke = </span><span style="color: #7f0055;"><strong>new </strong></span><span style="color: #000000;">BasicStroke</span><span style="color: #000000;">()</span><span style="color: #000000;">;</span>
<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>private static </strong></span><span style="color: #000000;">Shape shape = </span><span style="color: #7f0055;"><strong>new </strong></span><span style="color: #000000;">Rectangle2D.Double</span><span style="color: #000000;">()</span><span style="color: #000000;">;</span>
<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>private </strong></span><span style="color: #7f0055;"><strong>int </strong></span><span style="color: #000000;">cursor = </span><span style="color: #990000;">0</span><span style="color: #000000;">;</span>
<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>private </strong></span><span style="color: #000000;">List&lt;Color&gt; colorList;</span>

<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>public </strong></span><span style="color: #000000;">LocatusDrawingSupplier</span><span style="color: #000000;">(</span><span style="color: #000000;">List&lt;Color&gt; colorList</span><span style="color: #000000;">) {</span>
<span style="color: #ffffff;">        </span><span style="color: #7f0055;"><strong>this</strong></span><span style="color: #000000;">.colorList = colorList;</span>
<span style="color: #ffffff;">    </span><span style="color: #000000;">}</span>

<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>public </strong></span><span style="color: #000000;">Paint getNextPaint</span><span style="color: #000000;">() {</span>
<span style="color: #ffffff;">        </span><span style="color: #7f0055;"><strong>if </strong></span><span style="color: #000000;">(</span><span style="color: #000000;">colorList == </span><span style="color: #7f0055;"><strong>null </strong></span><span style="color: #000000;">|| colorList.size</span><span style="color: #000000;">() </span><span style="color: #000000;">== </span><span style="color: #990000;">0</span><span style="color: #000000;">) {</span>
<span style="color: #ffffff;">            </span><span style="color: #7f0055;"><strong>return </strong></span><span style="color: #000000;">Color.RED; </span><span style="color: #3f7f5f;">//return red on empty or no list</span>
<span style="color: #ffffff;">        </span><span style="color: #000000;">}</span>

<span style="color: #ffffff;">        </span><span style="color: #000000;">Color returnColor=colorList.get</span><span style="color: #000000;">(</span><span style="color: #000000;">cursor</span><span style="color: #000000;">)</span><span style="color: #000000;">;</span>

<span style="color: #ffffff;">        </span><span style="color: #000000;">cursor++;</span>

<span style="color: #ffffff;">        </span><span style="color: #3f7f5f;">//wrap cursor when all items in the list are traversed</span>
<span style="color: #ffffff;">        </span><span style="color: #7f0055;"><strong>if </strong></span><span style="color: #000000;">(</span><span style="color: #000000;">cursor &gt;= colorList.size</span><span style="color: #000000;">()) {</span>
<span style="color: #ffffff;">            </span><span style="color: #000000;">cursor = </span><span style="color: #990000;">0</span><span style="color: #000000;">;</span>
<span style="color: #ffffff;">        </span><span style="color: #000000;">}</span>

<span style="color: #ffffff;">        </span><span style="color: #7f0055;"><strong>return </strong></span><span style="color: #000000;">returnColor;</span>
<span style="color: #ffffff;">    </span><span style="color: #000000;">}</span>

<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>public </strong></span><span style="color: #000000;">Paint getNextOutlinePaint</span><span style="color: #000000;">() { </span><span style="color: #7f0055;"><strong>return </strong></span><span style="color: #000000;">Color.BLACK; </span><span style="color: #000000;">}</span>
<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>public </strong></span><span style="color: #000000;">Stroke getNextStroke</span><span style="color: #000000;">() { </span><span style="color: #7f0055;"><strong>return </strong></span><span style="color: #000000;">stroke; </span><span style="color: #000000;">}</span>
<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>public </strong></span><span style="color: #000000;">Stroke getNextOutlineStroke</span><span style="color: #000000;">() { </span><span style="color: #7f0055;"><strong>return </strong></span><span style="color: #000000;">stroke; </span><span style="color: #000000;">}</span>
<span style="color: #ffffff;">    </span><span style="color: #7f0055;"><strong>public </strong></span><span style="color: #000000;">Shape getNextShape</span><span style="color: #000000;">() { </span><span style="color: #7f0055;"><strong>return </strong></span><span style="color: #000000;">shape; </span><span style="color: #000000;">}</span>
<span style="color: #000000;">}</span></code>

I decided to give my DrawingSupplier a list with colors, when you prefer an array or random colors that’s also fine.

The final step is hooking up the DrawingSupplier to your chart:

<code>
<span style="color: #000000;">JFreeChart chart = ... create chart here ...</span>
<span style="color: #000000;">List&lt;Color&gt; colorList = .. create list with colors here ...</span>
<span style="color: #000000;">CategoryPlot cp = chart.getCategoryPlot</span><span style="color: #000000;">()</span><span style="color: #000000;">;</span>
<span style="color: #000000;">DrawingSupplier ds = </span><span style="color: #7f0055;"><strong>new </strong></span><span style="color: #000000;">AmisDrawing
Supplier</span><span style="color: #000000;">(</span><span style="color: #000000;">colorList</span><span style="color: #000000;">)</span><span style="color: #000000;">;</span>
<span style="color: #000000;">cp.setDrawingSupplier</span><span style="color: #000000;">(</span><span style="color: #000000;">ds</span><span style="color: #000000;">)</span><span style="color: #000000;">;</span></code>

And here the final result:

Conclusion

Well, that wasn’t to difficult wasn’t it?, it’s only too much work for such a simple thing.
Maybe I overlooked something, but I’m afraid this is the easiest way to change the color of a bar.

Share this on .. Tweet about this on Twitter0Share on LinkedIn0Share on Facebook0Share on Google+0Email this to someoneShare on TumblrBuffer this page

About Author

Oracle Consultant at AMIS

9 Comments

  1. Try this (apologies if the formatting is bad):

    CategoryPlot plot = (CategoryPlot) chart.getPlot();
    BarRenderer renderer = (BarRenderer) plot.getRenderer();
    renderer.setSeriesPaint(0, Color.red);
    renderer.setSeriesPaint(1, Color.green);

  2. Marc, when using commons-io you can do the following:
    File file = new File(“/commons/io/project.properties”);
    List lines = FileUtils.readLines(file, “UTF-8″);
    It also has stuff like line iterators resembling the way Ruby lets you access files. How much easier should it be?

  3. Jeroen van Wilgenburg on

    I think I didn’t look at the Javadoc at that time. Clicking on implement methods in my IDE has become to easy I guess ;-)

    The static fields are what I meant with default sequences.

    This makes this blog a bit useless, but at least someone else will find out how to do it when searching on google ;-)

    Mark >> With most open source libraries things actually become easier, there probably is an open source library that does IO for you the easy way. But I understand what you mean, things with Dates are also way too strange in Java.

  4. As you can see the DefaultDrawingSupplier has a couple of static fields containing the default sequences (like DEFAULT_OUTLINE_STROKE_SEQUENCE) which you can use to construct the new object. Strange that you didn’t see it though; it’s the only implementing class of the DrawingSupplier interface.

  5. Jeroen van Wilgenburg on

    I didn’t find the DefaultDrawingSupplier when I was figuring out how to do it. But it should do the trick, only drawback is that you have to put all the default sequences in the constructor when you only want a different paint sequence. But it is still way shorter than my idea. Thanks!

  6. Mark Hatham on

    But isn’t that the mantra of the Java World? Make things hard for things that should be much simpler.

    How to read a file?