<?php
###########################################################
#                         ATTENTION                       #
# LES COORDONNEES SUR L'IMAGE COMMENCENT EN HAUT A GAUCHE #
#        DONC : EN HAUT A GAUCHE = 0 , 0                  #
#        ET : EN BAS A DROITE = $Largeur , $Hauteur       #
###########################################################

class graphique
{
  var $repere;
  var $Largeur;
  var $Hauteur;
  var $Marge;
  
  var $xMin;
  var $xMax;
  var $xPasEntre2ValAffichables;
  var $xPasEntre2TiretsAffichables;
  
  var $yMin;
  var $yMax;
  var $yPasEntre2ValAffichables;
  var $yPasEntre2TiretsAffichables;
  
  var $BgColorHex;
  var $xColorAxeHex;
  var $yColorAxeHex;
  var $xColorTxtHex;
  var $yColorTxtHex;
  var $ColorQuaHex;
  
  var $xTailleAxe;
  var $xNbeTir;
  var $xEcartEntreTir; # utilisé pour la largeur des rectangles de l'histogramme
  var $yTailleAxe;
  var $yNbeTir;
  
  var $Valeurs;
  var $x;
  var $y;
  var $ColHex;
  var $x1;
  var $y1;
  var $x2;
  var $y2;
  var $RepereOptimal;
  var $Date;
  
  
  
  
  # QUELQUES VALEURS POUR SE REPERER SUR LE REPERE...
  # $Largeur = largeur de l'image
  # $Hauteur = hauteur de l'image
  # $Marge = marge entre les axes et les bords de l'image.
  #   il faut de la place pour les valeurs, donc mini 40... Pour la clarté
  # $Date = 1 les valeurs de l'axe des x sont des valeurs de temps, $UnixStamp en seconde depuis 1970
  #
  # $xMin = valeur minimale de x sur son axe
  # $xMax = valeur maximale de x sur son axe
  # $xPasEntre2ValAffichables = pas entre deux valeurs qui seront affichées
  #   si = 10, il affichera les valeurs de xMin+10, xMin+20...
  #   et si $xMin = 2... on aura 2, 12, 22, 32...
  # $xPasEntre2TiretsAffichables = pareil avec les petits tirets de l'axe
  #   si = 2, il affichera des tirets sur l'axe une fois sur deux A PARTIR DU PREMIER : $xMin
  # $yMin = idem
  # $yMax = idem
  # $yPasEntre2ValAffichables = idem
  # $yPasEntre2TiretsAffichables = idem
  #
  # METTONS DE LA COULEUR MAINTENANT... NE PAS METTRE LE # DEVANT LE CHIFFRE HEXADECIMAL
  # $BgColorHex = 'ffffff' = couleur blanche Hexadécimale du fond de l'image
  # $xColorAxeHex = '000000' = couleur noire Hex de l'axe x et des ses tirets
  # $yColorAxeHex = '000000' = idem pour y
  # $xColorTxtHex = couleur des valeurs de l'axe x
  # $yColorTxtHex = idem pour y
  # $ColorQuaHex = Couleur du quadrillage en pointillés
  function repere
  (
	$pLargeur, # le p indique que c'est un paramètre pour la fonction
			   # sa valeur  remplacera celle de la variable $Largeur dans la classe
	$pHauteur,
	$pMarge,
	$pDate,
	
	$pRepereOptimal,
	
	$pBgColorHex = 'ffffff',
	$pxColorAxeHex = '000000',
	$pyColorAxeHex = '000000',
	$pxColorTxtHex = 'ff6600',
	$pyColorTxtHex = '6666ff',
	$pColorQuaHex = 'dddddd'
  )
  {
	$this->Largeur = $pLargeur;
	$this->Hauteur = $pHauteur;
	$this->Marge = $pMarge;
	$this->Date = $pDate;
	
	$this->xMin = $pRepereOptimal[0];
	$this->xMax = $pRepereOptimal[1];
	$this->xPasEntre2ValAffichables = $pRepereOptimal[2];
	$this->xPasEntre2TiretsAffichables = $pRepereOptimal[3];
	
	$this->yMin = $pRepereOptimal[4];
	$this->yMax = $pRepereOptimal[5];
	$this->yPasEntre2ValAffichables = $pRepereOptimal[6];
	$this->yPasEntre2TiretsAffichables = $pRepereOptimal[7];
	
	$this->BgColorHex = $pBgColorHex;
	$this->xColorAxeHex = $pxColorAxeHex;
	$this->yColorAxeHex = $pyColorAxeHex;
	$this->xColorTxtHex = $pxColorTxtHex;
	$this->yColorTxtHex = $pyColorTxtHex;
	$this->ColorQuaHex = $pColorQuaHex;
	
	# on crée l'image $this->repere
	$this->repere = imagecreate($this->Largeur,$this->Hauteur);
	
	# extrait les trois valeurs Héxadécimales et les convertis en Décimales pour chaque couleur
	$BgColorDec = array(
	  hexdec (substr ($this->BgColorHex,0,2)),
	  hexdec (substr ($this->BgColorHex,2,2)),
	  hexdec (substr ($this->BgColorHex,4,2)));
	$xColorAxeDec = array(
	  hexdec (substr ($this->xColorAxeHex,0,2)),
	  hexdec (substr ($this->xColorAxeHex,2,2)),
	  hexdec (substr ($this->xColorAxeHex,4,2)));
	$yColorAxeDec = array(
	  hexdec (substr ($this->yColorAxeHex,0,2)),
	  hexdec (substr ($this->yColorAxeHex,2,2)),
	  hexdec (substr ($this->yColorAxeHex,4,2)));
	$xColorTxtDec = array(
	  hexdec (substr ($this->xColorTxtHex,0,2)),
	  hexdec (substr ($this->xColorTxtHex,2,2)),
	  hexdec (substr ($this->xColorTxtHex,4,2)));
	$yColorTxtDec = array(
	  hexdec (substr ($this->yColorTxtHex,0,2)),
	  hexdec (substr ($this->yColorTxtHex,2,2)),
	  hexdec (substr ($this->yColorTxtHex,4,2)));
	$ColorQuaDec = array(
	  hexdec (substr ($this->ColorQuaHex,0,2)),
	  hexdec (substr ($this->ColorQuaHex,2,2)),
	  hexdec (substr ($this->ColorQuaHex,4,2)));

	# on met les couleurs dans les variables lisibles par Graphic Library
	$BgColor = imagecolorallocate($this->repere,$BgColorDec[0],$BgColorDec[1],$BgColorDec[2]);
	$xColorAxe = imagecolorallocate($this->repere,$xColorAxeDec[0],$xColorAxeDec[1],$xColorAxeDec[2]);
	$yColorAxe = imagecolorallocate($this->repere,$yColorAxeDec[0],$yColorAxeDec[1],$yColorAxeDec[2]);
	$xColorTxt = imagecolorallocate($this->repere,$xColorTxtDec[0],$xColorTxtDec[1],$xColorTxtDec[2]);
	$yColorTxt = imagecolorallocate($this->repere,$yColorTxtDec[0],$yColorTxtDec[1],$yColorTxtDec[2]);
	$ColorQua = imagecolorallocate($this->repere,$ColorQuaDec[0],$ColorQuaDec[1],$ColorQuaDec[2]);
	
	# on colorie le fond avec $BgColor
	imagefill($this->repere,1,1,$BgColor);
	
	$this->xTailleAxe = $this->Largeur-2*$this->Marge;
	$this->yTailleAxe = $this->Hauteur-2*$this->Marge;
	
	# calculs pour l'échelle de l'axe horizontal x
	# l'Ecart est en Pixel
	# le Pas est dans l'unité de la Valeur
	$this->xNbeTir = $this->xMax - $this->xMin;
	$this->xEcartEntreTir = $this->xPasEntre2TiretsAffichables*($this->xTailleAxe/$this->xNbeTir);
	$xEcartEntreVal = $this->xPasEntre2ValAffichables*($this->xTailleAxe/$this->xNbeTir);
	$xValAffichee = $this->xMin;
	$xPos = $this->Marge;
	$xPosFin = $this->Largeur - $this->Marge;
	
	# ecriture sur l'axe x des graduations et de leur valeur suivant les écarts choisis
	do
	{
	  # on met les tirets, longs de 3 pixels, séparés de $this->xEcartEntreTir
	  imageline($this->repere,$xPos,$this->Hauteur - $this->Marge,$xPos,$this->Hauteur - $this->Marge+3,$xColorAxe);
	  $xPos += $this->xEcartEntreTir;
	} while ($xPos<=$xPosFin);
	$xPos = $this->Marge;
	do
	{
	  # on écrit les valeurs en face des tirets... et on transforme ces valeurs en date,
	  # si on a spécifié $Date = 1 dans les paramètres...
	  if ($this->Date == 1) $xValAffiche = date("j-n-y",$xValAffichee);
	  else $xValAffiche = $xValAffichee;
	  imagestringup($this->repere,1,$xPos-3,$this->Hauteur - $this->Marge/3,$xValAffiche,$xColorTxt);
	  imagedashedline($this->repere,$xPos,$this->Hauteur - $this->Marge,$xPos,$this->Marge,$ColorQua);
	  $xPos += $xEcartEntreVal;
	  $xValAffichee += $this->xPasEntre2ValAffichables;
	} while ($xPos<=$xPosFin);
	
	# calculs pour l'échelle de l'axe vertical y
	$this->yNbeTir = $this->yMax - $this->yMin;
	$yEcartEntreTir = $this->yPasEntre2TiretsAffichables*($this->yTailleAxe/$this->yNbeTir);
	$yEcartEntreVal = $this->yPasEntre2ValAffichables*($this->yTailleAxe/$this->yNbeTir);
	$yValAffichee = $this->yMin;
	$yPos = $this->Hauteur - $this->Marge;
	$yPosFin = $this->Marge;
	
	# ecriture sur l'axe y des graduations et de leur valeur suivant les écarts choisis
	do
	{
	  imageline($this->repere,$this->Marge,$yPos,$this->Marge-3,$yPos,$yColorAxe);
	  $yPos -= $yEcartEntreTir;
	} while ($yPos>=$yPosFin);
	
	$yPos = $this->Hauteur - $this->Marge;
	do
	{
	  # ici on ne propose pas de changer les valeurs en date, on est sur l'axe vertical
	  imagestring($this->repere,1,$this->Marge/3,$yPos-3,$yValAffichee,$yColorTxt);
	  imagedashedline($this->repere,$this->Marge,$yPos,$this->Largeur-$this->Marge,$yPos,$ColorQua);
	  $yPos -= $yEcartEntreVal;
	  $yValAffichee += $this->yPasEntre2ValAffichables;
	} while ($yPos>=$yPosFin);
	
	# on dessine les axes en dernier pour que les pointillés au niveau des axes soient cachés
	imageline($this->repere,$this->Marge,$this->Hauteur - $this->Marge,$this->Largeur - $this->Marge,$this->Hauteur - $this->Marge,$xColorAxe);
	imageline($this->repere,$this->Marge,$this->Marge,$this->Marge,$this->Hauteur - $this->Marge,$yColorAxe);
	
		return $this->repere;
  } # fin de la fonction repere
  
  
  
  
  
