JFreeChat学习笔记 ( by quqi99 )
作者:张华 发表于:2007-05-28 ( http://blog.csdn.net/quqi99 )
版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本版权声明。
为了创建一个可以在web 浏览器上查看到图表一般有两种做法:第一种就是使用applet 利用java 本身对图形的支持来显示一个图表;第二种就是直接在web 服务器端生成好图表图片文件后发送给浏览器。第一种方式显然对于客户端要求太高,随着现在主流浏览器放弃对JAVA 的支持后,这种方式只适合一些局域网的应用,而对于因特网的环境就显得不太适合。因此我们下面将介绍一个JAVA 的图表引擎JFreeChart 用来产生基于WEB 的图表。
入门资料:
1、 JFreeChart 介绍及经典入门资料(真的好文章)http://www.wang48.com/jishubaodian/jishubaodianview.jsp?jsd_id=17
2、 刘冬的“ 使用 JFreeChart 来创建基于web 的图表
3、 使用Jfreechart 在applet 中画动态曲线图 http://www.cnweblog.com/sundy/archive/2005/08/12/24480.aspx
4、 http://javasky.bloghome.cn/posts/2536.html 用JSP ,等几种方式
5、 http://www.chinaitpower.com/A200507/2005-07-24/166983.html
6、 JfreeChart学习总结 http://ltc603.javaeye.com/blog/30207
7、 用JSP +Servlet 实现二进制图像的动态显示http://www.tot.name/show/3/6/20051121084617.htm
8、 http://asdf1982.javaeye.com/blog/60307 (重要)
如果想在浏览器端用JavaScript 绘制,webfx 的chart 组件就是目前最成熟的了。
Dojo 也有一个,不过因为是基于SVG 的,目前仅支持Firefox ,以后的版本应该会支持所有主流的浏览器。
AJAX + SVG 实现实时监控图表
9、 动态生成图片。实际是写servlet 路径
<img src="../showimg.do">
showimg.do 里生成图片然后response 出来
为了配置成功,我们需要关注的 文件 有如下三个:jfreechart-0.9.21.jar 、lib/jcommon-0.9.6.jar 、
lib/gnujaxp.jar
如果是Application 开发,把上述三个 文件 拷贝到%JAVA_HOME%/LIB 中,同时在环境变量CLASSPATH 中加入
如果是WEB 开发,以TOMCAT 中的一个WEB 项目TEST 为例子说明:
把上述三个 文件 拷贝到TEST/WEB-INF/LIB 中,然后修改TEST/WEB-INF/web.xml 文件 ,在其中加入如下代码:
<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>
</servlet-mapping>
pie charts (2D and 3D) :饼图(平面和立体)
bar charts (regular and stacked, with an optional 3D effect) :柱状图
line and area charts :曲线图
scatter plots and bubble charts
time series, high/low/open/close charts and candle stick charts :时序图
combination charts :复合图
Pareto charts
Gantt charts :甘特图
wind plots, meter charts and symbol charts
wafer map charts
( 态图表, 饼图( 二维和三维) , 柱状图 ( 水平, 垂直), 线图, 点图, 时间变化图, 甘特图, 股票行情图, 混和图, 温度计图, 刻度图等常用商用图表)
图形可以导出成PNG 和JPEG 格式,同时还可以与PDF 和EXCEL 关联
核心类主要有:
org.jfree.chart.JFreeChart :图表对象,任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。JFreeChart 引擎本身提供了一个工厂类用于创建不同类型的图表对象
org.jfree.data.category.XXXDataSet: 数据集对象,用于提供显示图表所用的数据。根据不同类型的图表对应着很多类型的数据集对象类
org.jfree.chart.plot.XXXPlot :图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis 、Renderer 以及数据集对象的支持
org.jfree.chart.axis.XXXAxis :用于处理图表的两个轴:纵轴和横轴
org.jfree.chart.render.XXXRender :负责如何显示一个图表对象
org.jfree.chart.urls.XXXURLGenerator: 用于生成Web 图表中每个项目的鼠标点击链接
XXXXXToolTipGenerator: 用于生成图象的帮助提示,不同类型图表对应不同类型的工具提示类
要建立一個JFreeChart 的圖形主要有三個步驟
1. 建立一個擁有資料的DataSet
2. 用DataSet 創造JFreeChart
*. 對JFreeChart 作一些自訂的設計
3. 顯示JFreeChart
下面这个类目前的问题是:
1、 生成的是图片,网速太慢。
2、 在JFrame 里运行挺好,因为桌面应用自动刷新,但是在Servlet 中时,我们得人工控制JSP 页面的刷新,为了无频闪刷新,得用AJAX ,但又因为生成的是图片,处理起来很费事情
3、 出于以上原因,这个目录监测功能我们还是采用进度条的那种方式。
下面是一个实时曲线定时刷新的例子,自己编的,但无法实现无频闪刷新,采用javabean+jsp 方式 :
<%@ page language = "java" %>
<%@ page import = "org.jfree.data.general.DefaultPieDataset" %>
<%@ page import = "java.io.PrintWriter" %>
<%@ page import = "com.assoft.dirwatch.good.*" %>
<%@ page import = "org.jfree.data.time.*" %>
<!DOCTYPE HTML PUBLIC "-//w3c//dtd html 4.0 transitional//en">
<html>
<head>
<title> Lomboz JSP </title>
<script language="JavaScript" type="text/javascript">
<!--
function reload()
{
self.location.reload();
}
setInterval('reload()', 2000);
//-->
</script>
</head>
<body bgcolor="#FFFFFF">
<%
// 曲线图的数据
GenerateData generateData = GenerateData.getInstance(); // 这一条和下一条语句需要执行一次,改为单例方法
if (generateData.getCurrentThread() == null )
generateData.start(); // 启动线程不停产生数据
TimeSeriesCollection timeseriescollection = new TimeSeriesCollection();
timeseriescollection.addSeries(generateData.getFree());
timeseriescollection.addSeries(generateData.getTotal());
// 得到线图的图表对象
String p = ChartUtil2.generateLineChart(timeseriescollection, " 线图" ,500,300, null , new PrintWriter( out ));
String p1 = request .getContextPath() + "/servlet/DisplayChart?filename=" + p;
%>
<td> <img src=" <%= p1 %> " width=500 height=300 border=0 usemap="# <%= p %> "> </td>
</body>
</html>
package com.assoft.dirwatch.good;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.io.PrintWriter;
import javax.servlet.http.HttpSession;
import org.jfree.chart.ChartRenderingInfo;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.entity.StandardEntityCollection;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.servlet.ChartDeleter;
import org.jfree.chart.servlet.ServletUtilities;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;
/*
* @ 作者:张华 @ 日期:2001-4-19 @ 说明:
*/
public class ChartUtil2 {
// 生成曲线图图表
public static String generateLineChart(
TimeSeriesCollection timeseriescollection, String title, int width,
int height, HttpSession session, PrintWriter pw) {
String filename = null;
try {
if (session != null) {
ChartDeleter deleter = (ChartDeleter) session
.getAttribute("JFreeChart_Deleter");
session.removeAttribute("JFreeChart_Deleter");
session.setAttribute("JFreeChart_Deleter", deleter);
}
// 定义横轴
DateAxis dateaxis = new DateAxis(" 时间");
dateaxis.setTickLabelFont(new Font("SansSerif", 0, 12)); // 定义字体
dateaxis.setLabelFont(new Font("SansSerif", 0, 14));
dateaxis.setAutoRange(true);
dateaxis.setLowerMargin(0.0D);
dateaxis.setUpperMargin(0.0D);
dateaxis.setTickLabelsVisible(true);
// 定义竖轴
NumberAxis numberaxis = new NumberAxis(" 内存");
numberaxis.setTickLabelFont(new Font("SansSerif", 0, 12));
numberaxis.setLabelFont(new Font("SansSerif", 0, 14));
numberaxis
.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
//XXXRender 负责如何显示一个图表对象,前一个参数定义曲线是否显示,后一个参数定义曲线与坐标的交点是否显示
XYLineAndShapeRenderer xylineandshaperenderer = new XYLineAndShapeRenderer(
true, true);
xylineandshaperenderer.setSeriesPaint(0, Color.red); // 定义曲线的颜色
xylineandshaperenderer.setSeriesPaint(1, Color.green);
xylineandshaperenderer.setStroke(new BasicStroke(3F, 0, 2));
//XXXPlot
// 图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis 、Renderer 以及数据集对象的支持
// 参数依次是:数据,横轴,竖轴,曲线
XYPlot xyplot = new XYPlot(timeseriescollection, dateaxis,
numberaxis, xylineandshaperenderer);
xyplot.setBackgroundPaint(Color.lightGray);
xyplot.setDomainGridlinePaint(Color.white);
xyplot.setRangeGridlinePaint(Color.white);
xyplot.setAxisOffset(new RectangleInsets(5D, 5D, 5D, 5D));
// :图表对象,任何类型的图表的最终表现形式都是在该对象进行一些属性的定制。JFreeChart 引擎本身提供了一个工厂类用于创建不同类型的图表对象
JFreeChart chart = new JFreeChart(" 内存利用率", new Font("SansSerif", 1,
24), xyplot, true);
chart.setBackgroundPaint(Color.white);
// JFreeChart chart = ChartFactory.createPieChart3D(title, // chart
// // title
// dataset, // data
// true, // include legend
// true, false);
// 为了收集Map 信息
ChartRenderingInfo info = new ChartRenderingInfo(
new StandardEntityCollection());
filename = ServletUtilities.saveChartAsPNG(chart, width, height,
info, session);
// Write the image map to the PrintWriter
ChartUtilities.writeImageMap(pw, filename, info, true);
pw.flush();
} catch (Exception e) {
System.out.println("Exception - " + e.toString());
e.printStackTrace(System.out);
filename = "picture_error.png";
}
return filename;
}
}
在web.xml 中加入如下定义:
<!-- 定义JFreeChart 相关配置用于在JSP 页中使用JFreeChart -->
<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>
</servlet-mapping>
在HTML 中为了让一个图像具有可交互的功能就必须给该图像定义一个Map 对象。
在最后用MAP 时,图像的useMap 属性值必须与MAP 对象的名称结合起来
<map id="mapname" name="mapname">
<area shape="poly" coords="174,68,186,65,200,64,200,147,200,147" onMouseOver="return overlib(' 其他人员 = 5');" onMouseOut="return nd();" href="d:/map.html?category= 其他人员&pieIndex=0"/>
<area shape="poly" coords="200,230,184,229,170,225,157,219,145,210,135,200,127,188,121,175,117,160,116,145,118,130,122,116,128,103,137,92,148,82,160,74,174,68,200,147,200,147" onMouseOver="return overlib(' 开发人员 = 45');" onMouseOut="return nd();" href="d:/map.html?category= 开发人员&pieIndex=0"/>
<area shape="poly" coords="283,147,281,164,276,179,269,194,258,206,246,216,232,224,216,229,200,230,200,147,200,147" onMouseOver="return overlib(' 市场人员 = 25');" onMouseOut="return nd();" href="d:/map.html?category= 市场人员&pieIndex=0"/>
<area shape="poly" coords="200,64,216,65,232,70,246,78,258,88,269,100,276,115,281,130,283,147,200,147,200,147" onMouseOver="return overlib(' 管理人员 = 25');" onMouseOut="return nd();" href="d:/map.html?category= 管理人员&pieIndex=0"/>
</map>