java導出pdf報告之六:使用jfreechart生成餅狀圖和柱狀圖

關於使用jfreechart生成餅狀圖和柱狀圖網上也有一大推,我在這裏也不做太多介紹,就直接附上我的實現,並添加了一下注釋,供大家參考。

生成餅狀圖:

/**
 * @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;
    }

柱狀圖生成

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;
    }

對於生成柱狀圖,倒是遇到一個問題,查了好長時間,沒有找到辦法:如何是每項文字放置在柱子的中間。最後是通過設置柱子的寬度來完成的。如果誰有好的方法,可以留言告訴我,在此提前謝過。

最後附上生成的圖片樣子:

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章