Search code examples
javajfreechart

JFreeChart: Bar chart X axis labels overlapping with large datasets


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


Solution

  • 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.