C#实现简易标签云算法
日期:2010-5-13 15:46:59作者:QiuLiang |
标签云,作为Web2.0时代的一个显著特征,已经被大量的应用在各类网站。
Tag Clouds的属性一般有四种 【摘自百度百科】
- 字号一般与数目有关
- 排列 字典顺序、随机
- 颜色 固定渐进色、是否加背景等
- 字体 一般为固定
目前流行的标签云有两种形式:XHTML格式以及flash,这两种都是表现形式。今天研究了一下,用c#实现了一个简易标签云算法。
- 需求分析
标签云的产生首先需要一个数据源,数据库、XML都可以。XML多用于flash形式。一般数据源都至少有两个属性:标签名称、标签统计数量(或点击数量),根据这两个属性,最终生成具有不同字号、颜色的标签。
- 示例代码
public class TagCloud
{
public List<TagEntity> TagSource { get; set; }
public int RankMaxValue { get; set; } //最大权值
public int RankMinValue { get; set; } //最小权值
public int MaxFontSize { get; set; } //最大字体
public int MinFontSize { get; set; } //最小字体
public string TagUrl { get; set; } //标签链接
public delegate string AddUrlHandler(string tagName);
public event AddUrlHandler OnAddUrlHandler = null;
public TagCloud(List<TagEntity> tagSource) {
this.TagSource = tagSource;
this.RankMaxValue = 100;
this.RankMinValue = 1;
this.MaxFontSize = 50;
this.MinFontSize = 8;
this.TagUrl = "#";
}
public string GenHtmlTags() {
StringBuilder sb = new StringBuilder();
sb.Append("<div class=\"ql_lib_web_tagcloud\">");
List<int[]> rankList = GetRankList();
TagSource.ForEach(ts => {
int currentSizePercent = GetTagRank(rankList,ts.TagCount);
currentSizePercent = (int)Math.Round( (double)MaxFontSize * currentSizePercent/100);
if (OnAddUrlHandler != null)
TagUrl = OnAddUrlHandler(ts.TagName);
sb.Append(string.Format("<a style=\"font-size:{0}px;\" href=\"{1}\" target=\"_self\">",
currentSizePercent == 0 ? MinFontSize : currentSizePercent,TagUrl ) );
sb.Append(ts.TagName);
sb.Append("</a>");
});
sb.Append("</div>");
return sb.ToString();
}
public List<int[]> GetRankList() {
List<int[]> rankList = new List<int[]>();
int tmp = 0;
List<int> allCount = new List<int>();
TagSource.ForEach(t => allCount.Add(t.TagCount));
IEnumerable<int> noRepeatArray = allCount.Distinct().OrderByDescending(i => i); //将tag的count数组去除重复并倒序排列
int count = noRepeatArray.Count();
foreach (int d in noRepeatArray) {
if (tmp != 0 && tmp != count - 1)
rankList.Add(new int[] { d, (RankMaxValue - RankMaxValue * tmp / count) });
else {
if (tmp == 0)
rankList.Add(new int[] { d, RankMaxValue }); //如果是第一个tag,赋予最大的权值
if (tmp == count - 1)
rankList.Add(new int[]{d,RankMinValue}); //最后一个Tag,赋予最小的权值
}
tmp++;
}
return rankList;
}
/// <summary>
/// 遍历权值数组,根据当前tag的count数量,返回每个tag的权值
/// </summary>
/// <param name="compare">生成的权值数组</param>
/// <param name="c">单个tag的count数量</param>
/// <returns>每个tag的最终权值</returns>
private int GetTagRank(List<int[]> compare, int c) {
foreach (int[] aa in compare) {
if (c == aa[0])
return aa[1];
}
return RankMinValue; //如果count数不存在,则返回最小的权值
}
}
public class TagEntity
{
public string TagName { get; set; }
public int TagCount { get; set; }
}
关键点:
- 根据数据源的count数量实现权值算法。(本例相对简单,如果需要更高的精度,需要修改此部分算法)
- 利用委托实现URL绑定(当然也可以直接在数据源里把URL传递进来),只是本例的URL需要做一些处理后生成,所以使用了事件委托。
相关阅读
没有相关内容
已有 1 条评论,点击查看
评论:
| 姓名 | * |
| 内容 | * |
博主,能把这个例子说的更详细些吗?刚接触这方面,不太懂...