Image [inline], Mise à l'échelle [résolu] et Propagation de paramètres

Image [inline], Mise à l'échelle [résolu] et Propagation de paramètres - PHP - Programmation

Marsh Posté le 12-12-2003 à 11:46:56    

Bonjour à tous
 
 * Voilà, j'ai une application qui des informations dans une base de données et qui stocke ces données sous la forme d'un tableau à 2 dimensions. Pas de problèmes pour l'afficher/le manipuler.
 Maintenant, je veux afficher ces données sous la forme d'un graphique, mais je voudrais avoir une échelle correcte : par exemple, la valeur maximale que j'extrais de mon tableau est 7833, et donc je voudrais pouvoir afficher une ligne tous les 1000 (et monter jusqu'à 8000), plutôt qu'avoir un pas de 783, ce qui n'est pas très parlant pour comparer avec d'autres graphes. Je ne peux pas utiliser d'échelle fixe parce que les différents ensembles de données que je trace peuvent avoir un maximum de 90 à 20000 (je ne le sais pas a priori).
 J'ai une vague idée, mais je sèche un peu, donc si vous avez un algo qui calcule la meilleure échelle (ou un lien vers), ça m'intéresse.
 
 
 * Deuxième chose, c'est plus pour savoir comment vous vous faites : je récupère donc mes données dans un tableau à 2 dimensions (grâce à la page "index.php" ) et je veux créer une image à partir de ça (après avoir affiché ces valeurs sous forme de texte). Je vois en gros 3 solutions avec PHP :

  • Créer l'image directement dans la page "index.php", l'écrire dans un fichier -avec la fonction imagepng($img, "image.png" )- puis l'afficher juste après par le biais d'une balise <img>
  • Sauvegarder ce tableau dans un fichier texte puis générer l'image avec un script "image.php" qui va lire ce fichier de données ; c'est une balise <img> qui appelera ce script
  • Transmettre directement les données au script "image.php" par une méthode GET.


 J'utilise la dernière solution puisque j'ai une contrainte assez forte : je ne peux pas écrire de fichiers dans l'arborescence Web. La deuxième pourrait permettre d'écrire un fichier hors de l'arborescence, mais ça risque de poser des problèmes avec le safe_mode PHP.
 En gros je fais ça :

Code :
  1. --- index.php ---
  2. // requêtes SQL et initialisation du tableau $tab
  3. //  
  4. $data = base64_encode(gzdeflate(serialize($tab),9));
  5. echo "<img src=\"image.php?data=$data\" alt=\"Syslog\" />";


Puis

Code :
  1. -- image.php --
  2. // quelques vérifs...
  3. $tab = unserialize(gzinflate(base64_decode($_GET["data"])));
  4. // Et hop, je cherche le max et je fais tout le reste


 
 Notez que ça marche plutôt bien ; MS IE pose problème quand le tableau devient gros à cause de la chaine "data" trop longue passée par GET, semble-t-il, mais ça ne me dérange pas. Néanmoins, si vous utilisez une autre à laquelle je n'ai pas pensé, je suis tout ouïe.
 
 
Edit: zut, j'aurais du créer 2 messages, c'est un peu long, ça... Bref, trop tard...


Message édité par unk00 le 12-12-2003 à 18:13:58
Reply

Marsh Posté le 12-12-2003 à 11:46:56   

Reply

Marsh Posté le 12-12-2003 à 11:54:26    

Passe en POST !
 
EDIT :
Je suis trop con moi !
En POST dans une balise IMG  :ange:  
 
Oublie ce que j'ai dit...


Message édité par Mara's dad le 12-12-2003 à 11:55:44

---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 12-12-2003 à 11:56:37    

Est-ce que tu utilise les sessions ?


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 12-12-2003 à 12:29:09    

Mara's dad a écrit :

Est-ce que tu utilise les sessions ?


 
 Ah non, pas du tout...
 
 Mmmh, ah tu veux dire que je pourrais sauvegarder toutes ces données dans un cookie de session (ou même un simple cookie) et les récupérer depuis "image.php" ?
 C'est pas bête, je n'y avais pas pensé...
 En plus, si je me rappelle, la limite est d'en gros 4096 octets par cookie, mais je peux prévoir de découper ma valeur obtenue en base64 en plusieurs cookies si besoin est.
 
 Judicieux, merci !

Reply

Marsh Posté le 12-12-2003 à 12:35:16    

Je pensais plutôt à des Vraies sessions.
Un cookie ou une URL avec un ID de session, et les données associées stockées bien au chaud sur le serveur.
 
Sinon, tes données, elle viennent d'où ?
Elle sont saisies ou tu va les chercher en base de donnée...
Si tu va les chercher, ben ton script de génération de graphique doit pouvoir le faire aussi avec les bon paramètres.


---------------
Laissez l'Etat dans les toilettes où vous l'avez trouvé.
Reply

Marsh Posté le 12-12-2003 à 13:17:01    

Mara's dad a écrit :

Je pensais plutôt à des Vraies sessions.
Un cookie ou une URL avec un ID de session, et les données associées stockées bien au chaud sur le serveur.


 
 Ah ok, je n'ai jamais utilisé. Oui, je viens de regarder la doc PHP, je comprends en gros comment ça marche. C'est même plus logique, pas besoin de faire se balader les données et l'utilisateur ne peut pas les modifier (c'est pas trop gênant ici, mais bon...)
 

Citation :


Sinon, tes données, elle viennent d'où ?
Elle sont saisies ou tu va les chercher en base de donnée...
Si tu va les chercher, ben ton script de génération de graphique doit pouvoir le faire aussi avec les bon paramètres.


 Oui, bien sûr, je pourrais ré-exécuter la requête, mais c'est ça qui est le plus long et de plus, le script "image.php" est assez générique, je pourrais en avoir besoin pour afficher des tableaux de données à 2 dimensions non issus d'une base de données.
 
 En tout cas, merci pour les infos sur les sessions

