Você não está logado, deseja logar na comunidade? clique aqui.

SEXTA-FEIRA, 5 DE SETEMBRO DE 2008
Seja bem vindo(a) VISITANTE ao ASPNETi.com.

Heroes

Criando a Tag Cloud em C#


Data Publicação: 4/12/2007 13:13:47
Total de visualizações: 1241

comente

Aumentar / Diminuir Fonte   




Pessoal,

Estou aqui para ajudar e mostrar um artigo cujo está sendo muito usado nos sites e sistemas atuais para melhorar a indexação no sistema de busca.

Fonte: http://www.geekzilla.co.uk/View960C74AE-D01B-428E-BCF3-E57B85D5A308.htm

Creating a Tag Cloud in C#

I wanted to add a TagCloud to GeekZilla. The first thing I did was look around the web for some examples (or free components). To my supprise none jumped out at me. So, I decided to write my own.

At first I found myself wondering how I would render different size words randomly within a <div>. How would I be able to position them in relation to each other? float:right?? After looking at a few tag coulds de.licio.us , dotnetkicks etc I discovered that tag clouds are infact displayed in alphabetical order and the word size doesn't change much.

My Needs

The TagCloud would need to be able to be generated from a DataTable containing the columns 'tag' and 'count'. In my case the data would come from a Sql Server 2005 database. At the database level I'd be doing the aggregation and ordering. The TagCould code would only need to worry about weighting the tags.

The Data

First of all I created a view of all tags with their grouping:

SELECT TOP (60) 
    COUNT(1) AS Count
    Tag
FROM         
    dbo.ContentTag
GROUP BY 
    Tag
ORDER BY 
    'Count' DESC

I then created a stored procedure which would return me the top 60 tags ordered alphabetically:

SELECT 
    * 
FROM 
    vwTagCloud 
ORDER BY 
    Tag

The UI

I decided to place the tag control within a UserControl incase I needed to include it in more than one page, in the end it was only used in the MasterPage.

I created a method called GetCloud() which would contain the logic for the tag weighting. The method accepts a DataTable and a String based Cloud Template. The Cloud Template is tokenised, the replaced version is returned for each tag in the DataTable.

/// <summary>
/// Return a tag could.
/// </summary>
/// <param name="tagData">DataTable containing the columns 'tag' and 'count'</param>
/// <param name="cloudTemplate">
/// The template to return for each iten. Should include $tag$ and
/// $weight$ which will be replaced with actual data
/// <example>&lt;h$weight$&gt;&lt;a href='#$tag$'&gt;$tag$&lt;/a&gt;&lt;/h$weight$&gt;</example>
/// </param>
/// <returns>String containing tag cloud</returns>
private string GetCloud(DataTable tagData, string cloudTemplate)
{

Next I included some validation on the input table.

    // Check the input data
    if (!tagData.Columns.Contains("tag"))
        throw new Exception("Expected column 'tag' is missing");

    if (!tagData.Columns.Contains("count"))
        throw new Exception("Expected column 'count' is missing");

Now time to get down to business. To figure out the weight of the tag I first needed to know the Min and Max tag occurances. For this I used DataTable.Compute(). You can see more information on the Compute() method in my article about EvaluatingExpressions.

    // Lets get cracking
    StringBuilder outputBuffer = new StringBuilder();
    double max = 0;
    double min = 0;

    // Use Compute to get the min and max counts
    double.TryParse(tagData.Compute("min(count)"null).ToString(), out min);
    double.TryParse(tagData.Compute("max(count)"null).ToString(), out max);

With the Min and Max known I could loop through the DataTable figuring out the tag weight.

    // Loop through the data, generate the tag cloud
    foreach (DataRow row in tagData.Rows)
    {

First of all I needed to calculate the weight as a percentage. For this I divided the number of occuances by the maximum occurances and multiplied it by 100.

        // work out the weight
        double weightPercent = (double.Parse(row["count"].ToString()) / max) * 100;
        int weight = 0;

With the weight percentage I apply a bunch of cascading 'if' statements to figure out which weight classification the tag belongs to

        if (weightPercent >= 99)
        {
            //heaviest
            weight = 1;
        }
        else if (weightPercent >= 70)
        {
            weight = 2;
        }
        else if (weightPercent >= 40)
        {
            weight = 3;
        }
        else if (weightPercent >= 20)
        {
            weight = 4;
        }
        else if (weightPercent >= 3)
        {
            //weakest
            weight = 5;
        }
        else
        {
            // use this to filter out all low hitters
            weight = 0;
        }

Lastly I replace the tokens in the cloud template and append the result to a StringBuilder.

        // don't return data for unweighted items
        if (weight > 0)
            outputBuffer.Append(cloudTemplate.Replace("$weight$"
                weight.ToString()).Replace("$tag$"
                row["tag"].ToString()).Replace("$urlencodetag$",HttpUtility.UrlEncode(row["tag"].ToString())));
    }

When all are evaluated, return the StringBuilder

    return outputBuffer.ToString();
}

