/BlogEngine/BlogEngine.NET/App_Code/Controls/TagCloud.cs
C# | 218 lines | 140 code | 34 blank | 44 comment | 15 complexity | a789b29cfee85c3e39f4510900b98f14 MD5 | raw file
Possible License(s): LGPL-2.1, Apache-2.0, BSD-3-Clause
- // --------------------------------------------------------------------------------------------------------------------
- // <summary>
- // The tag cloud.
- // </summary>
- // --------------------------------------------------------------------------------------------------------------------
-
- namespace App_Code.Controls
- {
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Web;
- using System.Web.UI;
-
- using BlogEngine.Core;
-
- using Resources;
-
- /// <summary>
- /// The tag cloud.
- /// </summary>
- public class TagCloud : Control
- {
- #region Constants and Fields
-
- /// <summary>
- /// The link format.
- /// </summary>
- private const string Link = "<a href=\"{0}\" class=\"{1}\" title=\"{2}\">{3}</a> ";
-
- /// <summary>
- /// The sync root.
- /// </summary>
- private static readonly object SyncRoot = new object();
-
- /// <summary>
- /// The weighted list.
- /// </summary>
- private static Dictionary<Guid, Dictionary<string, string>> weightedList = new Dictionary<Guid, Dictionary<string, string>>();
-
- /// <summary>
- /// The minimum posts.
- /// </summary>
- private int minimumPosts = 1;
-
- /// <summary>
- /// The tag cloud size.
- /// </summary>
- private int tagCloudSize = -1;
-
- #endregion
-
- #region Properties
-
- /// <summary>
- /// Gets or sets MinimumPosts.
- /// </summary>
- public int MinimumPosts
- {
- get
- {
- return this.minimumPosts;
- }
-
- set
- {
- this.minimumPosts = value;
- }
- }
-
- /// <summary>
- /// Gets or sets TagCloudSize.
- /// </summary>
- public int TagCloudSize
- {
- get
- {
- return this.tagCloudSize;
- }
-
- set
- {
- this.tagCloudSize = value;
- }
- }
-
- /// <summary>
- /// Gets WeightedList.
- /// </summary>
- private Dictionary<string, string> WeightedList
- {
- get
- {
- Dictionary<string, string> list = null;
- Guid blogId = Blog.CurrentInstance.Id;
-
- if (!weightedList.TryGetValue(blogId, out list))
- {
- lock (SyncRoot)
- {
- if (!weightedList.TryGetValue(blogId, out list))
- {
- list = new Dictionary<string, string>();
- weightedList.Add(blogId, list);
-
- this.SortList();
- }
- }
- }
-
- return list;
- }
- }
-
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Outputs server control content to a provided <see cref="T:System.Web.UI.HtmlTextWriter"/> object and stores tracing information about the control if tracing is enabled.
- /// </summary>
- /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
- public override void RenderControl(HtmlTextWriter writer)
- {
- if (this.WeightedList.Keys.Count == 0)
- {
- writer.Write("<p>{0}</p>", labels.none);
- }
-
- writer.Write("<ul id=\"tagcloud\" class=\"tagcloud\">");
-
- foreach (var key in this.WeightedList.Keys)
- {
- writer.Write("<li>");
- writer.Write(
- string.Format(
- Link,
- string.Format("{0}?tag=/{1}", Utils.RelativeWebRoot, HttpUtility.UrlEncode(key)),
- this.WeightedList[key],
- string.Format("Tag: {0}", key),
- key));
- writer.Write("</li>");
- }
-
- writer.Write("</ul>");
- writer.Write(Environment.NewLine);
- }
-
- #endregion
-
- #region Methods
-
- /// <summary>
- /// Builds a raw list of all tags and the number of times
- /// they have been added to a post.
- /// </summary>
- /// <returns>A sorted dictionary of int with string keys.</returns>
- private static SortedDictionary<string, int> CreateRawList()
- {
- var dic = new SortedDictionary<string, int>();
- foreach (var tag in Post.Posts.Where(post => post.IsVisibleToPublic).SelectMany(post => post.Tags))
- {
- if (dic.ContainsKey(tag))
- {
- dic[tag]++;
- }
- else
- {
- dic[tag] = 1;
- }
- }
-
- return dic;
- }
-
- /// <summary>
- /// Sorts the list of tags based on how much they are used.
- /// </summary>
- private void SortList()
- {
- var dic = CreateRawList();
- var max = dic.Values.Max();
-
- var currentTagCount = 0;
-
- int count = currentTagCount;
- foreach (var key in
- dic.Keys.Where(key => dic[key] >= this.MinimumPosts).Where(key => this.TagCloudSize <= 0 || count <= this.TagCloudSize))
- {
- currentTagCount++;
-
- var weight = ((double)dic[key] / max) * 100;
- if (weight >= 99)
- {
- WeightedList.Add(key, "biggest");
- }
- else if (weight >= 70)
- {
- WeightedList.Add(key, "big");
- }
- else if (weight >= 40)
- {
- WeightedList.Add(key, "medium");
- }
- else if (weight >= 20)
- {
- WeightedList.Add(key, "small");
- }
- else if (weight >= 3)
- {
- WeightedList.Add(key, "smallest");
- }
- }
- }
-
- #endregion
- }
- }