This week's book giveaway is in the OCMJEA forum.
We're giving away four copies of OCM Java EE 6 Enterprise Architect Exam Guide and have Paul Allen & Joseph Bambara on-line!
See this thread for details.
The moose likes Other Open Source Projects and the fly likes JFreeChart : Item Label in STack Bar Chart Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login

Win a copy of OCM Java EE 6 Enterprise Architect Exam Guide this week in the OCMJEA forum!
JavaRanch » Java Forums » Products » Other Open Source Projects
Bookmark "JFreeChart : Item Label in STack Bar Chart" Watch "JFreeChart : Item Label in STack Bar Chart" New topic

JFreeChart : Item Label in STack Bar Chart

Mohit Agarwal
Ranch Hand

Joined: Mar 30, 2004
Posts: 88
Hi ,
I am using JFreeChart(ver 0.9.21) for generating Group Stacked Bar Charts for my Application .

I come across a problem for which i had no answer .

In the GroupStacked Bar Chart, i need to display the data values for each stck of the bar .
Upto this point things are going fine, next i need to show at the top of the Stacked Bar the
total of the stack values , which i am unable to do .

TO further clarify take an example :
Country Average Production
USA 80
UK 55
India 40 .

So i need to draw a stacked bar chart for this case which will show the resopective data values
for each & at the top of the Stacked bar display the total which in this case comes out to be 175.

Pls. help me out for this .
Thanks in Advance ,
Chris Buttner

Joined: Sep 14, 2009
Posts: 1

I have a solution which worked for me on a recent projet.

Basically what I did was extended the StackedBarRender3D and override the drawStackVertical method.
Looking at the cource code of StackedBarRenderer3D, the last step in the drawStackVertical method is
to draw the item labels, which makes it very easy to add an extra step in my custom class to draw a new

Things to note are that the calculateLabelAnchorPoint was copied from org.jfree.chart.renderer.category.BarRenderer
as the method is a private method in the BarRender class.
The createFrontFace method contains code which was copied from the StackedBarRenderer3D class, however modified to only
calulate the path which makes up the front face of the stack.

public class CustomStackedBarRenderer3D extends StackedBarRenderer3D
private static final long serialVersionUID = 1L;

private boolean categoryTotal = false;

private static final int TOTAL_LABEL_OFFSET = -10;

