3
votes

I am using JFreeChart to make a barchart vs time. For some reason on these charts, the tick labels on the x axis turn into "..." occasionally. There seems like there is plenty of room for the labels to expand, but instead it just cuts off the whole thing. How can I fix this.

I tried uploading a picture using the image button, but it does not seem to be working.

Here is code with a similar set up to my project. Strangely it acted different then what is happening to my build. On mine instead of saying "Hou...", it just says "...". Ignore comments and all other uneeded things please.

package dataDisplay;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.DefaultCategoryDataset;

public class mockTest extends JPanel{

    ChartPanel chartPanel;
    JFreeChart chart;
    CategoryAxis domainAxis;
    NumberAxis rangeAxis;

    public mockTest()
    {
        //Mock data
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        int[] times = new int[]{1,2,3,4,5,6,7,8,9,10,11,12};

        for ( int i = 0; i < times.length; i++ ){
            dataset.addValue(times[i], "Time", "Houreee" + String.valueOf(i+1));;

        }
        CategoryPlot plot = new CategoryPlot();

        //create the plot

        //add the first dataset, and render as bar values
        CategoryItemRenderer renderer = new BarRenderer();
        plot.setDataset(0,dataset);
        plot.setRenderer(0,renderer);  

        //set axis 
         domainAxis = new CategoryAxis("Time");  
        rangeAxis = new NumberAxis("Value"); 

        plot.setDomainAxis(0,domainAxis);
        plot.setRangeAxis(rangeAxis);
        chart = new JFreeChart(plot);
        chartPanel = new ChartPanel( chart ); 

           this.addComponentListener(new ComponentAdapter() {
                @Override
                /**
                 *  Makes it so it does not stretch out text. Resizes the fonts to scale with the screen width..
                 */
                public void componentResized(ComponentEvent e) {
                    chartPanel.setMaximumDrawHeight(e.getComponent().getHeight());
                    chartPanel.setMaximumDrawWidth(e.getComponent().getWidth());
                    chartPanel.setMinimumDrawWidth(e.getComponent().getWidth());
                    chartPanel.setMinimumDrawHeight(e.getComponent().getHeight());

                    // Makes the font size scale according to the width of the chart panel.
                    rangeAxis.setLabelFont(new Font("SansSerif", Font.PLAIN,e.getComponent().getWidth()/60));
                    domainAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN,e.getComponent().getWidth()/80));
                    rangeAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN,e.getComponent().getWidth()/75));
                }
            });


        this.add(chartPanel, "Center");
    }   
    public static void main (String[] args) 
    {

        // Get the default toolkit
        Toolkit toolkit = Toolkit.getDefaultToolkit();
        // Get the current screen size 
        Dimension scrnsize = toolkit.getScreenSize();
        int scrnWidth= (int)scrnsize.getWidth();
        int scrnHeight = (int) scrnsize.getHeight();

        JFrame J= new JFrame();
        JPanel jP = new JPanel();
        J.setContentPane(jP);
        J.setSize(scrnWidth, scrnHeight);
        jP.setBackground(Color.white);
        jP.setBounds(0,0,scrnWidth,scrnHeight);
        int xPercent= 50;
        int yPercent = 50;
        int widthPercent=50;
        int heightPercent=43;
        jP.setLayout(null);
        jP.setSize(scrnWidth, scrnHeight);
        mockTest b= new mockTest();


        jP.add(b);
        b.setBounds(new Rectangle((int)(scrnWidth*((double)xPercent/100)),(int)(scrnHeight*((double)yPercent/100)),(int)(scrnWidth*((double)widthPercent/100)),(int)(scrnHeight*((double)heightPercent/100))));
        J.setUndecorated(true);
        J.setVisible(true);




    }
1
How about provide a Minimal, Complete, and Verifiable example? It is hard to understand what you want.Bruno Ribeiro
Well I could paste the code to make one of the charts, but the way I am doing it, it takes data from a server and uses the information in a specific way. Then it scales the chart and all the text in it to fit the boundaries and screen size. I think a picture of the problem would help, but for some reason on the work computers with outdated internet explorer, it wont let me upload it.Cole Gordon
An MCVE means some work, yes. But it's the best way to get answers. If your code relies on a server, but the server is not an essential part of the problem then put some dummy data in a string variable, remove all irrelevant code, until you end up with an MCVE.RealSkeptic

1 Answers

1
votes

Don't use a null layout; let the layout manager do the work. The default layout of JPanel is FlowLayout, which ignores your subsequent changes. In the example below,

  • The chartPanel is given a GridLayout; when added to the enclosing frame's CENTER, the chart will be free to grow as the frame is resized.

  • Avoid unnecessarily nested panels.

  • Use setExtendedState() to maximize the frame.

  • If necessary, use one of the approaches suggested here to alter the chart's initial size.

  • If you choose to alter a Font, use deriveFont() to avoid abrupt disparities in the user's chosen settings.

image

import java.awt.EventQueue;
import java.awt.GridLayout;
import javax.swing.JFrame;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.BarRenderer;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.data.category.DefaultCategoryDataset;

/** @see https://stackoverflow.com/a/31014252/230513 */
public class Test {


    public void display() {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (int i = 0; i < 12; i++) {
            dataset.addValue(i, "Time", "Hours" + String.valueOf(i + 1));
        }
        CategoryPlot plot = new CategoryPlot();
        CategoryItemRenderer renderer = new BarRenderer();
        plot.setDataset(0, dataset);
        plot.setRenderer(0, renderer);
        CategoryAxis domainAxis = new CategoryAxis("Time");
        NumberAxis rangeAxis = new NumberAxis("Value");
        plot.setDomainAxis(0, domainAxis);
        plot.setRangeAxis(rangeAxis);
        JFreeChart chart = new JFreeChart(plot);
        ChartPanel chartPanel = new ChartPanel(chart);
        chartPanel.setLayout(new GridLayout());

        JFrame f = new JFrame();
        f.add(chartPanel);
        f.setExtendedState(f.getExtendedState() | JFrame.MAXIMIZED_BOTH);
        f.setUndecorated(true);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Test()::display);
    }
}