廢話不多說,先看看我們最終達(dá)到的效果.? 源碼下載在文章最后。
Style1:

Style2:

上面的tag cloud實(shí)現(xiàn)思想如下:
1. Server端提供Tag的相關(guān)信息,包括TagName,Posts等,使用JSON格式傳輸數(shù)據(jù)
??? 這個(gè)例子中,我使用Servlet,使用json-lib將Bean轉(zhuǎn)成JSON字符串。當(dāng)然Tag的相關(guān)信息這里只是演示,真實(shí)環(huán)境中可能就需要從數(shù)據(jù)庫(kù)取出來再處理了。
??? 代碼如下:???
import
?java.io.IOException;
import
?java.util.ArrayList;
import
?java.util.Random;

import
?javax.servlet.ServletException;
import
?javax.servlet.http.HttpServlet;
import
?javax.servlet.http.HttpServletRequest;
import
?javax.servlet.http.HttpServletResponse;

import
?net.sf.json.JSONSerializer;



public
?
class
?TagCloudAction?
extends
?HttpServlet?
{


????
private
?
static
?String?cache?
=
?
""
;

????
/**?*/
/**
?????*?
?????
*/
????
private
?
static
?
final
?
long
?serialVersionUID?
=
?
-
7031695721764039045L
;

????@Override
????
protected
?
void
?doGet(HttpServletRequest?req,?HttpServletResponse?resp)

????????????
throws
?ServletException,?IOException?
{
????????resp.setHeader(?
"
Pragma
"
,?
"
no-cache
"
?);
????????resp.addHeader(?
"
Cache-Control
"
,?
"
must-revalidate
"
?);
????????resp.addHeader(?
"
Cache-Control
"
,?
"
no-cache
"
?);
????????resp.addHeader(?
"
Cache-Control
"
,?
"
no-store
"
?);
????????resp.setDateHeader(
"
Expires
"
,?
0
);
????????resp.setContentType(
"
text/xml
"
);
????????resp.setCharacterEncoding(
"
UTF-8
"
);
????????
if
(cache.isEmpty())

????????
{
????????????cache?
=
?getTagCloudJSONString();
????????}
????????resp.getOutputStream().write(cache.getBytes(
"
UTF-8
"
));
????????resp.flushBuffer();
????}
????
????
private
?String?getTagCloudJSONString()

????
{
????????Category?c?
=
?
new
?Category(
"
Name
"
,
"
This?is?comments
"
,
10
);
????????c.setCategoryID(
10
);
????????
//
System.out.println(?JSONSerializer.toJSON(c).toString()?);
????????
//
System.out.println(?JSONSerializer.toJSON(c).toString(2)?);
????????
????????ArrayList
<
Category
>
?categoriesList?
=
?
new
?ArrayList
<
Category
>
();
????????Random?r?
=
?
new
?Random();

????????String[]?tags?
=
?
new
?String[]
{
????????????????
"
JAVA
"
,
"
Groovy
"
,
"
Servlet
"
,
"
J2EE
"
,
"
JSP
"
,
"
J2SE
"
????????????????,
"
JSON
"
,
"
AJAX
"
,
"
CaiClient
"
,
"
.NET
"
,
"
C#
"
,
"
Perl
"
,
????????????????
"
Python
"
,
"
Rails
"
,
"
Ruby
"
,
"
Boss
"
,
"
Nokia
"
,
"
GPhone
"
,
"
iPhone
"
????????????????,
"
HiPhone
"
,
"
Ericsson
"
,
"
Semens
"
,
"
Novels
"
,
"
春天
"
,
"
夏天
"
,
"
秋天
"
,
"
冬天
"
,
"
節(jié)日快樂
"
,
????????????????
"
破釜沉舟
"
,
"
瑞星殺毒
"
,
"
奶粉事故
"
????????????????,
"
奧運(yùn)會(huì)
"
,
"
Grails
"
,
"
Google
"
,
"
Baidu
"
,
"
XiaoNei
"
,
????????????????
"
開心網(wǎng)
"
,
"
校內(nèi)網(wǎng)
"
,
"
海內(nèi)網(wǎng)
"
,
"
都是垃圾
"
,
"
薩達(dá)姆
"
,
"
PK
"
,
"
網(wǎng)摘
"
????????}
;
????????
int
?len?
=
?tags.length
-
1
;

????????
for
?(
int
?i?
=
?
0
;?i?
<
?
100
;?i
++
)?
{
????????????Category?item?
=
?
new
?Category(tags[r.nextInt(len)],
"
This?is?comments?for?
"
+
i,r.nextInt(
100
));
????????????item.setCategoryID(i);
????????????categoriesList.add(item);
????????}
????????
????????System.err.println(?JSONSerializer.toJSON(categoriesList).toString()?);
????????
//
System.err.println(?JSONSerializer.toJSON(categoriesList).toString(2)?);
????????
????????
return
?JSONSerializer.toJSON(categoriesList).toString(
2
);
????}
}
2. 客戶端發(fā)起XMLHttpRequest請(qǐng)求,取得TagCloud需要的JSON數(shù)據(jù),進(jìn)行處理,生成鏈接,定義樣式
??? 當(dāng)然這里我們?cè)O(shè)計(jì)是將js文件,css文件,html分離了,為了更好的維護(hù)。
??? 目錄和文件結(jié)構(gòu)如下:
???? 
??? tagCloud.html 的內(nèi)容很簡(jiǎn)單,兩個(gè)Button,點(diǎn)擊之后調(diào)用獲取不同Style的Tag Cloud的函數(shù)???
<!
DOCTYPE?html?PUBLIC?"-//W3C//DTD?HTML?4.01?Transitional//EN"?"http://www.w3.org/TR/html4/loose.dtd"
>
<
html
>
<
head
>
<
meta?
http-equiv
="Content-Type"
?content
="text/html;?charset=UTF-8"
>
<
title
>
Tag?Cloud
</
title
>
<
script?
type
="text/javascript"
?src
="json2.js"
></
script
>
<
script?
type
="text/javascript"
?src
="tagcloud.js"
></
script
>
<
link?
rel
=StyleSheet?
type
="text/css"
?href
="tagCloud.css"
>
</
head
>
<
body
>
<
p
>
Version.1?use?raw?XMLHttpRequest?to?get?JSON?data?from?a?Servlet.
</
p
>
<
input?
id
="btn_getTagCloud1"
?type
="button"
?value
="Get?tag?cloud?style1"
????onclick
="getTagCloud();"
?
/>
<
div?
id
="tagcloud"
></
div
>
<
input?
id
="btn_getTagCloud2"
?type
="button"
?value
="Get?tag?cloud?style2"
????onclick
="getTagCloud2();"
?
/>
<
div?
id
="tagcloudwithstyle2"
></
div
>
</
body
>
</
html
>
??? 再看看我們定義的css文件,主要是字體顏色和大小的設(shè)置
@CHARSET?"UTF-8";


