Many examples of horizontal bar JfreeChart are available to be consulted. However, these examples often create complicated bar chart (too much decors) and far from real business report needs.
In this post I will show you how to custom and simplify (no axis, no title, no legend) the standard horizontal bar chart with JfreeChart. I will focus on :
- Customizing the space between bars and bar width (using BarRenderer – setMaximumBarWidth).
- Positioning the labels (outside the bars ItemLabelPosition)
- Creating a center line that separate the negative and positive bar on each row (add Maker to plot)
Bonus: an excellent work on bar chart margins and spacing can be found at:
http://stackoverflow.com/questions/16725545/closing-up-blank-space-in-jfreechart-bar-chart
Codes:
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.Marker;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.ValueMarker;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.general.DefaultKeyedValues2DDataset;
import org.jfree.data.general.KeyedValues2DDataset;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
import org.jfree.ui.TextAnchor;
import java.awt.*;
import java.text.NumberFormat;
public class TwoSidedBarChartDemo extends ApplicationFrame {
private static final long serialVersionUID = 1L;
public TwoSidedBarChartDemo() {
super("Two Sided Bar Chart Demo");
KeyedValues2DDataset keyedvalues2ddataset = createDataset();
// use stacked bar chart to have 2 columns on each row
JFreeChart jfreechart = ChartFactory.createStackedBarChart("", "", "", keyedvalues2ddataset, PlotOrientation.HORIZONTAL,
false, false, false);
jfreechart.setBackgroundPaint(new Color(255, 255, 255, 0));
CategoryPlot plot = (CategoryPlot) jfreechart.getPlot();
plot.setBackgroundPaint(Color.WHITE);
plot.setOutlineVisible(false);
plot.getDomainAxis().setVisible(false);
plot.getRangeAxis().setVisible(false);
// add 3 lines to the chart (1 black, 2 white) => seapration effect
Marker marker = new ValueMarker(0);
marker.setPaint(Color.black);
marker.setStroke(new BasicStroke(2));
plot.addRangeMarker(marker);
marker = new ValueMarker(0.12);
marker.setPaint(Color.WHITE);
marker.setStroke(new BasicStroke(1.5f));
plot.addRangeMarker(marker);
marker = new ValueMarker(-0.12);
marker.setPaint(Color.WHITE);
marker.setStroke(new BasicStroke(1.5f));
plot.addRangeMarker(marker);
BarRenderer renderer = (BarRenderer) plot.getRenderer();
renderer.setBarPainter(new StandardBarPainter());
// ajust the bar width and spacing between bars
renderer.setMaximumBarWidth(.03);
// custom columns color
renderer.setSeriesPaint(0, Color.RED);
renderer.setSeriesPaint(1, Color.BLUE);
renderer.setShadowVisible(false);
renderer.setBaseItemLabelGenerator(
new StandardCategoryItemLabelGenerator(
" {2} ", NumberFormat.getInstance()));
renderer.setBaseItemLabelsVisible(true);
renderer.setBaseItemLabelPaint(Color.BLACK);
// custom item labels position
ItemLabelPosition p1 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE11, TextAnchor.BASELINE_LEFT);
renderer.setBasePositiveItemLabelPosition(p1);
ItemLabelPosition p2 = new ItemLabelPosition(ItemLabelAnchor.OUTSIDE1, TextAnchor.BASELINE_RIGHT);
renderer.setBaseNegativeItemLabelPosition(p2);
plot.getDomainAxis().setCategoryMargin(0.5);
ChartPanel chartpanel = new ChartPanel(jfreechart);
chartpanel.setPreferredSize(new Dimension(500, 270));
setContentPane(chartpanel);
}
private KeyedValues2DDataset createDataset() {
DefaultKeyedValues2DDataset defaultkeyedvalues2ddataset = new DefaultKeyedValues2DDataset();
defaultkeyedvalues2ddataset.addValue(-6D, "Negative", "row 1");
defaultkeyedvalues2ddataset.addValue(-8D, "Negative", "row 2");
defaultkeyedvalues2ddataset.addValue(-11D, "Negative", "row 3");
defaultkeyedvalues2ddataset.addValue(-13D, "Negative", "row 4");
defaultkeyedvalues2ddataset.addValue(-14D, "Negative", "row 5");
defaultkeyedvalues2ddataset.addValue(-15D, "Negative", "row 6");
defaultkeyedvalues2ddataset.addValue(-19D, "Negative", "row 7");
defaultkeyedvalues2ddataset.addValue(10D, "Positive", "row 1");
defaultkeyedvalues2ddataset.addValue(12D, "Positive", "row 2");
defaultkeyedvalues2ddataset.addValue(13D, "Positive", "row 3");
defaultkeyedvalues2ddataset.addValue(14D, "Positive", "row 4");
defaultkeyedvalues2ddataset.addValue(15D, "Positive", "row 5");
defaultkeyedvalues2ddataset.addValue(17D, "Positive", "row 6");
defaultkeyedvalues2ddataset.addValue(19D, "Positive", "row 7");
return defaultkeyedvalues2ddataset;
}
public static void main(String args[]) {
TwoSidedBarChartDemo chartdemo = new TwoSidedBarChartDemo();
chartdemo.pack();
RefineryUtilities.centerFrameOnScreen(chartdemo);
chartdemo.setVisible(true);
}
}
And here is how the chart looks like:
HTH!