Evolution de la température moyenne des mois au fil des ans

Vous avez créé un tutoriel, postez-le ici

Modérateurs : jturlier, Météo Villarzel

Répondre
Avatar du membre
PascalWMR
Messages : 323
Enregistré le : 16 févr. 2014, 09:28
Localisation : CONFLANS EN JARNISY (F54800)
Contact :

Evolution de la température moyenne des mois au fil des ans

Message par PascalWMR » 27 févr. 2016, 14:42

Ce tuto a pour but d'afficher la température moyenne groupée par mois pour toutes les années présentent dans nos Base De Données (exemple, sur un graphique, tous les mois de janvier du début des relevés à aujourd'hui, sur un second, tous les mois de février du début des relevés à aujourd'hui, etc.. ).
Ce graphique permet également de déterminer ce que j'appellerai entre guillemets, la Normale pour la station. Ceci est d'autant plus valable pour ceux qui font des relevés depuis longtemps.

A la fin de ce tuto, vous devriez avoir ce graphique.
http://www.monsite-meteo.eu/Page/statte ... eparan.php
Ce graphique utilise bien sur les librairies Highcharts, mais aussi du PHP, du CSS et du Javascript.
En fait lorsqu'on regarde ce graphique, l'on voit qu'un seul mois est affiché. En réalité, sur la même page, 13 graphiques sont tracés. Un pour chaque mois et un pour comparer les normales Météo officielles et ce que j'appellerai la normale de la station. Seulement ceux qui ne sont pas nécessaire sont masqués.

Voyons cela en détail.

La partie PHP.
NB: le code PHP doit être saisi dans l'ordre que je donne car certaines valeurs définies en premier lieu servent à en calculer d'autres.
Cette partie sert à récupérer toutes les données.
En premier lieu, on ouvre la balise PHP et on fait appel au script de connexion (je ne m'étend pas sur cette partie, cela à déjà été évoqué dans d'autres tuto).

Code : Tout sélectionner

<?php
	
// appel du script de connexion
require("../Scripts/mysqli_connect.php");   
Ensuite, nous déterminons les normales officielles pour chaque mois et un pour la normale annuelle.

Code : Tout sélectionner

// Détermination des normales Météo France
$NormaleMF[1]=2.2;
$NormaleMF[2]=3.1;
$NormaleMF[3]=6.7;
$NormaleMF[4]=9.9;
$NormaleMF[5]=14.2;
$NormaleMF[6]=17.4;
$NormaleMF[7]=19.7;
$NormaleMF[8]=19.3;
$NormaleMF[9]=15.5;
$NormaleMF[10]=11.1;
$NormaleMF[11]=6.1;
$NormaleMF[12]=3.1;
$NormaleMF[13]=10.7;
J'ai nomé la variable $NormaleMF pour normale Météo France.
Elle est suivie d'un nombre entre crochets qui correspond au mois.
La dernière qui porte le numéro 13 correspond à la normale annuelle.
Bien entendu, vous devez remplacer ces valeurs par celles correspondant à votre situation géographique.

A partir de maintenant, toutes les données seront extraites de la table MiniMaxidata .

Maintenant, nous allons déterminer la valeur de la variables $NbMois.
Celle-ci sert tout simplement à indiquer le nombre de mois de collecte des données dans les div de renseignement situées sous les graphiques.
Ceci se fait tout simplement avec une requête SQL et la fonction mysqli_num_rows($query) qui compte le nombre de lignes de la requête.
La requête extrait du champ recdateTZ l'année et le mois de chaque enregistrements et les groupes par années et mois

Code : Tout sélectionner

// Calcul de la variable indiquant le nombre de mois de collecte des données
	$sql="SELECT SUBSTR(recdateTZ,1,6) AS AnMois FROM MiniMaxidata GROUP BY AnMois";
	$query = mysqli_query($conn,$sql);                   
	$NbMois = mysqli_num_rows($query);
A présent, nous allons initialiser 2 variables $AnneeInit et $AnneeFin qui serviront un peu plus loin à déterminer dans une requête SQL la plage de données à extraires.

$AnneeInit (pour Année initiale) est récupérée à l'aide d'une requête SQL qui sélectionne la valeur mini d'une partie du champ recdateTZ. Cette variable correspond à la 1ère année de collecte des données.

$AnneeFin est, elle, déterminée par la fonction PHP date("Y") qui donne pour valeur l'année en cours, à laquelle on ajoute 1.

Code : Tout sélectionner

// Initialisation des années de début et de fin
	$sql="SELECT MIN(SUBSTR(recdateTZ,1,4)) AS AnneeInit FROM MiniMaxidata";
	$query = mysqli_query($conn,$sql);                   
	$list = mysqli_fetch_assoc($query);
	$AnneeInit=$list['AnneeInit']*1;
	$AnneeFin = date("Y")+1;
Ensuite, nous allons récupérer les données du dernier graphique, celui ou l'on compare les normales officielles avec celles de la station. Ceci doit être exécuter ici car des valeurs récupérées ici serviront à en calculer d'autres plus tard.

La requête sql1 va extraire la température moyenne AVG(t_out_moy) que je nomme NormTempMoy de chaque mois GROUP BY Mois sur la totalité de la base de données.
On initialise la variable d'incrémentation $i avec la valeur 0. Cette variable sera incrémentée $i++; dans la boucle while.