  # cette fonction calcule automatiquement les valeurs du repère... à partir du tableau de données $Valeurs en paramètre
  # il faudra bien sur lui demander de travailler sur le tableau le plus grand
  # Si on met $Force = 0, le repère aura son axe des x sur y=0
  function calculrepereoptimal
  (
	$pValeurs,
	$Force
  )
  {
	$this->Valeurs = $pValeurs;
	ksort($this->Valeurs);
	# calcul pour l'axe des x
	# $xLeMin et $xLeMax sont les valeurs extrêmes du tableau mis en paramètre
	reset($this->Valeurs);
	$xLeMin = $xLeMax = key($this->Valeurs);
	for ($i = 1; $i <= count($this->Valeurs); $i++)
	{
	  if ( key($this->Valeurs) > $xLeMax )
		$xLeMax = key($this->Valeurs);
	  elseif ( key($this->Valeurs) < $xLeMin )
		$xLeMin = key($this->Valeurs);
	  next($this->Valeurs);
	}
	
	# ici on calcule les différences entre les valeurs et on retient la plus petite
	# pour trouver l'écart entre les tirets

	reset($this->Valeurs);
	$xDiffMin = 1000000000000;
	for ($i = 0; $i <= count($this->Valeurs)-1; $i++)
	{
	  $this->x1 = key($this->Valeurs);
	  next($this->Valeurs);
	  $this->x2 = key($this->Valeurs);
	  if ( abs($this->x1 - $this->x2) < $xDiffMin ) $xDiffMin = abs($this->x1 - $this->x2);
	}
	$this->RepereOptimal[3] = $xDiffMin; # l'écart entre deux tirets sur l'axe des x
	# on met ensuite la valeur sous un tiret sur deux
	$this->RepereOptimal[2] = 2 * $this->RepereOptimal[3]; # l'écart entre deux valeurs
	$this->RepereOptimal[0] = $xLeMin - $this->RepereOptimal[2]; # on met la première valeur sur le 2ème tiret
	$this->RepereOptimal[1] = $xLeMax + $this->RepereOptimal[2]; # on met la dernière valeur sur l'avant-dernier tiret
	
	# calcul pour l'axe des y
	# pas exactement pareil que x car
	reset($this->Valeurs);
	$yLeMin = $yLeMax = current($this->Valeurs);
	for ($i = 1; $i <= count($this->Valeurs); $i++)
	{
	  if ( current($this->Valeurs) > $yLeMax )
		$yLeMax = current($this->Valeurs);
	  elseif ( current($this->Valeurs) < $yLeMin )
		$yLeMin = current($this->Valeurs);
	  next($this->Valeurs);
	}
	# on prend les valeurs max et min et on commence le repère un peu en dessous et il fini un peu au-dessus
	$this->RepereOptimal[5] = $yLeMax + round (( $yLeMax - $yLeMin )/10);
	if ( $yLeMin <> 0 ) $this->RepereOptimal[4] = $yLeMin - round (( $yLeMax - $yLeMin )/10);
	elseif ( $yLeMin == 0 ) $this->RepereOptimal[4] = 0;
	if ($Force == 0) $this->RepereOptimal[4] = 0;
	$this->RepereOptimal[7] = round (( $this->RepereOptimal[5] - $this->RepereOptimal[4] )/10);
	$this->RepereOptimal[6] = 2 * $this->RepereOptimal[7];
	
	ksort($this->RepereOptimal);
	return $this->RepereOptimal;
  } # fin de la fonction calculrepereoptimal
  
  
  
  
  