Reply

Marsh Posté le 12-12-2003 à 14:22:45    

A propos de mon problème de mise à l'échelle, je viens de trouver une solution qui marche plutôt bien. J'ai pris le parti d'avoir un pas de 1, 2 ou 5 (à une puissance de 10 près), ce qui est couramment le cas.
 Je calcule d'abord la valeur maximale de mon tableau (stockée dans $maxval).
 J'initialise un tableau ($ypas) avec les pas qui m'intéressent, tableau indicé de 0 à n.
 

Code :
  1. // On affiche au minimum de 1 en 1
  2. // $pow10 doit être une puissance de 10 ; le pas minimal possible
  3. // est égal à $pow10 (d'après la boucle)
  4. $pow10 = 1;
  5. // Le pas maximum sera ici 100000 (avec n=16 et pow10 = 1)
  6. $n = 16;
  7. for ($i=0; $i <= $n; $i++) {
  8.    if ($i % 3 == 0) $ypas[$i] = 1*$pow10;
  9.    if ($i % 3 == 1) $ypas[$i] = 2*$pow10;
  10.    if ($i % 3 == 2) { $ypas[$i] = 5*$pow10; $pow10 = $pow10 * 10; }
  11. }


 
 Ensuite, je divise ma valeur maximale $maxval par 10. C'est arbitraire, ça signifie que je choisis en gros d'avoir 10 intervals de données. Si le graphique est assez grand (taille en pixel), on peut choisir 15 ou 20, et 5 ou 6 s'il est petit. C'est la variable $evalpas.
 
 Enfin, je compare les pas "corrects" du tableau $ypas avec cette valeur et je prend la valeur inférieure la plus proche, valeur qu'on va stocker dans $yechelle

Code :
  1. $yechelle = 0;
  2. // On traite le cas limite où $evalpas est inférieur à $ypas[0]
  3. if ($evalpas < $ypas[0]) {   // On prend $ypas[0]
  4.    $yechelle = $ypas[0];
  5. }
  6. else {
  7.    for ($i=0; $i < $n; $i++) {
  8.      // On a bien un inférieur strict et pas un inférieur ou
  9.      // égal car on a besoin de comparer avec le i+1
  10.      if ($evalpas >= $ypas[$i] and $evalpas < $ypas[$i+1]) {
  11.         // Ben ça y est, on a notre pas
  12.         $yechelle = $ypas[$i];
  13.      }
  14.    }
  15. }
  16. // On traite aussi le cas où $evalpas >= $ypas[$n]
  17. if ($evalpas >= $ypas[$n]) { $yechelle = $ypas[$n]; }


 
 Enfin, on calcule la valeur maximale absolue de notre graphique, qui sera supérieure à notre valeur max ; on la détermine en partant de $yechelle :

Code :
  1. $maxvalabsolue = 0;
  2. while ($maxvalabsolue <= $maxval) {
  3.    $maxvalabsolue = $yechelle+$maxvalabsolue;
  4. }


 
 Voilà, maintenant on peut faire les calculs nécessaires pour faire cadrer les données dans l'image.
 
 Si ça intéresse quelqu'un, voilà le résultat que j'obtiens :
 
http://wop-sys.org/ipt.png
 
 Y a des trucs à redire sur les couleurs, mais j'ai fait ça à la louche, et ça pourrait être pire   ;)


Message édité par unk00 le 12-12-2003 à 14:25:56
Reply

Marsh Posté le 12-12-2003 à 17:18:25    

Une autre solution pour les images, qui ne nécessite qu'un seul script : il suffit de faire afficher les images dans la page HTML ("inline" ), comme parfois dans les mails ; c'est tout bête (enfin, il faut le savoir). D'ailleurs, ça marche aussi pour d'autres types de contenu, pas seulement les images. Il suffit d'encoder l'image en base64 et d'utilser la balise <img> de la mnière suivante :
<img src="data:image/png;base64,données....." alt="blah" />
 
 Lien où j'ai trouvé ça :
http://www.selfhtml.com.fr/article [...] ne-images/
(et aussi la RFC 2397 http://www.ietf.org/rfc/rfc2397.txt)
 
 Avec PHP, il faut d'abord activer le tampon de sortie ("output buffering", fonction ob_start()) avant d'appeler les fonctions imagepng() ou imagejpeg().
 

Code :
  1. // -- index.php --
  2. // requêtes SQL et initialisation du tableau $tab
  3. ...
  4. // Création de l'image $im à partir des données de $tab
  5. ...
  6. // Puis, avant d'afficher l'image :
  7. ob_start();
  8. imagepng($im);
  9. $res = chunk_split(base64_encode(ob_get_contents()));
  10. ob_end_clean();  // ne pas utiliser ob_end_flush(), qui affiche le tampon
  11. // Et enfin l'affichage de l'image à l'endroit où on en a besoin
  12. echo "<img src=\"data:image/png;base64,\n".$res."\" alt=\"Syslog\">";


 
 Très pratique, on n'a qu'un seul fichier (HTML), même s'il y a plusieurs images, dans le cas où c'est un rapport qu'on veut transférer ou archiver. Certes, ça prend un peu plus de place qu'avec les images PNG, en gros 30% de plus par image, à cause du codage en base 64 (mais j'ai la place  :) ).
 
Edit: ah oui, a priori, ça ne marche pas avec MS IE 4-5.x. Pour IE 6, je ne sais pas. En tout cas, avec Mozilla (Gecko), c'est nickel.


Message édité par unk00 le 12-12-2003 à 17:20:56
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed