Tag cloud

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Pagina: 1 2 volgende »

Roel -

Roel -

09/01/2012 19:06:57
Quote Anchor link
Hoi hoi,

Ik ben voor de website van m'n vriendin bezig met een tag cloud. Per artikel worden er tags toegevoegd, die dan allemaal in de database komen te staan. Als ik ze op in de tag cloud wil ophalen, dan groepeer ik alle tags en staat daarachter het aantal keer dat die tag voorkomt.

Dit doe ik met de volgende query:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
SELECT tag, COUNT(tag) AS aantal
FROM tags
GROUP BY tag
ORDER BY tag ASC


Dit is m'n output:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
tag aantal
bloem         2
bruin         4
figuurtje     1
goud         1
grijs         1
kerst         3
nagellakpennen     1
paars         4
panterprint     1
patroon     1
randje         1
rood         2
rudolf         1
strak         1
strik         1
tekenen     1
wit         8
zilver         3
zwart         4


Nu wil ik natuurlijk dat de tag met het grootste aantal (wit in dit geval) het grootst is. Ik heb link classes w1 t/m w8, waarin w8 de grootste is. Ik heb al een tijdje zitten denken hoe ik dit wil doen, en ik wil van iedere grootte ongeveer 10%. Hoe moet ik dit doen?

Ik krijg het gewoon niet voor elkaar om me voor te stellen hoe ik dit zou moeten doen.

Bedankt...
 
PHP hulp

PHP hulp

23/11/2024 14:28:56
 
Wouter J

Wouter J

09/01/2012 19:16:44
Quote Anchor link
Ik heb dit nog niet getest, maar zit gewoon even hard op met je mee te denken:
- Je telt alle aantallen bij elkaar op. (COUNT(*) AS total ofzo)
- Je berekend het aantal procent van het totaal dat de tag heeft. (met zwart is dat (100 / totaal) * 4
- 100% in 8 stukken verdelen wordt ong. 11%. Dus w1 = 11%, w2 = 22%, ..., w8 = 88%
- Je kijkt in welk gebied het procent van de tag ligt.
 
Roel -

Roel -

09/01/2012 19:58:44
Quote Anchor link
Bedankt, ik ben al een stuk verder. Alleen komt alles nu ruim boven de 100%, en dan zijn de waardes niet juist meer denk ik. Althans, dan krijg ik veel te veel van hetzelfde. Dit zijn m'n waardes op jouw manier:
bloem (10.5263157895)
bruin (21.0526315789)
figuurtjes (5.26315789474)
goud (5.26315789474)
grijs (5.26315789474)
kerst (15.7894736842)
nagellakpennen (5.26315789474)
paars (21.0526315789)
panterprint (5.26315789474)
patroon (5.26315789474)
randje (5.26315789474)
rood (10.5263157895)
rudolf (5.26315789474)
strak (5.26315789474)
strik (5.26315789474)
tekenen (5.26315789474)
wit (42.1052631579)
zilver (15.7894736842)
zwart (21.0526315789)

(op alfabetische volgorde dit keer)
 
Erwin H

Erwin H

09/01/2012 20:06:28
Quote Anchor link
Zet het maximaal aantal dat gehaald is op 100%. Probleem bij dit soort dingen is dat als je heel veel opties hebt, alle opties redelijk dicht bij de 0% komen te liggen.
Je ziet het in jouw lijst al, de hoogste zit nog maar op 42%.
Als je echter de maximale waarde (in dit geval dus 8) neemt als maximum heb je dus altijd ook de hoogste categorie ook te pakken.
 
Noppes Homeland

Noppes Homeland

09/01/2012 20:07:29
Quote Anchor link
Laat dan maar een zien hoe je tot dat resultaat bent gekomen.

Uitgaande van de waarden in je openingspost
totaal = 41
Dan krijg je voor wit: 19.51219512
 
Roel -

Roel -

09/01/2012 20:46:39
Quote Anchor link
Het klopte inderdaad niet wat ik deed, ik krijg nu voor wit hetzelfde:
bloem (4.87804878049)
bruin (9.75609756098)
figuurtjes (2.43902439024)
goud (2.43902439024)
grijs (2.43902439024)
kerst (7.31707317073)
nagellakpennen (2.43902439024)
paars (9.75609756098)
panterprint (2.43902439024)
patroon (2.43902439024)
randje (2.43902439024)
rood (4.87804878049)
rudolf (2.43902439024)
strak (2.43902439024)
strik (2.43902439024)
tekenen (2.43902439024)
wit (19.512195122)
zilver (7.31707317073)
zwart (9.75609756098)
 
Roel -

Roel -

10/01/2012 21:09:17
Quote Anchor link
Iemand toevallig enig idee? :)
 