  # QUELQUES VALEURS POUR SE REPERER SUR LE REPERE...
  #  $x = coordonnée x du point
  #  $y = coordonnée y du point
  # METTONS DE LA COULEUR MAINTENANT... NE PAS METTRE LE # DEVANT LE CHIFFRE HEXADECIMAL
  #  $ColHex = 'ff6600' par exemple...
  function tracepoint
  (
	$pValeurs,
	$pColHex
  )
  {
	$this->Valeurs = $pValeurs;
	$this->ColHex = $pColHex;
	ksort($this->Valeurs);
	
	# extrait les trois valeurs Héxadécimales et les convertis en Décimales pour chaque couleur
	# puis on met les couleurs dans les variables lisibles par Graphic Library
	$Dec = array 
	( hexdec (substr ($this->ColHex,0,2)),
	  hexdec (substr ($this->ColHex,2,2)),
	  hexdec (substr ($this->ColHex,4,2)));
	$Color = imagecolorallocate($this->repere,$Dec[0],$Dec[1],$Dec[2]);
	
	# calcule la position et trace
	reset($this->Valeurs);
	for ($i = 1; $i <= count($this->Valeurs) ; $i++)
	{
	  $this->x = key($this->Valeurs);
	  $xPos = ($this->x - $this->xMin) * ($this->xTailleAxe / $this->xNbeTir) + $this->Marge;
	  $this->y = current($this->Valeurs);
	  $yPos = (-$this->y + $this->yMax) * ($this->yTailleAxe / $this->yNbeTir) + $this->Marge;
	  imagesetpixel ($this->repere,$xPos,$yPos,$Color);
	  next($this->Valeurs);
	}
	
	
	return $this->repere;
  } # fin de la fonction tracepoint
  
  
  
  
  