Dans la boucle while, pour chaque mois de l'année, on définit:
La valeur de ce que j'appelle la normale de la station $NormStation[$i] qui prend pour valeur la température moyenne récupérée dans la BDD NormTempMoy
La valeur de la normale officielle $NormMF[$i] qui prend pour valeur de la normale officielle $NormaleMF[$i+1] définie précédement.
Attention, dans la boucle while, $NormaleMF doit être celle de $i+1 car dans la boucle, $i va de 0 à 11 tandis que $NormaleMF va de 1 à 12.
Puis on calcule l'écart entre les Normales $EcartNorm[$i]; Celle de la station moins la normale officielle $NormStation[$i]-$NormMF[$i].
Enfin on incrémente $i. Donc, à la fin de la boucle while, $i a pour valeur 12.

La suite du code force une série de données à avoir la valeur NULL. Cette astuce, permet dans un graphique Highcharts de sauter une colonne car par défaut, les valeurs nulles ne sont pas tracées.
Puis on incrémente encore $i de 1. La variable a donc la valeur de 13.
Pourquoi sauter une colonne :?: Parce que la dernière donnée extraite par la requête suivante n'est pas une donnée mensuelle.

La requête $sql2="SELECT AVG(t_out_moy) AS TempMoyTotal FROM MiniMaxidata" va extraire la température moyenne totale de la BDD celle qui représente donc la température moyenne de toutes les années.
Puis comme précédemment, on détermine la valeur des Normales et l'écart entre ces normales.
Vous remarquerez ici que $NormaleMF est égale à celle de $i et non plus à celle de $i+1. Pourquoi?
Parce que $i ayant été incrémenté jusqu’à la valeur de 13, la donnée $NormMF[13] est celle de $NormaleMF[13] définie précédemment.

Voici ci-dessous le code servant à faire tout cela.

Code : Tout sélectionner

// ----------------------------- Début code graphique Comparaison des normales --------------------------------	
// code pour le tab d'évolution des normales (avec récupération de la Normale Station)
	//Requête pour récupérer la température moyenne de chaque mois sur la totalité de la BDD
	$sql1="SELECT SUBSTR(recdateTZ,5,2) AS Mois, AVG(t_out_moy) AS NormTempMoy FROM MiniMaxidata GROUP BY Mois";
	$query = mysqli_query($conn,$sql1);                   
	$i=0;
	while ($list = mysqli_fetch_assoc($query)) {
		$NormStation[$i]=$list['NormTempMoy']*1;
		$NormMF[$i]=$NormaleMF[$i+1];
		$EcartNorm[$i]=$NormStation[$i]-$NormMF[$i];
		$i++;
	}
	// On force une série de variables à avoir la valeur NULL pour sauter une colone dans le graphique
	$NormStation[$i]=NULL;
	$NormMF[$i]=NULL;
	$EcartNorm[$i]=NULL;
	$i=$i+1;
	// Requête pour récupérer la température moyenne totale de la BDD
	$sql2="SELECT AVG(t_out_moy) AS TempMoyTotal FROM MiniMaxidata";
	$query = mysqli_query($conn,$sql2);                   
	$list = mysqli_fetch_assoc($query);
	$NormStation[$i]=$list['TempMoyTotal']*1;
	$NormMF[$i]=$NormaleMF[$i];
	$EcartNorm[$i]=$NormStation[$i]-$NormMF[$i];
// ----------------------------- Fin code graphique Comparaison des normales --------------------------------	
La suite du code, va extraire pour chaque mois et pour chaque année présente dans la BDD, la température moyenne, déterminer la normale officielle, l'écart entre la température moyenne et la normale officielle, l'écart entre la température moyenne et la normale de la station, et,
la température moyenne pour chaque mois et pour toutes les années que j'appelle la normale mensuelle de la station, et calculer l’écart entre la normale officielle et cette normale de la station.

Pour cela, nous allons utiliser 2 boucles for imbriquées et une condition if dont voici le principe;

Pour chaque mois (1ère boucle)
  1. Je détermine les noms des variables à encoder,
  2. j'initialise une variable d'incrémentation $i.
    Cette variable sert en fait à ce que chaque série de données, aient le même nombre de données, pour que chaque graphique Higncharts ai le même nombre de colonnes.
    Si je me servait d'une requête SQL avec une boucle while, seules les données existantes dans la BDD seraient affichées.
    Or ce n'est pas ce que je veux.
    Ce que je veux, c'est que pour un mois, la colonne de l'année en cours soit affichée même si ce mois n'est pas encore écoulé. Je m'explique;
    Nous sommes en Janvier 2016.
    La colonne de l'année 2016 est affichée. Mais je veux également que pour les 11 autres mois de l'année, la colonne 2016 apparaisse, mais vide.
    Également, si l'enregistrement des données météo commence en cour d'année (avril par exemple), je veux que pour tous les mois précédents le 1er mois d'enregistrement (de janvier à mars), la colonne de la première année d'enregistrement soit affichée, mais vide.
  3. Pour chaque année présente dans la BDD (2ème boucle),
    1. A l'aide de la requête SQL, SELECT SUBSTR(recdateTZ,5,2) AS Mois, SUBSTR(recdateTZ,1,4) AS Annee, AVG(t_out_moy) AS TempMoy FROM MiniMaxidata WHERE SUBSTR(recdateTZ,5,2)=$mois AND SUBSTR(recdateTZ,1,4)=$an,
      j'extrait du champ recdateTZ le mois et l'année, la moyenne des températures dont le mois et l'année du champ recdateTZ correspondent au mois et à l'année en cours de traitement,
    2. Je donne à la variable $MoisSql3 la valeur du mois venant d'êtres extrait par la requête.
      Cette valeur sera 01,02, ..., 12 ou bien NULL
    3. Si ce mois existe (condition) (n'a pas la valeur NULL)
      Alors pour ce mois, je détermine
      • $Annee[$i]=$an; --> L'année qui servira à l'xAxis du graphique en lui donnant arbitrairement la valeur de l'année de la 2ème boucle for,
      • $TempMoy[$i]=$list['TempMoy']*1; --> La moyenne des températures moyenne,
      • $NMF[$i]=$NormaleMF[$mois]; --> La normale officielle (Météo France pour moi),
      • $Ecart[$i]=$TempMoy[$i]-$NMF[$i]; -->L'écart entre la température moyenne et la normale officielle,
      • $EcartANS[$i]=$TempMoy[$i]- $NormStation[$mois-1]; -->L'écart entre la température moyenne et la normale de la station déterminée précédemment avec la requête sql1
        Remarquez ici que la valeur de $NormStation est celle de $mois-1.
        Rappelez-vous l'incrémentation des données dans sql1 va de 0 à 11 alors qu'ici, l'incrémentation va de 1 à 12.
        Donc pour être comparé à la bonne valeur, il faut retirer 1 de $mois.
      • J'incrémente la variable d'incrémentation.
      Sinon pour ce mois qui n'existe pas (valeur NULL), je détermine
      • L'année qui servira à l'xAxis du graphique en lui donnant arbitrairement la valeur de l'année de la 2ème boucle for,
      • Les autres données, température moyenne, normales, écart auront toutes la valeur NULL.
        C'est cette astuce qui permet d'afficher une colonne vide sur le graphique.
      • J'incrémente la variable d'incrémentation.
    4. Fin de la 2ème boucle, puis
  4. Avec une 4ème requête SQL, j’extrais la température moyenne totale pour le mois en cour de traitement. Celle-ci correspond à la normale de la station.
    Les données récupérées ou définies ici servent à la dernière colonne de droite de chaque graphique.
    Je définis donc.
    • $Annee[$i]='Normale<br>station'; --> La valeur donnée à $Annee[$i] correspond à la légende affichée en bas de chaque colonne. Cela peut être n'importe quelle données alphanumérique. Nous verrons plus loin comment afficher cela sur l'xaxis des graphiques.
    • $TempMoy[$i]=$list['TempMoyMois']*1; --> La température moyenne récupérée avec la requête sql4
    • $NMF[$i]=$NormaleMF[$mois]; --> La normale mensuelle officielle
    • $Ecart[$i]=$TempMoy[$i]-$NMF[$i]; --> L'écart entre la température moyenne et la normale officielle
    • $EcartANS[$i]=NULL; --> L'écart entre la normale de la station et la normale de la station.
      Sur un graphique Highcharts, comme chaque série de données doivent avoir le même nombre de données, sous peine de plantage, nous sommes donc obligé de définir l'écart entre la normale de la station et la normale de la station.
      Par la force des chose, cette valeur est de 0.
      Comme ici il serait idiot d'afficher cette donnée, on lui donne arbitrairement la valeur NULL. Cette astuce permet que la données soit présente et donc que le graphique Highcharts ne plante pas mais que dans le tooltip cette valeur n'apparaisse pas.
  5. Important.
    Bien que la 1ère boucle for $mois ne soit pas terminée, nous allons maintenant fermer provisoirement la balise PHP avec ?> pour encoder les données du mois en cours de traitement en jSon.
  6. Nous encodons les données en jSON à l'aide du code javascript suivant. Je ne m'étends pas sur le sujet, Pierre-André l'a déjà expliqué dans sons tuto HIGHCHARTS

    <script type="text/javascript">
    eval(<?php echo "'var $SerieTempExtMoy = ".json_encode($TempMoy)."'" ?>);
    eval(<?php echo "'var $SerieAnnee = ".json_encode($Annee)."'" ?>);
    eval(<?php echo "'var $SerieNormaleMF = ".json_encode($NMF)."'" ?>);
    eval(<?php echo "'var $SerieEcart = ".json_encode($Ecart)."'" ?>);
    eval(<?php echo "'var $SerieEcartANS = ".json_encode($EcartANS)."'" ?>);
    </script>
  7. Maintenant que les données du mois en cours de traitement on été encodées, nous ré-ouvrons la balise PHP avec <?php
PUIS NOUS FERMONS LA PARENTHÈSE DE LA BOUCLE for $mois avec }

Ainsi, $mois est incrémenté de 1 et le code que je viens de décrire va être ré-exécuter pour le mois suivant jusqu'à ce que $mois soit égal à 12 pour les 12 mois de l'année.
Voici ce que donne les données encodées en JSON pour les mois de janvier
<script type="text/javascript">
eval('var TempExtMoy1 = [3.9,2.02580645161,5,3.16129032258,3.93870967742,3.60516129032]');
eval('var Annee1 = [2012,2013,2014,2015,2016,"Normale<br>station"]');
eval('var NormaleMF1 = [2.2,2.2,2.2,2.2,2.2,2.2]');
eval('var Ecart1 = [1.7,-0.174193548387,2.8,0.961290322581,1.73870967742,1.40516129032]');
eval('var EcartANS1 = [0.294838709677,-1.57935483871,1.39483870968,-0.443870967742,0.333548387097,null]');
</script>
Nous fermons maintenant définitivement la balise PHP puis nous encodons en jSON les données servant au dernier graphique.

Voila, la partie PHP et d'encodage des données est terminée.
Le code ci-dessous est celui que je viens d'expliquer. Vous devez le coller à la suite des autres. N'oubliez pas, les codes que je donnent doivent êtres collés les uns à la suite des autres, dans l'ordre ou je les ai donnés.

Code : Tout sélectionner

