2
votes

I'm facing the below issue while using JFreeChart for creating bar chart with relatively large dataset:

Bar chart generated with overlapping X-axis labels. I have tried positioning the labels vertical, still no help. Please provide the best possible way to solve this issue. Code snipped below:

CategoryDataset categoryDataSet = getBarDataset();
JFreeChart barChart = ChartFactory.createBarChart("TITLE", "X-LABEL","Y-LABEL", categoryDataSet, PlotOrientation.VERTICAL, true, true, false);
barChart.getCategoryPlot().getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_90);
barChart.getCategoryPlot().getDomainAxis().setMaximumCategoryLabelLines(4);
jpg = Image.getInstance(im, null);
document.add(jpg);

Update: As per the suggestion from @trashgod, I've used SlidingCategoryDataset indexing from 0 to the column count. When the column count is large(50 here), the X-Label's are overlapping. When the column count is set to a lower number, it's working fine. I want to find a solution for large column size. Importantly, I need to export the chart image to pdf. Please help me in arriving to a feasible solution. Thanks!

    private static void createBarChart() throws DocumentException, IOException {
        Document document = new Document();
        PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(FILE_LOCN));
        writer.setStrictImageSequence(true);
        document.open();
        CategoryDataset categoryDataset = createDataset();
        int colCount = categoryDataset.getColumnCount();
        SlidingCategoryDataset slidingCategoryDataSet = new SlidingCategoryDataset(categoryDataset, 0, colCount);
        JFreeChart barChart = ChartFactory.createBarChart("TITLE", "X-LABEL","Y-LABEL", slidingCategoryDataSet, 
                PlotOrientation.VERTICAL, true, true, false);
        barChart.getCategoryPlot().getDomainAxis().setCategoryLabelPositions(CategoryLabelPositions.UP_90);
        barChart.getCategoryPlot().getDomainAxis().setMaximumCategoryLabelLines(4);
        java.awt.Image im = barChart.createBufferedImage(400, 400);
        Image jpg = Image.getInstance(im, null);
        jpg.scaleToFit(400, 400);
        document.add(jpg);
        document.close();
        writer.close();
    }

    private static CategoryDataset createDataset() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (int i = 0; i <= 50; i++) {
            dataset.addValue(i, "R", "C" + i);
        }
        return dataset;
    }

enter image description here

1
@trashgod I've tried it, but still the same issue.Shihad Salam
int colCount = categoryDataset.getColumnCount(); SlidingCategoryDataset slidingCategoryDataSet = new SlidingCategoryDataset(categoryDataset, 0, colCount); JFreeChart barChart = ChartFactory.createBarChart("TITLE", "X-LABEL","Y-LABEL", slidingCategoryDataSet, PlotOrientation.VERTICAL, true, true, false);Shihad Salam
Where do you set the count and index, for examplke? If this is not a duplicate, please edit your question to include a minimal reproducible example that shows your revised approach.trashgod
@trashgod, Edited the question with your suggestion of using SlidingCategoryDataset.Shihad Salam

1 Answers

2
votes

With a large number of categories, specifying vertical labels via setCategoryLabelPositions() is a good choice for maximizing legibility. Arbitrary CategoryLabelPositions are supported.

In an interactive chart, SlidingCategoryDataset, mentioned here, allows your application to set the count and starting index of visible categories as desired, perhaps using a slider or spinner, as shown here.

How can I achieve this in a PDF?…More pixels seems a good idea, but how can we implement that here?

In a fixed size context with a given number of categories, you can optimize the size of the chart image via createBufferedImage(), as shown here, or Image.scaleToFit(). For yet larger datasets, it may be possible to create multiple linked charts in a domain specific way, e.g. by year or subsidiary.