Quick links: Content - sections - sub sections
EN FR
Quick Search Advanced search
 
Page

  [Opened] Les Graphes et Jelix

Posted by gael on 09/15/2011 11:33

Bonjour à tous, Je suis nouvellement en alternance dans une entreprise qui utilise Jelix.L'une de mes tâches consiste à créer des graphiques avec les données de la BDD (PhpMySQL). Après plusieurs recherches, j'ai retenu 2 solutions :

  • pchart: http://www.pchart.net/ Malheureusement, une fois l'archive téléchargé, je ne sais pas où placer les fichiers dans l'arborescence Jelix.
  • la libraire GD: http://www.lephpfacile.com/cours/22-la-librairie-gd#h7

Avec phpinfo(), j'ai pu vérifier que GB était actif. J'ai donc créer le fichier "mon_image.php" et ajouter le code: <img src="mon_image.php"> dans le template qui doit contenir le graphe. Malheureusement là aussi rien n'apparait.

Certains d'entre vous ont ils déjà du afficher des graphiques avec Jelix ? Quels solutions avez vous retenu ?

Je vous remercie par avance de vos réponses,

  [Opened] Les Graphes et Jelix

Reply #1 Posted by gael on 09/15/2011 12:19

Petite évolution, j'ai réussi a faire apparaitre un rectangle rouge avec GD. Mais soit j'ai le rectangle, soit le template.

  [Opened] Les Graphes et Jelix

Reply #2 Posted by laurentj on 09/15/2011 19:22

Bonjour,

Bienvenue sur jelix.

une fois l'archive téléchargé, je ne sais pas où placer les fichiers dans l'arborescence Jelix.

Pour les classes PHP, tu mettras ça dans lib/ ou dans ton module. Après, un simple include fera l'affaire. Et si il y a des fichiers js, css ou autre, faut les mettre de manière à ce que ce soit accessible pour un navigateur, c'est à dire dans le répertoire www de l'application en général. Et on rajoutera les liens vers ces fichiers, si nécessaire via l'objet réponse de la page qui affiche le graph (note que je n'ai pas regardé comment fonctionnait pchart).

ajouter le code: <img src="mon_image.php"> dans le template qui doit contenir le graphe. Malheureusement là aussi rien n'apparait.

ça c'est probablement un problème d'URL. peut-être écrire plutôt <img src="{$j_basepath}mon_image.php"> si ce fichier mon_image.php se trouve dans le répertoire www de l'application.

Mais peut être aussi faudrait-il plutôt développer un contrôleur dans un des modules, qui se chargera de générer l'image, plutôt que de se faire un fichier PHP à part tout seul...

  [Opened] Les Graphes et Jelix

Reply #3 Posted by gael on 09/16/2011 09:53

Je vais étudier tout ça et je vous tiens au courant ! Merci pour les réponses

  [Opened] Les Graphes et Jelix

Reply #4 Posted by gael on 09/20/2011 14:55

Je suis donc parti sur la librairie GD finalement, c'est à mon avis le plus simple à utiliser:

Dans le fichier tpl, j'ai :

<p>Nombre de clients créés : {$img}</p>

Dans le fichier .zone j'ai donc :

<code>
	// Recherche du nombre clients
        $image = $statsSrv->addImage();
        $this->_tpl->assign('img',$image);
</code>

Et dans le fichier class:

<code>
 public function addImage() 
		{
    	try {	
			$imagefinal = 0;
			$visites = array(138, 254, 381, 652, 896, 720, 140, 556, 663, 331, 407, 768);
	  
		   header ("Content-type: image/png" ); 
		   $largeurImage = 400;
		   $hauteurImage = 300;
		   $im = ImageCreate ($largeurImage, $hauteurImage) 
				   or die ("Erreur lors de la création de l'image" );         
		  $blanc = ImageColorAllocate ($im, 255, 255, 255); 
		   $noir = ImageColorAllocate ($im, 0, 0, 0); 
		   $bleu = ImageColorAllocate ($im, 0, 0, 255);   
	  
		   ImageLine ($im, 10, $hauteurImage-10, $largeurImage-10, $hauteurImage-10, $noir);
		   for ($mois=1; $mois<=12; $mois++) {
			   ImageString ($im, 0, $mois*30, $hauteurImage-10, $mois, $noir);
		   }
		
		   ImageLine ($im, 10, 10, 10, $hauteurImage-10, $noir);
		   $visitesMax = 1000;
		  
		   for ($mois=1; $mois<=12; $mois++) {
			   $hauteurImageRectangle = round(($visites[$mois-1]*$hauteurImage)/$visitesMax);
			   ImageFilledRectangle ($im, $mois*30-7, $hauteurImage-$hauteurImageRectangle, $mois*30+7, $hauteurImage-10, $bleu);
			   ImageString ($im, 0, $mois*30-7, $hauteurImage-$hauteurImageRectangle-10, $visites[$mois-1], $noir);
		   }
		  
		  $imagefinal = ImagePng ($im);
        }
        catch (JException $e) {
            jLog::log($e,'erreur');
            $imagefinal = 'erreur';
        }
        return $imagefinal;
    }
</code>

Malheureusement, avec ce fonctionnement, seule l'image est généré et le template n'apparait plus, ni les autres données sensées être intégré dans le .zone

  [Opened] Les Graphes et Jelix

Reply #5 Posted by laurentj on 09/21/2011 22:34

Bonjour,

ce que tu as fais, là, c'est de tenter d'envoyer à la fois le contenu de la page HTML qui veut afficher l'image, et le contenu d'une image, en générant en plus les headers pour l'image. Ce n'est pas possible, ce n'est pas comme ça que le web fonctionne.

Le principe normal et depuis toujours, pour afficher une image dans une page html, c'est d'avoir d'un coté la page HTML, et de l'autre l'image. Et dans la page html tu as une balise <img> qui indique l'url de l'image.

Donc si tu veux reproduire cela dans jelix, tu as une action A qui génère la page HTML d'une part, et une action B qui génère ton image d'autre part. Chacune de ces actions ont une URL. Donc dans le template de ta page HTML, ce n'est pas le resultat de la génération de l'image qu'il faut mettre (et qui vaut ici true ou false, et non pas le contenu de l'image, regarder la doc de la fonction imagepng), mais une balise <img> avec l'url de l'action B. C'est tout.

