J'ai déjà déjà parlé dans ces colonnes de Google Chart API qui permet de créer des graphiques simples, puissants et personnalisés avec une simple URL.
Plus récemment, j'ai donné mon opinion pour faire des statistiques faciles avec MySQL et afficher le résultat sous forme de texte. Cette fois, nous allons donc voir comment afficher le résultat sous forme de graphiques !

Exemple de graphique générés

Encore une fois, nous allons tenter de réaliser une solution élégante et polyvalente.
Nous allons donc développer une fonction qui prendra deux paramètres :

  • Le premier sera la requête SQL à exécuter. Elle renverra deux champs, auxquels nous donnerons les alias Abscisse et Ordonnee, et qui représenteront les données à afficher.
  • Le second sera un tableau contenant les paramètres à utiliser pour l'affichage du graphique : son type bien entendu (camembert, ligne, histogramme, diagramme de Venn,...), et toutes informations utiles. Afin de simplifier la fonction, le tableau sera pré-rempli avec certaines valeurs par défaut (voir section suivante).

Les paramètres

Je vois déjà des sourcils qui se lèvent quant à la dernière phrase, je vais donc l'éclaircir tout de suite.
PHP nous laisse utiliser des arguments facultatifs : si ils ne sont pas spécifiés lors de l'appel de la fonction, ils sont remplacés par leur valeur par défaut. Malheureusement, ici cela ne nous aide pas...
Nous allons donc construire un tableau qui contiendra les valeurs "standards" pour un graphique "de base" :

$Default=array(
'cht'=>'lc',
'chtt'=>'Statistiques',
'chs'=>'750x200',
'chco'=>'88AAD6',
);