- Jim  -

- Jim -

10/01/2012 21:18:25
Quote Anchor link
Begin eens met een loop door je resultaten en maak de tekst-grootte in pixels het percentage (afgerond).
 
Roel -

Roel -

10/01/2012 21:43:06
Quote Anchor link
Lijkt me niet verstandig, dan komen er woorden van twee pixels.
 
- Jim  -

- Jim -

10/01/2012 21:45:59
Quote Anchor link
Maak je een controle die alles onder de 6px overslaat.
 
Elwin - Fratsloos

Elwin - Fratsloos

10/01/2012 22:51:31
Quote Anchor link
Hierbij de werking van de tagcloud die ik heb gemaakt. Helaas heb ik op dit moment geen voorbeeld online...

Ik heb het volgende als CSS:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
div.tagcloud {
    /* border, background, etc van de div */
}

div.tagcloud a.tag1 {
    font-size: 8px;
}

div.tagcloud a.tag2 {
    font-size: 10px;
}

/*
    Dit gaat door tot tag5, waarbij font-size steeds groter word
    en er ook wat kleuren wijzigen.
*/


Voor de opslag van tags gebruik ik een tabel met tags (tabel: tag, kolommen: tag_id, tag_tag, tag_url) en een tabel met het gebruik (tabel: tag_gebruik, kolommen: tge_id, tge_tag_id, tge_datumtijd), deze wordt dus gevuld als een bezoeker op een tag bij een pagina of in de tagcloud klikt.

Als ik mijn tagcloud ga uitlezen gebruik ik een query om de 50 meest gebruikte tags van de afgelopen twee maanden op te halen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
$sql
= "SELECT
        COUNT(tge_tag_id) as tge_aantal,
        tag_tag,
        tag_url
    FROM
        tag_gebruik,
        tag
    WHERE
        tge_tag_id = tag_id
    AND
        tge_datumtijd > DATE_SUB(CURDATE(), INTERVAL 2 MONTH)
    GROUP BY
        tge_tag_id
    ORDER BY
        COUNT(tge_tag_id) DESC
    LIMIT
        0,50"
;
?>


Na het uitvoeren van die query maak ik een lege array aan ($aTags) en de twee variabelen $laagste (waarde: null) en $hoogste (waarde: 0). Waarom is $laagste null, dat komt omdat ik anders nooit de werkelijk laagste (minst gebruikte tag) kan achterhalen, want het kan nooit lager zijn dan 0, zie ook de volgende loop.

Vervolgens loop ik door de resultaten van de query:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php
while($row = mysql_fetch_assoc($res)) {
    // Laagste bepalen
    if($laagste == NULL) $laagste = $row['tge_aantal'];
    else if($laagste > $row['tge_aantal']) $laagste = $row['tge_aantal'];
        
    // Hoogste bepalen
    if($row['tge_aantal'] > $hoogste) $hoogste = $row['tge_aantal'];
    
    // Toevoegen aan de array
    $aTags[] = array('tag_tag' => $row['tag_tag'],'tag_url' => $row['tag_url'], 'tge_aantal' => $row['tge_aantal']);
}

?>


Nu heb ik dus in $laagste het aantal van de tag die het minst gebruikt is en in $hoogste die het meest gebruikt is. De array $aTag is nu gevuld met die 50 tags, en de data die nodig is om hem te laten zien/werken.

