Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rotate X-axis labels vertically #394

Open
sudarshansb143 opened this issue Mar 6, 2024 · 10 comments
Open

Rotate X-axis labels vertically #394

sudarshansb143 opened this issue Mar 6, 2024 · 10 comments

Comments

@sudarshansb143
Copy link

I want to show x-axis labels in complete vertical format just like the once mentioned in following diagram. I tried following code but none of them worked. Use case emerged because I want to fit a large date range on the x-axis

 CategoryAxis xAxis = (CategoryAxis) chart.getCategoryPlot().getDomainAxis();
 xAxis.setCategoryLabelPositions(CategoryLabelPositions.DOWN_90);
 xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90);
 xAxis.setCategoryLabelPositions(CategoryLabelPositions.STANDARD);

image

@trashgod
Copy link
Contributor

trashgod commented Mar 6, 2024

If CategoryLabelPositions.UP_90 is too crowded, consider a SlidingCategoryDataset, suggested here.

@sudarshansb143
Copy link
Author

@trashgod Can you provide code snippet of how can I use it ?
it would be a great help

@trashgod
Copy link
Contributor

trashgod commented Mar 7, 2024

SlidingCategoryDataset appears to be meant for interactive use: set the first index and count; the chart will update itself in response. Without context, it's hard to be more specific.

@sudarshansb143
Copy link
Author

To give you the context. I'm trying to generate a token distribution graph over the period of 24hrs of time. As per current implementation the graph looks something like this :
image

The implementation of above chart is done as per following snippet

  public JFreeChart generateGraphForTokensIn24hrs(List<TokenDistributionOverTimeDto> dataList, String chartTitle, String xAxisLabel, String yAxisLabel) {
        // Create dataset
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();

        // Add values to the dataset
        for (TokenDistributionOverTimeDto data : dataList) {
            dataset.addValue(data.getTokenCount(), "Tokens", data.getTime());
        }

        // Create stacked area chart
        JFreeChart chart = ChartFactory.createStackedAreaChart(
                chartTitle,
                xAxisLabel,
                yAxisLabel,
                dataset,                             // Dataset
                PlotOrientation.VERTICAL,            // Orientation
                true,                                // Include legend
                true,                                // Include tooltips
                false
        );
        // Set the background color of the chart
        chart.getPlot().setBackgroundPaint(Color.LIGHT_GRAY);
        chart.getPlot().setOutlineVisible(true);

        CategoryPlot plot = (CategoryPlot) chart.getPlot();
        CategoryAxis xAxis = (CategoryAxis) chart.getCategoryPlot().getDomainAxis();
        xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_90); // Rotate labels for better visibility
        xAxis.setTickMarksVisible(false); // Hide tick marks
        plot.setDomainGridlinesVisible(true); // Show vertical grid lines
        plot.setRangeGridlinesVisible(true);  // Show horizontal grid lines
        plot.setRangeMinorGridlinesVisible(true);

        NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
        rangeAxis.setNumberFormatOverride(new DecimalFormat("#,###"));
        rangeAxis.setAutoRange(true);

        // Rotate the labels
        xAxis.setCategoryLabelPositions(CategoryLabelPositions.UP_45);

        // Adjust the label font
        xAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 12));

        return chart;
    }

Here, I want the labels to be complete vertical manner just like the following graph

image

@sudarshansb143
Copy link
Author

@trashgod I hope this will help you to understand the usecase. I'm a bit constrained with width also. I'm using A4 page to generate charts hence I'm keeping height width as follow :

    if (!tokenDistributionOverTimeDtos.isEmpty()) {
            document.newPage();
            JFreeChart chart = generateGraphForTokensIn24hrs(tokenDistributionOverTimeDtos, "Ticket Distribution Over 24 Hour Timeline", "Time", "Number of Tokens");
            BufferedImage chartImage = chart.createBufferedImage(500, 400);
            ByteArrayOutputStream chartOut = new ByteArrayOutputStream();
            ChartUtils.writeBufferedImageAsPNG(chartOut, chartImage);
            com.lowagie.text.Element pdfImage = com.lowagie.text.Image.getInstance(chartOut.toByteArray());
            document.add(pdfImage);
        }

@trashgod
Copy link
Contributor

trashgod commented Mar 8, 2024

It looks like you're preparing PDFs on demand. As far as appearance, why not use a larger BufferedImage for better resolution? You are setting the desired tick label orientation, but I'm confused about setting it first to UP_90 and then to UP_45. As for displaying a days worth of data, it looks like you can use either DefaultCategoryDataset or SlidingCategoryDataset, whichever is more convenient.

@sudarshansb143
Copy link
Author

@trashgod Increasing BufferedImage resulting chart overflow out of page hence I after trial and error i kept the size as 500, 400 and regarding usage of SlidingCategoryDataset can you provide a usage reference here ?

@trashgod
Copy link
Contributor

I didn't find any SlidingCategoryDataset examples, but I usually rely on the API to set the first index and count.

@sudarshansb143
Copy link
Author

Ok. But, in this case it is managing columns very well only thing I wanted to improve is the X-axis Labels.
I'm focusing on this to improve label visibility. But, if we can't do this with then it might be a limitation

@trashgod
Copy link
Contributor

Yes, crowded charts are a perennial problem. To the extent that this is a user interface issue, SlidingCategoryDataset is the cleanest way to focus on a chosen subset of the data. In the context of PDFs, you might construct a series of charts based on user input.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants