关于使用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;
}
对于生成柱状图,倒是遇到一个问题,查了好长时间,没有找到办法:如何是每项文字放置在柱子的中间。最后是通过设置柱子的宽度来完成的。如果谁有好的方法,可以留言告诉我,在此提前谢过。
最后附上生成的图片样子: