[gd] présentation graphique de données : les polygones

Description

Ce script à pour but la présentation graphique de données sous forme de polygones. Il utilise la bibliothèque GD de php. N'importe quel polygone (du triangle à ce que vous voulez) sera générer automatiquement en fonction du nombre de données fournies.

Le script se veut minimal, sans superflux. J'ai jugé qu'il serait plus sage de ne pas créer de classe afin de le rendre directement fonctionnel. Un simple appel dans une balise img en précisant bien les arrays cle et valeur comme arguments _GET et vous voilà en possession d'une présentation claire de vos données.

Voici un exmple d'URL :
./polygon.img.php?cle[]=Cle1&valeur[]=90&cle[]=Cle2&valeur[]=80&cle[]=Cle3&valeur[]=93&cle[]=Cle4&valeur[]=70&cle[]=Cle5&valeur[]=65

NB : Ne pas oublier de joindre le fichier TTF dans le repertoire de ce script (vous pouvez en mettre un autre si vous voulez, dans ce cas prenez le temps de modifier la configuration), c'est lui qui permet l'affichage de vos données.

Source / Exemple :


<?php

// polygon.img.php : présentation graphique simple de données numériques.

// --- Utilisation : ---
// appel de l'URL : ......./polygon.img.php?cle[]=Cle1&valeur[]=90&cle[]=Cle2&valeur[]=80&cle[]=Cle3&valeur[]=93&cle[]=Cle4&valeur[]=70&cle[]=Cle5&valeur[]=65
// possibilité de paramétrer font, font_size, et le rayon de la présentation dans l'url.

// rayon et police (valeurs par défaut).
$font = 'AgencyR.TTF';
$font_size = 12;
$rayon = 100;

// valeurs $_GET : paramétrage du code.
if (!isset($_GET['cle']) || !isset($_GET['valeur']) || !is_array($_GET['cle']) || !is_array($_GET['valeur']) || sizeof($_GET['cle']) != sizeof($_GET['valeur']) || sizeof($_GET['cle']) < 3)
{
	echo '$cle ou $valeur invalide.'; exit;
}
else
{
	$donnees = array();
	for($i = 0; $i < sizeof($_GET['cle']); $i++)
	{
		$donnees[$_GET['cle'][$i]] = min(abs($_GET['valeur'][$i]),100);
	}
}
if (isset($_GET['font'])) $font = $_GET['font'];
if (isset($_GET['font_size']) and intval($_GET['font_size']) > 0) $font_size = intval($_GET['font_size']);
if (isset($_GET['rayon']) and intval($_GET['rayon']) > 0) $rayon = intval($_GET['rayon']);

// width, height, origine, rayon & angle (automatique).
$angle = 360 / sizeof($donnees);
$points_filled_polygone = array();
$points_polygone = array();
$width = 3 * $rayon;
$height = 3 * $rayon;
$origine = array(
	'x' => $width / 2,
	'y' => $height / 2,
	);

// image (création).
$timg = imagecreatetruecolor($width,$height) or die('Impossible d\'initialiser la bibliothèque GD');

// couleurs.
$cpourcent = imagecolorallocate($timg, 255, 255, 255);
$cpolice = imagecolorallocate($timg, 0, 0, 0);
$cfond = imagecolorallocate($timg, 180, 180, 180);
$cline = imagecolorallocate($timg, 40, 40, 40);
$cpolygon = imagecolorallocate($timg, 90, 90, 90);

// fond.
imagefilledrectangle($timg, 0, 0, $width, $height, $cfond);

