介紹:Cewolf
寫在JSP頁面中的Cewolf,能用于基于web工程的Servlet/JSP,來制作復(fù)雜的統(tǒng)計圖表.它提供幾乎圖的所有特征,象顏色,線條,圖形等等.所以能夠在不寫任何JAVA代碼的情況下讓JSP頁面顯示圖表.
Cewolf是基于JFreechart的,利用JFreechart的繪制引擎,將最終的圖片寫入客戶端.在服務(wù)器端不會創(chuàng)建任何文件.一切都是基于輕量級的會話對象和動態(tài)的數(shù)據(jù)分析的.
Cewolf有一個單例的servlet,這個servlet用來處理圖的繪畫和標(biāo)簽庫時,用這個標(biāo)簽庫將在JSP頁面的圖的定義轉(zhuǎn)成HTML img tag,servlet按HTML img tag繪制想要的圖片送給客戶端.
特點:
1:免費開源
2:可跑于J2EE compliant server or servlet container
3:圖標(biāo)簽庫特征: 1:jsp不需要編寫java代碼
2:由xml編寫
4:圖類型豐富: Line [XY]
[3D] Pie
[3D] Horizonal Bar
[3D] Vertical [XY] Bar
[3D] Stacked Vertical Bar
Area [XY]
Scatter Plot
Candlestick
High Low
Gantt
Overlaid
Combined
例子:在JSP中寫下以下代碼來表示一個圖
<cewolf:chart
id="XYChart"
type="xy"
title="XYChart"
<cewolf:gradient>
<cewolf:point x="0" y="0" color="#FFFFFF"/>
<cewolf:point x="0" y="300" color="#C8C8C8"/>
</cewolf:gradient>
<cewolf:data>
<cewolf:producer id="xyData"/>
</cewolf:data>
</cewolf:chart>
<cewolf:img chartid="XYChart" renderer="cewolf" width="400" height="300"/>
圖示:
當(dāng)然這個xyData在JSP上下文是必須有效的,這個圖是由id為xyData的DataProducer產(chǎn)生.
假設(shè)你想在工程的JSP里顯示一下圖片:
第一步:準(zhǔn)備
下載標(biāo)簽庫jar包:
將jar包下/Lib文件內(nèi)容放在工程的/WEB-INF/lib 下面,/Lib文件內(nèi)容:
jfreechart-*-demo.jar
jfreechart-*.jar
jcommon-*.jar
commons-logging.jar
cewolf.jar
batik-xml.jar
batik-util.jar
batik-svggen.jar
batik-dom.jar
batik-awt-util.jar
Mozilla瀏覽器需要/example目錄下的overlib.js,放入webapps根目錄下。
在用Cewolf標(biāo)簽出現(xiàn)問題時,例如:"No Tags" is displayed in your containers console。你可以將cewolf.tld或cewolf-1.1.tld 文件放入你在WEB項目根目錄下的新建的文件夾中,就能在JSP中使用這些標(biāo)簽咯。
第二步:生成一個DatasetProducer
因 為Cewolf使用MVC (Model-View-Control)處理顯示在圖中的數(shù)據(jù),而這些數(shù)據(jù)是于定義在JSP頁面中的VIEW層分離開的。為了給圖提供正確的數(shù)據(jù),你必 須生成一個實現(xiàn)了de.laures.cewolf.DatasetProducer接口的對象,每次重畫一個新的圖的時候這個對象將被用到。
下面請看一個DatasetProducer實現(xiàn)的例子。
package de.laures.cewolf.example;
import java.io.Serializable;
import java.util.Date;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;
import de.laures.cewolf.DatasetProduceException;
import de.laures.cewolf.DatasetProducer;
import de.laures.cewolf.links.CategoryItemLinkGenerator;
import de.laures.cewolf.tooltips.CategoryToolTipGenerator;
/**
* An example data producer.
* @author Guido Laures
*/
public class PageViewCountData implements DatasetProducer,
CategoryToolTipGenerator,
CategoryItemLinkGenerator,
Serializable {
private static final Log log = LogFactory.getLog(PageViewCountData.class);
// These values would normally not be hard coded but produced by
// some kind of data source like a database or a file
private final String[] categories = { "mon",
"tue",
"wen",
"thu",
"fri",
"sat",
"sun"};
private final String[] seriesNames = { "cewolfset.jsp",
"tutorial.jsp",
"testpage.jsp",
"performancetest.jsp"};
/**
* Produces some random data.
*/
public Object produceDataset(Map params)
throws DatasetProduceException {
log.debug("producing data.");
DefaultCategoryDataset dataset = new DefaultCategoryDataset(){
/**
* @see java.lang.Object#finalize()
*當(dāng)垃圾回收器確定不存在對該對象的更多引用時,
*由對象的垃圾回收器調(diào)用此方法
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this +" finalized.");
}
};
for (int series = 0; series < seriesNames.length; series ++) {
int lastY = (int)(Math.random() * 1000 + 1000);
for (int i = 0; i < categories.length; i++) {
final int y = lastY + (int)(Math.random() * 200 - 100);
lastY = y;
dataset.addValue(y, seriesNames[series], categories[i]);
}
}
return dataset;
}
/**
* This producer's data is invalidated after 5 seconds. By this method the
* producer can influence Cewolf's caching behaviour the way it wants to.
*/
public boolean hasExpired(Map params, Date since) {
log.debug(getClass().getName() + "hasExpired()");
return (System.currentTimeMillis() - since.getTime()) > 5000;
}
/**
* Returns a unique ID for this DatasetProducer
*/
public String getProducerId() {
return "PageViewCountData DatasetProducer";
}
/**
* Returns a link target for a special data item.
*/
public String generateLink(Object data, int series, Object category) {
return seriesNames[series];
}
/**
* @see java.lang.Object#finalize()
*/
protected void finalize() throws Throwable {
super.finalize();
log.debug(this + " finalized.");
}
/**
* @see org.jfree.chart.tooltips.CategoryToolTipGenerator#generateToolTip(CategoryDataset, int, int)
*/
public String generateToolTip(CategoryDataset arg0, int series, int arg2) {
return seriesNames[series];
}
}
正如所見,這個datasetproducer不是很有用,通常,這個類會去訪問一個數(shù)據(jù)源(例如一個數(shù)據(jù)庫)獲得需要的數(shù)據(jù),這里僅作例子展示而已。
一個DatasetProducer需要實現(xiàn)3個方法,最重要的一個是produceDataset()方法,它實際上生成了一個用于畫圖的數(shù)據(jù)。這個方法用一個map作參數(shù),這個map由許多指定的JSP標(biāo)簽填充,這個一會再介紹。
在當(dāng)前生數(shù)據(jù)成器確實生成數(shù)據(jù)對象后,方法hasExpired()被才被Cewolf框架調(diào)用。當(dāng)返回TRUE時,產(chǎn)生器將釋放以前的數(shù)據(jù)。
Cewolf框架通過 getProducerId()方法提生成的一個唯一ID來標(biāo)識一個生成者。2個具有相同ID生成實例將被認(rèn)為時生成相同的數(shù)據(jù)。
編譯該方法,然后把它放在WEB工程的/WEB-INF/類目錄下。
第三步:在WEB工程下安裝Cewolf Servlet
整個圖的繪制由一個servle產(chǎn)生,所以要事先裝入WEB工程,Cewolf提供了一個servlet類de.laures.cewolf.CewolfRenderer用來完成這個工作。
為了配置你的web工程,你必須編輯 /WEB-INF/web.xml,添加下列行。
<servlet>
<servlet-name>CewolfServlet</servlet-name>
<servlet-class>de.laures.cewolf.CewolfRenderer</servlet-class>
</servlet>
另外你要提供一個servlet-mapping來告訴容器URL與Cewolf繪圖servlet的映射關(guān)系.
Additionally you should provide a servlet-mapping to tell the container which URL maps to your Cewolf rendering servlet.
<servlet-mapping>
<servlet-name>CewolfServlet</servlet-name>
<url-pattern>/cewolf/ *</url-pattern>
</servlet-mapping>
你還需要告訴CeWolf的啟動:
<load-on-startup>1</load-on-startup>
檢查配置是否正確:
例如瀏覽器輸入http://localhost:8080/myapp/cewolf?state).
Cewolf應(yīng)該回應(yīng): "Cewolf servlet up and running."
下面是例子 web.xml的配置:
<web-app>
<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>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
</welcome-file-list>
<!-- resource-ref>
<description>
Resource reference to a factory for java.sql.Connection
instances that may be used for talking to a particular
database that is configured in the server.xml file.
</description>
<resource-ref-name>
jdbc/testdb
</resource-ref-name>
<res-type>
javax.sql.DataSource
</res-type>
<res-auth>
Container
</res-auth>
</resource-ref -->
</web-app>
第四步:在JSP定義圖
<%@page contentType="text/html"%>
<%@taglib uri='/WEB-INF/cewolf.tld' prefix='cewolf' %>
<HTML>
<BODY>
<H1>Page View Statistics</H1>
<HR>
<jsp:useBean id="pageViews"
class="de.laures.cewolf.example.PageViewCountData"/>
<cewolf:chart id="line" title="Page View Statistics"
type="line" xaxislabel="Page" yaxislabel="Views">
<cewolf:data>
<cewolf:producer id="pageViews"/>
</cewolf:data>
</cewolf:chart>
<p>
<cewolf:img chartid="line" renderer="cewolf"
width="400" height="300"/>
<P>
</BODY>
</HTML>
正如所見,有3個cewolf的標(biāo)簽。<cewolf:chart>定義一個可參數(shù)化的圖,
具體的繪畫是交給<cewolf:img>標(biāo)簽的,它向HTML頁面添加的正確的<img>標(biāo)簽。
JSP頁面中兩個cewolf標(biāo)簽之間的關(guān)聯(lián)是通過使用相同的ID。
當(dāng)在客戶端瀏覽器調(diào)用這個JSP時,你能看到靜態(tài)的圖。如果失敗,你可以查看容器的日志文件。
第五步:生成ImageMap和Tooltip信息
為了給你的圖生成ImageMap和Tooltip信息,你必須自己額外寫java類或者修改象下面的一個已經(jīng)存在的類。在這一步我們將向datasetproducer添加新的方法。
...
public String generateLink(Object data, int series, Object category)
{ return seriesNames[series]; }
public String generateToolTip(CategoryDataset arg0, int series, int arg2)
{ return seriesNames[series]; }
...
可見,生成ImageMap和Tooltip信息是很簡單的事情,
首先要實現(xiàn)接口CategoryItemLinkGenerator和CategoryToolTipGenerator (因為生成的是CategoryDataset). 別的數(shù)據(jù)類型請參見cewolf java api:http://cewolf.sourceforge.net/new/apidoc/index.html
de.laures.cewolf.tooltips下有4個接口:
CategoryToolTipGenerator
PieToolTipGenerator
ToolTipGenerator
XYToolTipGenerator