Jfreechart与Tapestry4.0 结合实现
【IT168技术文档】
Jfreechart简介:
JFreeChart是开放源代码站点SourceForge.net上的一个JAVA项目,它主要用来各种各样的图表,这些图表包括:饼图、柱状图(普通柱状图以及堆栈柱状图)、线图、区域图、分布图、混合图、甘特图以及一些仪表盘等等
开发必须要用的两个开发包是jfreechart-1.0.0-rc1.jar(现在最新为1.0.5版本)以及Jcommon-1.0.0.jar
下面介绍JFreeChart中几个核心的对象类:
JFreeChart:图表对象,任何类型的图表的最终表现形式都是在该对象 进行一些属性的定制。
JFreeChart引擎本身提供了一个工厂类用于创建不同类型的图表对象。
XXXXXDataset:数据集对象,用于提供显示图表所用的数据。根据不同类型的图表对应着很多类型的数据集对象类。
XXXXXPlot: 图表区域对象,基本上这个对象决定着什么样式的图表,创建该对象的时候需要Axis、Renderer以及数据集对象的支持。
XXXXXAxis: 用于处理图表的两个轴:纵轴和横轴。
XXXXXRenderer:负责如何显示一个图表对象。
XXXXXURLGenerator :用于生成Web图表中每个项目的鼠标点击链接。
XXXXXToolTipGenerator: 用于生成图象的帮助提示,不同类型图表对应不同类型的工具提示类。
基本上我认为JFreeChart项目本身的类结构的设计并不是很好,首先在创建图表的时候用到了大量的工厂方法,这样做虽然可以简化创建图表对象的代码,但是对项目本身或者开发人员来讲自行扩展一种新的图表都仍然是一件很麻烦的事情;其次除图表对象本身外其余的类过于复杂,使用者必须去了解每个类型的 图表对象应该对应哪些Axis、Plot、Renderer类,并且必须非常熟悉这些类的构造函数中每个参数的具体含义。这些问题都大大困扰很多初学者。 不过,虽然存在很多问题,但是JFreeChart本身仍不失为一个非常优秀的图表引擎,况且项目本身也在逐渐的发展中。
开发实例:
实现原理:通过文件流输出到页面显示,因为T4底层引擎已经封装了Servlet,故采用一个T4服务来进行画图操作。
1)创建一个Web项目JFreeChartDemo,导入所需的相关开发包。(再次创建过程不详述)
2)在Web.xml中添加如下配置:
<xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4"
xmlns="http://java.sun.com/xml/ns/j2ee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<display-name>JFreeChart Project<!--</span-->display-name>
<filter>
<filter-name>redirect<!--</span-->filter-name>
<filter-class>org.apache.tapestry.RedirectFilter<!--</span-->filter-class>
<!--</span-->filter>
<filter-mapping>
<filter-name>redirect<!--</span-->filter-name>
<url-pattern>/<!--</span-->url-pattern>
<!--</span-->filter-mapping>
<servlet>
<servlet-name>jfreechart<!--</span-->servlet-name>
<servlet-class>org.apache.tapestry.ApplicationServlet<!--</span-->servlet-class>
<load-on-startup>0<!--</span-->load-on-startup>
<!--</span-->servlet>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>/app<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>*.page<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>*.external<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>*.direct<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>*.sdirect<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>*.svc<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<servlet-mapping>
<servlet-name>jfreechart<!--</span-->servlet-name>
<url-pattern>/assets/*<!--</span-->url-pattern>
<!--</span-->servlet-mapping>
<session-config>
<session-timeout>30<!--</span-->session-timeout>
<!--</span-->session-config>
<!--</span-->web-app>
3)在hivemodule.xml中进行如下配置:
<xml version="1.0" encoding="gb2312"?>
<module id="jfreechart" version="1.0.0" package="com.ce.jfreechart">
<!-- 部署FriendlyURL -->
<contribution configuration-id="tapestry.url.ServiceEncoders">
<direct-service-encoder id="direct" stateless-extension="direct" stateful-extension="sdirect" />
<page-service-encoder id="page" extension="page" service="page" />
<page-service-encoder id="external" extension="external" service="external" />
<asset-encoder id="asset" path="/assets" />
<extension-encoder id="ext" extension="svc" after="*" />
<!--</span-->contribution>
<contribution configuration-id="tapestry.services.ApplicationServices">
<service name="chart" object="service:jfreechart.ChartService"/>
<!--</span-->contribution>
<service-point id="ChartService" interface="org.apache.tapestry.engine.IEngineService">
<invoke-factory>
<construct class="com.ce.jfreechart.service.StatChartService">
<set-object property="linkFactory"
value="service:tapestry.url.LinkFactory"/>
<!--</span-->construct>
<!--</span-->invoke-factory>
<!--</span-->service-point>
<!--</span-->module>
4)jfreechart.application文件配置如下:
<xml version="1.0" encoding="GBK"?>
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<application name="jfreechart" engine-class="org.apache.tapestry.engine.BaseEngine">
<description>jfreechart Module<!--</span-->description>
<meta key="org.apache.tapestry.disable-caching" value="true"/>
<meta key="org.apache.tapestry.default-page-class" value="true"/>
<meta key="org.apache.tapestry.template-encoding" value="utf-8"/>
<!--饼图-->
<page name="PieChart" specification-path="/WEB-INF/page/PieChart.page"/>
<!--</span-->application>
5)Java类文件:
5-1)StatChartServic.java类: java 代码
package com.ce.jfreechart.service;
![]()
import java.awt.Color;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
![]()
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
![]()
import org.apache.tapestry.IRequestCycle;
import org.apache.tapestry.engine.IEngineService;
import org.apache.tapestry.engine.ILink;
import org.apache.tapestry.services.Infrastructure;
import org.apache.tapestry.services.LinkFactory;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartUtilities;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.CategoryAxis;
import org.jfree.chart.axis.DateAxis;
import org.jfree.chart.labels.StandardCategoryItemLabelGenerator;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PiePlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.plot.XYPlot;
import org.jfree.chart.renderer.category.BarRenderer3D;
import org.jfree.chart.renderer.xy.XYItemRenderer;
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer;
import org.jfree.chart.urls.StandardPieURLGenerator;
import org.jfree.data.category.DefaultCategoryDataset;
import org.jfree.data.general.DefaultPieDataset;
import org.jfree.data.time.Day;
import org.jfree.data.time.Hour;
import org.jfree.data.time.Minute;
import org.jfree.data.time.Month;
import org.jfree.data.time.TimeSeries;
import org.jfree.data.time.TimeSeriesCollection;
import org.jfree.ui.RectangleInsets;
import com.ce.jfreechart.vo.PieChartVO;
![]()
/**//**
* 功能描述:生成统计结果图的服务类(现主要针对胼图)
*/
public class StatChartService implements IEngineService ...{
private HttpServletRequest request;
![]()
private HttpServletResponse response;
![]()
private LinkFactory linkFactory;
![]()
private Infrastructure infrastructure;
![]()
private final static String SERVICE_NAME = "chart";
![]()
public final static String CHART_PARAS_OBJ_NAME = "pcVo";
![]()
public void setResponse(HttpServletResponse response) ...{
this.response = response;
}
![]()
public void setRequest(HttpServletRequest request) ...{
this.request = request;
}
![]()
public void setLinkFactory(LinkFactory linkFactory) ...{
this.linkFactory = linkFactory;
}
![]()
public ILink getLink(boolean post, Object parameter) ...{
Map parameters = new HashMap();
return linkFactory.constructLink(this, post, parameters, false);
}
![]()
public void setInfrastructure(Infrastructure infrastructure) ...{
this.infrastructure = infrastructure;
}
![]()
public String getName() ...{
return SERVICE_NAME;
}
![]()
public void service(IRequestCycle cycle) throws IOException ...{
PieChartVO pcVo = (PieChartVO) request.getSession()
.getAttribute(CHART_PARAS_OBJ_NAME);
if (pcVo == null) ...{
return;
}
![]()
Chart chart = new Chart();
![]()
try ...{
chart.getPieChart3D(request, response, pcVo);
} finally ...{
request.getSession().removeAttribute(CHART_PARAS_OBJ_NAME);
}
}
}
![]()
/**//**
* 功能描述:输出JFreeChart图的类
*/
class Chart ...{
![]()
/**//**
* 方法描述:生成3D胼状图的方法
*
* @param request
* :HttpServletRequest
* @param response
* :HttpServletResponse
* @param PieChartVO
* :参数传递vo
* @throws IOException
*/
public void getPieChart3D(HttpServletRequest request,
HttpServletResponse response, PieChartVO pcVo) throws IOException ...{
response.setDateHeader("Expires", 0);
response.setContentType("image/jpeg");
![]()
String title = pcVo.getTitle();
![]()
String[] name = pcVo.getName();
![]()
double[] value = pcVo.getValue();
![]()
int width = pcVo.getWidth();
![]()
int hight = pcVo.getHight();
![]()
if (title == null || "".equals(title)) ...{
title = " ";
}
if (name == null || name.length == 0 || value == null
|| value.length == 0) ...{
return;
}
if (width <= 0) ...{
width = 400;
}
if (hight <= 0) ...{
hight = 400;
}
![]()
DefaultPieDataset defaultpiedataset = new DefaultPieDataset();
int j = name.length <= value.length ? name.length : value.length;
for (int i = 0; i < j; i++) ...{
defaultpiedataset.setValue(name[i], value[i]);
}
![]()
JFreeChart chart = ChartFactory.createPieChart3D(title,
defaultpiedataset, true, true, false);
![]()
chart.setBackgroundPaint(Color.WHITE);
PiePlot plot = (PiePlot) chart.getPlot();
plot.setNoDataMessage("No data available");
ChartUtilities.writeChartAsJPEG(response.getOutputStream(), chart,
width, hight);
}
![]()
}
PieChartPage.java页面类,java 代码
package com.ce.jfreechart.page;
![]()
import javax.servlet.http.HttpServletRequest;
![]()
import org.apache.tapestry.annotations.InjectObject;
import org.apache.tapestry.event.PageBeginRenderListener;
import org.apache.tapestry.event.PageEvent;
![]()
import com.ce.jfreechart.service.StatChartService;
import com.ce.jfreechart.vo.PieChartVO;
![]()
/**//**
* 功能描述:公司人员统计页
*/
public abstract class PieChartPage extends org.apache.tapestry.html.BasePage implements PageBeginRenderListener...{
private final String title = "公司人员统计饼状图";
![]()
@InjectObject("service:tapestry.globals.HttpServletRequest)
public abstract HttpServletRequest getRequest();
![]()
/**//**
* 页面开始表现时触发,或form重表现时也会触发
*/
public void pageBeginRender(PageEvent event) ...{
![]()
if (!event.getRequestCycle().isRewinding()) ...{
try...{
![]()
//画饼图
String[] name = ...{"管理人员","市场人员","开发人员","OEM人员","其他人员"};
double[] value = ...{10.02D,20.23D,56.80D,12.30D,5.98D};
PieChartVO pcVo = new PieChartVO();
pcVo.setTitle(title);
pcVo.setName(name);
pcVo.setValue(value);
pcVo.setWidth(450);
pcVo.setHight(300);
if(this.getRequest().getSession().getAttribute(StatChartService.CHART_PARAS_OBJ_NAME)==null)
this.getRequest().getSession().setAttribute(StatChartService.CHART_PARAS_OBJ_NAME, pcVo);
}catch(Exception e)...{
e.printStackTrace();
}
}
}
}
参数Vo对象: java 代码
/**//**
* 功能描述:生成JFreeChart饼图的参数Vo对象
*/
public class PieChartVO implements Serializable ...{
![]()
private static final long serialVersionUID = 1L;
![]()
/**//**
* 图表标题
*/
private String title;
![]()
/**//**
* 具体项名称数组
*/
private String[] name;
![]()
/**//**
* 具体项值数组
*/
private double[] value;
![]()
/**//**
* 图表宽度
*/
private int width;
![]()
/**//**
* 图表高度
*/
private int hight;
![]()
//方法略......
}
PieChart.html页面文件,xml 代码
<html>
<head>
<title>PieChart.html<!--</span-->title>
![]()
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="this is my page">
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
![]()
<!--<link rel="stylesheet" type="text/css" href="./styles.css">-->
![]()
<!--</span-->head>
![]()
<body>
<!--图片输出-->
<div align="center"><img src="app?service=chart" border="0"/><!--</span-->div>
<!--</span-->body>
<!--</span-->html>
PieChart.page文件,xml 代码
<xml version="1.0" encoding="GBK"?>
"-//Apache Software Foundation//Tapestry Specification 4.0//EN"
"http://jakarta.apache.org/tapestry/dtd/Tapestry_4_0.dtd">
<page-specification class="com.ce.jfreechart.page.PieChartPage">
<!--</span-->page-specification>