CSS

Ok, this code generates a bunch of Anchor tags. I'd need to use CSS to make the thing look decent. The cloud template used the weight to assign an appropriate style to each tag. The styles used are

  • weight1
  • weight2
  • weight3
  • weight4
  • weight5

The following StyleSheet was created to bring these tags to life within a <div> called tagCloud

<style>
#tagCloud
{
    width:238px;
    border:solid 1px #ccc;
    padding:5px;
    margin-bottom:10px;
    text-align:justify;
}

#tagCloud A
{
    text-decoration:none;
    margin-left:5px;
    margin-right:5px;
    font-family:Trebuchet MS, Verdana, Arial;
    text-transform:lowercase;
}

#tagCloud A:hover
{
    color:#00cc00;
    text-decoration:underline;
}

#tagCloud A.weight1
{
    color: #ff9900;
    font-size: 1.9em;
    font-weight:bolder;
}
#tagCloud A.weight2
{
    color: #4169e1;
    font-size:1.5em;
    font-weight:bolder;
}
#tagCloud A.weight3
{
    color: #009eff;
    font-size: 1.4em;
    font-weight:bolder;
}
#tagCloud A.weight4
{
    color: #4188cf;
    font-size: 1.2em;
}
#tagCloud A.weight5
{
    color: #83bcd8;
    font-size: 1.0em;
}
</style>

Adding my cloud to the UserControl

Html

The Html is really simple, as you can see below:

<div id="tagCloud">
      <asp:Literal ID="CloudLiteral" runat="server" />
</div>

Code Behind

The Page_Load() calls my DataAccessLayer to get the DataTable and passes the data to the local GetCloud() method. Note the use of ResolveClientUrl

protected void Page_Load(object sender, EventArgs e)
{
    String browseUrl = Page.ResolveClientUrl("~/TagBrowse.aspx");
    
    CloudLiteral.Text = GetCloud(ContentTag.GetCloudData().Tables[0], 
                "<a class='weight$weight$' href='" + browseUrl + "?tag=$urlencodetag$'>$tag$</a> ");
}

The Result

You can see the result of my efforts right here on GeekZilla, if you're interested in using or enhancing this code, feel free to download the example application linked from the bottom of this article.

I hope my code makes your life a bit easier, if nothing else I hope it inspires you to add a cloud to your site... doesn't just have to be for tags

kick it on DotNetKicks.com del.icio.us digg Mister Wong YahooMyWeb Reddit Furl Spurl blogmarks

Related Downloads




Total de visualizações: 1241
voltar   comente  subir

Por:Maurício Júnior
Maurício Júnior
Formado pela Faculdade Anhanguera, Especialista pela FGV (Fundação Getúlio Vargas), Pós-Graduação em Docência Superior e cursando Mestrado na UNB; linha de pesquisa Desenvolvimento de Aplicativos para TV Digital.
Tenho 26 anos e possuo cinco livros publicados pela editora Ciência Moderna no ano de 2007.Sou Certificado Microsoft MCP, faço parte da comunidade ASPNETI.COM, onde publico artigos, vídeos, ebooks e livros. Trabalho como Arquiteto de Software na empresa TATA. Sou professor universitário, da Universidade Paulista - UNIP, na qual ministro para o curso de Tecnólogo, Comunicação Web e Redes. Blog:  blog.mauriciojunior.orgSite pessoal  www.mauriciojunior.org




