Click here to Skip to main content
11,579,898 members (72,186 online)
Click here to Skip to main content

Cloud Control for ASP.NET

, 4 Jul 2006 CPOL 209.9K 1.6K 186
Rate this:
Please Sign up or sign in to vote.
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.

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 ASP.NET 2.0. First, you need to add a reference to the control assembly or the control project to your website. 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 a hyperlink on the page. You can supply the following properties for the items you want to add:

  • Text - The text of the hyperlink.
  • 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.
  • Title - The tooltip text of the HTML anchor.
  • 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 add 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. The following control properties can be used to supply the information:

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

The control then 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 the CSS classes Item1, Item2... Item7. If you don't specify the ItemCssClassPrefix, the font size CSS attribute is set depending on the weight, as follows:

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 between 1 and 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 the functions from the Statistics class similar to the Math class.
  2. 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.

  3. The weight factor is calculated according to the following formula:
  4. factor = (weight - mean)/(stddev)
  5. The normalized weights are obtained based on the following table:
  6. 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)

Share

About the Author

Rama Krishna Vavilala
Architect
United States United States
No Biography provided

You may also be interested in...

Comments and Discussions

 
GeneralNice! Pin
Sandeep Mewara27-Mar-10 5:03
memberSandeep Mewara27-Mar-10 5:03 
Questionkeywords are shown in one line Pin
manish_hwd11-Mar-10 2:23
membermanish_hwd11-Mar-10 2:23 
Generalit's great Pin
ernest_elias13-Jan-10 2:16
memberernest_elias13-Jan-10 2:16 
GeneralSome statistic Pin
maitola7928-Jul-09 6:28
membermaitola7928-Jul-09 6:28 
NewsSource code available online Pin
shookon30-May-09 16:33
membershookon30-May-09 16:33 
Generalselected tag Pin
sadeghhp7-Mar-09 22:47
membersadeghhp7-Mar-09 22:47 
GeneralRe: selected tag Pin
sadeghhp12-Mar-09 21:55
membersadeghhp12-Mar-09 21:55 
GeneralVisual Error Pin
sadeghhp30-Jan-09 22:55
membersadeghhp30-Jan-09 22:55 
GeneralRe: Visual Error Pin
Sam Shiles27-Feb-09 2:40
memberSam Shiles27-Feb-09 2:40 
QuestionOnItemClick Pin
Member 390410926-Sep-08 2:31
memberMember 390410926-Sep-08 2:31 
GeneralFont Size variation Pin
Vijay Karla25-Jun-08 19:40
memberVijay Karla25-Jun-08 19:40 
GeneralCentering the cloud Pin
musoswire18-Jun-08 4:24
membermusoswire18-Jun-08 4:24 
GeneralThe data in the Tag cloud will be lost after a post back.. Pin
miltash27-May-08 0:44
membermiltash27-May-08 0:44 
QuestionRe: The data in the Tag cloud will be lost after a post back.. Pin
asamite30-Sep-09 14:57
memberasamite30-Sep-09 14:57 
GeneralRe: The data in the Tag cloud will be lost after a post back.. Pin
DavidLieu2-Dec-09 12:03
memberDavidLieu2-Dec-09 12:03 
AnswerItemClick Pin
Adrian_Star28-Apr-08 7:01
memberAdrian_Star28-Apr-08 7:01 
GeneralDataSource Pin
111qwe22221-Apr-08 1:11
member111qwe22221-Apr-08 1:11 
GeneralOverflow Pin
bobbo052115-Apr-08 11:57
memberbobbo052115-Apr-08 11:57 
GeneralRe: Overflow Pin
utkuozturk7-May-08 10:15
memberutkuozturk7-May-08 10:15 
GeneralRe: Overflow Pin
SiB5726-Sep-08 5:28
memberSiB5726-Sep-08 5:28 
GeneralColors for the Tag cloud Pin
mavericksthrive14-Apr-08 20:20
membermavericksthrive14-Apr-08 20:20 
GeneralRe: Colors for the Tag cloud Pin
Sam Shiles27-Feb-09 2:37
memberSam Shiles27-Feb-09 2:37 
GeneralRe: Colors for the Tag cloud Pin
Steve Pieczko26-May-11 12:45
memberSteve Pieczko26-May-11 12:45 
GeneralResizing Tag Cloud Pin
mallyajiggs11-Apr-08 6:10
membermallyajiggs11-Apr-08 6:10 
GeneralRe: Resizing Tag Cloud Pin
Everton Molina10-Jun-08 10:42
memberEverton Molina10-Jun-08 10:42 
AnswerRe: Resizing Tag Cloud Pin
Tartatuga8-Oct-09 5:49
memberTartatuga8-Oct-09 5:49 
GeneralExcelent component! Pin
crfenix6-Apr-08 5:36
membercrfenix6-Apr-08 5:36 
QuestionItemClick Pin
fatgeorge13-Dec-07 0:35
memberfatgeorge13-Dec-07 0:35 
AnswerRe: ItemClick Pin
manish_hwd11-Mar-10 2:27
membermanish_hwd11-Mar-10 2:27 
QuestionCan I use a datatable for datasource? Pin
ameq1-Dec-07 21:27
memberameq1-Dec-07 21:27 
GeneralCompiled source Pin
dbalasko27-Nov-07 0:21
memberdbalasko27-Nov-07 0:21 
GeneralThanks!! Pin
bhardiatech26-Aug-07 5:33
memberbhardiatech26-Aug-07 5:33 
GeneralThank You! Pin
lucasstark@gmail21-Aug-07 1:21
memberlucasstark@gmail21-Aug-07 1:21 
QuestionError Creating Control Pin
Pandiya Krishnan8-Aug-07 1:33
memberPandiya Krishnan8-Aug-07 1:33 
GeneralWork's Perfect Pin
mandeep_bhangu18-Jul-07 0:31
membermandeep_bhangu18-Jul-07 0:31 
QuestionHow to populate Pin
faujiman11-Jun-07 9:12
memberfaujiman11-Jun-07 9:12 
QuestionCan we use xmldatasource ??? Pin
goodnfine0004-Apr-07 5:18
membergoodnfine0004-Apr-07 5:18 
GeneralGreat article. Pin
Praveen Angyan11-Mar-07 7:38
memberPraveen Angyan11-Mar-07 7:38 
GeneralItemClick does not get fired Pin
jaswinder1974121-Feb-07 18:07
memberjaswinder1974121-Feb-07 18:07 
GeneralUsed Cloud w/ Amazon API Pin
DigitalColony6-Dec-06 4:59
memberDigitalColony6-Dec-06 4:59 
GeneralWon't set below size 4 Pin
David Ing18-Oct-06 2:58
memberDavid Ing18-Oct-06 2:58 
GeneralRe: Won't set below size 4 Pin
tutejaamit522-May-07 3:17
membertutejaamit522-May-07 3:17 
GeneralControl will not render. Pin
ITS_Roberts_Chris20-Sep-06 9:18
memberITS_Roberts_Chris20-Sep-06 9:18 
GeneralRe: Control will not render. Pin
Rama Krishna Vavilala20-Sep-06 9:21
memberRama Krishna Vavilala20-Sep-06 9:21 
GeneralRe: Control will not render. Pin
ITS_Roberts_Chris20-Sep-06 9:26
memberITS_Roberts_Chris20-Sep-06 9:26 
GeneralRe: Control will not render. Pin
amossin2-May-07 23:32
memberamossin2-May-07 23:32 
AnswerRe: Control will not render. Pin
Certain Shadow23-Mar-09 18:00
memberCertain Shadow23-Mar-09 18:00 
Questionis there also 1.1 version to download? Pin
wingi17-Aug-06 14:18
memberwingi17-Aug-06 14:18 
AnswerRe: is there also 1.1 version to download? Pin
Rama Krishna Vavilala17-Aug-06 15:57
memberRama Krishna Vavilala17-Aug-06 15:57 
QuestiononMouseOver event? Pin
sheferlior17-Aug-06 6:06
membersheferlior17-Aug-06 6:06 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web04 | 2.8.150603.1 | Last Updated 4 Jul 2006
Article Copyright 2006 by Rama Krishna Vavilala
Everything else Copyright © CodeProject, 1999-2015
Layout: fixed | fluid