How do I change a JFreeChart's size
Asked Answered
T

4

10

I've added a JFreeChart to a JPanel (using a BorderLayout), and it's huge. Is there something I can do to make it smaller?

public void generateChart()
{
    DefaultCategoryDataset dataset = new DefaultCategoryDataset();

    //set the values of the chart
    for(int i=0; i<8; i++)
    {
        dataset.setValue(income_array[i], "Income",
            Double.toString(percent_array[i]));
    }

    JFreeChart chart = ChartFactory.createBarChart(
        "Required Annual Income for a Variety of Interest Rates",
        "Percent", "Income", dataset, PlotOrientation.VERTICAL,
        false,true, false);
    ChartPanel cp = new ChartPanel(chart);

    chart.setBackgroundPaint(Color.white);
    chart.getTitle().setPaint(Color.black); 
    CategoryPlot p = chart.getCategoryPlot(); 
    p.setRangeGridlinePaint(Color.blue); 

    //cp.setMaximumDrawHeight(5);
    //cp.setMaximumDrawWidth(5);
    //cp.setZoomOutFactor(.1);
    JPanel graph = new JPanel();
    graph.add(cp);
    middle.add(graph, BorderLayout.CENTER);
}   
Timehonored answered 23/4, 2012 at 3:8 Comment(0)
F
15

When you create your ChartPanel, you have several options that affect the result:

  1. Accept the DEFAULT_WIDTH and DEFAULT_HEIGHT: 680 x 420.

  2. Specify the preferred width and height in the constructor.

  3. Invoke setPreferredSize() explicitly if appropriate.

  4. Override getPreferredSize() to calculate the size dynamically.

    @Override
    public Dimension getPreferredSize() {
        // given some values of w & h
        return new Dimension(w, h);
    }
    
  5. Choose the layout of the container to which the ChartPanel will be added. Note that the default layout of JPanel is FlowLayout, while that of JFrame is BorderLayout. As a concrete example, ThermometerDemo uses both preferred values in the constructor and a GridLayout for the container to allow dynamic resizing.

image

Frissell answered 23/4, 2012 at 8:45 Comment(3)
If appropriate? From what I see in the mostly upvoted (and accepted) answer, it's never appropriate ;)Nonbelligerent
ok, I see what you did here. consider linking to your answer then, not to the question thenNonbelligerent
Thanks for reading and commenting. If only it were so simple! I'd say it's occasionally appropriate, as suggested here and here.Frissell
G
1

In addition to answer "4" of @trashgod, I had the same problem and managed to solve it like this: (1) create a custom class which extends JPanel (2) get the size somehow, that you would like to pass to your chart (3) create a method which returns a "ChartPanel" object like this:

ChartPanel chart() {
    //... custom code here
    JFreeChart chart = ChartFactory.createPieChart(title, pieDataset, false, false, false );`enter code here`
    // Now: this is the trick to manage setting the size of a chart into a panel!:
    return new ChartPanel(chart) { 
        public Dimension getPreferredSize() {
            return new Dimension(width, height);
        }
    };
}

I prepared a SSCCE to let you know how it works:

import java.awt.Dimension;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.general.DefaultPieDataset;

public class MyPieChart extends JPanel {

    public static void main(String[] args) {
        example1();
        example2();
        example3();
    }

    public static void example1() {
        JPanel panel = new JPanel();
        panel.setBounds(50, 80, 100, 100);
        MyPieChart piePanel = new MyPieChart("Example 1", dataset(), panel);
        panel.add(piePanel);
        JFrame frame = new JFrame();
        frame.setLayout(null); 
        frame.setBounds(10, 10, 200, 300);
        frame.add(panel);
        frame.setVisible(true);
    }

    public static void example2() {
        MyPieChart piePanel = new MyPieChart("Example 2", dataset(), 30, 50, 100, 100);
        JFrame frame = new JFrame();
        frame.setLayout(null); 
        frame.setBounds(210, 10, 200, 300);
        frame.add(piePanel);
        frame.setVisible(true);
    }

    public static void example3() {
        MyPieChart piePanel = new MyPieChart("Example 3", dataset(), 100, 100);
        piePanel.setLocation(0,0);
        JFrame frame = new JFrame();
        frame.setLayout(null); 
        frame.setBounds(410, 10, 200, 300);
        frame.add(piePanel);
        frame.setVisible(true);
    }

