Manipulation d'images en PHP - Librairie GD

Auteur: Mohamed CHINY Durée necessaire pour le cours de Manipulation d'images en PHP - Librairie GD Niveau recommandé pour le cours de Manipulation d'images en PHP - Librairie GD Supports vidéo non disponibles pour ce cours Exercices de renforcement disponibles pour ce cours Quiz non disponibles pour ce cours

Page 8: Exercice - Traçage de graphes en PHP

Toutes les pages

Enoncé

L'objectif est de générer automatiquement des graphes à l'aide de GDlib.

On suppose que l'on veut schématiser les ventes d'une entreprise répartis sur les 12 mois de l'année. Pour simplifier on va supposer que la valeur maximale que les ventes peuvent atteindre est 1000.

Les valeurs des ventes seront stockées dans une variable de type tableau. On prévoira également une liste de sélection qui nous permet de choisir le type de graphe à afficher (histogramme ou courbe d'évolution).

Solution

<?php
   @$type=$_POST["type"];
   if(empty($type)) $type="Histo";
   $x=800;
   $y=500;
   $marge=50;
   $intX=($x-(2*$marge))/12;
   $intY=($y-(2*$marge))/10;
   $ventes=array(250,280,360,410,800,650,740,900,800,500,420,300);
   $mois=array("JAN","FEV","MAR","AVR","MAI","JUI","JUL","AOU","SEP","OCT","NOV","DEC");
   $img=imagecreatetruecolor($x,$y);
   $noir=imagecolorallocate($img,0,0,0);
   $blanc=imagecolorallocate($img,255,255,255);
   $orange=imagecolorallocate($img,220,100,0);
   $gris=imagecolorallocate($img,220,220,220);
   imagefill($img,0,0,$blanc);
   imageline($img,$marge,$y-$marge,$x-$marge,$y-$marge,$noir);
   imageline($img,$marge,$y-$marge,$marge,$marge,$noir);
   imagettftext($img,20,0,$x-$marge-10,$y-$marge+30,$noir,"./AllCaps.ttf","Mois");
   imagettftext($img,20,0,$marge-45,$marge-25,$noir,"./AllCaps.ttf","Ventes");
   for($i=0;$i<=10;$i++){
      imageline($img,$marge-2,$y-$marge-($i*$intY),$marge+2,$y-$marge-($i*$intY),$noir);
      imagettftext($img,10,0,$marge-45,$y-$marge-($i*$intY),$noir,"./AllCaps.ttf",$i*100);
      if($i>0)
         imageline($img,$marge+2,$y-$marge-($i*$intY),$x-$marge,$y-$marge-($i*$intY),$gris);
   }
   for($i=0;$i<12;$i++){
      imageline($img,$marge+$i*$intX,$y-$marge-2,$marge+$i*$intX,$y-$marge+2,$noir);
      imagettftext($img,10,-45,$marge+$i*$intX,$y-$marge+20,$noir,"./AllCaps.ttf",$mois[$i]);
      if($type=="Histo"){
         imagefilledrectangle($img,$marge+$i*$intX+1,$y-$marge-($ventes[$i]*($y-2*$marge)/1000),$marge+$i*$intX+40,$y-$marge-1,$orange);
         imagefilledrectangle($img,$marge+$i*$intX+1,$y-$marge-($ventes[$i]*($y-2*$marge)/1000),$marge+$i*$intX+40,$y-$marge-($ventes[$i]*($y-2*$marge)/1000)+5,$noir);
      }
      elseif($type=="Courbe"){
         imagesetthickness($img,1);
         if($i<11){
            imageline($img,$marge+$i*$intX+1,$y-$marge-($ventes[$i]*($y-2*$marge)/1000),$marge+($i+1)*$intX+1,$y-$marge-($ventes[$i+1]*($y-2*$marge)/1000),$orange);
         }
         imagefilledellipse($img,$marge+$i*$intX+1,$y-$marge-($ventes[$i]*($y-2*$marge)/1000),10,10,$noir);
      }
      imagettftext($img,12,0,$marge+$i*$intX+8,$y-$marge-($ventes[$i]*($y-2*$marge)/1000)-10,$orange,"./AllCaps.ttf",$ventes[$i]);
   }
   imagepng($img,"histo.png");
?>
<html>
   <head>
      <style>
         select{
            border:solid 1px #AAAAAA;
            padding:10px;
            margin:10px;
            font:14pt "Century Gothic";
            color:#DD7700;
            border-radius:10px;
         }
      </style>
   </head>
   <body>
      <center>
         <form name="fo" method="post" action="">
            <select name="type" onChange="this.form.submit()">
               <option <?php if($type=="Histo") echo "selected";?>>Histo</option>
               <option <?php if($type=="Courbe") echo "selected";?>>Courbe</option>
            </select>      
         </form>
         <img src="histo.png">
      </center>
   </body>
</html>
Voici des extraits de l'écran après exécution:
Je reconnais que le seul souci que vous avez pu trouver avec cet exercice c'est le fait que le repère que nous avons créé dispose de son origine en bas à gauche, alors qu'en GD l'origine des dessins est le point haut à gauche. Il faut donc procéder à des soustractions pour calculer la position verticale d'un point.

Par exemple, si on veut calculer la position du haut du bâton de l'histogramme, on doit d'abord calculer sa hauteur puis soustraire celle ci de la hauteur de l'image (de l'espace de travail).

Soient les données suivantes:
  • $y désigne la hauteur de l'image
  • $marge désigne les marges horizontale et verticale à laisser par rapport aux bord de l'image (à compter à partir des bordures du repère)
  • $ventes[$i] correspond à une entrée du tableau $ventes que l'on veut schématiser.
  • 1000 représente la valeur maximale que les ventes peuvent atteindre.

Donc, il faut commencer par calculer la hauteur en pixel du bâton à dessiner par une simple règle de trois en procédant ainsi:
  • 1000 correspond à la hauteur $y - 2 * $marge
  • $ventes[$i] correspond à la hauteur du bâton en pixels.

Donc, la hauteur du bâton correspond à $ventes[$i] * ($y - 2 * $marge) / 1000)

Alors, la position verticale du haut du bâton correspond à $y - $marge - la_hauteur_du_bâton soit:

$y - $marge - ($ventes[$i] * ($y - 2 * $marge) / 1000)