Et l'action B, n'utilise pas un objet réponse de type html, mais un objet réponse de type binary (voir la doc), dans laquelle tu indiques donc le bon type mime, les bons entête et le contenu généré par ta fonction. Dans ton contrôleur, ça donne un truc du genre, pour l'action B:

<code>
 function actionB () {
    $rep = $this->getResponse('binary');
    $rep->mimeType = 'image/png';
    $rep->content = $statsSrv->addImage();
    return $rep;
 }
</code>

et voici ta fonction addImage

  • sans instruction de header (puisque c'est l'objet réponse qui s'en occupe),
  • on évite de catcher l'exception ça ne sert à rien dans le cas présent
  • on évite les die, parce que c'est très moche de tout arrêter brusquement, il est préférable de faire des exceptions.
  • on respecte aussi la casse des caractères dans les noms de fonctions, il pourrait y avoir sinon de mauvaises surprises à l'avenir si PHP evolue
  • on utilise le buffer pour récupérer le contenu
  • on n'oublie pas de libérer la mémoire avec imagedestroy
<code>
 public function addImage() {
	$imagefinal = 0;
	$visites = array(138, 254, 381, 652, 896, 720, 140, 556, 663, 331, 407, 768);
  
	$largeurImage = 400;
	$hauteurImage = 300;
	$im = imagecreate ($largeurImage, $hauteurImage)
		   or throw new Exception ("Erreur lors de la création de l'image" );         
	$blanc = imagecolorallocate ($im, 255, 255, 255); 
	$noir = imagecolorallocate ($im, 0, 0, 0); 
	$bleu = imagecolorallocate ($im, 0, 0, 255);   
	 
	imageline ($im, 10, $hauteurImage-10, $largeurImage-10, $hauteurImage-10, $noir);
	for ($mois=1; $mois<=12; $mois++) {
	   imagestring ($im, 0, $mois*30, $hauteurImage-10, $mois, $noir);
	}
		
	imageline ($im, 10, 10, 10, $hauteurImage-10, $noir);
	$visitesMax = 1000;
		  
	for ($mois=1; $mois<=12; $mois++) {
	  $hauteurImageRectangle = round(($visites[$mois-1]*$hauteurImage)/$visitesMax);
	  imagefilledrectangle ($im, $mois*30-7, $hauteurImage-$hauteurImageRectangle, $mois*30+7, $hauteurImage-10, $bleu);
	  imagestring ($im, 0, $mois*30-7, $hauteurImage-$hauteurImageRectangle-10, $visites[$mois-1], $noir);
	}

	ob_start();
	imagepng($im);
	$imagefinal = ob_get_contents();
	ob_end_clean();

         imagedestroy($im);

        return $imagefinal;
    }
</code>

enfin dans ton template html

<p>Nombre de clients créés : <img src="{jurl 'tonmodule~toncontrolleur:actionB'}" alt="graph" /></p>

Note : tout ces exemples de code n'ont pas été testé, et sont certainement à adapter, mais le principe général est le bon.

 
Page
  1. Les Graphes et Jelix