使用JfreeChart生成统计图

在项目中遇到按年度/月份销量生成柱装图的要求,记录下来。 这里有很详细的例子

做的过程中遇到了两个问题

  • 当所有的数据为0的时候,会在图片的中心显示一条横线

   解决办法:rangeAxis.setLowerBound(0.0);

  • 当按月份查询时候X轴的数据过多导致x轴的下标显示不出来

  解决办法:domainAxis.setMaximumCategoryLabelWidthRatio(xx);//xx的值稍微设大一点就好了

效果图:

    

 

  • 依赖jar包:jcommon-1.0.23.jar    jfreechart-1.0.19.jar

工具类

  1 package com.hangage.util;
  2  
  3 import java.awt.Color;
  4 import java.awt.Font;
  5 import java.text.DecimalFormat;
  6 import org.jfree.chart.ChartFactory;
  7 import org.jfree.chart.JFreeChart;
  8 import org.jfree.chart.axis.CategoryAxis;
  9 import org.jfree.chart.axis.NumberAxis;
 10 import org.jfree.chart.axis.ValueAxis;
 11 import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
 12 import org.jfree.chart.plot.CategoryPlot;
 13 import org.jfree.chart.plot.PlotOrientation;
 14 import org.jfree.chart.renderer.category.BarRenderer;
 15 import org.jfree.data.category.CategoryDataset;
 16 import org.jfree.data.general.DatasetUtilities;
 17  
 18 
 19 public class ChartUtil {
 20  
 21     private static ChartUtil charUtil=null;
 22     public static ChartUtil getInstance(){
 23         if(charUtil==null){
 24             return new ChartUtil();
 25         }else{
 26             return charUtil;
 27         }
 28     }
 29     
 30    /**
 31     *生成柱状统计图
 32     * @param srcData
 33     * @param imgName
 34     * @param xData
 35     * @param xMark
 36     * @param yMark
 37     * @param yFoamt
 38     * @return JFreeChart
 39     */
 40     public JFreeChart makeBarChart(double[] srcData,String imgName,String[] xData,String xMark,String yMark,String yFoamt) {
 41         double[][] data = new double[][]{srcData };
 42         String[] rowKeys = {imgName};
 43        
 44         CategoryDataset dataset = getBarData(data, rowKeys, xData);
 45       
 46         return createBarChart(dataset, xMark, yMark, null, yFoamt);
 47     }
 48  
 49     // 柱状图,折线图 数据集
 50     private CategoryDataset getBarData(double[][] data, String[] rowKeys,
 51             String[] columnKeys) {
 52         return DatasetUtilities.createCategoryDataset(rowKeys, columnKeys, data);
 53  
 54     }
 55  
 56     
 57     /**
 58      * 柱状图
 59      *
 60      *@param dataset 数据集
 61      * @param xName x轴的说明(如种类,时间等)
 62      * @param yName y轴的说明(如速度,时间等)
 63      * @param chartTitle 图标题
 64      * @param yFormat y坐标数字显示格式(#0.00)
 65      * @return
 66      */
 67     private JFreeChart createBarChart(CategoryDataset dataset, String xName,
 68             String yName, String chartTitle,String yFormat) {
 69         JFreeChart chart = ChartFactory.createBarChart(chartTitle, // 图表标题
 70                 xName, // 目录轴的显示标签
 71                 yName, // 数值轴的显示标签
 72                 dataset, // 数据集
 73                 PlotOrientation.VERTICAL, // 图表方向:水平、垂直
 74                 true, // 是否显示图例(对于简单的柱状图必须是false)
 75                 false, // 是否生成工具
 76                 false // 是否生成URL链接
 77                 );
 78         Font labelFont = new Font("SansSerif", Font.TRUETYPE_FONT, 12);
 79        
 80         /*
 81          * VALUE_TEXT_ANTIALIAS_OFF表示将文字的抗锯齿关闭,
 82          * 使用的关闭抗锯齿后,字体尽量选择12到14号的宋体字,这样文字最清晰好看
 83          */
 84         // chart.getRenderingHints().put(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
 85         chart.setTextAntiAlias(false);
 86         chart.setBackgroundPaint(Color.white);
 87         // create plot
 88         CategoryPlot plot = chart.getCategoryPlot();
 89         // 设置横虚线可见
 90         plot.setRangeGridlinesVisible(true);
 91         // 虚线色彩
 92         plot.setRangeGridlinePaint(Color.gray);
 93  
 94         // 数据轴精度
 95         NumberAxis vn = (NumberAxis) plot.getRangeAxis();
 96         vn.setStandardTickUnits(NumberAxis.createIntegerTickUnits());//控制y轴不会因为数据太小导致出现好几个0.00
 97         // vn.setAutoRangeIncludesZero(true);
 98         DecimalFormat df = new DecimalFormat(yFormat);
 99         vn.setNumberFormatOverride(df); // 数据轴数据标签的显示格式
100         // x轴设置
101        
102         CategoryAxis domainAxis = plot.getDomainAxis();
103         domainAxis.setLabelFont(labelFont);// 轴标题
104  
105         domainAxis.setTickLabelFont(labelFont);// 轴数值
106  
107         chart.getLegend().setItemFont(labelFont);//底部
108         // Lable(Math.PI/3.0)度倾斜
109         // domainAxis.setCategoryLabelPositions(CategoryLabelPositions
110         // .createUpRotationLabelPositions(Math.PI / 3.0));
111  
112         domainAxis.setMaximumCategoryLabelWidthRatio(5.0f);// 横轴上的 Lable 是否完整显示
113  
114         // 设置距离图片左端距离
115         domainAxis.setLowerMargin(0.02);
116         // 设置距离图片右端距离
117         domainAxis.setUpperMargin(0.02);
118         // 设置 columnKey 是否间隔显示
119         // domainAxis.setSkipCategoryLabelsToFit(true);
120  
121         plot.setDomainAxis(domainAxis);
122         // 设置柱图背景色(注意,系统取色的时候要使用16位的模式来查看颜色编码,这样比较准确)
123         plot.setBackgroundPaint(new Color(255, 255, 204));
124  
125         // y轴设置
126         ValueAxis rangeAxis = plot.getRangeAxis();
127         rangeAxis.setLabelFont(labelFont);
128         rangeAxis.setTickLabelFont(labelFont);
129         rangeAxis.setLowerBound(0.0); 
130         // 设置最高的一个 Item 与图片顶端的距离
131         rangeAxis.setUpperMargin(0.15);
132         // 设置最低的一个 Item 与图片底端的距离
133         rangeAxis.setLowerMargin(0.15);
134         plot.setRangeAxis(rangeAxis);
135  
136         BarRenderer renderer = new BarRenderer();
137         // 设置柱子宽度
138         renderer.setMaximumBarWidth(0.08);
139         // 设置柱子高度
140         renderer.setMinimumBarLength(0.2);
141         // 设置柱子边框颜色
142         renderer.setBaseOutlinePaint(Color.BLACK);
143         // 设置柱子边框可见
144         renderer.setDrawBarOutline(true);
145       
146  
147         // // 设置柱的颜色
148         renderer.setSeriesPaint(0, new Color(204, 255, 255));
149         renderer.setSeriesPaint(1, new Color(153, 204, 255));
150         renderer.setSeriesPaint(2, new Color(51, 204, 204));
151  
152         // 设置每个地区所包含的平行柱的之间距离
153         renderer.setItemMargin(0.0);
154  
155         // 显示每个柱的数值,并修改该数值的字体属性
156         renderer.setIncludeBaseInRange(true);
157         renderer.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
158         renderer.setBaseItemLabelsVisible(true);
159  
160         plot.setRenderer(renderer);
161         // 设置柱的透明度
162         plot.setForegroundAlpha(1.0f);
163  
164       return chart;
165     }
166 }
View Code

 

 

 Controller

  1 package com.hangage.controller;
  2 
  3 import java.util.Calendar;
  4 import java.util.List;
  5 
  6 import javax.servlet.http.HttpServletRequest;
  7 import org.jfree.chart.JFreeChart;
  8 import org.jfree.chart.servlet.ServletUtilities;
  9 import org.springframework.beans.factory.annotation.Autowired;
 10 import org.springframework.stereotype.Controller;
 11 import org.springframework.ui.ModelMap;
 12 import org.springframework.util.StringUtils;
 13 import org.springframework.web.bind.annotation.RequestMapping;
 14 import org.springframework.web.servlet.ModelAndView;
 15 
 16 import com.hangage.bean.YearCount;
 17 import com.hangage.dao.BookDao;
 18 import com.hangage.util.ChartUtil;
 19 
 20 @Controller
 21 public class ChartController {
 22     
 23     @Autowired
 24     private BookDao bookDao;
 25     private final static String years[]={"01","02","03","04","05","06","07","08","09","10","11","12"};
 26     
 27     @RequestMapping("showChart.do")
 28     public ModelAndView showChart(String year,String month,ModelMap model,HttpServletRequest request){
 29         int flag=getRequest(year,month);
 30         ChartUtil chartUtil=ChartUtil.getInstance();
 31         JFreeChart jfreeChart=null;
 32         switch (flag) {
 33         case 1:
 34             List<YearCount> yearCount=bookDao.getCountListByYear(year);
 35             String filename="";
 36             double [] data=new double[12] ;
 37             for (int i = 0; i < years.length; i++) {
 38                 data[i]=yearCount.get(i).getCount();
 39             }
 40             
 41              jfreeChart=chartUtil.makeBarChart(data, year+"年销量", years, "月", "件", "#0.00");
 42              try {
 43                  
 44                  filename=ServletUtilities.saveChartAsPNG(jfreeChart,900,500,request.getSession());
 45                  model.put("filename", filename);
 46             } catch (Exception e) {
 47                 
 48                 e.printStackTrace();
 49             }
 50             model.put("year", year);
 51             
 52             break;
 53         case 2:
 54             Calendar calendar=Calendar.getInstance();
 55             calendar.set(Integer.valueOf(year), Integer.valueOf(month)-1, Calendar.DAY_OF_MONTH);
 56             int maxDay=calendar.getActualMaximum(Calendar.DATE);
 57             String parm=year+"-"+month;
 58             double [] datas=new double [maxDay];
 59             String [] days=new String[maxDay];
 60             for (int i = 0; i < datas.length; i++) {
 61                 days[i]=addZero(i+1);
 62                 datas[i]=bookDao.getCountByDay(parm+"-"+addZero(i+1));
 63             }
 64             
 65              jfreeChart=chartUtil.makeBarChart(datas, year+"年"+month+"月销量", days, "日", "件", "#0");
 66              try {
 67                  
 68                  filename=ServletUtilities.saveChartAsPNG(jfreeChart,800,500,request.getSession());
 69                  model.put("filename", filename);
 70             } catch (Exception e) {
 71                 
 72                 e.printStackTrace();
 73             }
 74             model.put("year", year);
 75             model.put("month", month);
 76             
 77             break;
 78 
 79         default:
 80             break;
 81         }
 82         
 83         return new ModelAndView("showChart",model);
 84     }
 85 
 86     private int getRequest(String year,String month){
 87         if(!StringUtils.isEmpty(month)){
 88             return 2;
 89         }else{
 90             return 1;
 91         }
 92     }
 93     
 94     private String addZero(int num){
 95         if(num<10){
 96             return "0"+num;
 97         }else{
 98             return String.valueOf(num);
 99         }
100     }
101 }
View Code

 

 

 SQL语句

 1 <select id="getCountListByYear" resultMap="yearCount">
 2     SELECT MON,SUM(CNT) AS CNT
 3 FROM
 4 (
 5     SELECT
 6     SUBSTRING(CREATE_TIME, 6, 2) AS MON,
 7     COUNT(ID)  AS CNT
 8     FROM BOOK 
 9     WHERE SUBSTRING(CREATE_TIME, 1, 4)=#{year}
10     GROUP BY SUBSTRING(CREATE_TIME, 6, 2)
11     UNION 
12     SELECT '01'AS MON, '0' AS CNT
13     UNION 
14     SELECT '02'AS MON, '0' AS CNT
15     UNION 
16     SELECT '03'AS MON, '0' AS CNT
17     UNION 
18     SELECT '04'AS MON, '0' AS CNT
19     UNION 
20     SELECT '05'AS MON, '0' AS CNT
21     UNION 
22     SELECT '06'AS MON, '0' AS CNT
23     UNION 
24     SELECT '07'AS MON, '0' AS CNT
25     UNION 
26     SELECT '08'AS MON, '0' AS CNT
27     UNION 
28     SELECT '09'AS MON, '0' AS CNT
29     UNION 
30     SELECT '10'AS MON, '0' AS CNT
31     UNION 
32     SELECT '11'AS MON, '0' AS CNT
33     UNION 
34     SELECT '12'AS MON ,'0' AS CNT
35     )AS TEMP
36 GROUP BY TEMP.MON 
37 ORDER BY TEMP.MON 
38     </select>
39     
40     
41     <select id="getCountByDay" parameterType="java.lang.String" resultType="java.lang.Integer" >
42         SELECT
43         COUNT(ID)  AS CNT
44         FROM BOOK 
45         WHERE SUBSTRING(CREATE_TIME, 1, 10)=#{parm}
46     
47     </select>
View Code
  • JSP
 1 <%@ page language="java" contentType="text/html; charset=UTF-8"
 2     pageEncoding="UTF-8"%>
 3 <%@ page import="org.jfree.data.general.DefaultPieDataset,org.jfree.chart.ChartFactory
 4 ,org.jfree.chart.JFreeChart,org.jfree.chart.servlet.DisplayChart" %>
 5 
 6 <%
 7         String path=request.getServletContext().getContextPath();
 8         String fileName=(String)request.getAttribute("filename");
 9         String url = request.getContextPath() + "/DisplayChart?filename=" + fileName;
