Créer un nuage de mots clés

Le nuage de mots clés (tag cloud en anglais) est une façon de représenter visuellement les mots clés utilisés dans un site.
En général, les mots clés sont affichés avec un taille proportionnelle au nombre de fois où le mot clé est utilisé, les mots clés utilisés le plus souvent sont alors affichés en plus grand que les mots clés moins utilisés.

Cet article va vous permettre de créer un nuage de mots similaire à celui utilisé sur ce site.

Cet article ne s'applique qu'à la génération du nuage de mots clés, nous ne verrons donc pas ici la partie administration qui permet de lier un mot clé à un article.

La base de données

Pour réaliser notre nuage, nous aurons besoin d'au moins 3 tables :

  • une table articles qui continedra les articles
  • une table tags qui continedra les mots clés
  • une table intermédiaire articles_tags qui lie les tags aux article

La table articles :

Vous y mettrez les champs que vous voulez, seul contrainte il faudra impérativement qu'elle ai un champs id.

La table tags :

Cette table contient 3 champs : id, tag (le mot clé) et url (le mot clé épuré de caractères spéciaux).
Un mot clé ne sera présent qu'un seule fois dans cette table, même si utilisé pour plusieurs articles.

La table articles_tags :

Cette table contiendra 2 champs : article_id et tag_id.

Le fonctionnement

On commence par définir quelques paramètres :

// Nombre d'utilisation minimum pour être listé
$min_count = 1;

// Font-size (en %) du tag le moins utilisé
$min_size = 100;

// Font-size (en %) du tag le plus utilisé
$max_size = 200;

// Contiendra le nombre d'utilisation minimum d'un tag (on l'initialise en mettant un grand nombre)
$min = 100000;

// Contiendra le nombre d'utilisation maximum d'un tag
$max = 0;

On récupère ensuite tous les mots clés ainsi que le nombre de fois où ils sont utilisé :

$sql = "
SELECT DISTINCT t.tag, t.url, COUNT(at.tag_id) AS counter
FROM tags t
LEFT JOIN articles_tags at 
    ON at.tag_id = t.id
    GROUP BY at.tag_id
ORDER BY t.tag
";
$result = mysql_query($sql);

On met les tags dans un tableau et on en profite pour trouver le nombre d'utilisation minimum et maximum :

while ($row = mysql_fetch_assoc($result)) {
    if($row['counter'] >= $min_count) {
        $tags[$row['url']] = $row;
        if($row['counter'] < $min) $min = $row['counter'];
        if($row['counter'] > $max) $max = $row['counter'];
    }
}

Ensuite, il faut connaitre la différence de taille pour une utilisation d'un mot clé (j'entends par la différence de taille entre un tag utilisé une fois et un autre utilisé deux fois) :

// Espacement entre Min & Max
$spread = $max-$min;
if ($spread == 0) $spread = 1;    // Evite la division par zéro

// Espacement pour 1
$step = ($max_size - $min_size)/$spread;

Ceci fait, nous pouvons afficher notre nuage de mot clés en affichant les mots clés avec une taille proportionnelle à leur nombre d'utilisation :

// Boucle sur les tags
$out = '';
foreach ($tags as $tag) {
    $size = $min_size + (($tag['counter']-$min) * $step);
    $size = round($size);
    $style = 'style="font-size:'.$size.'%;"';

    $out .= '<a href="'.$tag['url'].'" '.$style.'>';
    $out .= $tag['tag'];
    $out .= '</a>' . "n";
}

// Affichage du nuage de tags
echo $out;

Le script complet

Pour vous faciliter le copier-coller, vous trouverez ci-dessous le script complet et commenté :

// Divers Paramètres

// Nombre d'utilisation minimum pour être listé
$min_count = 1;

// Font-size (en %) du tag le moins utilisé
$min_size = 100;

// Font-size (en %) du tag le plus utilisé
$max_size = 200;

// Contiendra le nombre d'utilisation minimum d'un tag (on l'initialise en mettant un grand nombre)
$min = 100000;

// Contiendra le nombre d'utilisation maximum d'un tag
$max = 0;



// Requête SQL
$sql = "
SELECT DISTINCT t.tag, t.url, COUNT(at.tag_id) AS counter
FROM tags t
LEFT JOIN articles_tags at 
    ON at.tag_id = t.id
    GROUP BY at.tag_id
ORDER BY t.tag
";
$result = mysql_query($sql);



// Mise en tableau des tags et recherche de min et max
while ($row = mysql_fetch_assoc($result)) {
    if($row['counter'] >= $min_count) {
        $tags[$row['url']] = $row;
        if($row['counter'] < $min) $min = $row['counter'];
        if($row['counter'] > $max) $max = $row['counter'];
    }
}



// Calcul de l'espacement (taille)

// Espacement entre Min & Max
$spread = $max-$min;
if ($spread == 0) $spread = 1;    // Evite la division par zéro

// Espacement pour 1
$step = ($max_size - $min_size)/$spread;



// Affichage

// Boucle sur les tags
$out = '';
foreach ($tags as $tag) {
    $size = $min_size + (($tag['counter']-$min) * $step);
    $size = round($size);
    $style = 'style="font-size:'.$size.'%;"';

    $out .= '<a href="'.$tag['url'].'" '.$style.'>';
    $out .= $tag['tag'];
    $out .= '</a>' . "n";
}

// Affichage du nuage de tags
echo $out;
comments powered by Disqus