Consider a smaller version of this example:
public class LayeredBarChartDemo2 extends ApplicationFrame {
public LayeredBarChartDemo2(final String title) {
super(title);
final double[][] data = new double[][] { { 55, 60 }, { 25.0, 13.0 } };
final CategoryDataset dataset = DatasetUtils.createCategoryDataset("Series ", "Factor ", data);
// create the chart...
final CategoryAxis categoryAxis = new CategoryAxis("Category");
final ValueAxis valueAxis = new NumberAxis("Score (%)");
final CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, new LayeredBarRenderer());
final JFreeChart chart = new JFreeChart("Layered Bar Chart Demo 2", JFreeChart.DEFAULT_TITLE_FONT, plot, true);
final LayeredBarRenderer renderer = (LayeredBarRenderer) plot.getRenderer();
// add the chart to a panel...
final ChartPanel chartPanel = new ChartPanel(chart);
chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
setContentPane(chartPanel);
}
public static void main(final String[] args) {
final LayeredBarChartDemo2 demo = new LayeredBarChartDemo2("Layered Bar Chart Demo 2");
demo.pack();
demo.setVisible(true);
}
}
It produces:
I want to add labels on it, and make it look like this:
I have tried what works for other renderers:
renderer.setDefaultItemLabelsVisible(true);
Or:
renderer.setSeriesItemLabelsVisible(0, true);
renderer.setSeriesItemLabelsVisible(1, true);
I also tried to declare a CategoryItemLabelGenerator
explicitly:
renderer.setDefaultItemLabelGenerator(new CategoryItemLabelGenerator() {
@Override
public String generateRowLabel(CategoryDataset dataset, int row) {
return "sasa";
}
@Override
public String generateLabel(CategoryDataset dataset, int row, int column) {
return "lalal";
}
@Override
public String generateColumnLabel(CategoryDataset dataset, int column) {
return "ababa";
}
});
(I also tried using setSeriesItemLabelGenerator(series, CategoryLabelGenerator)
too).
I changed the font & the paint in case they are there but I just do not see them.
I use JFreeChart 1.5.0.
Is there a way to add the labels?
The apparent bug identified here by @George Z. hinges on an incorrect value calculated by the LayeredBarRenderer
implementation of drawVerticalItem()
when it calls drawItemLabel()
as shown here. The predicate transX1 > transX2
should be inverted.
As a workaround when using v1.5, it's possible to specify a negative ItemLabelPosition
, as shown the variation below.
ItemLabelPosition position = new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setDefaultNegativeItemLabelPosition(position);
As the implementation of drawHorizontalItem()
appears correct, a positive ItemLabelPosition
works as expected.
ItemLabelPosition position = new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE3, TextAnchor.CENTER_LEFT);
renderer.setDefaultPositiveItemLabelPosition(position);
In addition, a StandardCategoryToolTipGenerator
works as expected. You can customize the DEFAULT_TOOL_TIP_FORMAT_STRING
as shown here and here.
renderer.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
Code:
import java.awt.Dimension;
import java.awt.EventQueue;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.ChartUtils;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.axis.ValueAxis;
import org.jfree.chart.labels.ItemLabelAnchor;
import org.jfree.chart.labels.ItemLabelPosition;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LayeredBarRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.general.DatasetUtils;
import org.jfree.chart.ui.ApplicationFrame;
import org.jfree.chart.ui.TextAnchor;
/** @see https://stackoverflow.com/a/63464855/230513 */
public class LayeredBarChartDemo2 extends ApplicationFrame {
private static final String TITLE = "Layered Bar Chart Demo 2";
public LayeredBarChartDemo2(final String title) {
super(title);
final double[][] data = new double[][]{{55, 60}, {25, 13}};
final CategoryDataset dataset = DatasetUtils.createCategoryDataset("Series ", "Factor ", data);
final CategoryAxis categoryAxis = new CategoryAxis("Category");
final ValueAxis valueAxis = new NumberAxis("Score (%)");
final LayeredBarRenderer renderer = new LayeredBarRenderer();
renderer.setDefaultToolTipGenerator(new StandardCategoryToolTipGenerator());
renderer.setDefaultItemLabelGenerator(new StandardCategoryItemLabelGenerator());
renderer.setDefaultItemLabelsVisible(true);
ItemLabelPosition position = new ItemLabelPosition(
ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER);
renderer.setDefaultNegativeItemLabelPosition(position);
final CategoryPlot plot = new CategoryPlot(dataset, categoryAxis, valueAxis, renderer);
plot.setOrientation(PlotOrientation.VERTICAL);
final JFreeChart chart = new JFreeChart(TITLE, JFreeChart.DEFAULT_TITLE_FONT, plot, true);
ChartUtils.applyCurrentTheme(chart);
add(new ChartPanel(chart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(640, 480);
}
});
}
public static void main(final String[] args) {
EventQueue.invokeLater(() -> {
final LayeredBarChartDemo2 demo = new LayeredBarChartDemo2(TITLE);
demo.pack();
demo.setLocationRelativeTo(null);
demo.setVisible(true);
});
}
}