probleme pour faire un graphique en fonction d'une requete

Eléphant du PHP | 183 Messages

21 févr. 2008, 17:57

Bonjour,

J'ai un soucis (Gros a mon niveau) j'ai fait une petite requete est on me demande de mettre le résultat de la requete également en image ... chose que je ne sais pas faire.


//on récupére la ligne 
$result = mysql_query("SELECT * FROM defaut WHERE idligne = '$_POST[ligne]' ");

//on affiche les résultats
while ($d=@mysql_fetch_array($result)) {
echo "$d[nom]<br>";

$result2 = mysql_query("SELECT SUM(quantitedef) as somme_quantitedef  FROM rec WHERE idligne = '$d[idligne]'  $Requipe AND iddefaut ='$d[id]'  AND date>='$date_debut' AND date<='$date_fin' ");
$c=mysql_fetch_array($result2);
// on affiche le resultat de la requete en fonction de la ligne choisi plus haut
echo "<input type=\"text\" value=\"$c[somme_quantitedef]\" size=\"27\"><br>";
}

$idprod = $c[idprod];

$result = mysql_query("SELECT * FROM production WHERE id = '$idprod' ");
$c=mysql_fetch_array($result);

// on affiche la quantité produite pour cette journée
echo "<b>Quantité fabriquée: </b><br> <input type=\"text\" value=\"$c[quantite]\" size=\"27\"><br>";
La chose que j'aimerai faire c'est faire un graphique comme ci dessous:

Image

sachant que dans mes colonne je veut y mettre des partie par millions c'est a dire la somme des défaut de la période en cours (Selection des dates dans la requete SQL) divisé par la somme de la production total fois 1 million.
_________
Fabien

ViPHP
ViPHP | 3607 Messages

21 févr. 2008, 18:51

Regarde du côté de librairie comme celle-là:
http://www.aditus.nu/jpgraph/index.php
http://www.artichow.org/

(fait attention aux licences, je ne sais plus trop laquelle n'autorise pas l'utilisation pour des sites marchant)

Eléphant du PHP | 183 Messages

22 févr. 2008, 15:01

Bonjour,

Merci de ta réponse, je me suis penché sur artichow qui ma l'air plutot bien !!

J'ai lu plusieurs totorial et vu le principe.

Cependant je n'arrive pas a modifier pour y mettre ma requette.

Pour affiché les données voici le code d'artichow :
$x = array();

for($i = 0; $i < 12; $i++) {
	$x[] = mt_rand(-20, 100);
}

$y = array(
'Janvier',
'Février',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Août',
'Septembre',
'Octobre',
'Novembre',
'Décembre'
);
Cela est un histogramme avec en Y la quantité et en X les mois.

Je n'arrive pas a reformuler ceci pour lui dire


$x = array();
Est égal a la somme de mes défaut pour chaque mois (de la variable Y)
$result2 = mysql_query("SELECT SUM(quantitedef) as somme_quantitedef FROM rec WHERE idligne = '3' AND date>='2008-02-21' AND date<='2008-02-21' ");



$y = array(
'Janvier',
'Février',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Août',
'Septembre',
'Octobre',
'Novembre',
'Décembre'
);
Y est égal a chaque mois de l'année dans le array Y (Je ne sais pas comment dire dans ma requete que array 1 = janvier donc prendre que les enrefistrement de janvier.

EDIT :
Je viens de trouver un post d'une personne demandant sensiblement la meme chose :
http://www.phpfrance.com/forums/voir_reponse-196916.php La requete SQL change et moi dans ma requete SQL je n'est pas de champs "mois" mois un champs date sous la forme 2008-02-21.


J'ai essayer ceci mais cela ne marche pas :
$result2 = mysql_query(" select SUM(quantitedef) as somme_quantitedef, year(date) as annee, month(date) as mois from rec WHERE idligne = '3' AND date>='2008-02-21' AND date<='2008-02-21' group by mois  "); 
	while ($c=mysql_fetch_array($result2)) {
            $x[] = $c['somme_quantitedef'];
         }