public CustomStackedBarRenderer3D() {

public boolean getCategoryTotal() {
return categoryTotal;

public void setCategoryTotal(boolean value) {
categoryTotal = value;

protected void drawStackVertical(List values, Comparable category,
Graphics2D g2, CategoryItemRendererState state,
Rectangle2D dataArea, CategoryPlot plot,
CategoryAxis domainAxis, ValueAxis rangeAxis,
CategoryDataset dataset) {

super.drawStackVertical(values, category, g2, state, dataArea, plot, domainAxis, rangeAxis, dataset);

if(getCategoryTotal()) {
// draw our total item label. The drawItemLabel method exists in the BarRenderer class.
ItemLabelPosition position = null;

// get the column and the last row.
int column = dataset.getColumnIndex(category);
int row = dataset.getRowCount();

// calculate the total value and convert to a string for the label.
double total = DataUtilities.calculateColumnTotal(dataset, dataset.getColumnIndex(category));

// if the total is zero, the don't draw a label.
if(total <= 0.0d)

// only show total if there are three or more values in the stack.
if(values.size() < 3)

System.out.println("For the label " + Double.toString(total) + " size of values is: " + values.size() );
String label = Double.toString(total);

// get the label position.
position = getPositiveItemLabelPosition(row, column);

// calculate the bounds of the stack.
double barX0 = domainAxis.getCategoryMiddle(column,
dataset.getColumnCount(), dataArea, plot.getDomainAxisEdge())
- state.getBarWidth() / 2.0;
double barW = state.getBarWidth();
int blockCount = values.size() - 1;
Object[] prev = (Object[]) values.get(blockCount - 1);
Object[] curr = (Object[]) values.get(blockCount);
double v0 = ((Double) prev[1]).doubleValue();
double vv0 = rangeAxis.valueToJava2D(v0, dataArea,
double v1 = ((Double) curr[1]).doubleValue();
double vv1 = rangeAxis.valueToJava2D(v1, dataArea,

Shape frontFace = createFrontFace(barX0, barW, vv0, vv1);

// get anchor point i.e. bottom left of the label.
Point2D anchorPoint = calculateLabelAnchorPoint(
ItemLabelAnchor.OUTSIDE12, frontFace.getBounds2D(), plot.getOrientation());

anchorPoint.setLocation(anchorPoint.getX(), anchorPoint.getY() + TOTAL_LABEL_OFFSET);

// draw the label.
TextUtilities.drawRotatedString(label, g2,
(float) anchorPoint.getX(), (float) anchorPoint.getY(),
position.getTextAnchor(), position.getAngle(),

* Calculates the path which makes up the front face of the stack.
* Taken from the StackedBarRenderer3D class.
private Shape createFrontFace(double x0, double width, double y0, double y1) {
Point2D p00 = new Point2D.Double(x0, y0);
Point2D p01 = new Point2D.Double(x0 + width, y0);
Point2D p0 = new Point2D.Double(x0, y1);
Point2D p1 = new Point2D.Double(x0 + width, y1);

GeneralPath front = new GeneralPath();
front.moveTo((float) p0.getX(), (float) p0.getY());
front.lineTo((float) p1.getX(), (float) p1.getY());
front.lineTo((float) p01.getX(), (float) p01.getY());
front.lineTo((float) p00.getX(), (float) p00.getY());

return front;

* Calculates the item label anchor point. Taken from org.jfree.chart.renderer.category.BarRenderer
* @param anchor the anchor.
* @param bar the bar.
* @param orientation the plot orientation.
* @return The anchor point.
private Point2D calculateLabelAnchorPoint(ItemLabelAnchor anchor,
Rectangle2D bar,
PlotOrientation orientation) {

Point2D result = null;
double offset = getItemLabelAnchorOffset();
double x0 = bar.getX() - offset;
double x1 = bar.getX();
double x2 = bar.getX() + offset;
double x3 = bar.getCenterX();
double x4 = bar.getMaxX() - offset;
double x5 = bar.getMaxX();
double x6 = bar.getMaxX() + offset;

double y0 = bar.getMaxY() + offset;
double y1 = bar.getMaxY();
double y2 = bar.getMaxY() - offset;
double y3 = bar.getCenterY();
double y4 = bar.getMinY() + offset;
double y5 = bar.getMinY();
double y6 = bar.getMinY() - offset;

if (anchor == ItemLabelAnchor.CENTER) {
result = new Point2D.Double(x3, y3);
else if (anchor == ItemLabelAnchor.INSIDE1) {
result = new Point2D.Double(x4, y4);
else if (anchor == ItemLabelAnchor.INSIDE2) {
result = new Point2D.Double(x4, y4);
else if (anchor == ItemLabelAnchor.INSIDE3) {
result = new Point2D.Double(x4, y3);
else if (anchor == ItemLabelAnchor.INSIDE4) {
result = new Point2D.Double(x4, y2);
else if (anchor == ItemLabelAnchor.INSIDE5) {
result = new Point2D.Double(x4, y2);
else if (anchor == ItemLabelAnchor.INSIDE6) {
result = new Point2D.Double(x3, y2);
else if (anchor == ItemLabelAnchor.INSIDE7) {
result = new Point2D.Double(x2, y2);
else if (anchor == ItemLabelAnchor.INSIDE8) {
result = new Point2D.Double(x2, y2);
else if (anchor == ItemLabelAnchor.INSIDE9) {
result = new Point2D.Double(x2, y3);
else if (anchor == ItemLabelAnchor.INSIDE10) {
result = new Point2D.Double(x2, y4);
else if (anchor == ItemLabelAnchor.INSIDE11) {
result = new Point2D.Double(x2, y4);
else if (anchor == ItemLabelAnchor.INSIDE12) {
result = new Point2D.Double(x3, y4);
else if (anchor == ItemLabelAnchor.OUTSIDE1) {
result = new Point2D.Double(x5, y6);
else if (anchor == ItemLabelAnchor.OUTSIDE2) {
result = new Point2D.Double(x6, y5);
else if (anchor == ItemLabelAnchor.OUTSIDE3) {
result = new Point2D.Double(x6, y3);
else if (anchor == ItemLabelAnchor.OUTSIDE4) {
result = new Point2D.Double(x6, y1);
else if (anchor == ItemLabelAnchor.OUTSIDE5) {
result = new Point2D.Double(x5, y0);
else if (anchor == ItemLabelAnchor.OUTSIDE6) {
result = new Point2D.Double(x3, y0);
else if (anchor == ItemLabelAnchor.OUTSIDE7) {
result = new Point2D.Double(x1, y0);
else if (anchor == ItemLabelAnchor.OUTSIDE8) {
result = new Point2D.Double(x0, y1);
else if (anchor == ItemLabelAnchor.OUTSIDE9) {
result = new Point2D.Double(x0, y3);
else if (anchor == ItemLabelAnchor.OUTSIDE10) {
result = new Point2D.Double(x0, y5);
else if (anchor == ItemLabelAnchor.OUTSIDE11) {
result = new Point2D.Double(x1, y6);
else if (anchor == ItemLabelAnchor.OUTSIDE12) {
result = new Point2D.Double(x3, y6);

return result;


Martijn Verburg

Joined: Jun 24, 2003
Posts: 3274

Hi Chris and welcome to Javaranch!

Thanks for posting a answer for others to share (although the original Q was in 2005, so I'm not sure Mohit will see it!). Just so you know you can also use [code ] [ /code] (remove the space) tags to highlight your code samples.

Cheers, Martijn - Blog,
Twitter, PCGen, Ikasan, My The Well-Grounded Java Developer book!,
My start-up.
Consider Paul's rocket mass heater.
subject: JFreeChart : Item Label in STack Bar Chart