用JFreeChart画统计分析曲线图(成功版)(转)

用JFreeChart画统计分析曲线图(成功版)(转)

用JFreeChart画统计分析曲线图(成功版)

[ 2006-6-22 11:27:00 | By: blueroc ][code]  
  package com.company.chart;

import org.jfree.ui.RefineryUtilities;
import org.jfree.ui.ApplicationFrame;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.DateTickUnit;
import org.jfree.chart.plot.XYPlot;
import org.jfree.data.xy.XYDataset;
import org.jfree.data.time.*;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.swing.*;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Properties;
import java.util.Vector;

/**
*  User: blueroc
* Date: 2006-6-19
* Time: 10:48:00
* 用于将统计结果显示成图形
* 使用用法(以日访问量查询为例子):
   ChartGender chartTime = new ChartGender();
   chartTime.chartTitle = "访问量统计图形";
   chartTime.chartSeriesDesc = "日访问量曲线";
   chartTime.chartXdesc = "时间";
   chartTime.chartYdesc = "访问量";
   chartTime.graphHigh = 600;
   chartTime.graphWidth = 800;
   chartTime.timeFormat = "yyyy-MM-dd";
   chartTime.periodType = "DAY";

   //add info data
   chartTime.addTimeSeriesUniteData("DAY",2006,6,10,5,100);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,11,5,200);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,12,5,300);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,13,5,400);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,14,5,350);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,15,5,200);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,16,5,500);
   chartTime.addTimeSeriesUniteData("DAY",2006,6,17,5,300);
   //add collections
   chartTime.addTimeSeries("DAY");
   
   chartTime.setDateInterval(1);
   chartTime.createTimeGraphByServlet(req,res);
*/



public class ChartGender
{

    JFreeChart chart = null;
    public String chartTitle = "";
    public String chartXdesc = "";
    public String chartYdesc = "";
    public String chartSeriesDesc = "";
    public int graphHigh = 650;
    public int graphWidth = 900;
    public String timeFormat = "yyyy-MM";  //按日:MM-dd ,按小时:hh:mm

    // 用于标志用户选择的是按哪种查询统计周期类型(月,天,小时).
    // 月:MONTH  , 天:DAY ,小时:HOUR
    public String periodType = "";
    // 用于确定时间间隔。
    public int dateInterval = 1;

    TimeSeriesCollection dataset = new TimeSeriesCollection();
    TimeSeries monthseries = null;
    TimeSeries dayseries = null;
    TimeSeries hourseries = null;




    public ChartGender() {

    }

    public void setPeriodType(String type) {
        periodType = type;
    }

    public void setPeriodUnitInfo(String name,String value) {
        //periodUnitInfo.put(name,value);
    }

    public void setDateInterval(int value) {
        dateInterval = value;
    }

    public void addPointList(Properties prop) {
        //pointList.add(prop);
    }



    /**
     * 画曲线图的方法
     * @param req
     * @param res
     * @throws java.io.IOException
     */
    public void createTimeGraphByServlet(ServletRequest req, ServletResponse res) throws IOException
    {
        res.setContentType("image/jpeg");
        chart = createTimeGraph();
        ChartUtilities.writeChartAsJPEG(res.getOutputStream(),100,chart,graphWidth,graphHigh,null);
    }