$y = array(
'Janvier',
'Février',
'Mars',
'Avril',
'Mai',
'Juin',
'Juillet',
'Août',
'Septembre',
'Octobre',
'Novembre',
'Décembre'
);
Je voudrais que pour chaque mois il me fasse le total et me l'affiche via le array $x

Merci de votre aide
_________
Fabien

d0m
Mammouth du PHP | 1141 Messages

22 févr. 2008, 17:15

Déjà ta requête me semble étrange :

Code : Tout sélectionner

... AND date>='2008-02-21' AND date<='2008-02-21' ...
revient à

Code : Tout sélectionner

... AND date='2008-02-21' ...
et donc ça ne prend qu'un jour.

Une fois ta requête correcte, il faut stocker dans les tableaux tes valeurs.

Pour le graphique d'artichow il te faut 2 tableaux :
- tableau de valeurs : les valeurs à afficher sous forme de graphiques, pour toi les sommes
- tableau de labels d'abscisses : les mois de l'année.
$label_abscisses = array();
$les_sommes      = array();
while ($c=mysql_fetch_array($result2)) {
 $label_abscisses[] = $c['mois']
 $$les_sommes[] = $c['somme_quantitedef'];
}

Attention :
Pour Artichow, il est important que les tableaux que tu lui passes soient indexés numériquement de 0 à n ( pas le nom des mois en index ou une autre chaine) et que les valeurs soient dans l'ordre d'affichage.

Mammouth du PHP | 881 Messages

22 févr. 2008, 17:22

Partons du principe qu'une année a généralement 12 mois.

Que dirais-tu de ceci:



for ($z=0; $z<12; $z++) {
     $requete  = "SELECT year(date) as annee, month(date) as mois from rec ";
     $requete .= "WHERE idligne = '3' AND annee = 2008 AND mois = ".($z+1);
     $result = mysql_query($requete, $db);
     $x[] = mysql_numrows($result);
}


$y = array( 
'Janvier', 
'Février', 
'Mars', 
'Avril', 
'Mai', 
'Juin', 
'Juillet', 
'Août', 
'Septembre', 
'Octobre', 
'Novembre', 
'Décembre' 
); 

J'ai choisi ici de faire 12 requêtes, pour être sûr que tous les mois passent à l'étude.
Avec ce que tu proposais, un mois de mai sans erreur aurait fait en sorte que le texte associé au mois de juin aurait été mai, de juillet juin et ainsi de suite, chaque texte étant décalé d'un ou de plusieurs mois par rapport à la somme calculée. Or, quand on cherche un nombre d'erreur, on aspire toujours - je pense - à atteindre le zéro.



On pourrait aussi faire ainsi:
$requete2 .= "SELECT SUM(quantitedef) as somme_quantitedef, MONTH(date) as mois  ";
$requete2 .= "FROM rec  ";
$requete2 .= "WHERE idligne = '".$d[idligne]."'  AND iddefaut ='".$d[id]."'  AND date>='".$date_debut."' AND date<='".$date_fin."'  ";
$requete2 .= "GROUP BY mois "

$result2 = mysql_query($requete2);


WHILE ($QuelResu=mysql_fetch_object($result2)) {
      $x[($QuelResu->mois-1)] = $QuelResu->somme_quantitedef;
}
Avec cette seconde façon, tu ne fais qu'une requête au serveur, il n'est pas nécessaire de mettre en ordre.

Si je puis me permettre un commentaire supplémentaire, je trouve mêlant et je crains toujours que le serveur se confonde aussi, de donner à des champs des noms qui ressemblent trop à des commandes. C'est le cas de ton champ "date" qui ressemble tellement à la commande date() et PHP et à la propriété DATE de MySQL. Pour mes champs, j'opte plutôt pour des nom comme Dte_Prod pour - Date de production. C'est un avis. T'en fais ce que t'en veux.
Soyez artisans de paix

Eléphant du PHP | 183 Messages

23 févr. 2008, 03:12

Bonjour,

Merci pour vos réponses, j'ai testé chacune de vos solution mais aucune ne fonctionne (peut etre de ma faute)

le code que j'ai mis :

$x = array();

