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:
public class AmisDrawingSupplier implements DrawingSupplier {
private static Stroke stroke = new BasicStroke();
private static Shape shape = new Rectangle2D.Double();
private int cursor = 0;
private List<Color> colorList;
public LocatusDrawingSupplier(List<Color> colorList) {
this.colorList = colorList;
}
public Paint getNextPaint() {
if (colorList == null || colorList.size() == 0) {
return Color.RED; //return red on empty or no list
}
Color returnColor=colorList.get(cursor);
cursor++;
//wrap cursor when all items in the list are traversed
if (cursor >= colorList.size()) {
cursor = 0;
}
return returnColor;
}
public Paint getNextOutlinePaint() { return Color.BLACK; }
public Stroke getNextStroke() { return stroke; }
public Stroke getNextOutlineStroke() { return stroke; }
public Shape getNextShape() { return shape; }
}
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:
JFreeChart chart = ... create chart here ...
List<Color> colorList = .. create list with colors here ...
CategoryPlot cp = chart.getCategoryPlot();
DrawingSupplier ds = new AmisDrawing
Supplier(colorList);
cp.setDrawingSupplier(ds);
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.
Dave thanks a lot …
your help made it very easy
Thanks Dave!
Your solution works as a charm !
Never been easier to change the bar’s color…
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);
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?
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.
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.
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!
Seems pretty straightforward to me… but… how does your implementation differ from the DefaultDrawingSupplier from JFreeChart? You can pass a color sequence in it’s constructor (haven’t tried it though). http://www.jfree.org/jfreechart/api/gjdoc/org/jfree/chart/plot/DefaultDrawingSupplier.html
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?