  # QUELQUES VALEURS POUR SE REPERER SUR LE REPERE...
  #  $x = coordonnée x du point
  #  $y = coordonnée y du point
  # METTONS DE LA COULEUR MAINTENANT... NE PAS METTRE LE # DEVANT LE CHIFFRE HEXADECIMAL
  #  $ColHex = 'ff6600' par exemple...
  function tracehisto
  (
	$pValeurs,
	$pColHex
  )
  {
	$this->Valeurs = $pValeurs;
	$this->ColHex = $pColHex;
	ksort($this->Valeurs);
	
	# extrait les trois valeurs Héxadécimales et les convertis en Décimales pour chaque couleur
	# puis on met les couleurs dans les variables lisibles par Graphic Library
	$Dec = array 
	( hexdec (substr ($this->ColHex,0,2)),
	  hexdec (substr ($this->ColHex,2,2)),
	  hexdec (substr ($this->ColHex,4,2)));
	$Color = imagecolorallocate($this->repere,$Dec[0],$Dec[1],$Dec[2]);
	
	# calcule la position et trace le rectangle de largeur $this->xEcartEntreTir
	# les coordonnées du rectangle sont OBLIGATOIREMENT :
	# x1, y1 en haut à gauche du rectangle
	# x2, y2 en bas à droite du rectangle
	#
	reset($this->Valeurs);
	for ($i = 1; $i <= count($this->Valeurs) ; $i++)
	{
	  $this->x = key($this->Valeurs);
	  $xPos = ($this->x - $this->xMin ) * ($this->xTailleAxe / $this->xNbeTir) + $this->Marge - ($this->xEcartEntreTir/2);
	  $this->y = current($this->Valeurs);
	  $yPos = (-$this->y + $this->yMax) * ($this->yTailleAxe / $this->yNbeTir) + $this->Marge;
	  if ( $this->y < 0 )
		imagefilledrectangle ($this->repere,$xPos + 1,( $this->yMax) * ($this->yTailleAxe / $this->yNbeTir) + $this->Marge,$xPos + $this->xEcartEntreTir - 1,$yPos,$Color);
	  else
		imagefilledrectangle ($this->repere,$xPos + 1,$yPos,$xPos + $this->xEcartEntreTir - 1,( $this->yMax) * ($this->yTailleAxe / $this->yNbeTir) + $this->Marge - 1,$Color);
	  next($this->Valeurs);
	}
	return $this->repere;
  } # fin de la fonction tracehisto
  
  
  
  
  