for ($z=0; $z<12; $z++) {
$result2 = mysql_query(" SELECT SUM(quantitedef) as somme_quantitedef, year(date) as annee, month(date) as mois from rec WHERE idligne = '3' AND annee = '2008' AND mois = '.($z+1).' GROUP BY mois ");
$x[] = mysql_numrows($result2);
} 
    


$y = array( 
'Janvier', 
'Février', 
'Mars', 
'Avril', 
'Mai', 
'Juin', 
'Juillet', 
'Août', 
'Septembre', 
'Octobre', 
'Novembre', 
'Décembre' 
); 
Cela me semble bien car pour chaque mois il m'indiquera 0 meme si il y a pa d'enregistrement ? (a ce que j'au cru comprendre)

Merci de votre aide
_________
Fabien

Mammouth du PHP | 881 Messages

23 févr. 2008, 05:40

La requête que tu essaies là te donnera la somme des valeurs recherchées. Il est donc inutile de demander le nombre de résultats. C'est, en quelque sorte, la combinaison des deux requêtes que je t'avais proposées, mais il faut les garder séparées.

Quels sont les résultats obtenus par la première suggestion? par la deuxième? Quels sont les résultats attendus?

Est-ce que ta vérification des requêtes proposées te permettent de croire qu'elles peuvent mener au résultat attendu? En le écrivant, j'avais nettement l'impression qu'il me manquait d'informations, c'est pourquoi je te les ai soumises comme des pistes de développement. Si tu veux de l'aide pour établir la requête précise, il faudrait que nous expliquer davantage le code que tu as soumis au départ.


Donne-nous la structure complète de tes deux tables (à faire générer par ton phpmyadmin) et nous pourrons peut-être mieux t'aider.
Soyez artisans de paix

Eléphant du PHP | 183 Messages

23 févr. 2008, 12:20

Re bonjour,

En faite j'ai toujours des erreurs SQL avec les 2 solutions c'est pour cela que j'ai un peu modifié le tout mais sans résultats

Voici mes 2 bases
CREATE TABLE `ligne` (
  `id` int(2) NOT NULL auto_increment,
  `nom` varchar(50) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=1 ;

CREATE TABLE `rec` (
  `id` int(2) NOT NULL auto_increment,
  `idligne` int(2) NOT NULL default '0',
  `quantitedef` varchar(200) NOT NULL default '',
  `date` date NOT NULL default '0000-00-00',
  `equipe` varchar(200) NOT NULL default '',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=3 ;

J'ai refait une requete mais toujours rien , la meme erreur : mysql_fetch_array(): supplied argument is not a valid MySQL result ...

Voici le code de la page Artichow

<?php

$connection=mysql_connect("xxxx","xxxxxxxxx","xxxxxx") or die("connexion au serveur impossible");
mysql_select_db("xxxxxxxxx"); 


require_once "BarPlot.class.php";

$graph = new Graph(800, 600/*, "Albert", time() + mt_rand(2, 15)*/);
$graph->setTiming(TRUE);
$graph->setAntiAliasing(TRUE);

$x = array();

for ($z=0; $z<12; $z++) {
$result2 = mysql_query("SELECT SUM(quantitedef) as somme_quantitedef, year(date) as annee, month(date) as mois from rec WHERE idligne = '3' AND annee = '2008' AND mois = '.($z+1).' GROUP BY mois ");
$somme = mysql_fetch_assoc($result2); 
$x[] = $somme['somme_quantitedef'];   
} 


$y = array( 
'Janvier', 
'Février', 
'Mars', 
'Avril', 
'Mai', 
'Juin', 
'Juillet', 
'Août', 
'Septembre', 
'Octobre', 
'Novembre', 
'Décembre' 
); 

$plot = new BarPlot($x);

$plot->setSpace(6, 6, 10, 10);

$plot->setBarColor(new Color(100, 100, 100, 50));
$plot->setBarPadding(mt_rand(0, 30) / 100, mt_rand(0, 30) / 100);

$plot->label->hideFirst(TRUE);
$plot->label->hideLast(TRUE);
$plot->label->set($x);
$plot->label->move(0, -23);
$plot->label->setBackgroundGradient(new LinearGradient(new Color(250, 250, 250, 10), new Color(255, 200, 200, 30), 0));
$plot->label->border->setColor(new Color(20, 20, 20, 20));
$plot->label->setPadding(0, 0, 0, 1);
$plot->label->setFont(new Tuffy(10));

$plot->setBackgroundGradient(new LinearGradient(new Color(210, 210, 210), new Color(255, 255, 255), 0));

$plot->grid->setBackgroundColor(new Color(235, 235, 180, 60));

$plot->yAxis->setLabelPrecision(2);
$plot->yAxis->label->setFont(new Tuffy(8));

$plot->xAxis->setLabelText($y);
$plot->xAxis->label->setFont(new Tuffy(8));
$plot->xAxis->label->setAngle(mt_rand(0, 90));

$plot->legend->add($plot, "Test", LEGEND_BACKGROUND);
$plot->legend->setModel(LEGEND_MODEL_BOTTOM);
$plot->legend->setPadding(10, 10, 10, 10);
$plot->legend->setPosition(NULL, 0.85);
$plot->legend->setTextMargin(8, 0);

$graph->add($plot);
$graph->draw();
?>
J'ai volontairement mis idligne = '3' AND annee = '2008' pour être sur , car j'ai inséré des données dans la base.

Merci de votre aide
_________
Fabien

Mammouth du PHP | 881 Messages

23 févr. 2008, 22:28

Salut!

première chose, il n'est pas étonnant que nous ayons un message d'erreur avec _fetch pour les valeurs de $z ou il n'y pas d'erreur (de valeur dans la base), c'était d'ailleurs pourquoi je suggérais en premier lieu d'utiliser _numrows. Voici ce que nous pourrions faire pour éviter cela:

$x = array();

for ($z=0; $z<12; $z++) {
     $requete  = "SELECT SUM(quantitedef) as somme_quantitedef, ";
     $requete .= "    YEAR( date_atelier ) AS annee, ";
     $requete .= "    MONTH( date_atelier ) AS mois ";
     $requete .= "FROM rec ";
     $requete .= "WHERE idligne =3 ";
     $requete .= "    AND year( date_atelier ) =2008 ";
     $requete .= "    AND MONTH( date_atelier ) = ".($z+1)." ";
     $requete .= "GROUP BY MONTH( date_atelier ) ";
//MONTH( date_atelier )
		 print 'Voici la requete: '.$requete.'<br>';
     $result = mysql_query($requete, $connection);

     $QuelSOMME =  ($result) ? mysql_fetch_object($result) : 0;
     $x[] = ($QuelSOMME == 0) ? 0: $QuelSOMME->somme_quantitedef;   
}
$y = array( 
'Janvier', 
'Février', 
'Mars', 
'Avril', 
'Mai', 
'Juin', 
'Juillet', 
'Août', 
'Septembre', 
'Octobre', 
'Novembre', 
'Décembre' 
);

print 'Voici les résultats de chaque mois: <ul>';
for ($z=0; $z<12; $z++) {
		print '<li>'.$y[$z].' : '.$x[$z].'</li>';
} 

Ceci fonctionne, je l'ai essayé.
Il y reste une erreur que toi seul pourra corriger, car je ne croyais pas qu'on puisse faire de SUM sur un champ de caractères (VARCHAR), mais je vois que ça marche. C'est cependant plutôt hasardeux. Si je comprends ton projet, je pense que ce champ devrait être numérique.


Avec le champ quantitedef changé en INTEGER, voici les résultats

* Janvier : 0
* Février : 1
* Mars : 7
* Avril : 0
* Mai : 0
* Juin : 0
* Juillet : 0
* Août : 0
* Septembre : 0
* Octobre : 0
* Novembre : 0
* Décembre : 0


Je n'ai pas essayé de nouveau après avoir changé le champ en VARCHAR. J'obtiens le même résultats, mais je n'ai pas changé les valeurs, ce sont donc tous des chiffres.

Voici les valeurs d'essai:
CREATE TABLE `rec` (
  `id` int(2) NOT NULL auto_increment,
  `idligne` int(2) NOT NULL default '0',
  `quantitedef` varchar(100) NOT NULL,
  `date_atelier` date NOT NULL default '0000-00-00',
  `equipe` varchar(200) NOT NULL default '',
  PRIMARY KEY  (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=latin1 AUTO_INCREMENT=5 ;

-- 
-- Contenu de la table `rec`
-- 

INSERT INTO `rec` (`id`, `idligne`, `quantitedef`, `date_atelier`, `equipe`) VALUES 
(1, 3, '3', '2008-03-13', 'Les jambons'),
(2, 2, '2', '2008-02-13', 'Les févriers'),
(3, 3, '4', '2008-03-23', 'Troisième de mars'),
(4, 3, '1', '2008-02-14', 'Deuxième de mars');
Soyez artisans de paix

Eléphant du PHP | 183 Messages

24 févr. 2008, 02:06

Bonsoir,

Merci de ta réponse. Cela marche !!!

Grand merci a toi pour ton aide.
_________
Fabien

Mammouth du PHP | 881 Messages

24 févr. 2008, 05:55

N'oublie pas de mettre "Résolu", c'est notre trophée.
Soyez artisans de paix

Avatar du membre
Administrateur PHPfrance
Administrateur PHPfrance | 13231 Messages

24 févr. 2008, 10:54

Modération :
fabien_14, si ta question est résolue, pense à ajouter le tag [Résolu]
pour indiquer aux personnes qui voudront consulter ce sujet qu'il contient une solution.
Tu peux réaliser cette opération en cliquant sur le bouton Image en haut à gauche de ce sujet.
Connaître son ignorance est la meilleure part de la connaissance
Pour un code lisible : n'hésitez pas à sauter des lignes et indenter

twitter - site perso - Github - Zend Certified Engineer

Eléphant du PHP | 183 Messages

24 févr. 2008, 11:06

Salut,

En faite on a pas totalement fini car (je devais pas être réveillé mais j'ai oublié qu'il me fallait ceci en partie par million :)

C'est a dire que nous avons les quantité produite mais j'ai une autre table "production"
CREATE TABLE `production` (
  `id` int(2) NOT NULL auto_increment,
  `idligne` int(2) NOT NULL default '0',
  `prod` int(10) NOT NULL default '0',
  `equipe` char(2) NOT NULL default '',
  `date_atelier` date NOT NULL default '0000-00-00',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;
et j'ai ajouter un champs "idprod" a la table REC
CREATE TABLE `rec` (
  `id` int(2) NOT NULL auto_increment,
  `idligne` int(2) NOT NULL default '0',
  `quantitedef` int(100) NOT NULL default '0',
  `date_atelier` date NOT NULL default '0000-00-00',
  `equipe` varchar(200) NOT NULL default '',
  `idprod` int(10) NOT NULL default '0',
  PRIMARY KEY  (`id`)
) TYPE=MyISAM AUTO_INCREMENT=7 ;
Le champs ID de "production" permet de faire la liaison avec REC et le champs idprod.


J'ai donc essayé de faire la liaison mais je n'arrive pas a prendre les 2 valeurs pour faire l'opération : somme_quantitedef " divisé par "somme_production" multiplié par 1000000.

Alors j'ai modifié la requete comme cela mais cela ne fonctionne pas
for ($z=0; $z<12; $z++) {


     $requete  = "SELECT idligne.rec, id.production, SUM(quantitedef.rec) as somme_quantitedef, ";
     $requete  = "SUM(production.prod) AS somme_production, ";
     $requete .= "    YEAR( date_atelier ) AS annee, ";
     $requete .= "    MONTH( date_atelier ) AS mois ";
     $requete .= "FROM production, rec ";
     $requete .= "WHERE production.id = rec.idprod AND ";
     $requete .= " idligne.rec =3 ";     
     $requete .= "    AND year( date_atelier ) =2008 ";
     $requete .= "    AND MONTH( date_atelier ) = ".($z+1)." ";
     $requete .= "GROUP BY MONTH( date_atelier ) ";
$qr1 = mysql_query ($requete);
     $QuelSOMME =  ($qr1) ? mysql_fetch_object($qr1) : 0;
     $x[] = ($QuelSOMME == 0) ? 0: $QuelSOMME->somme_quantitedef / somme_prodction * 1000000;   
}
_________
Fabien

Mammouth du PHP | 881 Messages

25 févr. 2008, 05:16

1) Au départ, il y a une erreur récurrente: l'identification de la table doit précéder le nom du champ et non l'inverse.
On doit lire: rec.idligne et non idligne.rec par exemple

2) Dès qu'il y a un champ d'une table qui partage une totale ressemblance au champ d'une autre table dans son nom, il faut recourir à des nomination de tables et les utiliser partout (fonction AS)

3) Finalement, la jonction entre les tables ne se fait pas par WHERE, mais par JOIN

Une visite de la documentation MySQL s'impose http://dev.mysql.com/doc/.

Voici, après toutes ces modifications un code fonctionnel avec tes tables. À toi de juger de la valeur des résultats obtenus, je ne les ai pas vérifiés.
for ($z=0; $z<12; $z++) {

     $requete  = "SELECT rec.idligne, prod.id, SUM(rec.quantitedef) as somme_quantitedef, ";
     $requete .= "SUM(prod.prod) AS somme_production, ";
     $requete .= "    YEAR( rec.date_atelier ) AS annee, ";
     $requete .= "    MONTH( rec.date_atelier ) AS mois ";
     $requete .= "FROM rec AS rec ";
		 $requete .= "LEFT JOIN production AS prod ON prod.id = rec.idprod ";
     $requete .= "WHERE  rec.idligne = 3 ";     
     $requete .= "    AND year(  rec.date_atelier ) = 2008 ";
     $requete .= "    AND MONTH( rec.date_atelier ) = ".($z+1)." ";
     $requete .= "GROUP BY MONTH(rec.date_atelier ) ";
		 print '<br><br>Voici ma requete: '.$requete;
		 $qr1 = mysql_query ($requete);
     $QuelSOMME = ($qr1) ? mysql_fetch_object($qr1) : 0;
     $x[] = ($QuelSOMME->somme_production == 0) ? 0 : ($QuelSOMME->somme_quantitedef / $QuelSOMME->somme_production) * 1000000;
} 
Avec les tables soumises (ton message) et les valeurs suivantes:

Code : Tout sélectionner

-- Contenu de la table `production` -- INSERT INTO `production` (`id`, `idligne`, `prod`, `equipe`, `date_atelier`) VALUES (1, 1, 1, 'GM', '0000-00-00'), (2, 1, 2, 'GM', '0000-00-00'), (3, 2, 2, 'GV', '2008-02-21'), (4, 2, 2, 'GA', '2008-02-28'); -- -- Contenu de la table `rec` -- INSERT INTO `rec` (`id`, `idligne`, `quantitedef`, `date_atelier`, `equipe`, `idprod`) VALUES (1, 3, 3, '2008-03-13', 'Les jambons', 1), (2, 2, 2, '2008-02-13', 'Les févriers', 2), (3, 3, 4, '2008-03-23', 'Troisième de mars', 2), (4, 3, 1, '2008-02-14', 'Deuxième de mars', 2);
Et les résultats obtenus sont:

* Janvier : 0
* Février : 500000
* Mars : 2333333.3333333
* Avril : 0
* Mai : 0
* Juin : 0
* Juillet : 0
* Août : 0
* Septembre : 0
* Octobre : 0
* Novembre : 0
* Décembre : 0


PS: J'espère que ton usine fera moins d'erreur que dans mes tests!!!
Soyez artisans de paix

Eléphant du PHP | 183 Messages

25 févr. 2008, 12:46

Salut

Ca marche !! cependant dés que je le met dans la boucle pour faire le graphique cela ne marche plus ... la je comprend pas trops

Si je mets que la requette pour faire apparaitre les résultat je trouve la meme chose que toi (D'ailleurs les résultats obtenu sont bon)

Mais avec artichow j'ai un message d'erreur trying to get property of non-object in on line 29

La ligne 29 : $x[] = ($QuelSOMME->somme_production == 0) ? 0 : ($QuelSOMME->somme_quantitedef / $QuelSOMME->somme_production) * 1000000;

Alors pour tester si cela venais du graphique j'ai mis $x[] = 2; le graphique se fait bien.

:?

PS : je suis sous easyphp au taf.
_________
Fabien