Is it possible to customize label for each category in bar chart?

|▌冷眼眸甩不掉的悲伤 提交于 2019-12-04 12:04:36

The answer depends on how your chosen CategoryDataset implements the KeyedValues2D interface. The interface expects the keys to be unique, and the default implementation, DefaultKeyedValues2D, requires that the keys be Comparable and immutable.

Unique String instances are the typical concrete parameter type, but nothing in JFreeChart enforces the unique constraint. One approach wold be to wrap your String in a class that implements Comparable and also enforces uniqueness. The class Value is an example that leverages the underlying Double implementation. Your implementation would require an additional attribute to distinguish one project form another, perhaps using the primary key of the source relation. You could override toString() to get a formatted representation of the name.

This is how I implement UniqueValue

public class UniqueValue implements Comparable<UniqueValue> {

    private final String uniqueId;
    private final String value;

    public UniqueValue(String uniqueId, String value) {
        this.uniqueId = uniqueId;
        this.value = value;
    }

    @Override
    public int compareTo(UniqueValue o) {
        return uniqueId.compareTo(o.uniqueId);
    }

    @Override
    public int hashCode() {
        return uniqueId.hashCode();
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj) {
            return true;
        }
        if (obj instanceof UniqueValue) {
            return uniqueId.equals(((UniqueValue)obj).uniqueId);
        }
        return false;
    }

    @Override
    public String toString() {
            return value;
        }
    }

You can use this class to deal with the uniqueness issue I mentioned in questions.


UPDATE

However, since JFreeChart use toString() method to create the label for categories. So the toString() implementation in UniqueValue can be pretty weird. So here is another attempt.

First, a generator interface

public interface CategoryLabelGenerator {
    public String generate(Comparable<?> category);
}

then I make a subclass for CategoryAxis

public class CategoryLabelCustomizableCategoryAxis extends CategoryAxis {

    private static final long serialVersionUID = 1L;
    private CategoryLabelGenerator labelGenerator;

    public CategoryLabelCustomizableCategoryAxis(String label) {
        super(label);
    }

    public void setCategoryLabelGenerator(CategoryLabelGenerator generator) {
        this.labelGenerator = generator;
    }

    @Override
    protected TextBlock createLabel(Comparable category, float width, 
        RectangleEdge edge, Graphics2D g2) {
        if (generator == null) {
            return super.createLabel(category, width, edge, g2);
        }
        return TextUtilities.createTextBlock(
            labelGenerator.generate(category),  // generate label for category on the fly
            getTickLabelFont(category), getTickLabelPaint(category), width,
            getMaximumCategoryLabelLines(), new G2TextMeasurer(g2));
    }
}

example :

JFreeChart chart = makeChart();
CategoryPlot plot = chart.getCategoryPlot();

CategoryAxis axis = new CategoryLabelCustomizableCategoryAxis();
axis.setCategoryLabelGenerator(new MyCategoryLabelGenerator());
plot.setDomainAxis(axis);

This is how I customize category label. (At least for chart that use CategoryAxis as domain axis..)

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!