zoukankan      html  css  js  c++  java
  • 使用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
     
     
  • 相关阅读:
    google
    html页面清除缓存
    EF中使用SQL语句或存储过程
    在存储过程中编写正确的事务处理代码
    .Net中Math.Round与四舍五入
    WebService中实现上传下载文件
    tony_linux下网站压力测试工具webbench
    把Nginx加为系统服务(service nginx start/stop/restart)
    Nginx+Tomcat+Keepalived+Memcache 负载均衡动静分离技术
    python学习笔记(1)--遍历txt文件,正则匹配替换文字
  • 原文地址:https://www.cnblogs.com/dafa4java/p/4524573.html
Copyright © 2011-2022 走看看