// ----------------------------- Début code graphique de chaque mois --------------------------------	
// Recupération des températures moyennes de chaque année pour chaque mois
	for ($mois=1 ; $mois<13 ; $mois++){
		// Détermine le nom des séries encodées en json qui servira au paramètre data des graphiques Highcharts
		$SerieTempExtMoy='TempExtMoy'.$mois;
		$SerieNormaleMF='NormaleMF'.$mois;
		$SerieEcart='Ecart'.$mois;
		$SerieEcartANS='EcartANS'.$mois;
		$SerieAnnee='Annee'.$mois;
		// Récupération des données proprement dites dans la BDD
		$i=0;                  
		for ($an=$AnneeInit ; $an < $AnneeFin; $an++){
		$sql3="SELECT SUBSTR(recdateTZ,5,2) AS Mois, SUBSTR(recdateTZ,1,4) AS Annee, AVG(t_out_moy) AS TempMoy FROM MiniMaxidata WHERE SUBSTR(recdateTZ,5,2)=$mois AND SUBSTR(recdateTZ,1,4)=$an";
		$query = mysqli_query($conn,$sql3);
		$list = mysqli_fetch_assoc($query);
			$MoisSql3 = $list['Mois'];
			if (isset($MoisSql3)){
				$Annee[$i]=$an;
				$TempMoy[$i]=$list['TempMoy']*1;
				$NMF[$i]=$NormaleMF[$mois];
				$Ecart[$i]=$TempMoy[$i]-$NMF[$i];
				$EcartANS[$i]=$TempMoy[$i]- $NormStation[$mois-1];
				$i++;
			}
			else {
				$Annee[$i]= $an;
				$TempMoy[$i]=NULL ;
				$NMF[$i]=NULL ;
				$Ecart[$i]=NULL ;
				$EcartANS[$i]=NULL;
				$i++;
			}
		}
	// Calcul de la température moyenne totale pour chaque mois (normale de la station) affichée dans la dernière colonne du graphique
		$sql4="SELECT SUBSTR(recdateTZ,5,2) AS Mois, AVG(t_out_moy) AS TempMoyMois FROM MiniMaxidata WHERE SUBSTR(recdateTZ,5,2)= $mois";
		$query = mysqli_query($conn,$sql4);                   
		$list = mysqli_fetch_assoc($query);
		$Annee[$i]='Normale<br>station';
		$TempMoy[$i]=$list['TempMoyMois']*1;
		$NMF[$i]=$NormaleMF[$mois];
		$Ecart[$i]=$TempMoy[$i]-$NMF[$i];
		$EcartANS[$i]=NULL;
	?>
	<script type="text/javascript"> 
	eval(<?php echo  "'var $SerieTempExtMoy =  ".json_encode($TempMoy)."'" ?>);  
	eval(<?php echo  "'var $SerieAnnee =  ".json_encode($Annee)."'" ?>);  
	eval(<?php echo  "'var $SerieNormaleMF =  ".json_encode($NMF)."'" ?>);  
	eval(<?php echo  "'var $SerieEcart =  ".json_encode($Ecart)."'" ?>);  
	eval(<?php echo  "'var $SerieEcartANS =  ".json_encode($EcartANS)."'" ?>);  
	</script>
	<?php
	}
// ----------------------------- Fin code graphique de chaque mois --------------------------------	
	?>
	<script type="text/javascript"> 
	eval(<?php echo  "'var NormStation =  ".json_encode($NormStation)."'" ?>);  
	eval(<?php echo  "'var NormMF =  ".json_encode($NormMF)."'" ?>);  
	eval(<?php echo  "'var EcartNorm =  ".json_encode($EcartNorm)."'" ?>);  
	</script>
Nous allons maintenant passer à la partie CSS.

Nous allons donc créer un fichier que vous devrez enregistrer avec l'extension .css.
Ce petit fichier va servir à mettre en forme la barre qui permet de sélectionner le graphique à afficher et les div qui servent à contenir les graphiques.

Je tiens à préciser que, hormis les classes .divtabs et .divcontenu ce code n'est pas de moi. je l'ai récupérer dans un tuto à cette adresse.

http://www.css3create.com/Navigation-a- ... ions-CSS#1

Dans la classe ul, vous pouvez modifier la propriété de width qui détermine la largeur de la barre

Dans la classe .divtabs, vous pouvez modifier les propriétés
width qui détermine la largeur du conteneur qui contient de la div d'affichage du graphique
height qui détermine la hauteur de ce même conteneur

Dans la classe .divcontenu, vous pouvez modifier les propriétés
width qui détermine la largeur de la div d'affichage du graphique
height qui détermine la hauteur de cette même div

Dans les 2 classes, la propriété de display ne doir pas être changée. Elle doit rester à none, faute de quoi, les 13 graphiques seront affichés en même temps.

Attention, on utilise la propriété display et non pas visibility. Vous trouverez bien comme moi sur internet la différence entre les deux.

Sélectionnez la totalité du code ci-dessous et enregistrez le dans un fichier nommé statevolutiontempmois.css

Code : Tout sélectionner

@charset "utf-8";
/* CSS Document */
/* Script pris ici http://www.css3create.com/Navigation-a-onglets-fluides-avec-les-transitions-CSS#1 */

