蓝森林首页 | 返回主页 | 本站地图 | 站内搜索 | 联系信箱 |
 您目前的位置:首页 > 自由软件 > 技术交流 > 应用编程


    

蓝森林 http://www.lslnet.com 2006年6月6日 10:18



使用JFreechart制作图表的过程详解

由于项目的需要,在开发过程中需要以图表的方式来向客户展示数据,因此采用Jfreechart来实现这一功能,现在我把实现的过程写了出来,希望对初学者读了以后能有所收获,我也不白忙活一场,详细的内容大家可以到我的博客上去找,由于我也是个菜鸟,有错误的地方还请大家指点。
一.        配置JDK环境
我用的是JDK1.4.2的版本,WIN2K专业版操作系统,安装过程我就不费话了,主要就是环境变量的配置,右击我的电脑—>;属性—>;高级,点击环境变量按钮即可打开系统的环境变量设置窗口。
在系统用户的环境变量中,设置以下几个变量(若没有则新建)
我的JDK装在D:\目录下,请大家根据实际情况做相应的修改
JAVA_HOME=D:\j2sdk1.4.2;
path=%JAVA_HOME%\bin;
classpath=.;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\jre\lib\rt.jar;%JAVA_HOME%\lib\dt.jar;
大小定无所谓,%JAVA_HOME%其实就是调用JAVA_HOME这个环境变量;
设置好以后重启系统,一般不会有什么问题,编个HelloWorld试试,呵呵呵。
二.        下载Jfreechart引擎并设置路径
下载地址:http://sourceforge.net/projects/jfreechart/
我下载后解压缩到了E:\SCM\这个文件夹下,接下来就需要将Jfreechart的.JAR文件添加到系统的CLASSPATH当中,修改后的CLASSPATH如下:
classpath=.;%JAVA_HOME%\lib\tools.jar;%JAVA_HOME%\jre\lib\rt.jar;%JAVA_HOME%\lib\dt.jar;E:\scm\jfreechart-0.9.21\lib\gnujaxp.jar;E:\scm\jfreechart-0.9.21\lib\jcommon-0.9.6.jar;E:\scm\jfreechart-0.9.21\jfreechart-0.9.21.jar;E:\scm\jfreechart-0.9.21\lib\junit.jar;E:\scm\jfreechart-0.9.21\lib\servlet.jar;
这样就完成了Jfreechart的配置工作,在我文章底下给出的参考文档中有关于Jfreechart的源码结构的分析,感兴趣的朋友可以看看。
三.        使用Jfreechart来生成柱状图和饼状图
1.        柱状图(BarChartDemo.java)
package demo;
import java.io.*;
import java.awt.Dimension;
import javax.swing.JPanel;
import org.jfree.chart.*;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.CategoryLabelPositions;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.ui.ApplicationFrame;
import org.jfree.ui.RefineryUtilities;
/**
* 该类用于演示最简单的柱状图生成
* @author Winter Lau
*/
public class BarChartDemo {
        public static void main(String[] args) throws IOException{
                CategoryDataset dataset = getDataSet2();
                JFreeChart chart = ChartFactory.createBarChart3D(
                                                        "水果产量图", // 图表标题
                                                        "水果", // 目录轴的显示标签
                                                        "产量", // 数值轴的显示标签
                                                        dataset, // 数据集
                                                        PlotOrientation.VERTICAL, // 图表方向:水平、垂直
                                                        true,         // 是否显示图例(对于简单的柱状图必须是false)
                                                        false,         // 是否生成工具
                                                        false         // 是否生成URL链接
                                                        );
                FileOutputStream fos_jpg = null;
                try {
                        fos_jpg = new FileOutputStream("D:\\fruit.jpg");
                        ChartUtilities.writeChartAsJPEG(fos_jpg,100,chart,400,300,null);
                } finally {
                        try {
                                fos_jpg.close();
                        } catch (Exception e) {}
                }
        }
        /**
         * 获取一个演示用的简单数据集对象
         * @return
         */
        private static CategoryDataset getDataSet() {
                DefaultCategoryDataset dataset = new DefaultCategoryDataset();
                dataset.addValue(100, null, "苹果");
                dataset.addValue(200, null, "梨子");
                dataset.addValue(300, null, "葡萄");
                dataset.addValue(400, null, "香蕉");
                dataset.addValue(500, null, "荔枝");
                return dataset;
        }
        /**
         * 获取一个演示用的组合数据集对象
         * @return
         */
        private static CategoryDataset getDataSet2() {
                DefaultCategoryDataset dataset = new DefaultCategoryDataset();
                dataset.addValue(100, "北京", "苹果");
                dataset.addValue(100, "上海", "苹果");
                dataset.addValue(100, "广州", "苹果");
                dataset.addValue(200, "北京", "梨子");
                dataset.addValue(200, "上海", "梨子");
                dataset.addValue(200, "广州", "梨子");
                dataset.addValue(300, "北京", "葡萄");
                dataset.addValue(300, "上海", "葡萄");
                dataset.addValue(300, "广州", "葡萄");
                dataset.addValue(400, "北京", "香蕉");
                dataset.addValue(400, "上海", "香蕉");
                dataset.addValue(400, "广州", "香蕉");
                dataset.addValue(500, "北京", "荔枝");
                dataset.addValue(500, "上海", "荔枝");
                dataset.addValue(500, "广州", "荔枝");
                return dataset;
        }
}
上面代码给出了两个简单的数据集对象getDataSet()和getDataSet2(),上例中使用的是getDataSet2(),生的图片如下:
http://blog.blogchina.com/upload/2005-03-07/2005030717465652714.bmp
如果用getDataSet()数据集,得到的图表如下图:
http://blog.blogchina.com/upload/2005-03-07/20050307175358472276.bmp

