随笔-46  评论-64  文章-2  trackbacks-0

废话不多说,先看看我们最终达到的效果.  源码下载在文章最后。
Style1:
tagcloudstyle1.png
Style2:
tagcloudstyle2.png


上面的tag cloud实现思想如下:
1. Server端提供Tag的相关信息,包括TagName,Posts等,使用JSON格式传输数据

    这个例子中,我使用Servlet,使用json-lib将Bean转成JSON字符串。当然Tag的相关信息这里只是演示,真实环境中可能就需要从数据库取出来再处理了。
    代码如下:   

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 " , " 春天 " , " 夏天 " , " 秋天 " , " 冬天 " , " 节日快乐 " ,
                
" 破釜沉舟 " , " 瑞星杀毒 " , " 奶粉事故 "
                ,
" 奥运会 " , " Grails " , " Google " , " Baidu " , " XiaoNei " ,
                
" 开心网 " , " 校内网 " , " 海内网 " , " 都是垃圾 " , " 萨达姆 " , " PK " , " 网摘 "
        }
;
        
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. 客户端发起XMLHttpRequest请求,取得TagCloud需要的JSON数据,进行处理,生成链接,定义样式
    当然这里我们设计是将js文件,css文件,html分离了,为了更好的维护。
    目录和文件结构如下:
     tagcloudproject.png

    tagCloud.html 的内容很简单,两个Button,点击之后调用获取不同Style的Tag Cloud的函数   

<! 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文件,主要是字体颜色和大小的设置
@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基本的东西,但是有注释应该不难看懂
var XMLHttpReq;
var maxTagPosts = 1// 这个变量用来保存包含关联文章最多的那个Tag的文章数

// 创建XMLHttpRequest对象
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) {
            }

        }

    }

}

// 发送请求函数
function sendRequest(url, callback) {
    createXMLHttpRequest();
    XMLHttpReq.open(
"GET", url, true);
    
//XMLHttpReq.onreadystatechange = processResponse;// 指定响应函数
    XMLHttpReq.onreadystatechange = callback;
    XMLHttpReq.send(
null); // 发送请求
}


// 处理返回信息函数
function processResponseStyle1() {
    
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+"\">"+tagCloud[j].categoryName+"</a></span>\n";
                
                tagCloudHTML 
+= aTag;
            }

            
            document.getElementById(
"tagcloud").innerHTML = tagCloudHTML;
        }
 else // 页面不正常
            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();
}


根据tag关联的posts的数量算出这个tag字体大小的class,第一个style的颜色是在css文件指定的,第二个style多彩文字,功劳都在getRandomColor这个函数上啦。


希望这个例子能给想DIY自己的TagCloud的朋友们一些帮助。

最后是这个Demo的Eclipse工程下载,有兴趣的同学吧。 点击下载
posted on 2008-09-28 16:10 jht 阅读(3129) 评论(3)  编辑  收藏 所属分类: J2EE

评论:
# re: 使用JSON和AJAX创建网站的标签云(TagCloud) 2008-09-29 09:09 | 52ict
很不错 够详细的 有收获  回复  更多评论
  
# re: 使用JSON和AJAX创建网站的标签云(TagCloud) 2011-09-01 11:44 | tbw
恩 不错啊 下载了   回复  更多评论
  
# re: 使用JSON和AJAX创建网站的标签云(TagCloud) 2014-09-16 16:55 | fffr
顶  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: