關於使用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;
}
對於生成柱狀圖,倒是遇到一個問題,查了好長時間,沒有找到辦法:如何是每項文字放置在柱子的中間。最後是通過設置柱子的寬度來完成的。如果誰有好的方法,可以留言告訴我,在此提前謝過。
最後附上生成的圖片樣子: