8791 sujets

Développement web côté serveur, CMS

Salut à tous,

j'ai retrouvé une de mes anciennes classes de génération de graphiques; Elle se base sur la bibliothèque JPGraph. Comme à l'époque j'avais galéré pour l'utiliser en objet avec pattern MVC (appel à un fichier php externe, avec variables GET pour remplir le bordel, ou génération directe de l'image sur le serveur...) j'avais donc fait cette ptite classe pour plus me prendre la tête. Je pense que cette base pourra servir à quelques uns...

Fichier Graphics.View.Class.php

<?php
	define( 'DS', DIRECTORY_SEPARATOR );
	
	//A remplacer par le répertoire contenant la bibliothèque JPGraph
	define( '_LIB_GRPH_', dirname( __FILE__ ). DS . 'jpgraph' . DS );
	require_once (_LIB_GRPH_ . "jpgraph.php" ); 
	
	/**
	* Classe permettant de créer des graphiques sous différents formats,
	* à l'aide de la bibliothèque :
	*   - JPGraph <www.jpgraph.net>
	*      * Des camemberts (pie chart)
	*      * Des graphiques affines
	*      * Des graphiques barres (barchart)
	*      * Des fonctions mathématiques (Y = f(x) )
	*
	* Partie View du MVC. Il suffit de renseigner la classe avec des
	* tableaux judicieusement choisis, et d'appeler une fonction pour afficher
	* le graphique. Cf les méthodes de génération de graphique.
	* Requis : PHP 5.1+ | JPGraph 3.0.7+
	*
	* @author JPGraph.net
	* @author A. Muller
	* @version 1.1
	*/
	Class DiagramGen {
		
		/**
		* Les labels/valeurs affichés selon l'axe des X (y en fonction de x)
		* Doit correspondre avec $Y
		* @var array $X tableau indicé de strings/numériques
		*/
		protected $X = array() ;
		
		/**
		* Les valeurs (entières ou flottantes) selon l'axe des Y
		* @var array $Y tableau indicé de numériques
		* Doit correspondre avec $X
		*/
		protected $Y = array() ;
	
		/**
		* @var String le titre du graphe
		*/
		protected $titre = '' ;
	
		/**
		* @var float $width largeur de l'image
		*/
		protected $width ;
		
		/**
		* @var float $height hauteur de l'image
		*/
		protected $height ;
	
		/**
		* Constructeur de classe
		*
		* @param String titre du graphique
		* @param array $X les valeurs de l'axe des X
		* @param array $Y tableau de numériques
		*/
		public function __construct( $titre = NULL, $X = NULL, 
		                             $Y = NULL, $width = 500,
									 $height = 500 ){
			$this->Y( $Y ) ;
			$this->X( $X ) ;
			$this->titre( $titre ) ;
			$this->width( $width ) ;
			$this->height( $height ) ;
		}
		
		
		//Méthodes de génération de graphiques
		
		/**
		* Permet de dessiner un camembert.
		* L'image est stockée sur le serveur si $nom non nul
		* sinon générée à la volée et retournée encodée en base64
		* Format des données :
		* 	X : tableau indicé de chaines de caractères
		*	Y : tableau indicé de numériques
		*
		* Exemple d'utilisation:
		* $graphic = new DiagramGen(); [...]
		* //A la volée
		* <img src="<?php echo $graphic->pie();?>" />
		* //Stockée sur serveur
		* <img src="<?php echo $graphic->pie('toto.png');?>" />
		*
		* @param string $nom le nom du fichier
		* @param int $w largeur (attribut si nul)
		* @param int $h hauteur (attribut si nul)
		* @param bool $val - affichage pourcentage ou valeur numérique
		* @return IMG l'image générée
		*/
		public function Pie( $nom = NULL, $percent = FALSE, $w = NULL, $h = NULL ){	
			require_once ( _LIB_GRPH_ . 'jpgraph_pie.php' );
		
			// Création du Pie chart si suffisamment de données
			if( sizeof( $this->X ) > 0 && sizeof( $this->Y ) > 0 ){
			
				if( is_numeric( $w ) && is_numeric( $h ) ){
					$graph = new PieGraph($w, $h,'auto');
				}else{
					$graph = new PieGraph($this->width, $this->height,'auto');
				}
				$graph->SetShadow();
				
				// Set a title for the plot
				$graph->title->Set( $this->titre );
				

				// Create
				$p1 = new PiePlot( $this->Y );
				$p1->SetCenter( 0.4, 0.5 );
				$p1->SetLegends( $this->X );
				
				if($percent == FALSE){
					$p1->SetLabelType(1);
					$p1->value->SetFormat("%d");
				}
			
				// Add plot to pie graph
				$graph->Add( $p1 );
			}else{
				$graph = $this->Blank("Aucun résultat retourné. [Pie]");
			}
			return $this->Stroke( $graph, $nom ) ;
		}
	
		/**
		* Permet de dessiner dans un graphique une fonction du style Y=f(x).
		* L'image est stockée sur le serveur si $nom non nul
		* sinon générée à la volée et retournée encodée en base64
		* Format des données :
		* 	X : tableau indicé de chaines de caractères
		*	Y : tableau indicé de numériques
		*
		* Exemple d'utilisation:
		* $graphic = new DiagramGen(); [...]
		* //A la volée
		* <img src="<?php echo $graphic->YfX_Line();?>" />
		* //Stockée sur serveur
		* <img src="<?php echo $graphic->YfX_Line('toto.png');?>" />
		*
		* @param string $titreX titre de l'axe des abscisses
		* @param string $titreY titre de l'axe des ordonnées
		* @param string $nom le nom du graphique généré
		* @param int $w largeur de l'image
		* @param int $h hauteur de l'image
		* @return IMG l'image générée
		*
		*/
		public function YfX_Line( $nom = NULL, $titreX = NULL, $titreY = NULL, $percent = FALSE, $w = NULL,$h = NULL){		
			require_once ( _LIB_GRPH_ . 'jpgraph_line.php' );
			
			if( sizeof( $this->X ) > 1 && sizeof( $this->Y ) > 1 ){
				
				//Déclaration des variables
				$nomi = $titreY;
				if( $w != NULL && $h != NULL && is_numeric( $w ) 
				    && is_numeric( $h ) && $w > 0 && $h > 0 ){
					$graph = new Graph( $w, $h , 'auto' ) ;
				}else{
					$graph = new Graph($this->width,$this->height,'auto') ;
				}
				
				$graph->SetScale("textlin");
				
				//Cas du pourcentage
				if( $percent == TRUE ){
					$nomi = "Pourcentage de " . $nomi;
				}
				
				$graph->img->SetMargin(50,50,50,50);
				$graph->xaxis->SetTitleMargin(50);
				$graph->yaxis->scale->SetGrace(30);
				$graph->xaxis->SetLabelAngle(90);
				$graph->SetShadow();
				$graph->SetMargin(50,50,50,100);
				$graph->title->Set($this->titre);

				$p1 = new LinePlot( $this->Y );
				$p1->SetFillColor( "orange" );
				$p1->mark->SetType( MARK_FILLEDCIRCLE );
				$p1->mark->SetFillColor( "red" );
				$p1->mark->SetWidth( 4 );
				$graph->Add( $p1 );
				
				$graph->xaxis->SetTitle($titreX,"high");
				$graph->xaxis->SetTitlemargin(30);
				$graph->yaxis->SetTitleMargin(30);
				$graph->yaxis->title->Set("$nomi");
				$graph->xaxis->SetTickLabels( $this->X );
				$graph->xaxis->SetFont(FF_FONT1);
			}
			else{
				$graph = $this->Blank('
Moins de deux enregistrements.
Impossible à afficher !');
			}
			
			return $this->Stroke( $graph, $nom ) ;
		}
	
		/**
		* Permet de dessiner un graphique barre.
		* L'image est stockée sur le serveur si $nom non nul
		* sinon générée à la volée et retournée encodée en base64
		* Format des données :
		* 	X : tableau indicé de chaines de caractères
		*	Y : tableau indicé de numériques
		*
		* Exemple d'utilisation:
		* $graphic = new DiagramGen(); [...]
		* //A la volée
		* <img src="<?php echo $graphic->YfX_Bar();?>" />
		* //Stockée sur serveur
		* <img src="<?php echo $graphic->YfX_Bar('toto.png');?>" />
		*
		* @param string $titreX titre de l'axe des abscisses
		* @param string $titreY titre de l'axe des ordonnées
		* @param string $nom le nom du graphique généré
		* @param int $w largeur de l'image
		* @param int $h hauteur de l'image
		* @return IMG l'image générée
		*
		*/
		public function YfX_Bar( $nom = NULL, $titreX = NULL, $titreY = NULL, $percent = FALSE, $w = NULL, $h = NULL ){	
			require_once (_LIB_GRPH_.'jpgraph_bar.php');
			
			if( sizeof($this->X) > 1 && sizeof($this->Y) > 1 ){
				// Create the graph. These two calls are always required
				if( $w != NULL && $h != NULL && is_numeric( $w ) 
				    && is_numeric( $h ) && $w > 0 && $h > 0 ){
					$graph = new Graph( $w, $h , 'auto' ) ;
				}else{
					$graph = new Graph($this->width,$this->height,'auto') ;
				}
				
				$graph->SetScale("textlin");
				$graph->img->SetMargin(50,50,50,50);
				$graph->yaxis->SetTitleMargin(30);
				$graph->yaxis->scale->SetGrace(30);
				$graph->xaxis->SetLabelAngle(90);
				$graph->SetMargin(50,50,50,100);   
				$graph->SetShadow();

				// Create the bar plots
				$bplot = new BarPlot($this->Y);
				$bplot->SetFillColor("green");
				
				// Create the accumulated bar plot
				$abplot = new AccBarPlot( array( $bplot ) );
				$abplot->SetShadow();

				// We want to display the value of each bar at the top
				$abplot->value->Show();
				$abplot->value->SetFont(FF_FONT1,FS_NORMAL);
				$abplot->value->SetAlign('center','center');
				$abplot->value->SetColor("black","darkred");
				
				if( $percent == TRUE ){
					$abplot->value->SetFormat('%0.00f%%');
				}
				
				$graph->xaxis->SetTickLabels($this->X);
				$graph->xaxis->SetFont(FF_FONT1);

				// ...and add it to the graPH
				$graph->Add( $abplot );
				$graph->title->Set( $this->titre );

				$graph->xaxis->SetTitle( $titreX, "high" );
				$graph ->xaxis->SetPos("min");
				$graph->yaxis->SetWeight(2);
				$graph->xaxis->SetTitlemargin(30);
				$graph->yaxis->title->Set( $titreY );
				$graph->xaxis->SetWeight(2);
				$graph ->yaxis->SetPos("min");

				$graph->xaxis->title->SetFont( FF_FONT1 );
			}else{
				$graph = $this->Blank('
Moins de deux enregistrements. 
Impossible à afficher !');
			}

			//Génération de l'image
			return $this->Stroke( $graph, $nom ) ;
		}
	
		/**
		* Permet de dessiner une fonction mathématique.
		* L'image est stockée sur le serveur si $nom non nul
		* sinon générée à la volée et retournée encodée en base64
		* Format des données :
		* 	X : tableau indicé de numériques uniques
		*	Y : tableau indicé de numériques
		*
		* Exemple d'utilisation:
		* $graphic = new DiagramGen(); [...]
		* //A la volée
		* <img src="<?php echo $graphic->YfX_Math();?>" />
		* //Stockée sur serveur
		* <img src="<?php echo $graphic->YfX_Math('toto.png');?>" />
		*
		* @param string $titreX titre de l'axe des abscisses
		* @param string $titreY titre de l'axe des ordonnées
		* @param string $nom le nom du graphique généré
		* @param int $w largeur de l'image
		* @param int $h hauteur de l'image
		* @return IMG l'image générée
		*
		*/
		public function YfX_Math( $nom = NULL, $titreX = NULL, $titreY = NULL, $w = NULL, $h = NULL ){
			require_once (_LIB_GRPH_.'jpgraph_line.php');
			require_once (_LIB_GRPH_.'jpgraph_scatter.php');
			require_once (_LIB_GRPH_.'jpgraph_regstat.php');
			
			$taille_X = sizeof( $this->X );
			$taille_Y = sizeof( $this->Y );
			
			//S'il existe suffisamment de valeurs
			if( $taille_X > 1 && $taille_Y > 1 ){

				//Si les tableaux sont de tailles identiques
				if( $taille_X == $taille_Y ){
					//Interpolation de valeurs
					$spline = new Spline($this->X,$this->Y);
					list( $newx,$newy ) = $spline->Get(100);

					//Création du graphe
					if( $w != NULL && $h != NULL && is_numeric( $w ) 
							&& is_numeric( $h ) && $w > 0 && $h > 0 ){
							$g = new Graph( $w, $h , 'auto' ) ;
						}else{
							$g = new Graph($this->width,$this->height,'auto') ;
					}
					$g->SetMargin(50,50,50,50);
					$g->title->Set( $this->titre );
					$g->title->SetFont(FF_ARIAL,FS_NORMAL,12);
					$g->SetMarginColor('lightblue');
					$g->SetScale('linlin');

					//Paramétrage des axes
					$g->xaxis->SetLabelFormat('%1.1f');
					$g->xaxis->SetTitle($titreX,"middle");
					$g->xaxis->SetTitlemargin(20);
					$g->yaxis->title->Set($titreY);
					$g->yaxis->SetTitleMargin(30);
					
					//Les points contenus dans le tableau
					$splot = new ScatterPlot( $this->Y,$this->X );
					$splot->mark->SetFillColor( 'red@0.3' );
					$splot->mark->SetColor( 'red@0.5' );

					//Création de la courbe liss&e
					$lplot = new LinePlot( $newy,$newx );
					$lplot->SetColor( 'navy' );

					//Ajout des éléments au graphe
					$g->Add( $lplot );
					$g->Add( $splot );
				}else{
					$g = $this->Blank('Tableaux de tailles différentes...');
				}
			}else{
				$g = $this->Blank('Fonction impossible à afficher.');
			}
			
			return $this->Stroke( $g , $nom ) ;
		}
	
		//Méthodes publiques setter/getter like
	
		/**
		* Fonction s'inspirant de JQuery : si paramètre change 
		* l'attribut Y sinon renvoie sa valeur
		* @return mixed
		*/
		public function Y( array $d = NULL ){
			if( is_array( $d ) ) {
				if( $d != NULL ){
					$this->Y = $d ;
					return $this ;
				}
			}
			return $this->Y ;
		}
		
		/**
		* Fonction s'inspirant de JQuery : si paramètre change 
		* l'attribut X sinon renvoie sa valeur
		* @return mixed
		*/
		public function X( array $d = NULL ){
			if( is_array( $d ) ) {
				if( $d != NULL ){
					$this->X = $d ;
					return $this ;
				}
			}
			return $this->X ;
		}
	
		/**
		* Fonction s'inspirant de JQuery : si paramètre change 
		* l'attribut labels sinon renvoie sa valeur
		* @return mixed
		*/
		public function titre( $t = NULL ){
			if( $t != NULL ){
				$this->titre = $t ;
				return $this ;
			}else{
				return $this->titre ;
			}
		}
		
		/**
		* Fonction s'inspirant de JQuery : si paramètre change 
		* l'attribut width sinon renvoie sa valeur
		* @return mixed
		*/
		public function width( $w = NULL ){
			if( $w != NULL && is_numeric( $w ) && $w > 0 ){
				$this->width = $w ;
				return $this ;
			}else{
				return $this->width ;
			}
		}
		
		/**
		* Fonction s'inspirant de JQuery : si paramètre change 
		* l'attribut height sinon renvoie sa valeur
		* @return mixed
		*/
		public function height( $h = NULL ){
			if( $h != NULL && is_numeric( $h ) && $h > 0 ){
				$this->height = $h ;
				return $this ;
			}else{
				return $this->height ;
			}
		}		
		
		/**
		* Change l'attribut height + width 
		* @return this
		*/
		public function dim( $v ){
			if( is_numeric( $v ) && $v > 0 ){
				$this->height = $v ;
				$this->width  = $v ;
				return $this ;
			}
		}

	
		//Méthodes protected
		
		/**
		* Permet de générer l'image soit directement sur le serveur 
		* (présence d'un nom/chemin) soit à la volée, sans stockage serveur
		*
		* @param String $nom  du fichier
		* @param JPGraph.Object
		* @return String soit le nom, soit l'image base64 encodée
		*/
		protected function Stroke( $graph , $nom = NULL){
			
			//Si génération du fichier sur le serveur
			if( $nom != NULL ){
				$graph->Stroke( $nom );
				//Eviter problème / \ sur environnement Windows
				return str_replace( '\\', '/', $nom ); 
			}else{
				//Si fichier en 'temporaire'
				$contentType = 'image/png';
				$gdImgHandler = $graph->Stroke(_IMG_HANDLER);

				ob_start();                        // Début du buffer
				$graph->img->Stream();             // On balance les données dans le buffer
				$image_data = ob_get_contents();   // On les récupère dans une variable
				ob_end_clean();                    // Vidage du buffer

				//Retour de l'image encodée base 64
				return "data:$contentType;base64," . base64_encode($image_data);
			}
		}
	
		/**
		* Affiche un texte à l'écran
		* Utilisé pour afficher les erreurs
		* @param String $msg
		* @return PieGraph
		*/
		protected function Blank( $msg ){
			require_once ( _LIB_GRPH_ . 'jpgraph_pie.php' );
			$graph = new PieGraph($this->width, $this->height,'auto');
			$graph->SetShadow();
			$caption=new Text($msg,0.1,0.8);
			$graph->AddText($caption); 
			return $graph ;
		}
	
	}

?>


Et le fichier de tests, pour voir comment ça marche:

<?php
	require_once( 'Graphics.View.Class.php' ) ;

	//Paramètrage du test
	$Y        = array(10,40,50,80,90,20,60,80,90,110) ;
	$X2       = array(1,1.5,1.8,2.1,2.3,6.5,7,8.2,9.2,69.5) ;
	$X        = array( "P1","P2","P3","P4","P5","P6","P7","P8","P9","P10" ) ;

	$titre    = "Répartition des ventes par produit";
	
	//Objets, avec paramétrage postérieur
	$i = new DiagramGen($titre, $X, $Y);
	$i->height(400)->width(400);
	
?>
<html>
<head>
	<title> Test de la classe DiagramGen</title>
</head>
<body>
	<img src="<?php echo $i->Pie();?>" />
	<img src="<?php echo $i->dim(600)->YfX_Bar( NULL, 'Produit' , 'Coût par produit (€)' );?>" />
	<img src="<?php echo $i->dim(500)->YfX_Line( NULL, 'Produit' , 'Coût par produit (€)', TRUE );?>" />
	<img src="<?php echo $i->dim(300)->X( $X2 )->YfX_Math( NULL,'Temps (ms)','Fréquence (Hz)');?>" />
	<img src="<?php echo $i->dim(300)->X( $X2 )->YfX_Math( 'imgs'.DS.'imgsrv.png','Temps (ms)','Fréquence (Hz)');?>" />
	
</body>
</html>


Modifié par Zed13 (20 Jul 2012 - 01:05)