    private JFreeChart createTimeGraph()
    {
        JFreeChart chart = ChartFactory.createTimeSeriesChart(
            chartTitle, chartXdesc, chartYdesc,getTimeDataSet(),true,false,false
        );
        XYPlot xyplot = chart.getXYPlot();
        DateAxis dateaxis = (DateAxis) xyplot.getDomainAxis();

        if(periodType.equalsIgnoreCase("MONTH")) {
            dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.MONTH,dateInterval));
        } else if(periodType.equalsIgnoreCase("DAY")) {
            dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.DAY,dateInterval));
        } else if(periodType.equalsIgnoreCase("HOUR")) {
            dateaxis.setTickUnit(new DateTickUnit(DateTickUnit.HOUR,dateInterval));
        }
        dateaxis.setDateFormatOverride(new SimpleDateFormat(timeFormat));

        return chart;
    }

    private XYDataset getTimeDataSet()
    {
        dataset.setDomainIsPointsInTime(true);
        return dataset;
    }

    public void addTimeSeries(String type)
    {
        if(type.equalsIgnoreCase("MONTH")) {
            dataset.addSeries(monthseries);
        } else if(type.equalsIgnoreCase("DAY")) {
            dataset.addSeries(dayseries);
        } else if(type.equalsIgnoreCase("HOUR")) {
            dataset.addSeries(hourseries);
        }
    }

    public void addTimeSeriesUniteData(String type,int year,int month,int day,int hour,int count)
    {
        if(type.equalsIgnoreCase("MONTH")) {
            if(monthseries == null) {
                monthseries = new TimeSeries(chartSeriesDesc, Month.class);
            }
            monthseries.add(new Month(month, year), count);
        } else if(type.equalsIgnoreCase("DAY")) {
            if(dayseries == null) {
                dayseries = new TimeSeries(chartSeriesDesc, Day.class);
            }
            dayseries.add(new Day(day,month,year), count);
        } else if(type.equalsIgnoreCase("HOUR")) {
            if(hourseries == null) {
                hourseries = new TimeSeries(chartSeriesDesc, Hour.class);
            }
            hourseries.add(new Hour(hour,day,month, year), count);
        }
    }
}[/code][color=blue]本文是转自一个博客里面的帖子,但博客已经被删除了,在百度快照中找到,故转载于此,大家一起研究一下.
快照地址:[/color][url=http://cache.baidu.com/c?word=must%2Cbe%2Cin%2Cthe%2Crange%2C0%3B%2E%3B0f%2Cto%2C1%3B%2E%3B0f&url=http%3A//www%2Eblogchinese%2Ecom/06042/201878/archives/2006/2006622112751%2Eshtml&p=882a971297895fb90be2923f56&user=baidu][color=blue]http://cache.baidu.com/c?word=mu ... e2923f56&user=baidu[/color][/url]

bufegar 2007-7-9 16:11

The 'quality' must be in the range 0.0f to 1.0f
我也碰到这个错了,把freeChart的源码对照看了看,是这个方法   

       ChartUtilities.writeChartAsJPEG(res.getOutputStream(),100,chart,graphWidth,graphHigh,null);

限制quality必须小于等于1,所以修改一下

把100改成 0.1f就可以显示了

bufegar 2007-7-9 16:14

你有生成饼图的main的例子吗,能生成JPEG图片的例子!

bufegar 2007-7-9 16:14

我用了jfreechart-1.0.1.jar 可是我把这个JAR文件导入到Myeclipse中之后,看不到里面的.class文件啊,但是在外面 用rar的后缀却能看到里面的文件,这个是为什么啊

bufegar 2007-7-9 16:15

[quote]原帖由 [i]bufegar[/i] 于 2007-7-9 16:14 发表 [url=http://www.newwhy.com/redirect.php?goto=findpost&pid=1321&ptid=981][img]http://www.newwhy.com/images/common/back.gif[/img][/url]
我用了jfreechart-1.0.1.jar 可是我把这个JAR文件导入到Myeclipse中之后,看不到里面的.class文件啊,但是在外面 用rar的后缀却能看到里面的文件,这个是为什么啊 [/quote]
仁兄,不是很懂你什么意思啊,是在Myeclipse导入jar包后,程序中import 时找不到吗??要是这种情况,从项目的Properties里的Java Build Path 中的 Libraries 导入这个jar包 看看,,应该好使 :)

bufegar 2007-7-9 16:15

我可能没说清楚,我再详细说一下,添加上

dataset.setDomainIsPointsInTime(true);这一句eclipse会出现警告信息.警告信息为:

Multiple markers at thia line

-line breakpoint:Chart Gender[line:78] -getTimeDataSet()

-The method setDomainIsPointInTime(boolean) from the type TimeSeriesCollection is deprecated.

我把这句删掉了.运行程序,Tomcat会报错,错误信息是:

type Exception report

message

description The server encountered an internal error () that prevented it from fulfilling this request.

exception

java.lang.IllegalArgumentException: The 'quality' must be in the range 0.0f to 1.0f
        org.jfree.chart.encoders.SunJPEGEncoderAdapter.setQuality(SunJPEGEncoderAdapter.java:102)
        org.jfree.chart.encoders.ImageEncoderFactory.newInstance(ImageEncoderFactory.java:131)
        org.jfree.chart.encoders.EncoderUtil.writeBufferedImage(EncoderUtil.java:152)
        org.jfree.chart.ChartUtilities.writeChartAsJPEG(ChartUtilities.java:474)
        com.company.chart.ChartGender.createTimeGraphByServlet(ChartGender.java:57)
        com.servlet.Statistic.doGet(Statistic.java:48)
        com.servlet.Statistic.service(Statistic.java:19)
        javax.servlet.http.HttpServlet.service(HttpServlet.java:802)


note The full stack trace of the root cause is available in the Apache Tomcat/5.0.28 logs.



请楼主帮我看看了.我实在不知道问题出在哪!

bufegar 2007-7-9 16:15

好久不搞这个了,也记不得了,不过记得当时我也报这个The method setDomainIsPointInTime(boolean) from the type TimeSeriesCollection is deprecated错,好像不影响使用,你再试试看

bufegar 2007-7-9 16:16

你好,我调了一下你的这个程序,

在调ChartGender类的下面语句时,系统报错!
错误语句为 dataset.setDomainIsPointsInTime(true);
private XYDataset getTimeDataSet()
    {
        dataset.setDomainIsPointsInTime(true);
        return dataset;
    }

我不知道它为什么报错,我看了一下,dataset对象是有setDomainIsPointslnTime这个方法的.

我用的软件环境是eclipse

jfreechart用的是1.0.2

bufegar 2007-7-9 16:16

楼主你好,

我有个一jfreechart的时序图的问题!请您帮一下忙!

时序图多条曲线对比的时候的,数据点重合的问题?怎么解决呢?>

bufegar 2007-7-9 16:16

不知道为什么总出现下面问题

D:/Tomcat/apache-tomcat-4.1.32-LE-jdk14/work/Standalone/localhost/panda/chart6_jsp.java:54: createBarChart3D(java.lang.String,java.lang.String,java.lang.String,org.jfree.data.CategoryDataset,org.jfree.chart.plot.PlotOrientation,boolean,boolean,boolean) in org.jfree.chart.ChartFactory cannot be applied to (java.lang.String,java.lang.String,java.lang.String,org.jfree.data.jdbc.JDBCCategoryDataset,org.jfree.chart.plot.PlotOrientation,boolean,boolean,boolean)
JFreeChart   chart=ChartFactory.createBarChart3D("姘存??????璁″?",   

是不是从数据库调数据的方法不对呀,请指教

bufegar 2007-7-9 16:16

我试了试,方法没问题,可以显示。按你提示的错误

D:/Tomcat/apache-tomcat-4.1.32-LE-jdk14/work/Standalone/localhost/panda/chart6_jsp.java:54: createBarChart3D(java.lang.String,java.lang.String,java.lang.String,org.jfree.data.CategoryDataset,org.jfree.chart.plot.PlotOrientation,boolean,boolean,boolean) in org.jfree.chart.ChartFactory cannot be applied to (java.lang.String,java.lang.String,java.lang.String,org.jfree.data.jdbc.JDBCCategoryDataset,org.jfree.chart.plot.PlotOrientation,boolean,boolean,boolean)

CategoryDataset是个接口,而JDBCCategoryDataset实现了CategoryDataset接口,把

JDBCCategoryDataset  dataSet=new  JDBCCategoryDataset(con,"select * from dc ");改为

CategoryDataset dataSet= ((CategoryDataset))  new  JDBCCategoryDataset(con,"select * from dc ");试试看。

        不过我按你的却可以运行

bufegar 2007-7-9 16:17

<%@   page   contentType="text/html;charset=GBK"%>   
  <%@   page   import="org.jfree.chart.ChartFactory,   
                       org.jfree.chart.JFreeChart,   
                       org.jfree.chart.plot.PlotOrientation,   
                       org.jfree.chart.servlet.ServletUtilities,   
                       org.jfree.data.jdbc.JDBCCategoryDataset"
   %>
   <%@ page import="java.sql.*"%>
<%
//连接数据库
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection con=DriverManager.getConnection("jdbc:odbc:sun","","");
Statement stmt=con.createStatement();
JDBCCategoryDataset  dataSet=new  JDBCCategoryDataset(con,"select * from dc ");
JFreeChart   chart=ChartFactory.createBarChart3D("水果销量统计图",     
                                      "水果",   
                                      "销量",   
                                      dataSet,   
                                      PlotOrientation.VERTICAL,   
                                      false,   
                                      false,   
                                      false);   
String   filename   =   ServletUtilities.saveChartAsPNG(chart,   500,   300,   null,   session);   
String   graphURL   =   request.getContextPath()   +   "/servlet/DisplayChart?filename="   +   filename;   
%>

bufegar 2007-7-9 16:17

先谢过楼主的耐心指导,我现在是直接把class ChartGender这个类放在Ststistic.java文件里面直接调用了,虽然还是会有报API过时的错误,但是,运行了以后已经能出来了,非常感谢楼主的教导,明白了很多,现在我想把数据导入SQL2000,实现分时间段查询,楼主有没有好的意见,access下面我是用JDBC-ODBC桥实现了数据库的

bufegar 2007-7-9 16:17

ChartGender.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.还是会出现过时的API的问题,我用的编译器是TextPad,

环境变量是:.;D:/Program Files/j2sdk1.4.2/lib;

D:/Program Files/j2sdk1.4.2/lib/tools.jar;

F:/jsp/jfreechart-1.0.1/lib/jfreechart-1.0.1.jar;

D:/Program Files/j2sdk1.4.2/lib/jfreechart-1.0.1.jar;

D:/Program Files/j2sdk1.4.2/lib/servlet.jar;

F:/jsp/jcommon-1.0.5/jcommon-1.0.5.jar;

同时,我已经把JfreeChart文件lib的文件复制到tomcat工程jspzhan下的web-inf下了,环境应该是没问题的,我用的是j2sdk1.4.2版的,谢谢楼主指导```

bufegar 2007-7-9 16:18

谢谢楼主耐心的指导,已经在向成功迈进了```

但是还是没能把statistic.java编译通过,主要问题还是出在ChartGender这个类没能连接上,我按照你的路径进行了放置,编译statistic.java时报错了:

D:/Program Files/Apache Group/Tomcat 4.1/webapps/jspzhan/WEB-INF/classes/com/servlet/statistic.java:27: class Statistic is public, should be declared in a file named Statistic.java
public class Statistic extends HttpServlet{
           ^
D:/Program Files/Apache Group/Tomcat 4.1/webapps/jspzhan/WEB-INF/classes/com/servlet/statistic.java:2: package com.company.chart does not exist
import com.company.chart.ChartGender;
                                           ^
D:/Program Files/Apache Group/Tomcat 4.1/webapps/jspzhan/WEB-INF/classes/com/servlet/statistic.java:43: cannot resolve symbol
symbol  : class ChartGender
location: class com.servlet.Statistic
    ChartGender chartTime = new ChartGender();
    ^
D:/Program Files/Apache Group/Tomcat 4.1/webapps/jspzhan/WEB-INF/classes/com/servlet/statistic.java:43: cannot resolve symbol
symbol  : class ChartGender
location: class com.servlet.Statistic
    ChartGender chartTime = new ChartGender();
                                                     ^
4 errors



再次谢谢楼主耐心的指导```

bufegar 2007-7-9 16:18

几点建议:

        文件名statistic.java改为Statistic.java, (文件名应与类名一样,public class Statistic extends HttpServlet)

         ChartGender.java编译时,报ChartGender.java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.这个不影响使用,暂时不用考虑,使用生成的ChartGender.class

        编译Statistic.java找不到import com.company.chart.ChartGender;是因为在ClassPath中没有找到此ChartGender.class,因为ClassPath中设置了.;(当前目录),所以可以先到com的上级目录(即/WEB-INF/classes)下编译Statistic.java,此时的命令应该为javac com/servlet/Statistic.java

bufegar 2007-7-9 16:18

ChartGender.java;这个类我放在工程的/Tomcat 4.1/webapps/jspzhan/WEB-INF/classes/company/chart文件夹下了。statistic.java我放在工程Tomcat 4.1/webapps/jspzhan/WEB-INF/classes/servlet下了。编译ChartGender.java时出现java uses or overrides a deprecated API.Note: Recompile with -deprecation for details.这个了;编译statistic.java时出现'.' expected
import ChartGender;这个了,所以出不来,楼主一定要帮我啊```````非常感谢````````(我用的是tomcat4.1和jfreechart1.0.1和jcommon1.0.5不知道会不会是版本问题?环境我已经搭好的)工程名是jspzhan

bufegar 2007-7-9 16:18

我用的是tomcat5和jfreechart1.0.1和jcommon1.0.0估计不是版本问题,几点建议:

   首先,在ChartGender.java中如果是package com.company.chart;则/WEB-INF/classes/company/chart目录应该是/WEB-INF/classes/com/company/chart.其次,没必要把ChartGender.java放在/WEB-INF/classes/...目录下,而应该把编译后的ChartGender.class文件copy过去.

   Statistic.java同样的道理,类中声明package com.servlet;则应该把编辑后的Statistic.class放在/WEB-INF/classes/com/servlet下,另外在Statistic.java中的import ChartGender;应该改为import com.company.chart.ChartGender;(即导入时应该写类的全路径).

    至于如何把ChartGender.java编译成ChartGender.class,就要老兄网上自己搜搜了.因为ChartGender用到jfreechart的类,所有应该保证编译时能找到相关的类(比如通过设置环境变量的ClassPath,当然如果你用Jbuilder或Eclipse等IDE的话,那就更方便了),否则又要报java uses or overrides a deprecated API.Note: Recompile with -deprecation for details

bufegar 2007-7-9 16:19

再次谢谢楼主的指导,

我目前用的是JFREECHART1.0.1版的,

没找到import ChartGender;这个类,.jsp文件和web.xml也都是对的,是不是还少一些类啊

bufegar 2007-7-9 16:19

晕,ChartGender就是我上边写的那个类啊,copy过去不就OK了

bufegar 2007-7-9 16:20

谢谢楼住的指导,但是还是通不过,ChartGender chartTime = new ChartGender()放在哪都不行,编译能同过,但是会出现java uses or overrides a deprecated API.
Note: Recompile with -deprecation for details.

希望楼主给个最完整的代码,刚学JFREE,还有很多不明白的地方,谢谢楼主了

bufegar 2007-7-9 16:20

我的可以跑通,你是不是没有把jfree需要的包导进来啊?

前边页面statistic.jsp


<%@ page language="java" contentType="text/html; charset=gb2312" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
   
    <title>statistic.jsp</title>
</head>

  <body>
<form action="statistic" method="get">
生成曲线图<input type="submit" name="submit" value=" 提交 " />
  </form>
</body>
</html>

点击提交按钮,则会生成曲线图,Servlet:Statistic.java代码:(注意把类ChartGender,import进来,红色部分为上边原文注释部分直接copy来得)

package com.servlet;

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 ChartGender;

public class Statistic extends HttpServlet
{
public void service(HttpServletRequest request,HttpServletResponse response)
throws IOException,ServletException{

//判断提交方式
if((request.getMethod()).equalsIgnoreCase("get")){
  this.doGet(request,response);
}
else{
  this.doPost(request,response);
}
}
public void doGet(HttpServletRequest request,
   HttpServletResponse response)
   throws ServletException, IOException {

    ChartGender chartTime = new ChartGender();
    chartTime.chartTitle = "访问量统计图形";
    chartTime.chartSeriesDesc = "日访问量曲线";
    chartTime.chartXdesc = "时间";
    chartTime.chartYdesc = "访问量";
    chartTime.graphHigh = 600;
    chartTime.graphWidth = 800;
    chartTime.timeFormat = "yyyy-MM-dd";
    chartTime.periodType = "DAY";
  
    //add info data
    chartTime.addTimeSeriesUniteData("DAY",2006,6,10,5,100);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,11,5,200);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,12,5,300);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,13,5,400);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,14,5,350);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,15,5,200);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,16,5,500);
    chartTime.addTimeSeriesUniteData("DAY",2006,6,17,5,300);
    //add collections
    chartTime.addTimeSeries("DAY");
   
    chartTime.setDateInterval(1);
    chartTime.createTimeGraphByServlet(request,response);
   }
public void doPost(HttpServletRequest request,
   HttpServletResponse response)
   throws ServletException, IOException {

//    使用“request”读取和请求有关的信息(比如Cookies)
//    和表单数据

//    使用“response”指定HTTP应答状态代码和应答头
//    (比如指定内容类型,设置Cookie)

   PrintWriter out = response.getWriter();
//    使用 "out"把应答内容发送到浏览器
   out.println("Hello World");
   }
}

注意web.xml中设置servlet哦

  <servlet>
        <servlet-name>statistic</servlet-name>
        <servlet-class>com.servlet.Statistic</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>statistic</servlet-name>
        <url-pattern>/statistic</url-pattern>
    </servlet-mapping> 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值