Hierna gooi ik de array $aTag overhoop, zodat de tagcloud er 'nooit' hetzelfde uitziet. Dit doe ik met shuffle.

Dan moet ik uitrekenen met welke stappen de tags een andere CSS-class krijgen. Dit bepaal ik op de volgende manier:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
$aStap
= array(); // Lege array om de stappen in te bewaren
$maxStappen = 5; // Er zijn dus 5 CSS-classes

$stappen = floor(($hoogste-$laagste) / $maxStappen); // Uitrekenen hoeveel er tussen stappen zit
for($i=1;$i<=$maxStappen;$i++) $aStap[$i] = $i*$stappen+$laagste; // En de array vullen met het begin van de stap
?>


Dus, als $hoogste 86 is en $laagste 12, dan is $stappen 14. En $aStap is dan het volgende:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
array(
    [1] => 26,
    [2] => 40,
    [3] => 54,
    [4] => 68,
    [5] => 82
)


Dan is het tijd om $aTag en $aStap te gaan matchen zodat de tags de juiste class krijgen:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?php
foreach($aTags as $tag) {
    $style = 'tag'.$maxStappen; // standaard de grootste
    for($i=1;$i<=$maxStappen;$i++) {
        if($tag['tge_aantal'] <= $aStap[$i]) {
            $style = 'tag'.$i;
            break;
        }
    }

    echo '<a href="/tag/'.$tag['tag_url'].'/" class="'.$style.'">'.$tag['tag_tag'].'</a> ';
}

?>


Nu ik er zo naar zit te kijken heb ik het idee dat het nog wel iets simpeler kan, maar ik hoop dat ik je zo op een idee gebracht heb.

Edit:
Bovenstaande komt uit een nieuw project, maar ik bedenk met net dat die is gebaseerd op de tagcloud van http://pointtopoint.nl/ (waar de CSS van de cloud niet echt optimaal is).
Gewijzigd op 10/01/2012 22:54:54 door Elwin - Fratsloos
 
Roel -

Roel -

11/01/2012 17:59:40
Quote Anchor link
Knap gemaakt. Waarom heb je overigens twee tabellen met tags?
 
Elwin - Fratsloos

Elwin - Fratsloos

11/01/2012 19:03:53
Quote Anchor link
Ik heb maar 1 tabel met tags. De andere bevat alleen de gegevens waneer de tags gebruikt zijn. Werkt met een 1-op-n relatie. De andere bevat alleen de inhoud; dus de tags. En die heeft dan weer meerdere 1-op-n relaties naar pagina_tag, actueel_tag.

Eerst gebruikte ik altijd gewoon een TEXT met daarin de tags komma-gescheiden, maar dat werkte niet naar behoren. Toen ben ik het gaan scheiden en kwam ik uiteindelijk op deze methode.
 
Roel -

Roel -

11/01/2012 20:00:58
Quote Anchor link
Heb je misschien een simpeler voorbeeld? Je hebt in jouw code een heel systeem met datums en alles erop en eraan, ik hoef alleen maar een simpele tag cloud. :-)
 
Elwin - Fratsloos

Elwin - Fratsloos

11/01/2012 20:36:06
Quote Anchor link
In principe kan je dat er gewoon uithalen. Ik haal het op met datums, omdat ik alleen het actieve gebruik van tags wil hebben (de tags waarop de laatste 2 maanden is geklikt).

Het belangrijkste is de laatste drie PHP-blokken (dus niet dat array-blok). Daarin leg ik uit hoe ik bepaal welke CSS-class een tag moet hebben.

Maar ik zat er al aan te denken om hier een mini-tutorial over te schrijven, heb ik ook weer wat content voor mijn eigen site, die ik weer wat probeer up-te-daten. :)
Dat zal denk ik in het weekend worden.
 
Roel -

Roel -

11/01/2012 21:09:59
Quote Anchor link
Dan wacht ik rustig af, dit gaat mij namelijk nog even boven m'n pet. Toch bedankt!
 
Elwin - Fratsloos

Elwin - Fratsloos

