Les nuages de tags de Dotclear sont bien pratiques pour mettre en valeur les thèmes les plus souvent abordés sur votre blog. Toutefois, la taille des tags étant directement proportionnelle à leur fréquence, si un des thèmes est abordé beaucoup plus souvent que les autres, il va en quelque sorte les « étouffer », empêchant de faire la distinction entre les tags de fréquence moyenne. Voici donc un petit hack pour remédier le problème en jouant sur la fonction de répartition…
Le principe est tout simple : Dotclear attribue à chaque tag un « poids » compris entre 0 et 10 en fonction du rapport entre la fréquence de ce tag et celle du tag le plus fréquent. Nous allons donc modifier la formule de calcul du poids de chaque tag pour qu’elle augmente le poids des tags les plus rares et diminue le poids des tags les plus fréquents en utilisant une fonction logarithmique.
Pour ce faire, il faut modifier le fichier plugins/metadata/class.dc.meta.php. À la ligne 248, vous devriez trouver la fonction de calcul du poids :
$percent = ((integer) $rs->count) * 100 / $max[$rs->meta_type];
Pour passer à une fonction logarithmique pour les tags (et uniquement les tags), il faut remplacer cette ligne par :
$count = (integer) $rs->count; if ($rs->meta_type == "tag") { $percent = log($count) * 100 / log($max[$rs->meta_type]); } else { $percent = ($count) * 100 / $max[$rs->meta_type]; }
Vous pouvez bien entendu utiliser n’importe quelle autre fonction pour effectuer ce calcul, la seule règle à respecter étant qu’elle doit être applique à la fois à $rs->count et $max[$rs->meta_type]. Par exemple, si tous vos tags ont des fréquences d’apparition élevées, vous pouvez utiliser une fonction exponentielle, pour amplifier les écarts au lieu de les resserrer.
Il peut également être bon de modifier l’algorithme pour qu’il affecte systématiquement un poids de 0 au tag de fréquence la plus faible. En effet, si vos tags sont par exemple tous compris entre 90 et 100 occurrences, ils auront tous un poids de 9 ou de 10. Pour étaler ces poids de 0 à 10, nous allons soustraire la fréquence minimale à chaque fréquence lors du calcul du poids.
Toujours dans le même fichier, il faut tout d’abord ajouter une variable stockant la fréquence minimale. Pour celà, il faut modifier le code déterminant la fréquence maximale. De la ligne 230 à la ligne 241, vous devriez trouver :
$max = array(); while ($rs->fetch()) { $type = $rs->meta_type; if (!isset($max[$type])) { $max[$type] = $rs->count; } else { if ($rs->count > $max[$type]) { $max[$type] = $rs->count; } } }
Remplacez ce code par :
$max = array(); $min = array(); while ($rs->fetch()) { $type = $rs->meta_type; if (!isset($max[$type])) { $max[$type] = $rs->count; } else { if ($rs->count > $max[$type]) { $max[$type] = $rs->count; } } if (!isset($min[$type])) { $min[$type] = $rs->count; } else { if ($rs->count < $min[$type]) { $min[$type] = $rs->count; } } }
Ensuite, il faut modifier la fonction de calcul en la remplaçant par :
$c = $rs->count - $min[$rs->meta_type]; $m =$max[$rs->meta_type] - $min[$rs->meta_type]; $percent = $c * 100 / $m;
Enfin, selon la façon dont sont réparties les fréquences de vos tags, il peut être intéressant de définir un intervalle de fréquences en dehors duquel le poids est fixé à 0 (fréquence inférieure à la borne basse de l’intervalle) ou 10 (fréquence supérieure à la borne haute de l’intervalle).
Ceci peut être fait en bornant la fréquence avant d’appliquer fonction de calcul (dans cet exemple, les bornes sont 20 et 60) :
$borneInf = 20; $borneSup = 60; $c = min($borneSup-$borneInf , max(1, $rs->count - $borneInf)); $m = min($borneSup-$borneInf , $max[$rs->meta_type]-$borneInf); $percent = $c * 100 / $m;
Bien entendu, il est possible de combiner toutes ces méthodes, ce qui donnera quelque choses comme ça :
$borneInf = max(20, $min[$rs->meta_type]); $borneSup = max(min(60, $max[$rs->meta_type]), $borneInf); $c = min($borneSup-$borneInf , max(1, $rs->count - $borneInf)); $m = min($borneSup-$borneInf , $max[$rs->meta_type]-$borneInf); $percent = log($c) * 100 / log($m);
Bonjour,
j’ai essayé de suivre la première procédure indiquée, et j’ai obtenu un message d’erreur.
Il me semble que c’est en raison d’une erreur dans ton deuxième encadré qui commence par
if ($rs->meta_type == « tag ») {
il y a deux signes = qui se suivent. Je n’y connais rien, mais quand j’ai supprimé le deuxième « = », le message d’erreur a disparu.
Cela dit, mon nuage de tag n’est toujours pas suffisamment rééquilibré (j’ai en effet un tag très présent…)
Comment renforcer le rééquilibrage ? (je ne comprends pas vraiment la fonction utilisée…)
Merci d’avance et bonne continuation
Claire Zerbinette
Le == est correct, il s’agit de l’opérateur de comparaison (pour tester si la variable $rs->meta_type est égale à « tag »).
L’erreur est en fait une ligne manquante avant le if : $count = (integer) $rs->count;
On peut aussi se passer de cette ligne, en remplacant « $count » par « (integer) $rs->count » dans le reste du code.
Merci de ta réponse
Claire