5,316,870 members and growing! (15,598 online)
Email Password   helpLost your password?
Web Development » ASP.NET » General     Intermediate License: The Code Project Open License (CPOL)

Cloud Control for ASP.NET

By Rama Krishna Vavilala

This cloud control displays a list of hyperlinks in varying styles depending on a weight. This is similar to tag clouds in del.icio.us or flickr.
Windows, .NET, Visual Studio, ASP.NET, Dev

Posted: 4 Jul 2006
Updated: 4 Jul 2006
Views: 75,615
Announcements
Want a new Job?



Search    
Advanced Search
Sitemap
Prize winner in Competition "ASP.NET Jun 2006"
30 votes for this Article.
Popularity: 6.78 Rating: 4.59 out of 5
1 vote, 3.3%
1
1 vote, 3.3%
2
3 votes, 10.0%
3
4 votes, 13.3%
4
21 votes, 70.0%
5
Note: This is an unedited contribution. If this article is inappropriate, needs attention or copies someone else's work without reference then please Report This Article
Download source code - 56.1 Kb

Introduction

Web sites such as del.icio.us, Technorati and Flickr, which allow tagging of their content, depict the popularity of tags using a tag cloud. The popular items have larger font sizes. This concept can be applied to any list of items where each item has an associated weight. For example, a list of products can be displayed in a cloud weighed by the cost of a product. Using the ASP.NET server control presented in this article, you can display your own domain specific items as a cloud. The image below shows a sample cloud for articles on Ajaxian.

sample image

Using the Control

 This control works only with the ASP.NET 2.0. First, you need to add a reference to the control assembly or the control project to your web site. In the page you need to use the control, add the following declaration.

<%@ Register Namespace="VRK.Controls" TagPrefix="vrk" Assembly="VRK.Controls" %>

This will allow you to use the control in the page using the following declaration.

<vrk:Cloud ID="c1" runat="server" />

Now you need to add items to the control. Each item will be displayed as an hyperlink on the page. You can supply following properties for the items you want to add.

  1. Text - The text of the hyperlink
  2. Href - The URL where the user will be navigated to when he clicks the hyperlink. If this property is left blank the control causes a postback and raises the ItemClick event.
  3. Title - The tooltip text of the HTML anchor.
  4. Weight - The weight determines how the item will be displayed.

You can add the items declaratively as shown:

<vrk:Cloud ID="c1" runat="server">
<Items>
   <vrk:CloudItem Text="Item1" 
      Href="Default.aspx?tag=Item1" 
      Title="Some title" Weight="4" />
   <vrk:CloudItem Text="Item2" 
      Href="Default.aspx?tag=Item2" 
      Title="Some title" Weight="4" />
</Items>
</vrk:Cloud>

You can also add the items programmatically:

c1.Items.Add(new CloudItem("Item1", 4, 
                           "Default.aspx?tag=Item1", 
                           "Some title"
                           ));

You can also use data binding to add items. First, you need to a data source to your page. The code example below shows an ObjectDataSource but you can use any ASP.NET DataSourceControl such as SqlDataSource or AccessDataSource.

<asp:ObjectDataSource 
   ID="ItemsSource" 
   runat="server" 
   SelectMethod="GetItems" 
   TypeName="CloudTest.ItemsSource" 
  />

You need to indicate to the cloud control that it needs to use the ItemsSource data source control by specifying its DataSourceID.

<vrk:Cloud ID="c1" runat="server" DataSourceID="ItemsSource" .... />

Once the data source is specified, you will need to indicate how the items should be populated from the data source. Following control properties can be used to supply the information:

  1. DataTextField - the name of the data field that is bound to the Text property of an item.
  2. DataTextFormatString - the format string for the Text property. {0} in the string is replaced with the value of the field from the data source.
  3. DataHrefField - the data field which is bound to the Href property of an item.
  4. DataHrefFormatString - the format string to format the Href property value.
  5. DataTitleField - the data field which is bound to the Title property of an item.
  6. DataTitleFormatString - the format string for the title (tooltip) of an item.
  7. DataWeightField - the field from the Data Source where the weight of an item is to be obtained.

The control than normalizes the weight of all the items so that they fit in the range 1 to 7. You can control the display of the normalized items using the optional ItemCssClassPrefix property. If you use the  ItemCssClassPrefix property you need to add seven different CSS classes to your HTML page. For example, if you specify the property value to be "Item", you need to specify CSS classes Item1, Item2... Item7. If you don't specify the ItemCssClassPrefix the font size CSS attribute is set depending on the weight as following:

Normalized Weight font-size
1 xx-small
2 x-small
3 small
4 medium
5 large
6 x-large
7 xx-large

Now let's examine how the control works.

How the Control Works?

The main logic is to convert the distribution of weights into a integral range that between 1 to 7. After struggling with statistics for some time I figured out the following algorithm for normalizing the weights.

  1. Compute the mean and the standard deviation(σ) of the weights. This is done using functions from Statistics class similar to Math class.
    private IEnumerable<double> ItemWeights
    {
      get
      {
        foreach (CloudItem item in this.Items)
        {
          yield return item.Weight;
        }
      }
    }
    
    ...
    
    double mean; 
    double stdDev = Statistics.StdDev(ItemWeights, out mean);
    
    The StdDev function takes an IEnumerable<double> parameter which is supplied by the ItemWeights method.
  2. The weight factor is calculated according to the following formula:
    factor = (weight - mean)/(stddev)
    
  3. The normalized weights are obtained based on the following table:
    Normalized Weight Condition
    1 factor <= -2*stddev
    2 -2*stddev < factor <= -1*stddev
    3 -1*stddev < factor <= -0.5*stddev
    4 -0.5*stddev < factor < 0.5*stddev
    5 0.5*stddev <=  factor < 1*stddev
    6 1*stddev < = factor < 2*stddev
    7 factor >= 2 * stddev

Once the normalized weights are obtained it is easy to set the font sizes and the classes.

foreach (CloudItem item in Items)
{
  HtmlAnchor a = new HtmlAnchor();
  a.HRef = String.IsNullOrEmpty(item.Href) ?
  this.Page.ClientScript.GetPostBackClientHyperlink(this, index.ToString()) :
                   item.Href;
  a.InnerText = item.Text;
  a.Title = item.Title;
  int normalWeight = NormalizeWeight(item.Weight, mean, stdDev);
  if (hasCssClassPrefix)
  {
    a.Attributes["class"] = this.ItemCssClassPrefix + normalWeight.ToString();
  }
  else
  {
    a.Style.Add(HtmlTextWriterStyle.FontSize, _fontSizes[normalWeight - 1]);
  }
  this.Controls.Add(a);
  this.Controls.Add(new LiteralControl(" "));
  index++;
}

The method seems to work reasonably well in most of the situations. Any suggestions to improve it further are welcome.

History

  • July 4, 2006 - First Version

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Rama Krishna Vavilala



Occupation: Architect
Location: United States United States

Other popular ASP.NET articles:

Article Top
Sign Up to vote for this article
You must Sign In to use this message board.
FAQ FAQ Noise ToleranceSearch Search Messages 
 Layout  Per page   
 Msgs 1 to 25 of 57 (Total in Forum: 57) (Refresh)FirstPrevNext
Subject  Author Date 
GeneralFont Size variationmemberVijay Karla20:40 25 Jun '08  
GeneralCentering the cloudmembermusoswire5:24 18 Jun '08  
GeneralThe data in the Tag cloud will be lost after a post back..membermiltash1:44 27 May '08  
AnswerItemClickmemberAdrian_Star8:01 28 Apr '08  
GeneralDataSourcemember111qwe2222:11 21 Apr '08  
GeneralOverflowmemberbobbo052112:57 15 Apr '08  
GeneralRe: Overflowmemberutkuozturk11:15 7 May '08  
GeneralColors for the Tag cloudmembermavericksthrive21:20 14 Apr '08  
GeneralResizing Tag Cloudmembermallyajiggs7:10 11 Apr '08  
GeneralRe: Resizing Tag CloudmemberEverton Molina11:42 10 Jun '08  
GeneralExcelent component!membercrfenix6:36 6 Apr '08  
QuestionItemClickmemberfatgeorge1:35 13 Dec '07  
QuestionCan I use a datatable for datasource?memberameq22:27 1 Dec '07  
GeneralCompiled sourcememberdbalasko1:21 27 Nov '07  
GeneralThanks!!memberbhardiatech6:33 26 Aug '07  
GeneralThank You!memberlucasstark@gmail2:21 21 Aug '07  
QuestionError Creating ControlmemberPandiya Krishnan2:33 8 Aug '07  
GeneralWork's Perfectmembermandeep_bhangu1:31 18 Jul '07  
QuestionHow to populatememberfaujiman10:12 11 Jun '07  
GeneralCan we use xmldatasource ???membergoodnfine0006:18 4 Apr '07  
GeneralGreat article.memberPraveen Angyan8:38 11 Mar '07  
GeneralItemClick does not get firedmemberjaswinder1974119:07 21 Feb '07  
GeneralUsed Cloud w/ Amazon APImemberDigitalColony5:59 6 Dec '06  
GeneralWon't set below size 4memberDavid Ing3:58 18 Oct '06  
GeneralRe: Won't set below size 4membertutejaamit54:17 22 May '07  

General General    News News    Question Question    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

PermaLink | Privacy | Terms of Use
Last Updated: 4 Jul 2006
Editor:
Copyright 2006 by Rama Krishna Vavilala
Everything else Copyright © CodeProject, 1999-2008
Web09 | Advertise on the Code Project