Chmura tagów Tagcloud w PHP

Ostatnio byłem zobligowany napisać nową klasę tagów do mojego projektu Sypacz.pl, która de facto zachowała stare API, lecz rozszerzyła swoje funkcjonalności, więc w kodzie projektu nie było wielu zmian. Wena spowodowała to, że zacząłem pisać kod od zera.

Cały problem polega na tym, aby napisać na tyle elastyczną klasę tagów, która przyjmie nam zestaw danych, a następnie zaprezentować ją w formie chmury, czym zaopiekuje się arkusz stylów CSS:

Nazwa tagu => Ilość występowań

Parę osób mnie pytało, jak wyciągnąć takie informacje z bazy danych:

SELECT tag_name, COUNT(tag_name) AS tag_times FROM tags GROUP BY tag_name ORDER BY tag_times LIMIT 1, 50

Uwaga! Zaprezentowane wyżej zapytanie jest przykładowe, nieoptymalne, a jedynie służące do testowania chmur tagów na małych, testowych bazach danych. Optymalna implementacja struktur tagów w bazie danych dla większych projektów została opisana we wpisie MySQL tags.

Wykorzystałem obiekt Vframe_Attribute, aby ustandaryzować komponent względem pozostałych w moim frameworku. Jeżeli ktoś nie chce używać obiektu Attribute, może w prosty sposób przekształcić klasę tagów, otrzymując ten sam efekt, deklarując tylko atrybut chroniony protected $_aAttributes = array();. Temat chmury tagów wydaje mi się na tyle trywialny, że nie ma się co nad nim zbyt wiele rozwodzić, zamieszczę tylko klasę i opiszę krótko w przykładach jej możliwości.

  • Vframe_Tagcloud – klasa tagów,
  • Vframe_Attribute – pomocnicza klasa atrybutów dla stosu $_aAttributes, dziedziczenie można usunąć i zadeklarować atrybut samemu.

Aby stworzyć nowy obiekt tagów, po prostu wywołujemy konstruktor:

$oCloud = new Vframe_Tagcloud();

Konstruktor nie przyjmuje żadnych argumentów, wiec możemy od razu przejść do podawania obiektowi tagów. W tym miejscu warto nadmienić, że każdy znak jest rozróżniany (ze względów elastycznych), więc jeżeli chcesz, aby Nazwatagu oraz nazwatagu były rozpoznawane jako jeden klucz, wypadałoby użyć funkcji strtolower lub mb_strtolower (dla Multibyte Strings):

foreach($aDataTags as $iKey => $aRow)
  $oCloud->add(strtolower($aRow['tag_name']), $aRow['tag_times']);

Najistotniejszą częścią klasy jest sposób renderowania chmury, które może działać w dwóch trybach:

  • Tryb prosty zwraca nam nazwę tagu oraz jego wagę po przeliczeniu w formie liczby.
  • Tryb zaawansowany zwraca nam nazwę tagu oraz tablicę z danymi:
    • level – waga tagu po przeliczeniu,
    • count – ilość występowań, taka jaką podaliśmy,
    • count_percentage – informacja, w jakiej procentowej części ilości występowań znajduje się tag, przyjmując za 100% tag, który występuje najczęściej.

Aby w prosty sposób wyrenderować chmurę tagów, używamy poniższego przykładu:

$aDataTagsRender = $oCloud->render();

Najczęściej używa się trybu prostego. Oba tryby są dalej rozbudowane, bowiem mamy możliwość zdefiniowania zakresu i dokładności wag tagów. Domyślnie wagi tagów zawierają się pomiędzy 1, a 10. Możemy na przykład przyjąć, że najmniejszą wagą jest liczba 3, największą 5, a precyzja wag tagów to 2 miejsca po przecinku:

$aDataTagsRender = $oCloud->render(3, 5, 2);

W celu uniknięcia precyzji po przecinku (chcemy otrzymać liczby całkowite), ustawimy precyzję na 0.

Aby wywołać tryb zaawansowany, musimy podać 4 argument dla metody render() i ustawić go na true.

$aDataTagsRender = $oCloud->render(1, 5, 0, true);

Warto w tym miejscu nadmienić, że tagi mogą nie być posortowane alfabetycznie (co ma miejsce podczas tworzenia chmury tagów). Wystarczy wywołać funkcję ksort (key sort).

Finalny przykład używania klasy tagów, celem wywołania klas CSS level_X, gdzie X to liczba całkowita z zakresu od 1 do 10, resztę robi CSS (kolorowanie, nakładanie rozmiaru):

if(count($aDataTags)) {
 
$oCloud = new Vframe_Tagcloud();
 
foreach($aDataTags as $iKey => $aRow)
  $oCloud->add(strtolower($aRow['tag_name']), $aRow['tag_times']);
 
$aDataTags = $oCloud->render(1, 10, 0);
ksort($aDataTags);
 
foreach($aDataTags as $sTag => $iTag)
  echo '<a class="level_' . $iTag . '" href="' . $this-&gt;route('tag', $sTag) . '">' . $sTag . '</a>';
 
}


3 Responses to “Chmura tagów Tagcloud w PHP”

  1. Userek says:

    Dobra robota z sypaczem. Zastanawia mnie jedno skąd bierzecie tak fajna grafikę i ile to kosztuje?

    Pozdrawiam ;)

  2. klocek says:

    Niestety na software.com.pl nie można dodać komentarza, zatem piszę tutaj:

    Przed publikacją może warto przeczytać artykuł (tutaj lepiej kod wygląda). Kod jest źle przetworzony i wyświetlany.
    Dodatkowo po co robić CSS stopniowanego. Nie lepiej zrobić zwiększanie procentowe w span?

  3. Athlan says:

    @kolcek: Lepiej, nie lepiej. Implementacja widoku to rzecz wtórna, podany jest przykład. Można nawet pobawić się w nagłówki n-tego stopnia. Sposobów na zastosowanie klasy jest wiele, natomiast tu podjęta została problematyka jej możliwości i działania.

Leave a Reply