PageRenderTime 50ms CodeModel.GetById 24ms RepoModel.GetById 1ms app.codeStats 0ms

/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
  1. // --------------------------------------------------------------------------------------------------------------------
  2. // <summary>
  3. // The tag cloud.
  4. // </summary>
  5. // --------------------------------------------------------------------------------------------------------------------
  6. namespace App_Code.Controls
  7. {
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Web;
  12. using System.Web.UI;
  13. using BlogEngine.Core;
  14. using Resources;
  15. /// <summary>
  16. /// The tag cloud.
  17. /// </summary>
  18. public class TagCloud : Control
  19. {
  20. #region Constants and Fields
  21. /// <summary>
  22. /// The link format.
  23. /// </summary>
  24. private const string Link = "<a href=\"{0}\" class=\"{1}\" title=\"{2}\">{3}</a> ";
  25. /// <summary>
  26. /// The sync root.
  27. /// </summary>
  28. private static readonly object SyncRoot = new object();
  29. /// <summary>
  30. /// The weighted list.
  31. /// </summary>
  32. private static Dictionary<Guid, Dictionary<string, string>> weightedList = new Dictionary<Guid, Dictionary<string, string>>();
  33. /// <summary>
  34. /// The minimum posts.
  35. /// </summary>
  36. private int minimumPosts = 1;
  37. /// <summary>
  38. /// The tag cloud size.
  39. /// </summary>
  40. private int tagCloudSize = -1;
  41. #endregion
  42. #region Properties
  43. /// <summary>
  44. /// Gets or sets MinimumPosts.
  45. /// </summary>
  46. public int MinimumPosts
  47. {
  48. get
  49. {
  50. return this.minimumPosts;
  51. }
  52. set
  53. {
  54. this.minimumPosts = value;
  55. }
  56. }
  57. /// <summary>
  58. /// Gets or sets TagCloudSize.
  59. /// </summary>
  60. public int TagCloudSize
  61. {
  62. get
  63. {
  64. return this.tagCloudSize;
  65. }
  66. set
  67. {
  68. this.tagCloudSize = value;
  69. }
  70. }
  71. /// <summary>
  72. /// Gets WeightedList.
  73. /// </summary>
  74. private Dictionary<string, string> WeightedList
  75. {
  76. get
  77. {
  78. Dictionary<string, string> list = null;
  79. Guid blogId = Blog.CurrentInstance.Id;
  80. if (!weightedList.TryGetValue(blogId, out list))
  81. {
  82. lock (SyncRoot)
  83. {
  84. if (!weightedList.TryGetValue(blogId, out list))
  85. {
  86. list = new Dictionary<string, string>();
  87. weightedList.Add(blogId, list);
  88. this.SortList();
  89. }
  90. }
  91. }
  92. return list;
  93. }
  94. }
  95. #endregion
  96. #region Public Methods
  97. /// <summary>
  98. /// 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.
  99. /// </summary>
  100. /// <param name="writer">The <see cref="T:System.Web.UI.HtmlTextWriter"/> object that receives the control content.</param>
  101. public override void RenderControl(HtmlTextWriter writer)
  102. {
  103. if (this.WeightedList.Keys.Count == 0)
  104. {
  105. writer.Write("<p>{0}</p>", labels.none);
  106. }
  107. writer.Write("<ul id=\"tagcloud\" class=\"tagcloud\">");
  108. foreach (var key in this.WeightedList.Keys)
  109. {
  110. writer.Write("<li>");
  111. writer.Write(
  112. string.Format(
  113. Link,
  114. string.Format("{0}?tag=/{1}", Utils.RelativeWebRoot, HttpUtility.UrlEncode(key)),
  115. this.WeightedList[key],
  116. string.Format("Tag: {0}", key),
  117. key));
  118. writer.Write("</li>");
  119. }
  120. writer.Write("</ul>");
  121. writer.Write(Environment.NewLine);
  122. }
  123. #endregion
  124. #region Methods
  125. /// <summary>
  126. /// Builds a raw list of all tags and the number of times
  127. /// they have been added to a post.
  128. /// </summary>
  129. /// <returns>A sorted dictionary of int with string keys.</returns>
  130. private static SortedDictionary<string, int> CreateRawList()
  131. {
  132. var dic = new SortedDictionary<string, int>();
  133. foreach (var tag in Post.Posts.Where(post => post.IsVisibleToPublic).SelectMany(post => post.Tags))
  134. {
  135. if (dic.ContainsKey(tag))
  136. {
  137. dic[tag]++;
  138. }
  139. else
  140. {
  141. dic[tag] = 1;
  142. }
  143. }
  144. return dic;
  145. }
  146. /// <summary>
  147. /// Sorts the list of tags based on how much they are used.
  148. /// </summary>
  149. private void SortList()
  150. {
  151. var dic = CreateRawList();
  152. var max = dic.Values.Max();
  153. var currentTagCount = 0;
  154. int count = currentTagCount;
  155. foreach (var key in
  156. dic.Keys.Where(key => dic[key] >= this.MinimumPosts).Where(key => this.TagCloudSize <= 0 || count <= this.TagCloudSize))
  157. {
  158. currentTagCount++;
  159. var weight = ((double)dic[key] / max) * 100;
  160. if (weight >= 99)
  161. {
  162. WeightedList.Add(key, "biggest");
  163. }
  164. else if (weight >= 70)
  165. {
  166. WeightedList.Add(key, "big");
  167. }
  168. else if (weight >= 40)
  169. {
  170. WeightedList.Add(key, "medium");
  171. }
  172. else if (weight >= 20)
  173. {
  174. WeightedList.Add(key, "small");
  175. }
  176. else if (weight >= 3)
  177. {
  178. WeightedList.Add(key, "smallest");
  179. }
  180. }
  181. }
  182. #endregion
  183. }
  184. }