    static ArrayList<ArrayList<String>> dataset() {
        ArrayList<ArrayList<String>> dataset = new ArrayList<ArrayList<String>>();
        dataset.add(row( "Tom", "LoggedIn", "Spain" ));
        dataset.add(row( "Jerry", "LoggedOut", "England" ));
        dataset.add(row( "Gooffy", "LoggedOut", "France" ));
        return dataset;
    }

    static ArrayList<String> row(String name, String actualState, String country) {
        ArrayList<String> row = new ArrayList<String>();
        row.add(name); row.add(actualState); row.add(country); 
        return row;
    }

    ArrayList<ArrayList<String>> dataset;
    DefaultPieDataset pieDataset = new DefaultPieDataset(); 
    int width, height, posX, posY;
    int colState = 1;
    String title;
    String LoggedIn = "LoggedIn";
    String LoggedOut = "LoggedOut";

    public MyPieChart(String title, ArrayList<ArrayList<String>> dataset, int...args) {

        if(args.length==2) {
            this.width = args[0];
            this.height = args[1];
            this.setSize(width, height);
        }
        else if(args.length==4) {
            this.posX = args[0];
            this.posY = args[1];
            this.width = args[2];
            this.height = args[3];
            this.setBounds(posX, posY, width, height);
        }
        else {
            System.err.println("Error: wrong number of size/position arguments");
            return;
        }

        this.title = title;
        this.dataset = dataset;
        this.add(chart());
    }

    public MyPieChart(String title, ArrayList<ArrayList<String>> dataset, JPanel panel) {
        this.title = title;
        this.dataset = dataset;
        this.width = panel.getWidth();
        this.height = panel.getHeight();
        this.setBounds(panel.getBounds());
        this.add(chart());
    }

    ChartPanel chart() {

        int totalLoggedIn = 0;
        int totalLoggedOut = 0;

        for(ArrayList<String> user : dataset) {
            if(user.get(colState).equals(LoggedIn)) totalLoggedIn++;
            else totalLoggedOut++;
        }
        pieDataset.clear();
        pieDataset.setValue(LoggedIn +": "+ totalLoggedIn, totalLoggedIn);
        pieDataset.setValue(LoggedOut +": "+ totalLoggedOut, totalLoggedOut);

        JFreeChart chart = ChartFactory.createPieChart(title, pieDataset, false, false, false );

        return new ChartPanel(chart) { // this is the trick to manage setting the size of a chart into a panel!
            public Dimension getPreferredSize() {
                return new Dimension(width, height);
            }
        };
    }
}

I really hope it helps!

Glorygloryofthesnow answered 6/3, 2018 at 5:36 Comment(0)
N
1

I had a problem with my pie chart being too big with BorderLayout too. I ended up solving my problem by converting the chart to an image instead.

Before enter image description here

After enter image description here

Code

 private PieDataset updateCSFDataSet(){
        DefaultPieDataset dataSet = new DefaultPieDataset();
            dataSet.setValue("Clear(" + clearCount + ")" , clearCount);
            dataSet.setValue("Smoky(" + smokyCount + ")", smokyCount);
            dataSet.setValue("Foggy(" + foggyCount + ")", foggyCount);
            dataSet.setValue("Skipped(" + skipCount + ")", skipCount);
            dataSet.setValue("Unlabeled(" + unlabeledCount + ")", unlabeledCount);
        return dataSet;
    }

    private ImageIcon createChart(String title, PieDataset dataSet){
        JFreeChart chart = ChartFactory.createPieChart(
                title,
                dataSet,
                true,
                false,
                false
        );

        PiePlot plot = (PiePlot) chart.getPlot();
        plot.setLabelFont(new Font("SansSerif", Font.PLAIN, 12));
        plot.setNoDataMessage("No data available");
        plot.setCircular(true);
        plot.setIgnoreZeroValues(true);
        plot.setLabelGap(0.02);

        return new ImageIcon(chart.createBufferedImage(400,300));
    }
Ns answered 7/3, 2018 at 23:17 Comment(0)
H
0

Try setting the size of the Panel your chart is in.

You might need to set both JPanel middle and ChartPanel cp

Haemal answered 23/4, 2012 at 3:23 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.