Java export pdf report six: use jfreechart to generate pie charts and histograms

There is also a big push on the Internet about using jfreechart to generate pie charts and histograms. I will not introduce too much here, but I will directly attach my implementation and add some notes for your reference.

Generate a pie chart:

/**
 * @param name 图片的名称
 * @param params 参数
 * @param title 图片中要显示图片题目,如果不希望展示,需要送空字符串,不能送null
 * @return 图片的路径或获取地址
 */
public String createPie(String name, Map<String, Double> params, String title) {
        DefaultPieDataset data = getPieDataSet(params);
        JFreeChart chart = ChartFactory.createPieChart3D(title, data, true, false, false);
        chart.getTitle().setFont(new Font("黑体", Font.BOLD, 20));//设置标题字体
        PiePlot piePlot = (PiePlot) chart.getPlot();//获取图表区域对象
        piePlot.setCircular(true);//设置饼图为圆形
        piePlot.setBackgroundAlpha(0f);
        piePlot.setLabelGenerator(null);//取消图中标签

        chart.getLegend().setItemFont(new Font("黑体", Font.BOLD, 10)); //设置图例说明的字体、颜色和大小
        chart.getLegend().setPosition(RectangleEdge.TOP); //设置图例说明在图片中的位置
        chart.getLegend().setBorder(0, 0, 0, 0); //设置图例说明的边框
        chart.getLegend().setMargin(10, 30, 10, 0); //设置图例说明内边距
        piePlot.setLegendLabelGenerator(new StandardPieSectionLabelGenerator("{0}({2})", NumberFormat.getNumberInstance(), new DecimalFormat("0.00%"))); //设置图例的格式
        String filePath = picturePath + REPORT + "/" + name;
        FileOutputStream fos_jpg = null;
        try {
            fos_jpg = new FileOutputStream(filePath);
            ChartUtilities.writeChartAsJPEG(fos_jpg, 1.0f, chart, 400, 400, null);
            return filePath;
        } catch (Exception e) {
            logger.error("生成饼状图失败");
        } finally {
            try {
                fos_jpg.close();
            } catch (Exception e) {
            }
        }
        return null;
    }

private DefaultPieDataset getPieDataSet(Map<String,Double> params) {
        DefaultPieDataset dataset = new DefaultPieDataset();
        String[] sum = {"Bacteroidetes","Firmicutes","Proteobacteria","Actinobacteria","Cyanobacteria","Other"};
        for (String item:sum) {
            if (params.containsKey(item)) {  
                dataset.setValue(item,params.get(item));
            } else { //由于参数中对于没有value=0的项目,但生成的图片中需要体现出来,所以在此做了判断赋值的操作
                dataset.setValue(item,0d);
            }
        }
        return dataset;
    }

Histogram Generation

public String createBar(String name, Map<String, Double> params, String title) {
        DefaultCategoryDataset dataset = getCategoryDataSet(params);

        JFreeChart chart = ChartFactory.createBarChart(title, null, null, dataset,
             PlotOrientation.HORIZONTAL, //设置柱状图的样式HORIZONTAL:横向 VERTICAL:纵向
             false, false,false);
        chart.setBackgroundPaint(ChartColor.WHITE); // 设置背景颜色

        CategoryPlot categoryplot = (CategoryPlot) chart.getPlot(); //获取图表对象
        categoryplot.setBackgroundPaint(ChartColor.WHITE); //设置图表的背景颜色
        categoryplot.setOutlinePaint(ChartColor.BLACK); //图表边框颜色
        categoryplot.setDomainAxisLocation(AxisLocation.BOTTOM_OR_LEFT); //设置xy轴的位置
        categoryplot.setRangeAxisLocation(AxisLocation.BOTTOM_OR_LEFT);

        BarRenderer customBarRenderer = (BarRenderer) categoryplot.getRenderer();
        //取消柱子上的渐变色
        customBarRenderer.setBarPainter( new StandardBarPainter() );
        //设置阴影,false代表没有阴影
        customBarRenderer.setShadowVisible(false);
        //设置柱子宽度,如果宽度设置的太小,会导致文字不在柱子的中间。至于有没有更好的设置办法,我暂时没有找到。如果谁有好的方法,可以留言告诉我,在此提前谢过
        customBarRenderer.setMaximumBarWidth(30);
        customBarRenderer.setMinimumBarLength(0.8);       
        customBarRenderer.setItemMargin(-1.2); //设置柱子间距

        //数据轴设置
        NumberAxis numberaxis = (NumberAxis) categoryplot.getRangeAxis();     
        numberaxis.setUpperMargin(0.05);//设置最高的一个柱与图片顶端的距离(最高柱的10%)
        numberaxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 12));
        numberaxis.setLabelFont(new Font("黑体", Font.PLAIN, 12));

        //项目轴设置
        CategoryAxis domainAxis = categoryplot.getDomainAxis();
        domainAxis.setTickLabelFont(new Font("sans-serif", Font.PLAIN, 15));

        String filePath = picturePath + REPORT + "/" + name;
        FileOutputStream fos_jpg = null;
        try {
            fos_jpg = new FileOutputStream(filePath);
            ChartUtilities.writeChartAsJPEG(fos_jpg,1.0f,chart,500,300,null);
            return filePath;
        } catch (Exception e) {
            logger.error("生成柱状图失败");
        } finally {
            try {
                fos_jpg.close();
            } catch (Exception e) {}
        }
        return null;
    }

private DefaultCategoryDataset getCategoryDataSet(Map<String,Double> params) {
        DefaultCategoryDataset dataset = new DefaultCategoryDataset();
        for (Map.Entry<String,Double> param: params.entrySet()) {
            dataset.addValue(param.getValue(),param.getKey(),param.getKey());
        }
        return dataset;
    }

For the generation of the histogram, I encountered a problem. After searching for a long time, I couldn't find a way: how to place each text in the middle of the column. This is finally done by setting the width of the columns. If anyone has a good method, you can leave a message and tell me, thank you in advance.

Finally, attach the generated picture:

 

 

Guess you like

Origin blog.csdn.net/wzl19870309/article/details/103439631