ul{
	display: table;
	width: 1050px;
	margin: 5px auto;
	padding: 0;
	background: -webkit-linear-gradient(deepskyblue, dodgerblue);
	background:    -moz-linear-gradient(deepskyblue, dodgerblue);
	background:     -ms-linear-gradient(deepskyblue, dodgerblue);
	background:      -o-linear-gradient(deepskyblue, dodgerblue);
	background:         linear-gradient(deepskyblue, dodgerblue);
	border-radius: 3px;
	box-shadow: 0 1px 3px rgba(0, 0, 0, .3),
                0 3px 5px rgba(0, 0, 0, .2),
                0 5px 10px rgba(0, 0, 0, .2),
                0 20px 20px rgba(0, 0, 0, .15);
	font-family: "Comic Sans MS", cursive;
	font-weight: bold;
	font-size: small;
}
ul li{
    display: table-cell;
}
ul li a{
    display: block;
    text-align: center;
    color: rgba(0, 0, 0, .7); 
    text-decoration: none;
    padding: 8px 8px 17px 8px;
	text-shadow: 0 1px 0 rgba(255, 255, 255, .4);
	box-shadow: 0 1px 0 rgba(255, 255, 255, .7) inset, 
					0 -1px 0 hsl(210, 100%, 32%) inset, 
					0 -2px 0 hsl(210, 100%, 38%) inset, 
					0 -3px 0 hsl(210, 100%, 44%) inset, 
					0 -4px 0 hsl(210, 100%, 50%) inset, 
					0 -5px 0 hsl(210, 100%, 60%) inset;
	transition: all .3s .1s;
	position: relative;
}
ul li:first-child a{
    border-radius: 3px 0 0 3px;
}
ul li:last-child a{
    border-radius: 0 3px 3px 0;
}
ul li a:hover, 
ul li a:focus{
    background: rgba(255,255,255,.2);
    box-shadow: 0 1px 0 rgba(255, 255, 255, .7) inset, 
                0 -1px 0 hsl(210, 100%, 42%) inset, 
                0 -2px 0 hsl(210, 100%, 48%) inset, 
                0 -3px 0 hsl(210, 100%, 54%) inset, 
                0 -4px 0 hsl(210, 100%, 60%) inset, 
                0 -5px 0 hsl(210, 100%, 70%) inset; 
	padding: 8px 25px 17px 25px;
	transition: all .3s 0s;
}
ul li a:active{
    background: linear-gradient(rgba(0,0,0,.2),rgba(0,0,0,.1)); 
    box-shadow: 0 0 2px rgba(0,0,0,.3) inset;
}
ul li a::before{
    content: '';
    position: absolute;
    left: 50%;
    bottom: 9px;
    margin-left: -2px;
    width: 6px;
    height:6px;
    border-radius: 50%;
    background: rgba(0, 0, 0, .5);
}
ul li a:hover::before,
ul li a:focus::before{
    background: white;
    box-shadow: 0 0 2px white, 
                0 -1px 0 rgba(0, 0, 0, .4);
}
.divtabs{
	width:1040px;
	height:530px;
	margin:30 0 0 0;
	background-image:url(../Images/PapierBleuClair.jpg);
	border:groove #666;
	border-radius:15px;
	display:none;
}
.divcontenu{
	width:1030px;
	height:500px;
	margin-top:15px;
	display:none;
}
Voila, fin de la partie CSS.

La partie JavaScript.

Comme nous avons créé un fichier .css, nous allons maintenant créer un fichier .js
Je lui ai donné le même nom que le fichier css, j'ai juste changé l'extension.
Donc sélectionnez le code ci-dessous et enregistrez le dans un fichier nommé statevolutiontempmois.js

Ce petit fichier contient 3 fonctions.
La première, affiche et masque les divs d'explications adéquates en bas de ma page html en fonction de l'onglet sélectionné. Ceci se fait simplement par appel à cette fonction lorsque l'on clique sur l’un des boutons de la barre de sélection du graphique à afficher.

La deuxième fonction a exactement la même utilité et est appelée exactement de la même manière que la première.
Sa fonction, si je puis dire, est d'afficher et de masquer l'onglet et le conteneur du graphique adéquat en fonction de la sélection que l'on fait dans la barre de selection.

Mais rendons à César ce qui est à César, dans les deux cas, je me suis inspiré d'un tuto expliqué ici.
http://www.supportduweb.com/scripts_tut ... -page.html

La dernière fonction, DerniereColonne(), sert elle, dans les graphiques mensuels, à récupérer le numéro de la dernière colonne tracée, afin de récupérer la valeur de la température moyenne, pour déterminer sur les yAxis la valeur de la plotLines Normale mensuelle de la station.
Dans cette fonction, vous devez changer la valeur de var debut .
Vous devez y donner comme valeur l'année précédant le début de vos relevés.

Code : Tout sélectionner

// JavaScript Document

// Fonction pour afficher ou masquer la div d'explication en bas de page
function CacheLaDivNumTab(NumTab) {
	switch(NumTab){
		case 13:
			document.getElementById('explic1').style.display="none";
			document.getElementById('explic2').style.display ="block";
			break;
			
		default:
			document.getElementById('explic1').style.display="block";
			document.getElementById('explic2').style.display ="none";
			break;
	}
}

// Fonction pour afficger ou masquer les div contenant les graphiques
// Partie du script prise ici http://www.supportduweb.com/scripts_tutoriaux-code-source-48-systeme-d-039-onglets-en-javascript-x-html-et-css-dans-la-meme-page.html

function change_onglet(onglet, conteneur){
	document.getElementById(anc_onglet).style.display = 'none';
	document.getElementById(anc_conteneur).style.display = 'none';
	document.getElementById(onglet).style.display = 'block';
	document.getElementById(conteneur).style.display = 'block';
	anc_onglet = onglet;
	anc_conteneur= conteneur;
}

function DerniereColonne(){
	var CetteAnnee = new Date()
	var debut = 2011
	var fin = CetteAnnee.getFullYear()*1
	var diff = fin - debut
	return diff
}
Passons maintenant à la partie HTML de la page web

