[英]Get rid of jfreechart chartpanel unnecessary space
我正在尝试获取JFreeChart ChartPanel
来删除面板边缘和图形本身之间不需要的多余空间。
为了最好地说明,这是一个SSCCE(已安装JFreeChart):
public static void main(String[] args) {
JPanel panel = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.fill = GridBagConstraints.BOTH;
gbc.gridwidth = 1;
gbc.gridheight = 1;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.gridy = 1;
gbc.gridx = 1;
panel.add(createChart("Sales", Chart_Type.DOLLARS, 100000, 115000), gbc);
gbc.gridx = 2;
panel.add(createChart("Quotes", Chart_Type.DOLLARS, 250000, 240000), gbc);
gbc.gridx = 3;
panel.add(createChart("Profits", Chart_Type.PERCENTAGE, 40.00, 38.00), gbc);
JFrame frame = new JFrame();
frame.add(panel);
frame.setSize(800, 300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private static ChartPanel createChart(String title, Chart_Type type, double goal, double actual) {
double maxValue = goal * 2;
double yellowToGreenNum = goal;
double redToYellowNum = goal * .75;
DefaultValueDataset dataset = new DefaultValueDataset(actual);
JFreeChart jfreechart = createChart(dataset, Math.max(actual, maxValue), redToYellowNum, yellowToGreenNum, title, type);
ChartPanel chartPanel = new ChartPanel(jfreechart);
chartPanel.setBorder(new LineBorder(Color.red));
return chartPanel;
}
private static JFreeChart createChart(ValueDataset valuedataset, Number maxValue, Number redToYellowNum, Number yellowToGreenNum, String title, Chart_Type type) {
MeterPlot meterplot = new MeterPlot(valuedataset);
meterplot.setRange(new Range(0.0D, maxValue.doubleValue()));
meterplot.addInterval(new MeterInterval(" Goal Not Met ",
new Range(0.0D, redToYellowNum.doubleValue()), Color.lightGray, new BasicStroke(2.0F),
new Color(255, 0, 0, 128)));
meterplot.addInterval(new MeterInterval(" Goal Almost Met ",
new Range(redToYellowNum.doubleValue(), yellowToGreenNum.doubleValue()), Color.lightGray, new BasicStroke(2.0F),
new Color(255, 255, 0, 64)));
meterplot.addInterval(new MeterInterval(" Goal Met ",
new Range(yellowToGreenNum.doubleValue(), maxValue.doubleValue()), Color.lightGray, new BasicStroke(2.0F),
new Color(0, 255, 0, 64)));
meterplot.setNeedlePaint(Color.darkGray);
meterplot.setDialBackgroundPaint(Color.white);
meterplot.setDialOutlinePaint(Color.gray);
meterplot.setDialShape(DialShape.CHORD);
meterplot.setMeterAngle(260);
meterplot.setTickLabelsVisible(false);
meterplot.setTickSize(maxValue.doubleValue() / 20);
meterplot.setTickPaint(Color.lightGray);
meterplot.setValuePaint(Color.black);
meterplot.setValueFont(new Font("Dialog", Font.BOLD, 0));
meterplot.setUnits("");
if(type == Chart_Type.DOLLARS)
meterplot.setTickLabelFormat(NumberFormat.getCurrencyInstance());
else if(type == Chart_Type.PERCENTAGE)
meterplot.setTickLabelFormat(NumberFormat.getPercentInstance());
JFreeChart jfreechart = new JFreeChart(title,
JFreeChart.DEFAULT_TITLE_FONT, meterplot, false);
return jfreechart;
}
enum Chart_Type {
DOLLARS,
PERCENTAGE
}
如果调整框架的大小,则会看到您无法使图形的边缘移至面板的边缘(面板以红色框出)。 特别是在底部-图形底部和面板底部之间始终存在间隙。
有没有办法使图形填充整个区域? 有没有一种方法可以至少保证它触摸面板的一个边缘(即它触摸顶部和底部或左侧和右侧)?
作为参考,在不更改图的情况下,以下是具有以下设置的结果:
在封闭框架上调用pack()
。
使用无间隙GridLayout
。
返回等边的首选大小。
setMeterAngle(360);
。
setDrawBorder(true);
调整为非正方形外观的大小会填充较窄的尺寸。
附录:如图所示在这里 ,您可以覆盖图表的draw()
方法。 为了改善以下变体的大小调整行为,将覆盖图的draw()
方法以将area
移动其高度的一小部分。 基于getMeterAngle()
函数也可能有用。
MeterPlot meterplot = new MeterPlot(valuedataset) {
@Override
public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, PlotState parentState, PlotRenderingInfo info) {
double h = area.getHeight() * 6 / 5;
area.setRect(area.getX(), area.getY(), area.getWidth(), h);
super.draw(g2, area, anchor, parentState, info);
}
};
更新的代码:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.plot.DialShape;
import org.jfree.chart.plot.MeterInterval;
import org.jfree.chart.plot.MeterPlot;
import org.jfree.chart.plot.PlotRenderingInfo;
import org.jfree.chart.plot.PlotState;
import org.jfree.data.Range;
import org.jfree.data.general.DefaultValueDataset;
import org.jfree.data.general.ValueDataset;
//* @see https://stackoverflow.com/a/25416067/230513 */
public class Test {
public static void main(String[] args) {
JPanel panel = new JPanel(new GridLayout());
panel.add(createChart("Sales", Chart_Type.DOLLARS, 100000, 115000));
panel.add(createChart("Quotes", Chart_Type.DOLLARS, 250000, 240000));
panel.add(createChart("Profits", Chart_Type.PERCENTAGE, 40.00, 38.00));
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static ChartPanel createChart(String title, Chart_Type type, double goal, double actual) {
double maxValue = goal * 2;
double yellowToGreenNum = goal;
double redToYellowNum = goal * .75;
DefaultValueDataset dataset = new DefaultValueDataset(actual);
JFreeChart jfreechart = createChart(dataset, Math.max(actual, maxValue), redToYellowNum, yellowToGreenNum, title, type);
ChartPanel chartPanel = new ChartPanel(jfreechart) {
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 300);
}
};
chartPanel.setBorder(new LineBorder(Color.red));
return chartPanel;
}
private static JFreeChart createChart(ValueDataset valuedataset, Number maxValue, Number redToYellowNum, Number yellowToGreenNum, String title, Chart_Type type) {
MeterPlot meterplot = new MeterPlot(valuedataset) {
@Override
public void draw(Graphics2D g2, Rectangle2D area, Point2D anchor, PlotState parentState, PlotRenderingInfo info) {
double h = area.getHeight() * 6 / 5;
area.setRect(area.getX(), area.getY(), area.getWidth(), h);
super.draw(g2, area, anchor, parentState, info);
}
};
meterplot.setRange(new Range(0.0D, maxValue.doubleValue()));
meterplot.addInterval(new MeterInterval(" Goal Not Met ",
new Range(0.0D, redToYellowNum.doubleValue()), Color.lightGray, new BasicStroke(2.0F),
new Color(255, 0, 0, 128)));
meterplot.addInterval(new MeterInterval(" Goal Almost Met ",
new Range(redToYellowNum.doubleValue(), yellowToGreenNum.doubleValue()), Color.lightGray, new BasicStroke(2.0F),
new Color(255, 255, 0, 64)));
meterplot.addInterval(new MeterInterval(" Goal Met ",
new Range(yellowToGreenNum.doubleValue(), maxValue.doubleValue()), Color.lightGray, new BasicStroke(2.0F),
new Color(0, 255, 0, 64)));
meterplot.setNeedlePaint(Color.darkGray);
meterplot.setDialBackgroundPaint(Color.white);
meterplot.setDialOutlinePaint(Color.gray);
meterplot.setDialShape(DialShape.CHORD);
meterplot.setMeterAngle(260);
meterplot.setTickLabelsVisible(false);
meterplot.setTickSize(maxValue.doubleValue() / 20);
meterplot.setTickPaint(Color.lightGray);
meterplot.setValuePaint(Color.black);
meterplot.setValueFont(new Font("Dialog", Font.BOLD, 0));
meterplot.setUnits("");
if (type == Chart_Type.DOLLARS) {
meterplot.setTickLabelFormat(NumberFormat.getCurrencyInstance());
} else if (type == Chart_Type.PERCENTAGE) {
meterplot.setTickLabelFormat(NumberFormat.getPercentInstance());
}
meterplot.setDrawBorder(true);
meterplot.setDialShape(DialShape.CHORD);
JFreeChart jfreechart = new JFreeChart(title,
JFreeChart.DEFAULT_TITLE_FONT, meterplot, false);
return jfreechart;
}
enum Chart_Type {
DOLLARS,
PERCENTAGE
}
}
多亏了rashgod的建议,我改写了JFreeChart::draw()
方法,将Rectangle2D chartArea
的高度减少了50个像素(从技术上讲,我想我向该高度增加了50个像素?不确定为什么这样工作):
码:
JFreeChart jfreechart = new JFreeChart(title, JFreeChart.DEFAULT_TITLE_FONT, meterplot, false) {
@Override
public void draw(Graphics2D g2, Rectangle2D chartArea, Point2D anchor, ChartRenderingInfo info) {
chartArea.setRect(chartArea.getX(), chartArea.getY(), chartArea.getWidth(), chartArea.getHeight() + 50);
super.draw(g2, chartArea, anchor, info);
}
};
结果:
因此,多亏了rashgod的帮助为我指明了正确的方向。
编辑:后来,我仍然在图表的左侧和右侧遇到一些额外的空间。 可以通过以下代码解决: chartPanel.setMinimumDrawWidth(0);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.