// stockage des coordonnées pour le dessin.
$angle_courant = -90; // départ à la verticale.
foreach ($donnees as $cle => $valeur)
{
	// coordonnées polaires vers coordonnées cartésiennes.
	$coefficientx = $rayon * cos(deg2rad($angle_courant));
	$coefficienty = $rayon * sin(deg2rad($angle_courant));

	// un polygone échelon à 100 (nous pourrons en rajouter à notre guise).
	$points_polygone[0][] = 1 * $coefficientx + $origine['x'];
	$points_polygone[0][] = 1 * $coefficienty + $origine['y'];
	
	// un polygone échelon à 50.
	$points_polygone[1][] = 0.5 * $coefficientx + $origine['x'];
	$points_polygone[1][] = 0.5 * $coefficienty + $origine['y'];
	
	// exemple : un polygone à 20%.
	/*
	$points_polygone[3][] = 0.2 * $coefficientx + $origine['x'];
	$points_polygone[3][] = 0.2 * $coefficienty + $origine['y'];

  • /
// le polygone de présentation des données. $points_filled_polygone[] = ($valeur/100) * $coefficientx + $origine['x']; $points_filled_polygone[] = ($valeur/100) * $coefficienty + $origine['y']; // mise à jour de l'angle. $angle_courant += $angle; } // dessin du polygone de présentation. imagefilledpolygon($timg, $points_filled_polygone, sizeof($donnees), $cpolygon); // dessin des polygones échelons. foreach ($points_polygone as $polygone_courant) imagepolygon($timg, $polygone_courant, sizeof($polygone_courant)/2, $cline); // ne pas oublier de diviser par 2 (se référer à la structure de cet array). // on écrit maintenant les clés et les valeurs. $trcr = 0; foreach ($donnees as $cle => $valeur) { $x_100 = $points_polygone[0][$trcr]; $x_poly = $points_filled_polygone[$trcr]; $trcr++; // on passe au y. $y_100 = $points_polygone[0][$trcr]; $y_poly = $points_filled_polygone[$trcr]; $trcr++; // on passe au prochain x (se référer aux structures de ces arrays données plus haut). // ligne raccord entre l'origine et le point actuel des 100%. imageline($timg, $origine['x'], $origine['y'], $x_100, $y_100, $cline); // pour que les clés n'empiètent pas sur le polygone. if ($x_100 < $origine['x']) $x_100 -= strlen($cle) * ($font_size/2); if ($y_100 < $origine['y']) $y_100 -= ($font_size + 4); // centrer s'il le faut. if ($x_100 == $origine['x']) $x_100 -= (strlen($cle) * 5) / 2; if ($y_100 == $origine['y']) $y_100 -= ($font_size + 4) / 2; // les pourcentages maintenant. if ($x_poly > $origine['x'] && $valeur > 50) $x_poly -= strlen($valeur.'%') * ($font_size/2 + 2); if ($y_poly > $origine['y'] && $valeur > 50) $y_poly -= ($font_size + 12); if ($x_poly < $origine['x'] && $valeur < 50) $x_poly -= strlen($valeur.'%') * ($font_size/2 + 2); if ($y_poly < $origine['y'] && $valeur < 50) $y_poly -= ($font_size + 12); // centrer s'il le faut. if ($x_poly == $origine['x']) $x_poly -= (strlen($valeur.'%') * ($font_size/2)) / 2; if ($y_poly == $origine['y']) $y_poly -= ($font_size + 12) / 2; // affichage : nom de la donnée. imagettftext($timg, $font_size, 0, $x_100 + 5, $y_100 + $font_size + 2, $cpolice, $font, $cle); // affichage : pourcentage. imagettftext($timg, $font_size, 0, $x_poly + 5, $y_poly + $font_size + 6, $cpourcent, $font, $valeur.'%'); } // affichage. header('Content-type: image/png'); imagepng($timg); imagedestroy($timg); ?>

Conclusion :


Bugs connus :
-- les écritures peuvent parfois dépasser sur le polygone, je fais mon possible pour trouver d'autres solutions.
-- pas de gestion des erreurs en GD donc il faut parfois vérifier si l'image fonctionne en l'appelant directement depuis votre navigateur.

Codes Sources

A voir également

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.