cewolf应用

cewolf的应用

Cewolf可以在一个基于Servlet/JSP的Web应用程序内部使用,基于JFreechart的,利用JFreechart的绘制引擎的开源项目。以在Web页中嵌入各种复杂的图形图表(如,直方图、饼图、棒图等等)。它提供了一个功能完备的标签库来定义图表的所有属性(颜色、笔画、图例等),这样嵌入了图表的JSP就不用使用任何Java代码。

遇到的问题:最初遇到的问题是一个关于作用域的问题,在网上找了一些资料,发现cewolf的比较少,慢慢摸索了一下,弄明白与作用域有关。

环境:myeclipse+tomcat6+jdk5

前提:由于公司里面很多统计数据,和日期有关,因此横坐标都是使用的日期,纵坐标是数据。

结果:这里把cewolf的东西进行了封装,在使用时只需提供按要求所提供的数据以及重新写servlet类即可,当然还可以继续进行封装,只是这可能就可能会与其余的东西相依赖了。

最新的思路:
还可以进行更深的抽象,即servlet只需一些很基本的操作,这里需要使用接口,然后只需把实现几口的类的.class传进去坐参数。
前台的参数也不用去获取,只需存到一个数组中,这可以在util里面写,然后再数据库查询的时候可以做成一个通用的东西,比如用jdbc连数据库,自己写数据库的一些东西等等。

1.首先是从http://cewolf.sourceforge.net/new/index.html下载最新的包,把相应的包(不仅是cewolf,JFreechart,还有好几个所依赖的包)都复制到项目工程里去。


2.配置web.xml文件,把下面的xml代码复制到web.xml中,然后把img和etc文件夹复制到工程目录里面去,这里有绘图需要的东东,配置文件里写有

<!-- cewolf的配置 -->
<servlet>
<servlet-name>CewolfServlet</servlet-name>
<servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>
<!-- sets storage implementation -->
<init-param>
<param-name>storage</param-name>
<param-value>de.laures.cewolf.storage.TransientSessionStorage</param-value>
</init-param>
<!-- sets overlib.js location relative to webapp -->
<init-param>
<param-name>overliburl</param-name>
<param-value>/etc/overlib.js</param-value>
</init-param>
<!-- turn on or off debugging logging -->
<init-param>
<param-name>debug</param-name>
<param-value>true</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>CewolfServlet</servlet-name>
<url-pattern>/cewolf/*</url-pattern>
</servlet-mapping>

<session-config>
<session-timeout>1</session-timeout>
</session-config>

<mime-mapping>
<extension>css</extension>
<mime-type>text/css</mime-type>
</mime-mapping>

3.cewolf的核心处理类,这里参考了cewolf的例子

public class PageViewData implements DatasetProducer, CategoryToolTipGenerator,CategoryItemLinkGenerator, Serializable{

private static final long serialVersionUID = 1829275651312989845L;
private List list=new ArrayList();



public List getList() {
return list;
}

public void setList(List list) {
this.list.addAll(list);
}


/**
* 产生一个唯一的标识符,这里还需要进行修改
*/
public String getProducerId() {
return "PageViewData ";
}

/**
* 5m时间作为图片的过期时间,即在5m内刷新图片,图片不会发生变化。
*/
public boolean hasExpired(Map arg0, Date arg1) {
return (System.currentTimeMillis() - arg1.getTime()) > 5000;
}

/**
* 主要的方法,报表的图片的数据显示在这里进行设置
*/
public Object produceDataset(Map arg0) throws DatasetProduceException {
//这个对象的建立参考网上的例子
DefaultCategoryDataset dataset = new DefaultCategoryDataset(){
/*
* @see java.lang.Object#finalize()
*当垃圾回收器确定不存在对该对象的更多引用时,
*由对象的垃圾回收器调用此方法
*/
protected void finalize() throws Throwable {
super.finalize();
}
};
ReportImgBean rb;
String seriesName;
List imgDataList;
ImgData imgData;
if(list!=null&&list.size()>0){
//外层循环是几条折线,内层循环是一条折线
for(int i=0;i<list.size();i++){
rb=(ReportImgBean)list.get(i);
seriesName=rb.getSeriesName();
// System.out.println("seriesName:"+seriesName);
imgDataList=rb.getImgDataList();
// System.out.println("seriesName:"+seriesName+":"+imgDataList.size());
if(imgDataList!=null&&imgDataList.size()>0){//必须要有数据,否则无意义
for(int j=0;j<imgDataList.size();j++){
imgData=(ImgData)imgDataList.get(j);
dataset.addValue(imgData.getData(),seriesName, imgData.getXcoordinate());
}
}
}
}
return dataset;
}

public String generateToolTip(CategoryDataset arg0, int arg1, int arg2) {
// 返回描述,相当于提示作用吧
return this.getDescription(arg1);
}

public String generateLink(Object arg0, int arg1, Object arg2) {
//返回描述,在底部的说明
return this.getDescription(arg1);
}

protected void finalize() throws Throwable {
super.finalize();
}
/**
* 返回描述的内容
* @param i
* @return
*/
public String getDescription(int i){
String result="";
if(list!=null&&list.size()>0){
ReportImgBean rb=(ReportImgBean)list.get(i);
result=rb.getSeriesName();
}
return result;
}
}


cewolf所需数据的结构如下:

public class ImgData {
private String xcoordinate;//日期,横坐标
private double data;//数据,纵坐标的数据

public String getXcoordinate() {
return xcoordinate;
}
public void setXcoordinate(String xcoordinate) {
this.xcoordinate = xcoordinate;
}
public double getData() {
return data;
}
public void setData(double data) {
this.data = data;
}
}



public class ReportImgBean {

private String seriesName;//描述数据是哪种数据
private List imgDataList;


public List getImgDataList() {
return imgDataList;
}
public void setImgDataList(List imgDataList) {
this.imgDataList = imgDataList;
}
public String getSeriesName() {
return seriesName;
}
public void setSeriesName(String seriesName) {
this.seriesName = seriesName;
}

}


4.数据处理的核心类,主要是对查询数据库所得到的数据进行处理成cewolf所需要的类型

public class BaseImgPhaseData {
/**
*
* @param dataList 这里面的数据都必须是必要的,若添加了不必要的则会出错,里面的元素的第一个为横坐标,之后的为具体的数据
* @param seriiseNames 折线的显示项。如:pv,click,ctr
* @return
*/
public PageViewData phaseData(List dataList,String[] seriiseNames) throws Exception{
PageViewData pvd=null;
List<ReportImgBean> result=new ArrayList<ReportImgBean>();
List<ArrayList<ImgData>> tempList=new ArrayList<ArrayList<ImgData>>();
//判断是否有数据
if(dataList==null||dataList.size()==0||seriiseNames==null||seriiseNames.length==1){
return pvd;
}
for(int i=0;i<seriiseNames.length;i++){
tempList.add(new ArrayList());
}
String seriesName="";
//相当于数据解析成需要的数据
for(int i=0;i<dataList.size();i++){
Object[] obj=(Object[])dataList.get(i);
for(int j=0;j<tempList.size();j++){
List<ImgData> list=(List<ImgData>)tempList.get(j);
ImgData temp=new ImgData();
temp.setXcoordinate(obj[0].toString());
//数据从1开始
temp.setData(Double.parseDouble(obj[1+j].toString()));
list.add(temp);
}
}
//把数据加入到最终的结构中
for(int i=0;i<seriiseNames.length;i++){
ReportImgBean tempBean=new ReportImgBean();
List<?> imgDataList=tempList.get(i);
seriesName=seriiseNames[i];
tempBean.setSeriesName(seriesName);
tempBean.setImgDataList(imgDataList);
result.add(tempBean);
}
pvd=new PageViewData();
pvd.setList(result);
return pvd;
}
}


5.数据准备,数据格式必须如下所示那样(这样只是迎合hibernate所生成的数据):

public class TestImpl2 extends BaseImgPhaseData {
public PageViewData getData(String beginDate,String endDate){
PageViewData result=null;
List list=new ArrayList();
Object[] obj1={"20090613","200","150"};
Object[] obj2={"20090614","200","250"};
Object[] obj3={"20090615","100","350"};
Object[] obj4={"20090616","250","150"};
Object[] obj5={"20090617","300","400"};
String[] seriiseNames={"测试pv","测试click"};
list.add(obj1);
list.add(obj2);
list.add(obj3);
list.add(obj4);
list.add(obj5);
try {
result=super.phaseData(list, seriiseNames);
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
}

6.servlet类,主要是供前台调用

public class TestServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse res) throws ServletException, IOException{
request.setCharacterEncoding("utf-8");
String beginDate="2009-06-01";
String endDate="2009-06-06";
TestImpl2 ti=new TestImpl2();
PageViewData pvd=ti.getData(beginDate, endDate);
//常用参数的设置
Util util=new Util();
util.setCommonParam(request,pvd);
request.setAttribute("beginDate", beginDate);
request.setAttribute("endDate", endDate);
// res.sendRedirect("report/test.jsp");//这种方式不行
request.getRequestDispatcher("report/test.jsp").forward(request, res);
}

public void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException{
this.doGet(req, res);
}
}

7.jsp页面,核心代码

<form name="theFrom" action="${actionName}" method="post">
宽度:<input type="text" name="widths" value="${widths}" />
高度:<input type="text" name="hights" value="${hights}" /><br />
<input type="hidden" name="xname" value="${xname}" />
<input type="hidden" name="yname" value="${yname}" />
<input type="hidden" name="type" value="${type}" />
<input type="hidden" name="title" value="${title}" />
<input type="hidden" name="beginDate" value="${beginDate}" />
<input type="hidden" name="endDate" value="${endDate}" />
<input type="submit" value="提交" />
</form>
<br />
<p>

<cewolf:chart
id="line"
title="${title}"
type="line"
xaxislabel="${xname}"
yaxislabel="${yname}">
<cewolf:data>
<cewolf:producer id="${pageViews}"/>
</cewolf:data>
</cewolf:chart>
<p>
<cewolf:img chartid="line" renderer="/cewolf" width="${widths}" height="${hights}">
<cewolf:map linkgeneratorid="${pageViews}" tooltipgeneratorid="${pageViews}"/>
</cewolf:img>



附件为myeclipse工程

图片为最终运行之后的效果图
[img]http://www.iteye.com/upload/attachment/116081/0e006c94-6a1f-3311-96d7-c330aa6a6a00.png[/img]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值