11/01/2012 23:09:43
Quote Anchor link
Kan je mij een dump sturen van je tabel, incl. de CREATE syntax? Dan kan ik kijken of ik die van Jou en mij kan samenvoegen.

Mag wat mij betreft als tekst in dit topic, per PM of als download ergens.
 
Roel -

Roel -

12/01/2012 17:55:41
Quote Anchor link
Verstuurd als PM!
 
Arjan -

Arjan -

12/01/2012 19:07:45
Quote Anchor link
Het lijkt mij beter om het zo te doen:

Bepaal het minimaal en maximaal aantal. Dus in jouw voorbeeld 1 en 8.

Bepaal vervolgens de minimale lettergrootte en maximale lettergrootte. Bijvoorbeeld 10 en 30 pixels.

Dus:
$aantal_bepalen = 5; // Voor 5 keer wil je de lettergrootte bepalen

$aantal_min = 1;
$aantal_max = 8;

$font_min = 10;
$font_max = 30;

Formule:
$lettergrootte = $font_min + round((($font_max - $font_min) / ($aantal_max - $aantal_min)) * ($aantal_bepalen - $aantal_min));

Op deze manier heb je altijd een minimale en maximale grootte en daarbinnen variëert de lettergrootte.

Wat je dan kan doen is het resultaat van je query in een array zetten met de tagnaam als key (aangezien deze altijd uniek is) en het aantal als value, dus:

$array = array('wit' => 20, 'blauw' => '10');

Vervolgens is met min() en max() simpel het maximale en minimale aantal uit de array te halen:

$min = min($array);
$max = max($array);
Gewijzigd op 12/01/2012 19:21:19 door Arjan -
 
Roel -

Roel -

12/01/2012 19:31:25
Quote Anchor link
Met jouw voorbeeld zijn alle woorden even groot, 21px om precies te zijn.
Wat overigens ook logisch is, want de formule is altijd hetzelfde in m'n foreach.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php
$tags
= array();
                        
                        $aantal_bepalen = 5; // Voor 5 keer wil je de lettergrootte bepalen

                        $aantal_min = 1;
                        $aantal_max = 8;

                        $font_min = 10;
                        $font_max = 30;
                        while ($tag = mysql_fetch_assoc($sql))
                        {

                                $tags[$tag['tag']] = $tag['aantal'];
                        }

                        
                        $min = min($tags);
                        $max = max($tags);
                        
                        foreach ($tags as $tag => $aantal)
                        {

                                $lettergrootte = $font_min + round((($font_max - $font_min) / ($aantal_max - $aantal_min)) * ($aantal_bepalen - 1));
                                echo '<a href="#" style="font-size: '.$lettergrootte.'px">'.$tag.'</a> ';
                        }

?>
 
Arjan -

Arjan -

12/01/2012 19:38:25
Quote Anchor link
$aantal_bepalen is het aantal dat het woord voorkomt. Dus dat gaat zo niet werken. Hier een werkend voorbeeld:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
<?php

// mysql query hier

$tags = array();

while ($tag = mysql_fetch_assoc($sql))
{

     $tags[$tag['tag']] = $tag['aantal'];
}


if(is_array($tags) AND count($tags) > 0) {

$aantal_min = min($tags);
$aantal_max = max($tags);

$font_min = 10;
$font_max = 30;

foreach($tags AS $key => $value) {

    $lettergrootte = $font_min + round((($font_max - $font_min) / ($aantal_max - $aantal_min)) * ($value - $aantal_min));;

    echo '<span style="font-size: '.$lettergrootte.'px;"><a href="/zoeken?tag='.urlencode($key).'">'.htmlspecialchars($key).'</a></span> ';

}


}

?>


Zoals je ziet raad ik je aan om geen classes te gebruiken maar gewoon 'hardcoded' in de html de lettergrootte te bepalen. Hierdoor heb je altijd een mooie tagcloud met een minimale en maximale lettergrootte.
Gewijzigd op 12/01/2012 19:46:59 door Arjan -
 

Pagina: 1 2 volgende »



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.