【问题标题】:Jfreechart - any option for multiple XY charts like with the multi pie plot?Jfreechart - 多个 XY 图表的任何选项,例如多饼图?
【发布时间】:2012-08-09 17:46:59
【问题描述】:

除了 xy 图,还有什么类似于 multiPiePlot 图表的吗?我有一个应用程序需要在一页上打印两个或三个 xy 图。我知道您可以将多个数据集放在同一个图上,但要求规定每个数据集必须是同一页面上的单独图表。

【问题讨论】:

    标签: java jfreechart


    【解决方案1】:

    是的,只需将您的 ChartPanel 实例添加到具有 GridLayout(0, 1)JPanel 即可进行自上而下的排列。这个example 使用正交GridLayout(1, 0) 来设置三个面板。

    【讨论】:

    • AFAIK,打印通过渲染屏幕上的内容来工作,尽管您可能希望更改页面方向以进行水平布局。
    • 我使用了您的解决方案来显示它们,然后定制了一些东西以使它们能够正确打印。我在另一个答案中概述了我的解决方案。感谢您的帮助。
    【解决方案2】:

    我使用了垃圾邮件的解决方案,但我已经扩展了解决方案以支持我希望能够在我的应用程序中执行的那种打印。

    我希望能够像 JFreechart 通常那样进行打印,但是将它的多个图形放在网格中的每个页面上,并让它很好地伸展和扩展到页面。使用此功能,我能够生成与下图匹配的打印:

    基本上我扩展了 JPanel 并实现了 Printable 接口。制作一个包含我可能想要显示/打印的所有 JFreecharts 的面板。面板将根据您提供的一些布局说明以网格方式排列它们。

    面板的打印功能基本上采用正常的页面格式,但随后将页面细分为之前指定的网格。然后,它获取每个单元格并为每个单元格制作一个页面格式。然后它会告诉每个 JFreeChart ChartPanel 打印到每个 PageFormat 单元格。

    自定义图表面板:

    package com.company.jfreeChartCustom;
    
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.GridLayout;
    import java.awt.geom.Rectangle2D;
    import java.awt.print.PageFormat;
    import java.awt.print.Paper;
    import java.awt.print.Printable;
    import java.awt.print.PrinterException;
    import java.awt.print.PrinterJob;
    import java.util.ArrayList;
    import java.util.List;
    
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    
    import org.jfree.chart.ChartPanel;
    import org.jfree.chart.JFreeChart;
    
    import com.lowagie.text.Row;
    
    /**
     * The CustomChartPanel is used to display/print multiple JFreeCharts
     * Users should only interact with this class with the methods defined
     * below in order to get the proper functionality.  Using
     * inherited methods may produce unwanted display/print behavior if you
     * add components other than JFreeCharts.
     * 
     */
    public class CustomChartPanel extends JPanel implements Printable{
    
        List<JFreeChart> charts = new ArrayList<JFreeChart>();
        List<ChartPanel> panels = new ArrayList<ChartPanel>();
        ChartLayoutInstructions layoutInstructions;
    
        public CustomChartPanel(){
            super();
        }
    
        public CustomChartPanel(JFreeChart chart){
            super();
            charts.add(chart);
        }
    
        /**
         * Creates a CustomChartPanel which displays 1 or more charts in a grid-like fashion
         * described by the layoutInstructions you pass in.  Note that if you pass in more
         * charts than there are columns specified in the ChartLayoutInstructions then excess
         * charts will not be displayed or printed.
         * @param charts
         * @param layoutInstructions
         */
        public CustomChartPanel(List<JFreeChart> charts, ChartLayoutInstructions layoutInstructions){
            super();
            this.layoutInstructions = layoutInstructions;
            for(JFreeChart chart : charts){
                this.charts.add(chart);
            }
            createUIComponents();
        }
    
        protected void createUIComponents(){
            int size = Math.min(layoutInstructions.getColumns() * layoutInstructions.getRows(), charts.size());
            this.setLayout(new GridLayout(layoutInstructions.getRows(), layoutInstructions.getColumns()));
    
    
            for(int i = 0; i < size; i++ ){
                System.err.println("Adding chart");
                ChartPanel chartPanel = new ChartPanel(charts.get(i));
                chartPanel.setMaximumDrawHeight(20000);
                chartPanel.setMinimumDrawHeight(0);
                chartPanel.setMaximumDrawWidth(20000);
                chartPanel.setMinimumDrawWidth(0);
                chartPanel.setPopupMenu(null);
                panels.add(chartPanel);
                this.add(chartPanel);
            }
        }
    
        public void createPrintJob(){
            PrinterJob job = PrinterJob.getPrinterJob();
            PageFormat pf = job.defaultPage();
            PageFormat pf2 = job.pageDialog(pf);
            if (pf2 != pf) {
                job.setPrintable(this, pf2);
                if (job.printDialog()) {
                    try {
                        job.print();
                    }
                    catch (PrinterException e) {
                        JOptionPane.showMessageDialog(this, e);
                    }
                }
            }
        }
    
        @Override
        public int print(Graphics g, PageFormat pf, int pageIndex)
                throws PrinterException {
            System.err.println("PRINTING");
            //Divide the current page format into sections based
            //on the layout instructions received in the constructor
            //a new pagelayout is created for each cell in the grid
            //that will then be passed along to the print method of
            //each chart panel.  
    
    
            if(pageIndex != 0){
                return NO_SUCH_PAGE;
            }
    
            List<PageFormat> pageFormats = new ArrayList<PageFormat>();
    
            //setup all the page formats needed for the grid cells.
            double x = pf.getImageableX();
            double y = pf.getImageableY();
            double cellWidth = pf.getImageableWidth() / layoutInstructions.getColumns();
            double cellHeight = pf.getImageableHeight() / layoutInstructions.getRows();
    
            for(int i=1; i <= layoutInstructions.getRows(); i++){
                double rowOffset = (i-1)*cellHeight + y;
                for(int j=1; j <= layoutInstructions.getColumns(); j++){
                    PageFormat format = new PageFormat();
                    Paper paper = new Paper();
                    double columnOffset = (j-1)*cellWidth + x;
                    paper.setImageableArea(columnOffset, rowOffset, cellWidth, cellHeight);
                    format.setPaper(paper);
                    pageFormats.add(format);
                }
            }
    
            //have each chartpanel print on the graphics context using its
            //particular PageFormat
            int size = Math.min(pageFormats.size(), panels.size());
            for(int i = 0; i < size; i++ ){
                panels.get(i).print(g, pageFormats.get(i), pageIndex);
    
            }
    
            return PAGE_EXISTS;
        }
    

    图表布局说明:

    我计划扩展这个类以用于定义更高级的行为。这就是为什么我使用这个类,而不仅仅是在 CustomChartPanel 类的构造函数中定义行和列。

    package com.company.jfreeChartCustom;
    
    /**
     * ChartLayoutInstructions are used to specify how charts should be
     * layed out on screen and in print format.  
     *
     */
    public class ChartLayoutInstructions {
    
        int rows;
        int columns;
    
        /**
         * Constructor
         * @param rows number of rows in the display/print grid
         * @param columns number of columns in the display/print grid
         */
        public ChartLayoutInstructions(int rows, int columns, boolean allowSwap){
            this.rows = Math.abs(rows);
            this.columns = Math.abs(columns);
        }
    
        public int getRows() {
            return rows;
        }
    
        public void setRows(int rows) {
            this.rows = Math.abs(rows);
        }
    
        public int getColumns() {
            return columns;
        }
    
        public void setColumns(int columns) {
            this.columns = Math.abs(columns);
        }
    }
    

    【讨论】:

    • 只有一个图表参数的构造函数不完整。添加; code layoutInstructions = new ChartLayoutInstructions(1, 1, false); createUIComponents();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-10-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多