#tagcloud,#tagcloudwithstyle2{
}{
????width:?500px;

????background:#FFFFFF;/**//*#FFFFCC;*/
????padding:?10px;
????border:?1px?solid?#FFE7B6;
????text-align:center;
????font-family:'Trebuchet?MS',Arial,Verdana,sans-serif;
}


#tagcloud?a:link,?#tagcloud?a:visited?{
}{
????text-decoration:none;
????color:?#87A800;
}


#tagcloud?a:hover,?#tagcloud?a:active?{
}{
????color:?#FFFFFF;
????background-color:?#87A800;
}


#tagcloud?span,?#tagcloudwithstyle2?span{
}{
????padding:?4px;
}


#tagcloudwithstyle2?a:link,?#tagcloudwithstyle2?a:visited?{
}{
????text-decoration:none;
????color:?#ff4500;
}


#tagcloudwithstyle2?a:hover,?#tagcloudwithstyle2?a:active?{
}{
????color:?#FF3300;
????background-color:?#ffff00;
}

.smallest?{
}{
????font-size:?10px;
}


.small?{
}{
????font-size:?15px;
}


.medium?{
}{
????font-size:?20px;
}


.large?{
}{
????font-size:?25px;
}


.largest?{
}{
????font-size:?30px;
}來看看這里最重要的javascript文件,有些AJAX基本的東西,但是有注釋應(yīng)該不難看懂
var?XMLHttpReq;
var?maxTagPosts?=?1;?//?這個(gè)變量用來保存包含關(guān)聯(lián)文章最多的那個(gè)Tag的文章數(shù)

//?創(chuàng)建XMLHttpRequest對(duì)象

function?createXMLHttpRequest()?
{

????if?(window.XMLHttpRequest)?
{?//?Mozilla?瀏覽器
????????XMLHttpReq?=?new?XMLHttpRequest();

????}?else?if?(window.ActiveXObject)?
{?//?IE瀏覽器

????????try?
{
????????????XMLHttpReq?=?new?ActiveXObject("Msxml2.XMLHTTP");

????????}?catch?(e)?
{

????????????try?
{
????????????????XMLHttpReq?=?new?ActiveXObject("Microsoft.XMLHTTP");

????????????}?catch?(e)?
{
????????????}
????????}
????}
}
//?發(fā)送請(qǐng)求函數(shù)

function?sendRequest(url,?callback)?
{
????createXMLHttpRequest();
????XMLHttpReq.open("GET",?url,?true);
????//XMLHttpReq.onreadystatechange?=?processResponse;//?指定響應(yīng)函數(shù)
????XMLHttpReq.onreadystatechange?=?callback;
????XMLHttpReq.send(null);?//?發(fā)送請(qǐng)求
}

//?處理返回信息函數(shù)

