繁体   English   中英

摆脱jfreechart chartpanel不必要的空间

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM