前端时间看了java1234站长,小锋老师关于JFreeChart的视频教程,正好项目需要使用JFreeChart做折线报表,我把我做的一些内容贴出来大家参考下:
1、添加JFreeChart的Jar包,这个就不说了
2、配置web.xml
<servlet>
<servlet-name>DisplayChart</servlet-name>
<servlet-class>org.jfree.chart.servlet.DisplayChart</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>DisplayChart</servlet-name>
<url-pattern>/DisplayChart</url-pattern>
</servlet-mapping>
3、编写接口,和接口实现类(我这里的折线共有两条,一条是当月的、一条是上个月的,所以提供2个方法,我这里返回的是查询出来的Map集合)
/**
* @时间 上午10:42:28 2016年5月14日
* @创建人 zhangll
* @目的 此方法用于获取当月每天用户新增数据的集合
* @方法名 curMonth
* @return
*/
@Override
public Map<Integer,Integer> curMonth(){
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);//当前年份
int month = calendar.get(Calendar.MONTH)+1;//当前月份,月份以0开头,11结束,故当前月份需+1
String today = "";
String nextday = "";
//如果当前月份是12月
if(month ==12){
//以当前月份1号,即12月1日开始
today = year+"-12-01";
//以明年1月1日结束(不含1月1日)
nextday =(year+1)+"-01-01";
//如果当前月份不是12月的普通月份
}else{
//以当前月份的1号开始查询
today = year+"-"+month+"-01";
//以下个月的1号结束查询(不含下个月的1号)
nextday = year+"-"+(month+1)+"-01";
}
conn = super.getConnection();
//此sql获取方法前面获取的时间段,按每日分组显示每天的用户数据量
String sql = "SELECT DAY(cCreatetime),COUNT(*) FROM tblcustomer WHERE cCreatetime >=? and cCreatetime< ? GROUP BY DAY(cCreatetime)";
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
try {
pst = conn.prepareStatement(sql);
pst.setString(1, today);
pst.setString(2, nextday);
rs = pst.executeQuery();
while(rs.next()){
map.put(rs.getInt(1), rs.getInt(2));
}
} catch (SQLException e) {
log.error("\n sql :执行SQL语句出错,请检查!\n" + sql, e);
} finally{
super.closeConnection(rs, pst, conn);
}
return map;
}
/**
* @时间 上午10:48:28 2016年5月14日
* @创建人 zhangll
* @目的 此方法用于获取上个月份每天的用户数据量
* @方法名 lastMonth
* @return
*/
@Override
public Map<Integer,Integer> lastMonth(){
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);//当前年份
int month = calendar.get(Calendar.MONTH)+1;//当前月份,月份以0开头,11结束,故当前月份需+1
String today="";
String nextday ="";
//如果当前月份是1月,所以上月是去年的12月
if(month==1){
//查询以去年12月1日开始
today = (year-1)+"-12-01";
//以今年1月1日(不含1月1日)结束
nextday = year+"-01-01";
//如果当前月份不是1月的普通月份
}else{
//则查询以上月的1号开始查询
today = year+"-"+(month-1)+"-01";
//以本月的1号(不含本月1日)结束
nextday = year+"-"+month+"-01";
}
conn = super.getConnection();
//此sql用于获取方法上面 得到的时间区间分组查询出上个月每天的用户数据量
String sql = "SELECT DAY(cCreatetime),COUNT(*) FROM tblcustomer WHERE cCreatetime >=? and cCreatetime< ? GROUP BY DAY(cCreatetime)";
Map<Integer,Integer> map = new HashMap<Integer,Integer>();
try {
pst = conn.prepareStatement(sql);
pst.setString(1, today);
pst.setString(2, nextday);
rs = pst.executeQuery();
while(rs.next()){
map.put(rs.getInt(1), rs.getInt(2));
}
} catch (SQLException e) {
log.error("\n sql :执行SQL语句出错,请检查!\n" + sql, e);
} finally{
super.closeConnection(rs, pst, conn);
}
return map;
}
4、编写Action类
public String genLineChartMonth()throws Exception{
tblcustomerService = (TblcustomerService)applicationContext.getBean("tblcustomerService");
Calendar calendar = Calendar.getInstance();
int year = calendar.get(Calendar.YEAR);
int month = calendar.get(Calendar.MONTH)+1;
int day=calendar.getActualMaximum(Calendar.DATE);//获取当前月份最大天数
// 用户数据统计
TimeSeries timeSeries=new TimeSeries("本月用户数据", Day.class);
// 添加数据
Map<Integer,Integer> map1 = tblcustomerService.curMonth();
for(int i=1;i<29;i++){
timeSeries.add(new Day(i,month,year), map1.get(i)==null?0:map1.get(i));
}
if(day>=29){
timeSeries.add(new Day(29,month,year), map1.get(29)==null?0:map1.get(29));
if(day>=30){
timeSeries.add(new Day(30,month,year), map1.get(30)==null?0:map1.get(30));
if(day>=31){
timeSeries.add(new Day(31,month,year), map1.get(31)==null?0:map1.get(31));
}
}
}
// 用户数据统计
TimeSeries timeSeries2=new TimeSeries("上月用户数据", Day.class);
Map<Integer,Integer> map2 = tblcustomerService.lastMonth();
// 添加数据
for(int i=1;i<29;i++){
timeSeries2.add(new Day(i,month,year), map2.get(i)==null?0: map2.get(i));
}
if(day>=29){
timeSeries2.add(new Day(29,month,year), map2.get(29)==null?0: map2.get(29));
if(day>=30){
timeSeries2.add(new Day(30,month,year), map2.get(30)==null?0: map2.get(30));
if(day>=31){
timeSeries2.add(new Day(31,month,year), map2.get(31)==null?0: map2.get(31));
}
}
}
// 定义时间序列的集合
TimeSeriesCollection lineDataset=new TimeSeriesCollection();
lineDataset.addSeries(timeSeries);
lineDataset.addSeries(timeSeries2);
JFreeChart chart=ChartFactory.createTimeSeriesChart("用户数据", "时间", "用户数量", lineDataset, true, true, true);
//设置主标题
chart.setTitle(new TextTitle("用户数据对比图", new Font("黑体", Font.BOLD, 15)));
//背景设置颜色
chart.setBackgroundPaint(ChartColor.WHITE);
//设置子标题
TextTitle subtitle = new TextTitle("本月,上月用户数据对比", new Font("黑体", Font.BOLD, 10));
chart.addSubtitle(subtitle);
chart.setAntiAlias(true);
//设置时间轴的范围。
XYPlot plot = (XYPlot) chart.getPlot();
DateAxis dateaxis = (DateAxis)plot.getDomainAxis();
dateaxis.setDateFormatOverride(new java.text.SimpleDateFormat("d日"));
dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY,1));
//y轴去掉小数点
NumberAxis numberaxis = (NumberAxis)plot.getRangeAxis();
numberaxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
//设置曲线是否显示数据点
XYLineAndShapeRenderer xylinerenderer = (XYLineAndShapeRenderer)plot.getRenderer();
xylinerenderer.setBaseShapesVisible(true);
//折线加粗
xylinerenderer.setSeriesStroke(0, new BasicStroke(2.0F));
//设置曲线显示各数据点的值
XYItemRenderer xyitem = plot.getRenderer();
xyitem.setBaseItemLabelsVisible(true);
xyitem.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));
xyitem.setBaseItemLabelGenerator(new StandardXYItemLabelGenerator());
xyitem.setBaseItemLabelFont(new Font("Dialog", 1, 15));
plot.setRenderer(xyitem);
String fileName=ServletUtilities.saveChartAsPNG(chart, 1050, 460, session);
JSONObject json = new JSONObject();
json.put("filename", fileName);
returnJson(json.toString());
return "jsonresult";
}
5、编写页面(我这里总共写了四张报表,有按年的、按月的、按周的、按日的,上面只贴了按月的供参考)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<%@ include file="/common/taglibs.jsp"%>
<%@ include file="/common/meta.jsp"%>
<%@include file="/common/include/rootPath.jsp"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>demo</title>
<title>用户数据报表</title>
</head>
<body>
<script type="text/javascript">
$(function(){
$.ajax({
type: 'POST',
url: "chart!genLineChart.action",
async: false ,
datatype:"json",
success: function(data){
var json = eval("(" + data + ")");
$("#img").attr("src","DisplayChart?filename="+json.filename)
}
});
})
function change(value){
var url;
if(value=="1"){
url="chart!genLineChart.action";
}
if(value=="2"){
url="chart!genLineChartWeek.action";
}
if(value=="3"){
url="chart!genLineChartMonth.action";
}
if(value=="4"){
url="chart!genLineChartYear.action";
}
$.ajax({
type: 'POST',
url: url,
async: true ,
datatype:"json",
success: function(data){
var json = eval("(" + data + ")");
$("#img").attr("src","DisplayChart?filename="+json.filename)
}
});
}
</script>
<select οnchange="change(this.value);">
<option value="1">按日查看</option>
<option value="2">按周查看</option>
<option value="3">按月查看</option>
<option value="4">按年查看</option>
</select><br/>
<img id="img" style="width:auto;height:auto;" border="0"/>
</body>
</html>
最后,报表就做完了,上图