Comentários:



Comente (dê sua opinião):

Nome:
E-mail:
Comentário:
Código Imagem:  (digite o código da imagem respeitando maiúsculo e minúsculo)

Favor digitar o código da imagem para cadastramento.

 

PROGRAMANDO EM ASP.NET

Informações Online:   aparecer | sumir

Usuários Online: 59
Artigos:  418
Fórum:  2982
Empregos:  960
Usuários Cadastrados:   4417

Patrocinador

Artigos do Autor ASPNETi.COM

Nem tudo é o que parece!
Autor: Maurício Júnior acesse

IsWholeNumber
Autor: Maurício Júnior acesse

Criando Pastas no Mail com o Macbook
Autor: Maurício Júnior acesse

Visual Source Safe ? Série 2
Autor: Maurício Júnior acesse

Visual SourceSafe - Série 5
Autor: Maurício Júnior acesse

Novo Firefox 3.0 - o chamado Minefield
Autor: Maurício Júnior acesse

Código fonte do livro DESENVOLVENDO WEBSERVICES
Autor: Maurício Júnior acesse

Java J2EE – Primeiro Passo
Autor: Maurício Júnior acesse

Criando Alias no Pacote
Autor: Maurício Júnior acesse

Loja Apple (a2you.com.br) feita em .NET (Microsoft)
Autor: Maurício Júnior acesse

Gerando word com Visual Studio.NET 2005
Autor: Maurício Júnior acesse

Criando a Tag Cloud em C#
Autor: Maurício Júnior acesse

Evento BrasilDotNet 2008
Autor: Maurício Júnior acesse

Vídeo - Criando um WebBrowser
Autor: Maurício Júnior acesse

Insistência com Vírus por E-mail
Autor: Maurício Júnior acesse

Chamando Programas de Dentro do Windows Forms
Autor: Maurício Júnior acesse

Sistema de Login em ASP – Parte VI
Autor: Maurício Júnior acesse

Artigo Criando RSS Xml para o Seu Próprio Site
Autor: Maurício Júnior acesse

Themas - Muito Simples
Autor: Maurício Júnior acesse

Vírus - Telegrama Eletrônico
Autor: Maurício Júnior acesse

Vírus - Full video Pamela Anderson
Autor: Maurício Júnior acesse

II Encontro .NET em Brasília
Autor: Maurício Júnior acesse

Novo SO Palm, depois da venda...
Autor: Maurício Júnior acesse

Vídeo - Ler EventLog do Windows usando C#.NET
Autor: Maurício Júnior acesse

Resources e Internacionalização usando Visual Studio.NET 2005 (Parte IV)
Autor: Maurício Júnior acesse

Criando Help com Visual Studio.NET
Autor: Maurício Júnior acesse

Dados via Post no VS 2005
Autor: Maurício Júnior acesse

Trabalhando com Session
Autor: Maurício Júnior acesse

Ebook Grátis Microsoft
Autor: Maurício Júnior acesse

Criando arquivo usando Visual Studio.NET 2005
Autor: Maurício Júnior acesse

Exemplo usando try e catch
Autor: Maurício Júnior acesse

Criando XML a partir do DataSet Tipado com Visual Studio.NET 2005 – Parte I
Autor: Maurício Júnior acesse

101 Exemplos de Linq
Autor: Maurício Júnior acesse

Vídeo - Themes/Skin/Stylo
Autor: Maurício Júnior acesse

Coalescing Operador C# ?? null
Autor: Maurício Júnior acesse

Empregos Publicados ASPNETi.COM

Programador COBOL 400 acesse
Tester Sênior acesse
Analista de Suporte acesse
Financial Analyst acesse
Técnico de Suporte Windows Júnior acesse
DBA SQL Server acesse
Desenvolvedor .NET acesse
Consultor VB acesse
Consultor Oracle acesse
Gerente de Projetos acesse