  # QUELQUES VALEURS POUR SE REPERER SUR LE REPERE...
  # $x1 = coordonnée x du 1er point du segment
  # $y1 = coordonnée y du 1er point du segment
  # $x2 = coordonnée x du 2nd point du segment
  # $y2 = coordonnée y du 2nd point du segment
  # METTONS DE LA COULEUR MAINTENANT... NE PAS METTRE LE # DEVANT LE CHIFFRE HEXADECIMAL
  # $ColHex = 'ff6600' par exemple...
  function tracesegment
  (
	$pValeurs,
	$pColHex
  )
  {
	$this->Valeurs = $pValeurs;
	$this->ColHex = $pColHex;
	ksort($this->Valeurs);
	
	# extrait les trois valeurs Héxadécimales et les convertis en Décimales pour chaque couleur
	# puis on met les couleurs dans les variables lisibles par Graphic Library
	$Dec = array 
	( hexdec (substr ($this->ColHex,0,2)),
	  hexdec (substr ($this->ColHex,2,2)),
	  hexdec (substr ($this->ColHex,4,2)));
	$Color = imagecolorallocate($this->repere,$Dec[0],$Dec[1],$Dec[2]);
	
	# calcule les positions et trace
	reset($this->Valeurs);
	for ($i = 1; $i <= count($this->Valeurs)-1; $i++)
	{
	  $this->x1 = key($this->Valeurs);
	  $xPos1 = ($this->x1 - $this->xMin) * ($this->xTailleAxe / $this->xNbeTir) + $this->Marge;
	  $this->y1 = current($this->Valeurs);
	  $yPos1 = (-$this->y1 + $this->yMax) * ($this->yTailleAxe / $this->yNbeTir) + $this->Marge;
	  next($this->Valeurs);
	  $this->x2 = key($this->Valeurs);
	  $xPos2 = ($this->x2 - $this->xMin) * ($this->xTailleAxe / $this->xNbeTir) + $this->Marge;
	  $this->y2 = current($this->Valeurs);
	  $yPos2 = (-$this->y2 + $this->yMax) * ($this->yTailleAxe / $this->yNbeTir) + $this->Marge;
	  imageline ($this->repere,$xPos1,$yPos1,$xPos2,$yPos2,$Color);
	}
	return $this->repere;
  } # fin de la fonction tracesegment
  
  
  
  
  
} # fin de la classe graphique

?>