function?processResponseStyle1()?
{

????if?(XMLHttpReq.readyState?==?4)?
{?//?判斷對(duì)象狀態(tài)

????????if?(XMLHttpReq.status?==?200)?
{?//?信息已經(jīng)成功返回,開始處理信息
????????????????????????
????????????var?tagCloud?=?JSON.parse(?XMLHttpReq.responseText?);
????????????for(var?i=0;?i<?tagCloud.length;i++)

????????????
{
????????????????if(tagCloud[i].relatedPosts>maxTagPosts)

????????????????
{
????????????????????maxTagPosts?=?tagCloud[i].relatedPosts;
????????????????}
????????????}

????????????var?tagCloudHTML?=?"";
????????????for(var?j=0;?j<?tagCloud.length;j++)

????????????
{
????????????????var?searchCondition?=?encodeURI(tagCloud[j].categoryName);
????????????????var?classSize?=?getClass(tagCloud[j].relatedPosts);
????????????????var?aTag?=?"<span?class='"+classSize+"'><a?href=\"#?search="+searchCondition
????????????????+"\"?title=\"Posts:?"+tagCloud[j].relatedPosts+"\">"+tagCloud[j].categoryName+"</a></span>\n";
????????????????
????????????????tagCloudHTML?+=?aTag;
????????????}
????????????
????????????document.getElementById("tagcloud").innerHTML?=?tagCloudHTML;

????????}?else?
{?//?頁(yè)面不正常
????????????window.alert("Page?Exception!");
????????}
????}
}


function?processResponseStyle2()?
{

????if?(XMLHttpReq.readyState?==?4)?
{

????????if?(XMLHttpReq.status?==?200)?
{
????????????var?tagCloud?=?JSON.parse(?XMLHttpReq.responseText?);
????????????for(var?i=0;?i<?tagCloud.length;i++)

????????????
{
????????????????if(tagCloud[i].relatedPosts>maxTagPosts)

????????????????
{
????????????????????maxTagPosts?=?tagCloud[i].relatedPosts;
????????????????}
????????????}
????????????
????????????var?tagCloudHTML?=?"";
????????????for(var?j=0;?j<?tagCloud.length;j++)

????????????
{
????????????????var?searchCondition?=?encodeURI(tagCloud[j].categoryName);
????????????????var?classSize?=?getClass(tagCloud[j].relatedPosts);
????????????????var?aTag?=?"<span?class='"+classSize+"'><a?href='#?search="+searchCondition
????????????????????+?"'?title='Posts:?"+tagCloud[j].relatedPosts+"'"
????????????????????+?"?style='color:"?+?getRandomColor()?+"'?>"
????????????????????+?tagCloud[j].categoryName?+?"</a></span>\n";
????????????
????????????????tagCloudHTML?+=?aTag;
????????????}????????????
????????????document.getElementById("tagcloudwithstyle2").innerHTML?=?tagCloudHTML;

????????}?else?
{
????????????window.alert("Page?Exception!");
????????}
????}
}

function?getRandomColor()


{
????var?r=Math.floor((Math.random()*256)).toString(16);
????var?g=Math.floor((Math.random()*256)).toString(16);
????var?b=Math.floor((Math.random()*256)).toString(16);
????var?colorString="#"+r+g+b;
????return?colorString;
}

function?getTagCloud()?
{
????sendRequest('getTagCloud',processResponseStyle1);
}

function?getTagCloud2()?
{
????sendRequest('getTagCloud',processResponseStyle2);
}

function?getClass(relatedPosts)


{
????var?presentage?=?Math.floor((relatedPosts/maxTagPosts)*100);
????var?classSize;
????if(presentage<20)

????
{
????????classSize?=?'smallest';
????}
????else?if(20<=presentage?&&?presentage?<40)

????
{
????????classSize?=?'small';
????}
????else?if(40<=presentage?&&?presentage?<60)

????
{
????????classSize?=?'medium';
????}
????else?if(60<=presentage?&&?presentage?<80)

????
{
????????classSize?=?'large';
????}
????else?if(80<=presentage)

????
{
????????classSize?=?'largest';
????}
????return?classSize;
}


window.onload?=?function()
{
????createXMLHttpRequest();
????getTagCloud();
}

根據(jù)tag關(guān)聯(lián)的posts的數(shù)量算出這個(gè)tag字體大小的class,第一個(gè)style的顏色是在css文件指定的,第二個(gè)style多彩文字,功勞都在getRandomColor這個(gè)函數(shù)上啦。
希望這個(gè)例子能給想DIY自己的TagCloud的朋友們一些幫助。
最后是這個(gè)Demo的Eclipse工程下載,有興趣的同學(xué)吧。
點(diǎn)擊下載
posted on 2008-09-28 16:10
jht 閱讀(3161)
評(píng)論(3) 編輯 收藏 所屬分類:
J2EE