jfreechart与servlet的结合做折线图,实现热点

这两天在做项目,做性能监控的时候需呀用图表来直观的显示。选择了jfreechart。

中间遇到了不少的问题,但是经过两天的尝试,问题都被解决了。

jfreechart用到的jar包网上都有。

 

 首先把servlet代码显示如下:

package com.pzoom.crabman.servlet;

import java.awt.Rectangle;
import java.awt.Shape;
import java.io.CharArrayWriter;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.entity.ChartEntity;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.imagemap.ImageMapUtilities;
import org.jfree.chart.imagemap.OverLIBToolTipTagFragmentGenerator;
import org.jfree.chart.imagemap.StandardToolTipTagFragmentGenerator;
import org.jfree.chart.imagemap.StandardURLTagFragmentGenerator;
import org.jfree.chart.imagemap.ToolTipTagFragmentGenerator;
import org.jfree.chart.labels.StandardPieToolTipGenerator;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.chart.urls.StandardPieURLGenerator;

import com.pzoom.crabman.util.ChartUtil;


public class CharServlet extends HttpServlet {

 
 public CharServlet() {
  super();
 }

 
 public void destroy() {
  super.destroy(); // Just puts "destroy" string in log
  // Put your code here
 }

 
 public void doGet(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  response.setContentType("text/html; charset=UTF-8");
  
  Shape shape = new Rectangle(20, 10);  
        ChartEntity entity = new ChartEntity(shape);  
        StandardEntityCollection coll = new StandardEntityCollection();  
        coll.add(entity);  
        //该工具类上面没有介绍,在鼠标移动到图片时显示提示信息是用Map实现的,这些Map是用该类生成的。  
        ChartRenderingInfo info = new ChartRenderingInfo(coll);  
        PrintWriter pw=response.getWriter();//输出MAP信息 
       
        //CharArrayWriter   cawMap   =   new   CharArrayWriter();
  //PrintWriter   pwMap   =   new   PrintWriter(cawMap);
         
        JFreeChart chart = null;
     
       
        boolean useOverLibForToolTips = true;
  ToolTipTagFragmentGenerator toolTipTagFragmentGenerator = null;
  if (useOverLibForToolTips) {
   toolTipTagFragmentGenerator = new OverLIBToolTipTagFragmentGenerator();
  } else {
   toolTipTagFragmentGenerator = new StandardToolTipTagFragmentGenerator();
  }
       
  //显示样式(是否为3D效果) 
  String style = request.getParameter("style"); 
  String fileName = null;     //生成图片的文件名 
  if(style != null && "3d".equals(style)){      //获取生成图片的名称     
   fileName = ServletUtilities.saveChartAsPNG(             
     ChartUtil.createChart(true), 500,300, request.getSession());

   //ChartUtilities.writeImageMap(pw, fileName, info, false);
   //System.out.println(ChartUtilities.getImageMap(, info));
   request.setAttribute("fileName", fileName);
   //pw.flush();
   }else{
    chart = ChartUtil.createChart(false);
     //ChartUtilities.writeChartAsPNG(respon, chart, 500, 500, info);
    fileName = ServletUtilities.saveChartAsPNG(          
      chart, 500, 500,info, request.getSession());

//注意,这个savesaveChartAsPNG方法的第四个参数,info,如果没有这个参数的话,是不能将图片的map存入的,也就是说生成的图片没有热点。。。
    //ChartUtilities.writeImageMap(pw, fileName, info, false);
    
    
    ChartUtilities.writeImageMap(pw, "chartMap",info,false); //这里的参数chartMap,意思是:把map信息写入request中key值为chartMap的map中。取出的时候,在页面上用getAttribute(“chartMap”)
    //String   sMap   =   cawMap.toString();
    //String sMap = ChartUtilities.getImageMap(fileName, info);
    
    // 获得"map"
    String sMap = ImageMapUtilities.getImageMap("chartMap", info,
      toolTipTagFragmentGenerator,
      new StandardURLTagFragmentGenerator());
    
    System.out.println(sMap);
    request.setAttribute("sMap", sMap);//存储map信息

    request.setAttribute("chartMap", "chartMap");
    
    request.setAttribute("fileName", fileName);
    //pw.flush();
    } 
  //获取图片的路径 
  String graphURL = request.getContextPath() + "/servlet/DisplayChart?filename=" + fileName;  //将路径放到request对象中 

//注意这里的"/servlet/DisplayChart?filename=" 是jfreechart的虚拟的存储路径。一定要与在web.xml中配置的servlet一致
  request.setAttribute("graphURL", graphURL);  //页面转发到result.jsp 
    
  request.getRequestDispatcher("result.jsp").forward(request, response);
  
 }

 
 public void doPost(HttpServletRequest request, HttpServletResponse response)
   throws ServletException, IOException {

  response.setContentType("text/html");
  PrintWriter out = response.getWriter();
  out
    .println("<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">");
  out.println("<HTML>");
  out.println("  <HEAD><TITLE>A Servlet</TITLE></HEAD>");
  out.println("  <BODY>");
  out.print("    This is ");
  out.print(this.getClass());
  out.println(", using the POST method");
  out.println("  </BODY>");
  out.println("</HTML>");
  out.flush();
  out.close();
 }

 
 public void init() throws ServletException {
  
 }

}

 

 

 

 


下面把ChartUtil类的代码弄出来:

 

 

package com.pzoom.crabman.util;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.text.DecimalFormat;
import java.util.Random;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.labels.StandardCategoryToolTipGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;


public class ChartUtil {     
 //字体     
 private static final Font PLOT_FONT = new Font("宋体", Font.BOLD, 15);     
     
