Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Implementace tag cloudu

18.53 - 28. února 2009 | Webdesign

Zajímavé je, jak se problematice celkem rozšířené vlastnosti webových aplikací v éře Webu 2.0, kterou tag cloud bezesporu je, věnuje málo prostoru. Protože pracuju na jednom sociálním webu a k implementaci tag cloudu jsem se také dostal, tak se na něj pojďme podívat.

Top-down design

Začneme implementací na výstupu. To je to, co vidí uživatel. Porozhlédněme se nejprve po nějakém vhodném mikroformátu. Na snadě je rel-tag, který slouží k označování odkazů tagu. Když budeme hledat dál, jistě narazíme na hTagCloud. Tento mikroformát je sice ve stádiu návrhu, ale dá se říct, že je použitelný v praxi. Jak vypadá?

hTagCloud

Cloud je vyznačen elementem s třídou hTagCloud. Tento element by měl obsahovat seznam tagů. Seznam můžeme označit třídou, zda jde je seřazen podle abecedy (class="alphabetical") nebo podle popularity (class="popularity"). Popularitu jednotlivých tagů označíme posléze třídou. Základní úroveň popularity vyznačuje třída popular. Oblíbenější tagy mají třídu v-popular. Nejoblíbenější tagy pak třídou vvvv-popular. Můžeme takto tedy odlišit pět úrovní popularity.

Ukázka mikroformátu přímo z wiki autorů:

<div class="hTagCloud">
  <ul class="popularity">
    <li class="vvvv-popular"><a href="/tags/Web+Standards+Group">Web Standards Group</a></li>
    <li class="vvv-popular"><a href="/tags/accessibility">accessibility</a></li>
    <li class="popular"><a href="/tags/beta+tester">beta tester</a></li>
    <li class="vvv-popular"><a href="/tags/css">css</a></li>
    <li class="v-popular"><a href="/tags/ex-coder">ex-coder</a></li>
    <li class="vv-popular"><a href="/tags/usability">usability</a></li>
    <li class="vvvv-popular"><a href="/tags/wsg">wsg</a></li>
  </ul>
</div>

To bychom měli HTML kód, teď ještě nastylovat, aby z toho opravdu cloud byl:

.hTagCloud {text-align:center}
.hTagCloud ul{list-style-type:none;padding:0;margin:0}
.hTagCloud li{display:inline;font:.6875em sans-serif;margin:0;padding:0}
.hTagCloud .v-popular{font-size:1.273em}
.hTagCloud .vv-popular{font-size:1.818em}
.hTagCloud .vvv-popular{font-size:2.545em}
.hTagCloud .vvvv-popular{font-size:3em}

Máme tedy připraveno to, co uvidí uživatelé. Teď ještě potřebujeme logiku, která rozhodne, jak populární tagy vlastně jsou.

Implementace na serveru

Nejprve si vytvoříme třídu reprezentující tag. Ta bude obsahovat text tagu a jeho četnost.

public class Tag {
  public string Text { get; set; }
  public int Count { get; set; }
}

Teď budeme potřebovat vypočítat, jak populární vlastně konkrétní tag je. Tady se dostáváme k poměrně zajímavému problému. Nejprve potřebujeme spočítat váhu tagu v cloudu a tu pak promítnout na pětistupňové škále. Praxí je ověřeno, že hezky cloud vypadá, když se použije logaritmická distribuční funkce. Proto si vytvoříme jednoduchý helper, který nám bude váhu tagu vypočítávat a rovnou nám vrátí CSS třídu vhodnou pro hTagCloud.

using System;
using System.Linq;
using System.Text;

public static class TagCloudExtensions {
  private const int MostPopular = 5;
  private const int MorePopular = 2;
  private const int Popular = 1;

  public static string GetCssClass(this IEnumerable<Tag> tags, Tag tag) {
    int minOccurs = tags.Min(t => t.Count);
    int maxOccurs = tags.Max(t => t.Count);

    int distribution = CountDistribution(tag.Count, minOccurs, maxOccurs);

    return GetCssClass(distribution).ToString();
  }

  private static StringBuilder GetCssClass(int distribution) {
    if (distribution < MorePopular) {
      return new StringBuilder("popular");
    }
    if (distribution == MorePopular) {
      return GetCssClass(--distribution).Insert(0, "v-");
    }
    return GetCssClass(--distribution).Insert(0, "v");
  }

  private static int CountDistribution(int currentOccurences, int minOccurs, int maxOccurs) {
    if (minOccurs < Popular) {
      throw new ArgumentOutOfRangeException("There must be atleast one occurence.");
    }

    double weight = (Math.Log(currentOccurences) - Math.Log(minOccurs))
      / (Math.Log(maxOccurs) - Math.Log(minOccurs));
    int distribution = Popular + (int)Math.Round(weight * (MostPopular - Popular));

    return distribution;
  }
}

Tento helper rozšiřuje kolekci tagů o metodu o metodu, která vrátí CSS třídu pro konkrétní tag. A to je vše. Happy tagging!

Autor: Aleš Roubíček | Přidej komentář | Delicious | Digg | FriendFeed | Facebook | Linkuj! | Jagg

Komentáře RSS

  1.  

    eMkousák nesmrtelný

    22.27 - 28. února 2009 | #

    Krása! Ještě bych ale zapracoval na tom coding style – počáteční závorka na stejném řádku mi k srdci nikdy nepřirostla.

  2.  

    karel

    22.50 - 28. února 2009 | #

    počáteční závorka na stejném řádku mi k srdci nikdy nepřirostla.

    mě zase naopak, takže v coding style nevidím žádný problém :-)

  3.  

    ja

    22.52 - 28. února 2009 | #

    Ano ano super, jen může mi někdo probůh vysvětlit k čemu jsou mikroformáty tagů dobré?

  4.  

    Vojtech Kopal

    22.59 - 28. února 2009 | #

    Přidám své řešení tag cloudu. :)

    http://vojtechko­pal.cz/labs/clou­dy/

  5.  

    aprilchild

    00.00 - 1. března 2009 | #

    no nevim, matematik nejsem, ale co kdyz budu mit v polevce jen jeden tag? Nebo treba 2 se stejnym count? :)

  6.  

    Aleš Roubíček

    07.19 - 1. března 2009 | #

    [1] eMkousák nesmrtelný: Víš jak by ten spot byl dlouhej, kdybych psal každou otvírací závorku na novým? ;)

    [5] aprilchild: Taky se mi to dělení nulou nelíbí, ale taková situace IMO nastat nemůže :D

  7.  

    Filosof

    10.20 - 1. března 2009 | #

    Tag cloud jsme onehdá rozmlouvali jednomu zákazníkovi. Ono je to hezké, ale funguje to jen na flickru..

  8.  

    Daniel Steigerwald

    07.07 - 2. března 2009 | #

    Animovaný AJAXový tagCloud – http://daniel­.steigerwald.cz/…tag­cloud.htm

  9.  

    Honza Marek

    20.03 - 3. března 2009 | #

    Vyrobil jsem tag cloud pro nette inspirovaný tímto článkem.

  10.  

    Aleš Roubíček

    07.50 - 4. března 2009 | #

    [9] Honza Marek: Cool. Taky z toho asi udělám control :)

Místo pro tvůj názor

Povinné je jméno a komentář, z e-mailu se rozpoznají Gravatary.
Komentář je formátován pomocí Texy! syntaxu.
Například: **tučný text**, *kurzíva*, "text odkazu":adresa.
Internetové adresy jsou převáděny na odkazy.
Na komentáře se můžete odkazovat pomocí [číslo komentáře].

Nový komentář