2.        饼状图(PieChartDemo.java)
package demo;
import java.io.*;
import java.lang.Object.*;
import org.jfree.data.*;
import org.jfree.chart.*;
import org.jfree.data.general.DatasetUtilities;
import org.jfree.data.general.DefaultPieDataset;
/**
* 用于演示饼图的生成
* @author Winter Lau
*/
public class PieChartDemo {
        public static void main(String[] args) throws IOException{
                DefaultPieDataset dataset = getDataSet();
                JFreeChart chart = ChartFactory.createPie3DChart("水果产量图",  // 图表标题
                dataset,
                true, // 是否显示图例
                false,
                false
                );
                //写图表对象到文件,参照柱状图生成源码
                FileOutputStream fos_jpg = null;
                try {
                        fos_jpg = new FileOutputStream("D:\\fruit_1.jpg");
                        ChartUtilities.writeChartAsJPEG(fos_jpg,100,chart,400,300,null);
                } finally {
                        try {
                                fos_jpg.close();
                        } catch (Exception e) {}
                }
        }
         /**
         * 获取一个演示用的简单数据集对象
         * @return
         */
        private static DefaultPieDataset getDataSet(){
                DefaultPieDataset dataset = new DefaultPieDataset();
                dataset.setValue("苹果",100);
                dataset.setValue("梨子",200);
                dataset.setValue("葡萄",300);
                dataset.setValue("香蕉",400);
                dataset.setValue("荔枝",500);
                return dataset;
        }
}
编译并运行该文件,生成的文件如下图:
http://blog.blogchina.com/upload/2005-03-08/20050308081919342617.bmp
四.        图表在网页中的显示
我们使用servlet来实现这一功能,将前面两个例子中的文件流换成通过HttpServletResponse对象获取得到的输出流,我用的是Weblogic8.1+sp1版本,关于它的配置请到我的博客上找相关文章。
package servlet;
import java.io.IOException;
import javax.servlet.*;
import javax.servlet.http.HttpServlet;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.*;
import org.jfree.chart.*;
/**
* 演示通过servlet直接输出图表
* @author Winter Lau
*/
public class ChartDemoServlet extends HttpServlet {

