Calculettes pour l'hydraulique
graph.class.php
Aller à la documentation de ce fichier.
1 <?php
2 /*
3  * hydraulic/inc_hyd/graph.class.php
4  *
5  *
6  *
7  * Copyright 2012 David Dorchies <dorch@dorch.fr>
8  *
9  *
10  *
11  * This program is free software; you can redistribute it and/or modify
12  *
13  * it under the terms of the GNU General Public License as published by
14  *
15  * the Free Software Foundation; either version 2 of the License, or
16  *
17  * (at your option) any later version.
18  *
19  *
20  *
21  * This program is distributed in the hope that it will be useful,
22  *
23  * but WITHOUT ANY WARRANTY; without even the implied warranty of
24  *
25  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26  *
27  * GNU General Public License for more details.
28  *
29  *
30  *
31  * You should have received a copy of the GNU General Public License
32  *
33  * along with this program; if not, write to the Free Software
34  *
35  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
36  *
37  * MA 02110-1301, USA.
38  *
39  */
40 
41 /**
42  * Classe pour l'affichage des graphiques
43  *
44  * @date 09/01/2012
45  * @author David Dorchies
46  *
47  */
48 class cGraph {
49 
50  const DBG = false; /// Activation des messages de débuggage de la classe
51 
52  private $tSeries; //!< Tableau des séries
53  private $echo; //!< Chaine contenant le script jqPlot
54  private $tLabels; /// Respectivement les titres du graphique, des abscisses, des ordonnées
55  ///@todo Transférer les deux constantes de graduation dans la configuration du plugin
56  const nbTickXmax = 10; // Nbre max de graduation sur l'axe des abscisses
57  const nbTickYmax = 10; // Nbre max de graduation sur l'axe des ordonnées
58 
59  function __construct($Title = '', $Xlabel='', $Ylabel='') {
60  $this->tSeries = array();
61  $this->tLabels = array(
62  'title' => $Title,
63  'X' => $Xlabel,
64  'Y' => $Ylabel
65  );
66  }
67 
68  /**
69  * Ajout d'une série de données dans le graph
70  *
71  * @param $sNom Nom de la série dans la légende
72  * @param $tY Tableau des ordonnées de la série
73  * @param $tX Tableau des abscisses de la série (facultatif à partir de la 2ème série)
74  */
75  function AddSerie($sNom, $tX, $tY, $sCouleur, $tOptions = array()) {
76  $num = count($this->tSeries) + 1;
77  $this->tSeries[$num] = new cSerie($num, $sNom, $tX, $tY, $sCouleur, $tOptions);
78  }
79 
80  function GetAxesOptions($rDecal = 0, $rPente = 0, $rXFin = 0) {
81  // Tableau des Abscisses et des ordonnées
82  $tX = array(); $tY = array();
83  foreach($this->tSeries as $oSeries) {
84  $tX = array_merge($tX,array_keys($oSeries->tXY));
85  $tY = array_merge($tY, array_values($oSeries->tXY));
86  }
87  // Options pour chacun
88  $XOptions = $this->Get1AxeOptions($tX, self::nbTickXmax);
89  $YOptions = $this->Get1AxeOptions($tY, self::nbTickYmax);
90  return array_merge($XOptions, $YOptions);
91  }
92 
93  function Get1AxeOptions($tX, $Tmax) {
94  $Xmin = min($tX);
95  $Xmax = max($tX);
96 
97  if($Xmin == $Xmax){
98  $Xmin = $Xmin * 0.9;
99  $Xmax = $Xmax * 1.1;
100  }
101 
102  if($Xmin == 0 && $Xmax == 0){
103  $Xmin = -1;
104  $Xmax = 1;
105  }
106 
107  $r1 = ($Xmax - $Xmin) / floatval($Tmax);
108  $r2 = floor($r1 * pow(10,(-floor(log10($r1))))*10)/10;
109 
110  if($r2 > 5) {
111  $XTick = 10;
112  }
113  elseif($r2 > 2.5) {
114  $XTick = 5;
115  }
116  elseif($r2 > 2) {
117  $XTick = 2.5;
118  }
119  elseif($r2 > 1) {
120  $XTick = 2;
121  }
122  else {
123  $XTick = 1;
124  }
125 
126  // Ecart entre chaque graduation
127  $XTick = $XTick * pow(10, floor(log10($r1)));
128 
129  // Minimum et maximum arrondis par rapport à $XTick
130  $Xmin = floor($Xmin / $XTick) * $XTick;
131  $Xmax = ceil($Xmax / $XTick) * $XTick;
132 
133  return array($Xmin, $Xmax, $XTick);
134  }
135 
136  /**
137  * Décale les ordonnées selon un offset et une pente
138  * @param $rDecal Offset pour décaler l'affichage des ordonnées
139  * @param $rPente Pente pour décaler l'affichage des ordonnées
140  * @param $rXFin Si différent de zéro, abscisse à partir de laquelle calculer la pente
141  */
142  function Decal($rDecal = 0, $rPente = 0, $rXFin = 0) {
143  foreach($this->tSeries as $oSerie) {
144  $oSerie->RecalOrdonnees($rDecal, $rPente, $rXFin);
145  }
146  }
147 
148  /**
149  * Renvoie le script jqplot du graphique
150  * @param $sId Attribut id de la balise DIV où sera créé le graphique
151  * @param $iHeight Hauteur du graphique en pixels
152  * @param $iWidth Largeur du graphique en pixels
153  */
154  function GetGraph($sId, $iHeight, $iWidth) {
155  if(self::DBG) spip_log($this->tSeries,'hydraulic',_LOG_DEBUG);
156  $sId = 'jqplot_'.$sId;
157  $this->echo = sprintf('
158  <div id="%s" style="height:%spx;width:%spx; "></div>',
159  $sId, $iHeight, $iWidth);
160  $this->echo .= '
161  <script language="javascript" type="text/javascript">';
162  // On récupère les données de chaque série
163  foreach($this->tSeries as $oSerie) {
164  $this->echo .= $oSerie->GetPush();
165  }
166  $tS = array();
167  for($i=1; $i<=count($this->tSeries); $i++) {
168  $tS[]='tSerie'.$i;
169  }
170  $this->echo .= sprintf('
171  chart=$.jqplot(\'%s\',
172  [%s],',
173  $sId,
174  implode(', ',$tS));
175  $this->echo .= '
176  {';
177  if($this->tLabels['title']) {
178  $this->echo .= '
179  title:\''.$this->tLabels['title'].'\',';
180  }
181  $this->echo .= '
182  seriesDefaults: {showMarker:false},';
183  $tS = array();
184  foreach($this->tSeries as $oSerie) {
185  $tS[] = $oSerie->GetConfig();
186  }
187  $this->echo .= sprintf('
188  series:[
189  %s
190  ],',
191  implode(',
192  ',$tS)
193  );
194  // Options de légende et curseur
195  $this->echo .= '
196  legend: {show: true, location:\'ne\', fontSize:\'1em\'},
197  cursor: {
198  show:true,
199  showVerticalLine: true,
200  showHorizontalLine: true,
201  showCursorLegend: true,
202  showTooltip: false,
203  zoom: true,
204  dblClickReset: false,
205  intersectionThreshold: 6
206  },';
207  // Options des axes
208  list($Xmin, $Xmax, $XTick, $Ymin, $Ymax, $YTick) = $this->GetAxesOptions();
209  $this->echo .= sprintf('
210  axes:{
211  xaxis:{
212  label:\'%s\',
213  labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
214  min:%s,
215  max:%s,
216  tickInterval:%s},
217  yaxis:{
218  label:\'%s\',
219  labelRenderer: $.jqplot.CanvasAxisLabelRenderer,
220  min:%s,
221  max:%s,
222  tickInterval:%s,
223  tickOptions:{formatString:\'%%.3f\'}
224  }
225  }
226  }
227  );
228  </script>',
229  addslashes($this->tLabels['X']),$Xmin,$Xmax,$XTick,
230  addslashes($this->tLabels['Y']),$Ymin,$Ymax,$YTick);
231 
232  return $this->echo;
233  }
234 }
235 
236 /**
237  * Classe pour la gestion des séries dans le graph
238  *
239  * @date 09/01/2012
240  * @author David Dorchies
241  *
242  */
243 class cSerie {
244  private $num; //!< Numéro d'ordre de la série
245  private $sNom; //!< Nom de la série (Balise de langue telle que définie dans lang/hydraulic_xx.php)
246  public $tXY; //!< Tableau $this->tXY[abscisse]=ordonnée
247  private $sCouleur; //!< Couleur de la courbe (Code HTML)
248  private $sOptions; //!< Options supplémentaires
249 
250  /**
251  * Construction de la classe
252  *
253  * @param $sNom Nom de la série (Balise de langue telle que définie dans lang/hydraulic_xx.php)
254  * @param $tX Tableau des abscisses
255  * @param $tY Tableau des ordonnées (Même taille que $tX) ou réel pour une valeur fixe
256  * @param $sCouleur Couleur de la courbe (Code HTML)
257  * @param $iLineWidth Epaisseur de la courbe
258  * @param $sOptions Options supplémentaires
259  */
260  function __construct($num, $sNom, $tX, $tY, $sCouleur, $sOptions = '') {
261  $this->num = $num;
262  $this->sNom = $sNom;
263  if(is_array($tY)) {
264  $this->tXY = array_combine($tX, $tY);
265  }
266  else {
267  $this->tXY = array_fill_keys($tX, $tY);
268  }
269  $this->sCouleur = $sCouleur;
270  $this->sOptions = $sOptions;
271  }
272 
273  /**
274  * Retourne la chaine à insérer dans l'option series de jqplot
275  */
276  function GetConfig() {
277  $ret = sprintf(
278  '{label:\'%s\', color:\'%s\'',
279  addslashes(_T('hydraulic:'.$this->sNom)),
280  $this->sCouleur);
281  if($this->sOptions) {
282  $ret .= ', '.$this->sOptions;
283  }
284  $ret .= '}';
285  return $ret;
286  }
287 
288  /**
289  * Retourne la chaine des push du tableau de la série
290  */
291  function GetPush() {
292  $ret = sprintf("\nvar tSerie%s=[];",$this->num);
293  foreach($this->tXY as $rX=>$rY) {
294  $ret .= sprintf("\ntSerie%s.push([%s, %s]);", $this->num, $rX, $rY);
295  }
296  return $ret."\n";
297  }
298 
299  /**
300  * Recalcule les ordonnées sur une base Y * pente + fond
301  * @param $rDecal Offset pour décaler l'affichage des ordonnées
302  * @param $rPente Pente pour décaler l'affichage des ordonnées
303  * @param $rXFin Si différent de zéro, abscisse à partir de laquelle calculer la pente
304  * @bug ne fonctionne pas si l'abscisse minimum est différente de 0
305  */
306  function RecalOrdonnees($rDecal = 0, $rPente = 0, $rXFin = 0) {
307  $rCoteFond = $rDecal;
308  foreach($this->tXY as $rX=>&$rY) {
309  if($rPente) {
310  if($rXFin) {
311  $rY = $rY + $rDecal + $rPente * ($rXFin - $rX);
312  }
313  else {
314  $rY = $rY + $rDecal + $rPente * $rX;
315  }
316  }
317  }
318  }
319 }
320 ?>
$num
Numéro d&#39;ordre de la série.
RecalOrdonnees($rDecal=0, $rPente=0, $rXFin=0)
Recalcule les ordonnées sur une base Y * pente + fond.
__construct($num, $sNom, $tX, $tY, $sCouleur, $sOptions='')
Construction de la classe.
$tXY
Tableau $this->tXY[abscisse]=ordonnée.
const DBG
Definition: graph.class.php:50
AddSerie($sNom, $tX, $tY, $sCouleur, $tOptions=array())
Ajout d&#39;une série de données dans le graph.
Definition: graph.class.php:75
$sNom
Nom de la série (Balise de langue telle que définie dans lang/hydraulic_xx.php)
$sCouleur
Couleur de la courbe (Code HTML)
GetAxesOptions($rDecal=0, $rPente=0, $rXFin=0)
Definition: graph.class.php:80
$tSeries
Activation des messages de débuggage de la classe.
Definition: graph.class.php:52
GetGraph($sId, $iHeight, $iWidth)
Renvoie le script jqplot du graphique.
const nbTickXmax
Respectivement les titres du graphique, des abscisses, des ordonnées.
Definition: graph.class.php:56
$echo
Chaine contenant le script jqPlot.
Definition: graph.class.php:53
Classe pour l&#39;affichage des graphiques.
Definition: graph.class.php:48
GetConfig()
Retourne la chaine à insérer dans l&#39;option series de jqplot.
const nbTickYmax
Definition: graph.class.php:57
Decal($rDecal=0, $rPente=0, $rXFin=0)
Décale les ordonnées selon un offset et une pente.
Get1AxeOptions($tX, $Tmax)
Definition: graph.class.php:93
GetPush()
Retourne la chaine des push du tableau de la série.
__construct($Title='', $Xlabel='', $Ylabel='')
Definition: graph.class.php:59
Classe pour la gestion des séries dans le graph.
$sOptions
Options supplémentaires.