Je ne m'étendrai pas en détail sur tous les points. Pour cela, vous devez vous référer au tuto HIGHCHARTS de Pierre-André.

Dans un premier temps, nous devons créer un lien vers le fichier CSS que nous avons créer précédemment.
Ceci se fait bien évidement entre les balises <head> et </head> comme ceci;
<link href="../css/statevolutiontempmois.css" rel="stylesheet" type="text/css" hreflang="fr" charset="UTF-8">

Bien évidemment, n’oubliez pas de changer le chemin d'accès au fichier statevolutiontempmois.css.

Maintenant, nous devons charger les librairies JavaScript. Nous avons besoin de
La librairie jquery.min.js
Les librairies Highcharts highcharts.js, grid.js, exporting.js et highcharts-more.js
La librairie jquery-ui.js.
Cette librairie, sert dans mes graphiques, à créer l'effet de rebondissement lors du traçage des colonnes ou des lignes.

Et enfin des scripts que nous avons créés précédemment statevolutiontempmois.js.

N'oubliez pas en recopiant le code, de changer le chemin des librairies

Code : Tout sélectionner

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Evolution de la température moyenne mensuelle à Conflans en Jarnisy</title>
<meta name="description" content="Graphique dynamique montrant l'évolution de la température moyenne mensuelle relevée par la station Davis Instrument Vantage PRO2 Plus de Météo Conflans en Jarnisy au fil des année">
<meta name="robots" content="index,follow">
<meta name="category" content="education, information, weather, météo">
<meta http-equiv="Content-Language" content="fr" />

<link href="../css/Styles commun.css" rel="stylesheet" type="text/css" hreflang="fr" charset="UTF-8">
<link href="../css/statevolutiontempmois.css" rel="stylesheet" type="text/css" hreflang="fr" charset="UTF-8">
      <!-- 1. Add these JavaScript inclusions in the head of your page -->
<script type="text/javascript" src="../Scripts/jquery.min.js"></script>           
<script type="text/javascript" src="../Scripts/Highcharts/js/highcharts.js"></script> 
<script type="text/javascript" src="../Scripts/Highcharts/js/themes/grid.js"></script>
<script type="text/javascript" src="../Scripts/Highcharts/js/modules/exporting.js"></script>
<script type="text/javascript" src="../Scripts/Highcharts/js/highcharts-more.js"></script>
<script type="text/javascript" src="../Scripts/jquery-ui/jquery-ui.js"></script>
<script type="text/javascript" src="../Scripts/overlib.js"></script>
<script type="text/javascript" src="../Scripts/overlib_fade.js"></script>
<script type="text/javascript" src="../Scripts/statevolutiontempmois.js"></script>
Maintenant, passons au code Highcharts proprement dit.
Celui-ci est un peu différent de celui de Pierre-André dans le sens ou, Pierre-André dans son tuto ne trace qu'un seul graphique alors qu'ici, nous allons tracer 13 graphiques sur la même page.

Nous commençons bien sur, par ouvrir la balise JavaScript <script type="text/javascript">
Nous appelons ensuite la fonction Highcharts puis nous définissons les options générales et de traduction des graphiques.