        public void service(ServletRequest req, ServletResponse res)
                throws ServletException, IOException
        {
                res.setContentType("image/jpeg");
                DefaultPieDataset data = getDataSet();
                JFreeChart chart = ChartFactory.createPie3DChart("水果产量图",
                data,
                true,
                false,
                false
                );
                               
                ChartUtilities.writeChartAsJPEG(res.getOutputStream(),
                        100,chart,400,300,null);
        }
        /**
         * 获取一个演示用的简单数据集对象
         * @return
         */
        private static DefaultPieDataset getDataSet() {
                DefaultPieDataset dataset = new DefaultPieDataset();
                dataset.setValue("苹果",100);
                dataset.setValue("梨子",200);
                dataset.setValue("葡萄",300);
                dataset.setValue("香蕉",400);
                dataset.setValue("荔枝",500);
                return dataset;
        }
}
这个文件放到Weblogic的应用目录下WEB-INF文件中,然后执行编译命令:
E:\2k\bea\user_projects\applications\mydomain\DefaultWebApp\WEB-INF>;javac -d ./c
lasses HelloWorldServlet.java
编译成功以后,在web.xml文件当部署class路径:
<web-app>;
        <servlet>;
                <servlet-name>; ChartDemoServlet</servlet-name>;
                <servlet-class>;servlet. ChartDemoServlet</servlet-class>;
        </servlet>;
        <servlet-mapping>;
                <servlet-name>; ChartDemoServlet</servlet-name>;
                <url-pattern>;/chardemo</url-pattern>;
        </servlet-mapping>;
        <welcome-file-list>;
                <welcome-file>;index.html</welcome-file>;
        </welcome-file-list>;
</web-app>;
在修改XML文件时,最好使用安装weblogic安装时自带的软件XMLSPY这个工具,因为它可以帮你检查语法的正确性,否则若有语法的错误会导致weblogic服务无法正常启动。
在浏览器中提交:
http://127.0.0.1:7001/chardemo
即可在浏览器中看到生成的图片
五.整个过程中所遇见问题的解决
在编译程序的过程中,报出如下的错误:
BarChartDemo.java:51: cannot resolve symbol
symbol  : class CategoryDataset
location: class demo.BarChartDemo
        private static CategoryDataset getDataSet() {
                   ^
BarChartDemo.java:52: cannot resolve symbol
symbol  : class DefaultCategoryDataset
location: class demo.BarChartDemo
                DefaultCategoryDataset dataset = new DefaultCategoryDataset();
                ^
这是由于未找到相应的类,在程序前面加上以下两句即可解决这个问题:
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
编译成功以后,用java命令运行class文件,报出如下错误:
E:\javaprogram\demo>;java BarChartDemo
Exception in thread "main" java.lang.NoClassDefFoundError: BarChartDemo (wrong n
ame: demo/BarChartDemo)
        at java.lang.ClassLoader.defineClass0(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClassInternal(Unknown Source)

E:\javaprogram\demo>;
在网上查找原因大致说是因为安全性的设置导致了java的这个漏洞,不过我查看版本还是适合的,然后又一家网站上看到了一个方法,
E:\javaprogram\demo>;javac -d . BarChartDemo.java

E:\javaprogram\demo>;java demo.BarCharDemo
Exception in thread "main" java.lang.NoClassDefFoundError: demo/BarCharDemo

E:\javaprogram\demo>;java demo.BarChartDemo
Using: org.jfree.chart.encoders.SunJPEGEncoderAdapter

E:\javaprogram\demo>;
这样就在D:\下生成了一个图像文件,程序运行成功。
我的配置环境是JDK1.4.2版本,Weblogic8.1+SP1,WIN2K专业版操作系统;如果大家有什么疑问或者说是更好的实现方法,请联系QQ:282405882
参考文档:
http://www-900.ibm.com/developerWorks/cn/java/l-jfreechart/index.shtml
http://e-docs.bea.com/wls/docs81/servlet/index.html




Copyright © 1999-2000 LSLNET.COM. All rights reserved. 蓝森林网站 版权所有。 E-mail : webmaster@lslnet.com