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);
}
When you create your ChartPanel
, you have several options that affect the result:
Accept the DEFAULT_WIDTH
and DEFAULT_HEIGHT
: 680 x 420.
Specify the preferred width
and height
in the constructor.
Invoke setPreferredSize()
explicitly if appropriate.
Override getPreferredSize()
to calculate the size dynamically.
@Override
public Dimension getPreferredSize() {
// given some values of w & h
return new Dimension(w, h);
}
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.
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!
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
After
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));
}
Try setting the size of the Panel your chart is in.
You might need to set both JPanel middle and ChartPanel cp
http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=18631
http://www.jfree.org/forum/viewtopic.php?f=3&t=109615
http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=31582