Kettch19
Kettch19

Reputation: 404

jFreeChart custom domain axis labels

I'm hoping someone can help me with setting a custom label for the domain axis tick labels within a jFreeChart being created by Jasper Reports. I've tried everything that I've found online and still no dice. Here's my code:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.util.List;

import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.SymbolAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.CategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.data.Range;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.text.TextBlock;
import org.jfree.text.TextUtilities;
import org.jfree.ui.RectangleEdge;

import net.sf.jasperreports.engine.JRChart;
import net.sf.jasperreports.engine.JRChartCustomizer;

public class ChartCustomizer  implements JRChartCustomizer{
    public class CustomColorRenderer extends BarRenderer {
        private static final long serialVersionUID = -9045170581109026224L;

        @Override 
        public Paint getItemPaint(int row, int col) {
            CategoryDataset currentDataset = getPlot().getDataset();

            String columnKey = (String) currentDataset.getColumnKey(col);
            String[] columnKeyValues = columnKey.split(":");

            if(columnKeyValues.length < 2) return getSeriesPaint(row);

            String columnActualEstimated = columnKeyValues[2];
            if(columnActualEstimated.equals("A")) {
                return Color.RED;
            } else if(columnActualEstimated.equals("E")) {
                return Color.BLUE;
            }       

            return getSeriesPaint(row);
        }
    }

    public void customize(JFreeChart chart, JRChart jasperChart)
    {
        if(jasperChart.getChartType() == JRChart.CHART_TYPE_BAR) {
            CategoryPlot plot = chart.getCategoryPlot();
            CategoryDataset currentDataset = plot.getDataset();
            double maxValue = Double.MIN_VALUE;

            // Scan to get total max value for the chart in order to set chart height appropriately
            for(int i = 0; i < currentDataset.getRowCount(); i++) { 
                //System.out.println(i);
                for(int j = 0; j < currentDataset.getColumnCount(); j++) {
                    Number numberValue = currentDataset.getValue(i, j);

                    //System.out.println("Column " + j + " key: " + currentDataset.getColumnKey(j));

                    double value = numberValue == null ? Double.NaN : numberValue.doubleValue();
                    if(value > maxValue) {
                        maxValue = value;
                    }
                }
            }

            // Add 10% to top margin
            double tenPercent = maxValue * 0.1;
            maxValue = (Math.round((maxValue * 1.1) / tenPercent) * tenPercent) + tenPercent;

            // Set max bar height to max value
            ValueAxis yAxis = plot.getRangeAxis();
            yAxis.setAutoRange(false);
            yAxis.setRange(0, maxValue);

            CategoryAxis xAxis = plot.getDomainAxis();

            // Set label font size
            xAxis.setTickLabelFont(new Font("Arial", Font.PLAIN, 4));

            // Will set single bar colors by value with a custom renderer
            CustomColorRenderer customRenderer = new CustomColorRenderer();

            // Set the chart to apply the custom renderer
            plot.setRenderer(customRenderer);
        }
    }
}

Here is what my chart looks like currently:

Chart example

Note that the domain axis is displaying keys such as "1:N:A". In this case, 1 refers to the order, N refers to November, A refers to the value being "Actual" vs. "Estimated" which are the two series. All I'd like to do is change the visible tick label to "Nov" for the "1:N:A" example. Things like custom label generators change the labels for other parts of the chart and not the tick labels. I can set the tick label fonts successfully but just cannot seem to get the labels themselves to change.

Edit: The other tricky part about this situation is that the requirement is to display 13 months comprising the previous 11, current, and the upcoming. The upcoming month is always an estimated value, hence the "A" and "E" series). This makes it painful since that means there's always a duplicate month therefore columns that will want to merge.

Any help would be appreciated. Let me know if more info is needed.

Crossposted to http://www.jfree.org/forum/viewtopic.php?f=3&t=117811

Upvotes: 1

Views: 3492

Answers (1)

trashgod
trashgod

Reputation: 205785

A custom CategoryItemLabelGenerator, which is typically used to label the bars, is probably not the right choice for this. As shown here, a CategoryAxis obtains the text of the category labels from the column keys of the CategoryDataset via the plot's getCategoriesForAxis() method. You can specify the desired keys when you create the dataset.

Upvotes: 1

Related Questions