L'astuce va consister à fusionner ce tableau avec le tableau fourni, la priorité de conservation allant bien entendu au tableau spécifié lors de l'appel (autrement dit, si les deux tableaux ont une clé "cht", c'est la valeur du second tableau qui sera retenue). Ceci est réalisable très simplement avec array_merge ; nous avons donc dès maintenant la base complète de notre fonction.

function GraphIt($SQL,$Settings)
{
	//Explication de la ligne suivante dans la section suivante
	$Encodage=str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
	//Valeurs par défaut
	$Default=array(
	'cht'=>'lc',
	'chtt'=>'Statistiques',
	'chs'=>'750x200',
	'chco'=>'88AAD6',
	);
	//Combiner les valeurs demandées avec les valeurs par défaut
	$Settings=array_merge($Default,$Settings);


	$Ds=mysql_query($SQL) or die(mysql_error());//Récupérer les données

L'enregistrement des données

Comme la dernière fois, nous allons passer la ressource SQL dans un tableau afin de pouvoir manipuler tout ça facilement :

	$Tab=array();
	$Abscisses=array();
	while($D=mysql_fetch_assoc($Ds))
	{
		$Tab[]=$D['Ordonnee'];
		$Abscisses[]=utf8_encode($D['Abscisse']);//Les URL doivent être en UTF-8. Enlevez le utf8_decode si votre serveur toutrne déjà avec cet encodage.
	}

	//Normaliser le tableau
	$Max=Normalize($Tab);

N'oubliez pas la fonction Normalize, qui permet de s'assurer que toutes les données sont dans la bonne plage de valeurs. Ce qui m'amène tout naturellement à un petit problème : l'encodage des données.

L'encodage

Afin de gagner de la place, nous n'allons pas utiliser l'encodage brut que je préconise dans l'article sur les graphiques : en effet celui-ci nécessite des URL assez longues, et le service de Google a une limite qui s'atteint plus rapidement qu'on ne le croit. Par défaut, les données sont comma-separated : 0,15,10,28,50,12,... mais une autre solution consiste à encoder chaque valeur par une lettre afin de gagner de la place (0:A,1:B,...,26:a,27:b,...,36:0,...) ; autrement dit toutes les valeurs doivent être comprises entre 0 et 61, d'où notre fonction Normalize :

function Normalize(&$Tab)
{
	$Max=max($Tab);
	foreach($Tab as &$Cell)
		$Cell=round(61*$Cell/$Max);

	return $Max;
}

L'encodage se fait ensuite très simplement :

	//Rentrer les données
	$Settings['chd']='s:';
	foreach($Tab as $Cell)
		$Settings['chd'] .=$Encodage[$Cell];

URL de l'image

Maintenant, tout est prêt. Il ne reste plus qu'à mettre tout ça ensemble en créant l'adresse de l'image à partir des données du tableau $Settings.

	$Abscisses=implode('|',$Abscisses);

	//Générer l'URL à partir des Settings
	$URL='http://chart.apis.google.com/chart?1';
	foreach($Settings as $K=>$V)
	{
		if($V!='')
			$URL .='&' . $K . '=' . str_replace('$ABSCISSES',$Abscisses,str_replace('$MAX',$Max,$V));
	}
	echo '

';

On notera que la fonction remplace $MAX par la valeur Maximum, et $ABSCISSES par la liste des abscisses, ce qui permet d'utiliser les données pour les axes.

En résumé...

Pour ceux qui n'auraient pas tout suivi, voilà le code complet :

function GraphIt($SQL,$Settings)
{
	$Encodage=str_split('ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789');
	//Valeurs par défaut
	$Default=array(
	'cht'=>'lc',//Type du graphique
	'chtt'=>'Statistiques',//Titre
	'chs'=>'750x200',//Taille
	'chco'=>'88AAD6',//Couleur des traits
	);
	//Combiner les valeurs demandées avec les valeurs par défaut
	$Settings=array_merge($Default,$Settings);


	$Ds=mysql_query($SQL) or die(mysql_error());
	$Tab=array();
	$Abscisses=array();
	while($D=mysql_fetch_assoc($Ds))
	{
		$Tab[]=$D['Ordonnee'];
		$Abscisses[]=utf8_encode($D['Abscisse']);//str_replace(str_split('éèêàù'),str_split('eeeau'),$D['Abscisse']);
	}

	//Normaliser le tableau
	$Max=Normalize($Tab);
	$Abscisses=implode('|',$Abscisses);

	//Rentrer les données
	$Settings['chd']='s:';
	foreach($Tab as $Cell)
		$Settings['chd'] .=$Encodage[$Cell];

	//Générer l'URL à partir des Settings
	$URL='http://chart.apis.google.com/chart?1';
	foreach($Settings as $K=>$V)
	{
		if($V!='')
			$URL .='&' . $K . '=' . str_replace('$ABSCISSES',$Abscisses,str_replace('$MAX',$Max,$V));
	}
	echo '

'; } function Normalize(&$Tab) { $Max=max($Tab); foreach($Tab as &$Cell) $Cell=round(61*$Cell/$Max); return $Max; }

Utilisation

Comment utiliser la fonction ? Rien de bien compliqué, et quelques exemples aideront :

GraphIt('SELECT Auteurs.Auteur AS Abscisse,COUNT(*) AS Ordonnee
FROM Omnilogismes
LEFT JOIN OMNI_Auteurs ON (Auteurs.ID = Omnilogismes.Auteur)
GROUP BY Auteurs.Auteur
ORDER BY COUNT(*) DESC
LIMIT 12',array('cht'=>'p3','chs'=>'500x200','chtt'=>'Nb Omnilogismes','chco'=>'FF0000,00FF00,88AAD6','chl'=>'$ABSCISSES'));

Résultat : Résultat

GraphIt('SELECT CONCAT(HOUR(Date),"h") As Abscisse,COUNT(*) AS Ordonnee
FROM Modifs
GROUP BY HOUR(Date)
ORDER BY HOUR(Date)',array('cht'=>'bvs','chtt'=>'Modifications par heure','chxt'=>'x,y','chxl'=>'0:|$ABSCISSES|1:|0|$MAX','chbh'=>'a'));

Résultat : Résultat

Comme vous le voyez, l'ensemble reste modulable mais facile à utiliser. Pour plus d'exemples, vous pouvez consulter cette page web.