Nous commençons le traçage du premier graphique.
Souvenez-vous, dans le tuto de Pierre-André, le graphique commence comme ceci
chart = new Highcharts.Chart({
chart: {
renderTo: 'container',


Ici, il n'y a plus de new Highcharts.Chart ni de renderTo:
Nous commençons le graphique directement de cette façon
$('#container1').highcharts({

Il faudra changer pour chaque graphique le numéro du conteneur '#container1' par un numéro allant de 1 à 13.

Nous définissons ensuite les propriétés de chart: (dimensions du graphique, marges, bordures etc) et le type. Pour les graphiques de 1 à 12, il doit être de type column et pour le graphique 13 il doit être de type spline.

Ensuite, nous empêchons l'affichage du bouton d'options permettant l'impression et l'export du graphique en donnant la valeur false à l'option enabled de la propriété buttonOptions
Vous pouvez l'activer, mais il faudra recalculer la position du bouton en fonction de la dimension du graphique

Nous définissons ensuite, le titre, le sous-titre, le crédit, la légende.

Maintenant, le tooltip. Vous avez vu mon tooltip, il est joli mon tooltip.
Un joli tableau ou toutes les valeurs sont bien alignées.
Dans son tuto, Pierre-André utilise une fonction JavaScript pour mettre en forme son tooltip.
Ici, c'est un peu différent. On utilise un tableau HTML.
  • On ouvre la balise tooltip: {
  • On active le paramètre qui montre la position de la souris sur le graphique crosshairs: true,
  • On défini la couleur de la bordure borderColor: 'royalblue',
  • On détermine le nombre de décimales devant s'afficher pour chaque valeur valueDecimals: 2,
  • On détermine le suffixe devant s'afficher après chaque valeur. Ici des degrés centigrade valueSuffix: ' °C',
  • On active le partage de la bulle pour que toutes les valeurs de la colonne s'affichent dans la bulle shared: true,
  • On défini la couleur du fond backgroundColor
  • On arrondi les angles borderRadius: 5,
Maintenant on créé le tableau qui contient les valeurs. Ce tableau contient 3 colonnes
Pour ce faire, nous utilisons le paramètre
  • useHTML auquel on donne la valeur true suivi de 3 autres;
  • headerFormat,
  • pointFormat et
  • footerFormat.
  • puis on ferme la parenthèse de la balise tooltip },
Dans headerFormat, on défini la mise en forme de l'entête (l'année).
La valeur de l'année, est récupérée sur l'xAxis par la variable {point.key} puis
On ouvre la table avec la balise HTML <table> à laquelle on donne la mise en forme (le style), la largeur et la dimension de la police
headerFormat: '<span style="color:#FF0000; text-shadow:#900; font-size:14px"><b>{point.key}</b></span><table width="250px" style="border-top:ridge; font-size:12px">',

Dans pointFormat pour chaque valeur du tableau, on ouvre une ligne avec la balise HTML <tr> puis
une première colone avec la balise HTML <td> dans laquelle on met le nom de la série récupérée par la variable {series.name}, on ferme la colonne </td>
NB: ici, le nom de la série est déterminé par la variable name du paramètres series
une deuxième colonne dans laquelle on met un séparateur : en oubliant pas le l'ouvrir <td> et de la fermer </td>
enfin on ouvre une dernière colonne <td> dans laquelle on met la valeur de la série récupérée sur l'yAxis par la variable {point.y}
puis on ferme la colonne </td> et la ligne</tr>
pointFormat: '<tr><td style="color:#0099FF">{series.name}</td>' + '<td style="text-align: center"><b>:</td>' + '<td style="text-align: right"><b>{point.y}</b></td></tr>',

Dans footerFormat on ferme simplement la balise HTML '</table>'
footerFormat: '</table>',

La rubrique plotOptions.
Dans la rubrique plotOptions, pour la configuration des series, l'on configure 2 paramètres;
  • animation auquel on attribue une durée de 2000 millisecondes et l'effet (easing) auquel on attribue la valeur easeOutBounce.
    C'est cette valeur qui permet d'avoir l'effet de rebondissement des colonnes ou des lignes lors de l'affichage du graphique.
  • states ou l'on donne la valeur -0.2 au paramètre brightness de l’évènement souris hover .
    Ceci se traduit par un assombrissement de la zone de traçage d'une colonne lorsque la souris passe sur celle-ci.
L'on configure également ici, l’option générale d'affichage des colonnes, et en particulier le paramètre grouping. Celui-ci doit obligatoirement avoir la valeur false sinon, les différentes séries affichées en colonnes ne se superposerons pas mais s’afficheront cote à cote.

Le paramétrage de xAxis
Dans le tuto de Pierre-André comme dans la plupart de nos graphiques, on ne définissait qu'un seul paramètre, le type auquel on attribuait la valeur datetime. Ensuite la valeur datetime de chaque points était retournée par la fonction comArr qui transformait le tstamp de chaque point en date et heure.
Ici c'est un peu différent. Rappelez-vous un peu plus haut dans ce tuto, dans la partie PHP lors de l'extraction de $Annee[$i] je vous ai dit que c'était cette valeur qui allait servir à l'xAxis. Or celle-ci n'est pas de type datetime. Elle est de type alphanumérique.
Tantôt l'on a une valeur numérique, celle des années, tantôt une valeur alphabétique, celle de la dernière colonne de droite.
Comment faire alors. Tout simple. On défini 2 paramètres.
  • type auquel on attribue la valeur category
  • categories auquel on attribue la valeur Anneex
    le x de Anneex doit être remplacé pour chaque graphique. De 1 à 12 pour les mois de janvier à décembre.
    Anneex est tout simplement la valeur des données $Annee[$i] encodées plus tôt en JSON.
.

Le paramétrage de yAxis.
Je ne m'étendrai pas sur tous les paramètres de l'yAxis. Pour cela référez-vous au tuto de Pierre-André ou à la documentation Highcharts.
Je ne parlerai ici que des 2 plotLines et de la plotBand.

La valeur du paramètre value de la plotLines Normale mensuelle de la station est celle de la colonne Normale Station.
Pour récupérer cette valeur, l'on se sert de la fonction DerniereColonne() qui va chercher dans les données encodées en JSON la dernière valeur du champ TempExtMoyx. Cette fonction calcule l'index de la dernière valeur du champ TempExtMoyx.
N'oubliez pas de bien paramétrer la variable var debut de cette fonction afin de bien récupérer la bonne valeur. Pour cela, voir plus haut la partie JavaScript.
Bien sur comme précédemment pour Anneex , le x de TempExtMoyx doit être remplacer par un chiffre de 1 à 12 pour les 12 mois de l'année.
Pour le graphique des mois de janvier, cela donne ceci: value: TempExtMoy1[DerniereColonne()],

La deuxième plotLines correspond à la normale officielle de votre station de référence (Météo France, Suisse, Espagne, etc...) encodée dans le champ NormaleMFx.
Pour récupérer sa valeur, on prend simplement celle de la première colonne comme ceci; NormaleMFx[0]. Le zéro entre crochet est l'index de la première valeur du champ NormaleMFx.
Pour les mois de janvier, cela donne ceci: value: NormaleMF1[0],.
Comme précédemment, noubliez pas de changer la valeur de x.

Enfin, dans mes graphiques, j'ai ajouté une plotBand (ça fait joli et ça fait un repère).
Comme toutes les normales mensuelles de ma station de référence sont positives, toutes les valeurs du paramètre from de la plotBand est 0.
La valeur du paramètre to est égale à la valeur de la normale mensuelle. On la défini de la même façon que la dernière plotLines.

Le paramétrage des series
Ici aussi je ne m'étendrai pas sur le sujet.
Je n'indique ici que la valeur des paramètres name et data de chaque série.
  • name: 'T° Moyenne' --> data: TempExtMoyx
  • name: 'Normale Météo France' --> data: NormaleMFx
  • name: 'Ecart avec Normale M.F.' --> data: Ecartx
  • name: 'Ecart avec Normale Station' --> data: EcartANSx
Changez le x en fonction du mois à tracer.

La valeur de name sert à identifier la série dans le tooltip et la légende.
Deux autres paramètres ont aussi leur importance. Ne changer pas leurs valeurs. Ce sont:
  • pointPadding qui sert a obtenir un décalage entre chaque colonnes de série de données
  • zIndex qui sert à ce que la colonne ou le marker de chaque série de données soit toujours visible
Pour la série Normale Météo France, vous aurez besoin d'un petit fichier image pour le paramètre symbol de marker. Le voici
iconethermometre.png
Pour chaque graphique, pensez à enlever function(chart) {chart.renderer.image( ou à modifier le chemin des images pour y mettre les votres.

Le dernier graphique intitulé Différence entre les normales Météo France et celles dites de la Station est un peu différent des autres dans le sens ou l'on défini directement les categories du paramètre type de l'xAxis.
Ce graphique est également de type spline alors que les autres sont de type column.

Voila la partie script Highcharts est terminée. Pour des raison de limite du forum, je ne met pas le code ici mais.

Le code complet peut être téléchargé via un lien en fin de ce tuto.

Un peu de HTML à présent.
Nous allons maintenant créer la barre de menu qui permet de sélectionner le mois à afficher sur la page.
Pour cela regardez ce tuto car comme je l'ai dit précédemment cette partie n'est pas de moi. je l'ai reprise ici
http://www.css3create.com/Navigation-a- ... ions-CSS#1

J'indiquerai dans cette partie, que les id des différents éléments, les liens des balises <a> et le code à exécuter sur l'évènement onClick.
  • L'id de la div conteneur est tabs
  • L'id de la balise ul est listetabs
  • L'id de la balise li est tabx
    Vous devez créer 13 balises li. Remplacez le x de tabx par un numéro allant de 1 à 13.
    Chaque balise li contient une balise <a> qui contient une balise href dont le lien est #tabs-x ou x a la même valeur que le x de la balise li. Ce lien pointe vers la div conteneur du graphique à afficher.
  • Chaque balise li contient également un évènement onClick
    Lorsque l'on clique sur un lien, on exécute 2 scripts
    • change_onglet('tabs-x','containerx'). Ce scrit que l'on a vu plus haut dans la partie JavaScript affiche le conteneur du graphique à afficher.
    • CacheLaDivNumTab(1). Ce script affiche ou masque une div d'explications qui se trouve sous les graphiques.
Maintenant nous allons créer 13 div contenant la div conteneur de chaque graphique.
La 1ère doit avoir la classe divtabs et la seconde, celle qui contient le graphique, la classe divcontenu.

Un dernier code JavaScript va forcer l'affichage du graphique du mois en cours à l'ouverture de la page et enfin trois div d'explications en bas de page(voir le script complet à télécharger).

Lien vers le code complet à télécharger. http://www.monsite-meteo.eu/Download/st ... eparan.txt
Faites un clic droit sur le lien ci-dessus puis, cliquez sur Enregistrer la cible du lien sous...
lorsque la fenêtre d'enregistrement du fichier s'ouvre, changer l'extension .txt en .php

Voila. Fin du tuto. Volontairement, je ne me suis pas étendu sur la partie HTML. S'il y a des fautes :oops: , ne m'en voulez pas mais j'ai les yeux qui commencent à papilloter :roll: à force de relire le texte au milieu du code.
Vous n’avez pas les permissions nécessaires pour voir les fichiers joints à ce message.
Modifié en dernier par PascalWMR le 28 févr. 2016, 09:30, modifié 1 fois.
Station VP2Plus, Windows 10 64 bits,WeatherLink 6.0.5, VP2SQL, Graphiques Dynamiques à partir d'une BDD MySQL
Météo Conflans-en-Jarnisy
Image

Avatar du membre
Météo Villarzel
Administrateur du site
Messages : 524
Enregistré le : 06 févr. 2014, 09:48
Contact :

Re: Evolution de la température moyenne des mois au fil des

Message par Météo Villarzel » 27 févr. 2016, 17:25

Pascal,

Oh putain c'est un vrai cours PHP, Highcharts,html,JS.. que tu nous donnes, chapeau bas pour ce tutoriel qui a dû te prendre un sacré temps.
Il va falloir que je prenne une semaine de vacances pour le lire et pour le comprendre :lol:

En tous cas merci pour cet excellent travail.

A+
Station Vantage Pro2+ avec station agricole - Weatherlink - GraphWeather 3.0.15b - Cumulus 1.9.4 - Windows 7/64
Graphique dynamique à partir d'une bd MySql - VP2SQL

Image

Javier
Messages : 263
Enregistré le : 15 févr. 2014, 09:23
Localisation : San Sebastián, España
Contact :

Re: Evolution de la température moyenne des mois au fil des

Message par Javier » 17 mars 2016, 20:08

Salut Pascal (et Pierre-André) :P

Je ai maintenant votre graphique sur mon site:

http://kocher.es/meteotemplate/plugins/ ... eparan.php

http://kocher.es/meteotemplate/plugins/ ... n-menu.php

Je vous félicite pour l'excellent travail que vous avez fait; de design des couleurs qui changent selon la saison, à l'intégration de 12 mois obtenus avec ce magnifique menu, que je trouve très réussi.

En outre, la quantité et la qualité des informations fournies par le graphique, me fait penser le nombre d'heures passées à l'obtenir.

Félicitations pour ce grand travail !!! :D
Davis Vantage Pro2 +, Windows 10, Windows 7 (64), Graphweather 3.0.15, Weatherlink 6.0.3, template Pierre-André, template Jachym
Image

Répondre