Question

Is there a way to accomplish the following in JFreeChart?

I am specifically asking about the elegantly printed numbers at the top of each bar. In this particular specimen it is easy to guess the values but such a feature would be useful if the y-axis run in the thousands or more. In such a case, the length of the bar wouldn't much help to discover the exact value.

enter image description here

Was it helpful?

Solution

Yes, it is possible. You need to specify ItemLabelPosition in CategoryItemLabelGenerator.

For example:

renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setBaseItemLabelsVisible(true);
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, 
        TextAnchor.TOP_CENTER);
renderer.setBasePositiveItemLabelPosition(position);

EDIT:

enter image description here

import javax.swing.JFrame;
import javax.swing.SwingUtilities;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.ui.TextAnchor;

public class DemoBarChart {
    public DemoBarChart() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        dataset.setValue(6, "test", "A");
        dataset.setValue(7, "test", "B");
        dataset.setValue(15, "test", "C");

        JFreeChart chart = ChartFactory.createBarChart(
                "Demo", "Test", "Value", dataset,
                PlotOrientation.VERTICAL, false, false, false);

        CategoryItemRenderer renderer = ((CategoryPlot)chart.getPlot()).getRenderer();

        renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
        renderer.setBaseItemLabelsVisible(true);
        ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, 
                TextAnchor.TOP_CENTER);
        renderer.setBasePositiveItemLabelPosition(position);

        JFrame frame = new JFrame("DemoTable");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(new ChartPanel(chart));
        frame.setLocationByPlatform(true);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new DemoBarChart();
            }
        });
    }
}

EDIT (version 1.5.0):

In current JFreeChart version (1.5.0), the "Base" in methods name has changed to Default.

For example:

renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setDefaultItemLabelsVisible(true);
ItemLabelPosition position = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, 
        TextAnchor.TOP_CENTER);
renderer.setDefaultPositiveItemLabelPosition(position); 

OTHER TIPS

As per new version if you don't set Position ItemLabelPosition

Just add and it will automatically set Value OutSide Top of bar And Sometime it will hide Max Bar value as Max Limit of X-Axis so you have to Increase X Axis Limit by margin

BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator(
            "{1}", NumberFormat.getInstance()));
renderer.setBaseItemLabelsVisible(true);

NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); 
rangeAxis.setUpperMargin(0.15); 

But If you want to change Bar Value Position You can try Like

For center

renderer.setPositiveItemLabelPosition(new ItemLabelPosition( 
         ItemLabelAnchor.CENTER, TextAnchor.CENTER, TextAnchor.CENTER, 
         - 0 / 2));

For Top Inside of Bar

renderer.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12,TextAnchor.TOP_CENTER  ));

For Adding value's Font Style and modify as per your needed

renderer.setItemLabelFont(new Font("SansSerif", Font.PLAIN, 12));
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top