10 %>
11 <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
12 <html>
13 <head>
14 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
15 <title>Insert title here </title>
16 </head>
17 <body>
18 <div>
19     <form action="<%=path %>/showChart.do" method="post">
20     选择年份:<select name="year">
21                 <option value="2013" ${year=='2013'? 'selected':'' }>2013年</option>
22                 <option value="2014" ${year=='2014'? 'selected':'' }>2014年</option>
23                 <option value="2015" ${year=='2015'? 'selected':'' }>2015年</option>
24            </select>
25           <input type="submit" value="查询">
26     </form>
27     </div>
28     <div align="center">
29         <img  src="<%=url%>">
30     </div>
31 </body>
32 </html>
View Code

 在jsp页面中从model取得JFreeChart生成图片的名字,通过JFreeChart提供的工具DisplayChart取得生成临时图片的路径,要使用DisplayChart这个Servlet提供的service方法 必须在web.xml中做如下配置

 1 <servlet>
 2     <servlet-name>DisplayChart</servlet-name>
 3     <servlet-class>
 4         org.jfree.chart.servlet.DisplayChart
 5     </servlet-class>
 6   </servlet>
 7   <servlet-mapping>
 8     <servlet-name>DisplayChart</servlet-name>
 9     <url-pattern>/DisplayChart</url-pattern>
10   </servlet-mapping>
View Code

 

 

 
 
posted @ 2015-05-23 17:30  大发  阅读(494)  评论(0编辑  收藏  举报