 public static CategoryDataset createDataSet() {         
  //图例名称         
  String[] line = { "JAVA", "C#", "C++" };         
  //类别         
  String[] category = { "2000年","2001年","2002年", "2003年", "2004年" };         
  Random random = new Random();  
  //实例化Random对象         
  //实例化DefaultCategoryDataset对象         
  DefaultCategoryDataset dataSet = new DefaultCategoryDataset();         
  //使用循环向数据集合中添加数据         
  for (int i = 0; i < line.length; i++) {             
   for (int j = 0; j < category.length; j++) {                 
    dataSet.addValue(100000 + random.nextInt(100000), line[i],                         
      category[j]);             
    }          }         
  return dataSet;     
  }     
     
 public static JFreeChart createChart(boolean is3D) {         
  JFreeChart chart = null;         
  if(is3D){             
   chart = ChartFactory.createLineChart3D(                     
     "2000-2004年优秀程序员数量统计",   //图表标题                     
     "程序开发语言",   //X轴标题                     
                          
     "程序员数量",   //Y轴标题                
                      
     createDataSet(),     //绘图数据集          
                       
     PlotOrientation.VERTICAL,     //绘制方向 
                        
     true,       //显示图例                    
                        
     true,            //采用标准生成器                
                       
     false             //是否生成超链接             
                         
     );         
   }else{             
    chart = ChartFactory.createLineChart("2000-2004年优秀程序员数量统计",
      //图表标题                     
      "程序开发语言",                 
      //X轴标题                     
      "程序员数量",           
      //Y轴标题                     
      createDataSet(),                
      //绘图数据集                     
      PlotOrientation.VERTICAL,   
      //绘制方向                     
      true,                       
      //是否显示图例                     
      true,                       
      //是否采用标准生成器                     
      false                   
      //是否生成超链接                     
      );         
    }                   
  //设置标题字体         
  chart.getTitle().setFont(new Font("隶书", Font.BOLD, 23));         
  //设置图例类别字体         
  chart.getLegend().setItemFont(new Font("宋体", Font.BOLD, 15));         
  chart.setBackgroundPaint(new Color(192,228,106));  
  //设置背景色         
  //获取绘图区对象         
  CategoryPlot plot = chart.getCategoryPlot();         
  plot.getDomainAxis().setLabelFont(PLOT_FONT);    
  //设置横轴字体         
  plot.getDomainAxis().setTickLabelFont(PLOT_FONT);//设置坐标轴标尺值字体         
  plot.getRangeAxis().setLabelFont(PLOT_FONT);    //设置纵轴字体         
  plot.setBackgroundPaint(Color.WHITE);         //设置绘图区背景色         
  plot.setRangeGridlinePaint(Color.RED);       //设置水平方向背景线颜色         
  plot.setRangeGridlinesVisible(true);       //设置是否显示水平方向背景线,默认值为true         
  
  plot.setDomainGridlinePaint(Color.RED);     //设置垂直方向背景线颜色         
  plot.setDomainGridlinesVisible(true);    //设置是否显示垂直方向背景线,默认值为false         
  //获取折线对象         
  LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot.getRenderer(); 
  
  
  renderer.setShapesVisible(true);
  renderer.setDrawOutlines(true);
  renderer.setUseFillPaint(true);
  renderer.setFillPaint(java.awt.Color.white);
  //renderer.setToolTipGenerator(new   StandardCategoryToolTipGenerator( "{2} ",new   DecimalFormat()));//前面参数是标签,可以是{0},{1}或者{2},{2}代表数值,后面那个参数就是数据格式


  
  
  
  BasicStroke realLine = new BasicStroke(1.6f);       //设置实线         
  float dashes[] = { 8.0f };                      //定义虚线数组         
  BasicStroke brokenLine = new BasicStroke(1.6f,      //线条粗细                 
    BasicStroke.CAP_SQUARE,             //端点风格                 
    BasicStroke.JOIN_MITER,                 //折点风格                 
    8.f,                                //折点处理办法                 
    dashes,                         //虚线数组                 
    0.0f);                          //虚线偏移量         
  renderer.setSeriesStroke(1, brokenLine);     //利用虚线绘制         
  renderer.setSeriesStroke(2, brokenLine);   //利用虚线绘制         
  renderer.setSeriesStroke(3, realLine);    //利用实线绘制        
  return chart;     
  }
 
  
}

然后是web.xml 里的配置:

<!-- 第一个servlet 是我自己写的用于接收页面发来的请求-->

<servlet>
    <servlet-name>CharServlet</servlet-name>
    <servlet-class>com.pzoom.crabman.servlet.CharServlet</servlet-class>
  </servlet>

   
  <servlet-mapping>
    <servlet-name>CharServlet</servlet-name>
    <url-pattern>/CharServlet</url-pattern>
  </servlet-mapping>
 

<!-- 第二个servlet 是jfreechart的servlet,用于返回图片的-->
  <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>/servlet/DisplayChart</url-pattern>

<!--注意这个url-patten与前面我说到的配置是一致的-->  
  </servlet-mapping>

 

 

最后是页面:

首先是index.jsp页面:发起请求.

<h1>查看统计报表</h1>         
    <a href="CharServlet">普通样式</a>         
    <a href="CharServlet?style=3d">3D样式</a> 

 

然后是result.jsp页面:显示jfreechart生成的图片

<img src="${graphURL}" border="0" ismap="ismap" usemap="#chartMap"/>      <br><br> 
   <%=request.getAttribute("sMap")%>

注:usermap="#chartMap" 也可以替换为usermap="#<%=request.getAttibute("chartMap")%>"

都行。

 

至此万事大吉。

但是运行后会出现,map没有出来,鼠标移动到节点时没有效果。

原来jfreechart需要调用一个js:overlib.js  直接在google中搜索。然后添加到项目中。

<script type="text/javascript" src="js/overlib.js"></script>

 

然后再运行。okjfreechart与servlet的结合做折线图,实现热点_第1张图片

效果图如上。

另外在补充一个问题,就是如果生成的图片或内容过多时会出项cannot forward afrter response has been commited ,如果你确定没有任何flush语句的话,那么你可以这样处理。response.setBufferSize(1024*100);

这是因为你的输出缓冲区太小,输入满之后,就会向外输出,这是系统就会提示response已被提交。

 

希望对有需要的朋友有用。如有错误,请不吝指正。十分感谢。

你可能感兴趣的:(jfreechart)