PageRenderTime 46ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/htdocs/core/class/dolgraph.class.php

https://github.com/asterix14/dolibarr
PHP | 674 lines | 373 code | 98 blank | 203 comment | 65 complexity | 8b0b107939bc8372bc1bfbace4dd74bc MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (c) 2003-2006 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (c) 2004-2008 Laurent Destailleur <eldy@users.sourceforge.net>
  4. *
  5. * This program is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or
  8. * (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. /**
  19. * \file htdocs/core/class/dolgraph.class.php
  20. * \ingroup core
  21. * \brief Fichier de la classe mere de gestion des graph
  22. *
  23. * Usage:
  24. * $graph_data = array(array('labelA',yA),array('labelB',yB));
  25. * array(array('labelA',yA1,...,yAn),array('labelB',yB1,...yBn));
  26. * $px = new DolGraph();
  27. * $px->SetData($graph_data);
  28. * $px->SetMaxValue($px->GetCeilMaxValue());
  29. * $px->SetMinValue($px->GetFloorMinValue());
  30. * $px->SetTitle("title");
  31. * $px->SetLegend(array("Val1","Val2"));
  32. * $px->SetWidth(width);
  33. * $px->SetHeight(height);
  34. * $px->draw("file.png");
  35. */
  36. /**
  37. * \class DolGraph
  38. * \brief Parent class of graph classes
  39. */
  40. class DolGraph
  41. {
  42. //! Type du graphique
  43. var $type='bars'; // bars, lines, ...
  44. var $mode='side'; // Mode bars graph: side, depth
  45. //! Tableau de donnees
  46. var $data; // array(array('abs1',valA1,valB1), array('abs2',valA2,valB2), ...)
  47. var $width=380;
  48. var $height=200;
  49. var $MaxValue=0;
  50. var $MinValue=0;
  51. var $SetShading=0;
  52. var $PrecisionY=-1;
  53. var $horizTickIncrement=-1;
  54. var $SetNumXTicks=-1;
  55. var $labelInterval=-1;
  56. var $hideXGrid=false;
  57. var $hideYGrid=false;
  58. var $Legend=array();
  59. var $LegendWidthMin=0;
  60. var $graph; // Objet Graph (Artichow, Phplot...)
  61. var $error;
  62. var $library=''; // Par defaut on utiliser PHPlot
  63. var $bordercolor; // array(R,G,B)
  64. var $bgcolor; // array(R,G,B)
  65. var $bgcolorgrid; // array(R,G,B)
  66. var $datacolor; // array(array(R,G,B),...)
  67. /**
  68. * Constructor
  69. */
  70. function DolGraph()
  71. {
  72. global $conf;
  73. global $theme_bordercolor, $theme_datacolor, $theme_bgcolor, $theme_bgcoloronglet;
  74. // Test si module GD present
  75. $modules_list = get_loaded_extensions();
  76. $isgdinstalled=0;
  77. foreach ($modules_list as $module)
  78. {
  79. if ($module == 'gd') { $isgdinstalled=1; }
  80. }
  81. if (! $isgdinstalled)
  82. {
  83. $this->error="Error: PHP GD module is not available. It is required to build graphics.";
  84. return -1;
  85. }
  86. // Defini proprietes de l'objet graphe
  87. $this->library=$conf->global->MAIN_GRAPH_LIBRARY;
  88. $this->bordercolor = array(235,235,224);
  89. $this->datacolor = array(array(120,130,150), array(160,160,180), array(190,190,220));
  90. $this->bgcolor = array(235,235,224);
  91. $color_file = DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/graph-color.php";
  92. if (is_readable($color_file))
  93. {
  94. include_once($color_file);
  95. if (isset($theme_bordercolor)) $this->bordercolor = $theme_bordercolor;
  96. if (isset($theme_datacolor)) $this->datacolor = $theme_datacolor;
  97. if (isset($theme_bgcolor)) $this->bgcolor = $theme_bgcolor;
  98. }
  99. //print 'bgcolor: '.join(',',$this->bgcolor).'<br>';
  100. return 1;
  101. }
  102. /**
  103. * Set Y precision
  104. *
  105. * @param float $which_prec
  106. * @return string
  107. */
  108. function SetPrecisionY($which_prec)
  109. {
  110. $this->PrecisionY = $which_prec;
  111. return true;
  112. }
  113. /**
  114. * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
  115. *
  116. * @param float $xi
  117. */
  118. function SetHorizTickIncrement($xi)
  119. {
  120. $this->horizTickIncrement = $xi;
  121. return true;
  122. }
  123. /**
  124. * Utiliser SetNumTicks ou SetHorizTickIncrement mais pas les 2
  125. *
  126. * @param float $xt
  127. */
  128. function SetNumXTicks($xt)
  129. {
  130. $this->SetNumXTicks = $xt;
  131. return true;
  132. }
  133. /**
  134. * Set label interval to reduce number of labels
  135. *
  136. * @param float $x
  137. */
  138. function SetLabelInterval($x)
  139. {
  140. $this->labelInterval = $x;
  141. return true;
  142. }
  143. /**
  144. * Hide X grid
  145. */
  146. function SetHideXGrid($bool)
  147. {
  148. $this->hideXGrid = $bool;
  149. return true;
  150. }
  151. /**
  152. * Hide Y grid
  153. */
  154. function SetHideYGrid($bool)
  155. {
  156. $this->hideYGrid = $bool;
  157. return true;
  158. }
  159. /**
  160. *
  161. * @param unknown_type $label
  162. */
  163. function SetYLabel($label)
  164. {
  165. $this->YLabel = $label;
  166. }
  167. /**
  168. *
  169. * @param $w
  170. */
  171. function SetWidth($w)
  172. {
  173. $this->width = $w;
  174. }
  175. /**
  176. *
  177. * @param $title
  178. */
  179. function SetTitle($title)
  180. {
  181. $this->title = $title;
  182. }
  183. /**
  184. *
  185. * @param $data
  186. */
  187. function SetData($data)
  188. {
  189. $this->data = $data;
  190. }
  191. /**
  192. *
  193. * @param $type
  194. */
  195. function SetType($type)
  196. {
  197. $this->type = $type;
  198. }
  199. /**
  200. *
  201. * @param $legend
  202. */
  203. function SetLegend($legend)
  204. {
  205. $this->Legend = $legend;
  206. }
  207. /**
  208. *
  209. * @param $legendwidthmin
  210. */
  211. function SetLegendWidthMin($legendwidthmin)
  212. {
  213. $this->LegendWidthMin = $legendwidthmin;
  214. }
  215. /**
  216. *
  217. * @param $max
  218. */
  219. function SetMaxValue($max)
  220. {
  221. $this->MaxValue = $max;
  222. }
  223. /**
  224. *
  225. */
  226. function GetMaxValue()
  227. {
  228. return $this->MaxValue;
  229. }
  230. /**
  231. *
  232. * @param $min
  233. */
  234. function SetMinValue($min)
  235. {
  236. $this->MinValue = $min;
  237. }
  238. /**
  239. *
  240. */
  241. function GetMinValue()
  242. {
  243. return $this->MinValue;
  244. }
  245. /**
  246. *
  247. * @param $h
  248. */
  249. function SetHeight($h)
  250. {
  251. $this->height = $h;
  252. }
  253. /**
  254. *
  255. * @param $s
  256. */
  257. function SetShading($s)
  258. {
  259. $this->SetShading = $s;
  260. }
  261. /**
  262. *
  263. */
  264. function ResetBgColor()
  265. {
  266. unset($this->bgcolor);
  267. }
  268. /**
  269. *
  270. */
  271. function ResetBgColorGrid()
  272. {
  273. unset($this->bgcolorgrid);
  274. }
  275. /**
  276. *
  277. */
  278. function isGraphKo()
  279. {
  280. return $this->error;
  281. }
  282. /**
  283. * Definie la couleur de fond de l'image complete
  284. *
  285. * @param array $bg_color array(R,G,B) ou 'onglet' ou 'default'
  286. * @return void
  287. */
  288. function SetBgColor($bg_color = array(255,255,255))
  289. {
  290. global $theme_bgcolor,$theme_bgcoloronglet;
  291. if (! is_array($bg_color))
  292. {
  293. if ($bg_color == 'onglet')
  294. {
  295. //print 'ee'.join(',',$theme_bgcoloronglet);
  296. $this->bgcolor = $theme_bgcoloronglet;
  297. }
  298. else
  299. {
  300. $this->bgcolor = $theme_bgcolor;
  301. }
  302. }
  303. else
  304. {
  305. $this->bgcolor = $bg_color;
  306. }
  307. }
  308. /**
  309. * Definie la couleur de fond de la grille
  310. *
  311. * @param array $bg_colorgrid array(R,G,B) ou 'onglet' ou 'default'
  312. */
  313. function SetBgColorGrid($bg_colorgrid = array(255,255,255))
  314. {
  315. global $theme_bgcolor,$theme_bgcoloronglet;
  316. if (! is_array($bg_colorgrid))
  317. {
  318. if ($bg_colorgrid == 'onglet')
  319. {
  320. //print 'ee'.join(',',$theme_bgcoloronglet);
  321. $this->bgcolorgrid = $theme_bgcoloronglet;
  322. }
  323. else
  324. {
  325. $this->bgcolorgrid = $theme_bgcolor;
  326. }
  327. }
  328. else
  329. {
  330. $this->bgcolorgrid = $bg_colorgrid;
  331. }
  332. }
  333. /**
  334. *
  335. */
  336. function ResetDataColor()
  337. {
  338. unset($this->datacolor);
  339. }
  340. /**
  341. *
  342. */
  343. function GetMaxValueInData()
  344. {
  345. $k = 0;
  346. $vals = array();
  347. $nblines = count($this->data);
  348. $nbvalues = count($this->data[0]) - 1;
  349. for ($j = 0 ; $j < $nblines ; $j++)
  350. {
  351. for ($i = 0 ; $i < $nbvalues ; $i++)
  352. {
  353. $vals[$k] = $this->data[$j][$i+1];
  354. $k++;
  355. }
  356. }
  357. rsort($vals);
  358. return $vals[0];
  359. }
  360. /**
  361. *
  362. */
  363. function GetMinValueInData()
  364. {
  365. $k = 0;
  366. $vals = array();
  367. $nblines = count($this->data);
  368. $nbvalues = count($this->data[0]) - 1;
  369. for ($j = 0 ; $j < $nblines ; $j++)
  370. {
  371. for ($i = 0 ; $i < $nbvalues ; $i++)
  372. {
  373. $vals[$k] = $this->data[$j][$i+1];
  374. $k++;
  375. }
  376. }
  377. sort($vals);
  378. return $vals[0];
  379. }
  380. /**
  381. * Return max value of all data
  382. *
  383. * @return int Max value of all data
  384. */
  385. function GetCeilMaxValue()
  386. {
  387. $max = $this->GetMaxValueInData();
  388. if ($max != 0) $max++;
  389. $size=dol_strlen(abs(ceil($max)));
  390. $factor=1;
  391. for ($i=0; $i < ($size-1); $i++)
  392. {
  393. $factor*=10;
  394. }
  395. $res=0;
  396. if (is_numeric($max)) $res=ceil($max/$factor)*$factor;
  397. //print "max=".$max." res=".$res;
  398. return $res;
  399. }
  400. /**
  401. * Return min value of all data
  402. *
  403. * @return int Max value of all data
  404. */
  405. function GetFloorMinValue()
  406. {
  407. $min = $this->GetMinValueInData();
  408. if ($min != 0) $min--;
  409. $size=dol_strlen(abs(floor($min)));
  410. $factor=1;
  411. for ($i=0; $i < ($size-1); $i++)
  412. {
  413. $factor*=10;
  414. }
  415. $res=floor($min/$factor)*$factor;
  416. //print "min=".$min." res=".$res;
  417. return $res;
  418. }
  419. /**
  420. * Build a graph onto disk using correct library
  421. *
  422. * @param string $file Image file name on disk to generate
  423. * @return void
  424. */
  425. function draw($file)
  426. {
  427. if (! is_array($this->data) || count($this->data) < 1)
  428. {
  429. $this->error="Call to draw method was made but SetData was not called or called with an empty dataset for parameters";
  430. dol_syslog("DolGraph::draw ".$this->error, LOG_ERR);
  431. return -1;
  432. }
  433. $call = "draw_".$this->library;
  434. $this->$call($file);
  435. }
  436. /**
  437. * Build a graph onto disk using Artichow library
  438. *
  439. * @param string $file Image file name on disk to generate
  440. * @return void
  441. */
  442. private function draw_artichow($file)
  443. {
  444. global $artichow_defaultfont;
  445. dol_syslog("DolGraph.class::draw_artichow this->type=".$this->type);
  446. if (! defined('SHADOW_RIGHT_TOP')) define('SHADOW_RIGHT_TOP',3);
  447. if (! defined('LEGEND_BACKGROUND')) define('LEGEND_BACKGROUND',2);
  448. if (! defined('LEGEND_LINE')) define('LEGEND_LINE',1);
  449. // Create graph
  450. $classname='';
  451. if ($this->type == 'bars') $classname='BarPlot';
  452. if ($this->type == 'lines') $classname='LinePlot';
  453. include_once(ARTICHOW_PATH.$classname.".class.php");
  454. // Definition de couleurs
  455. $bgcolor=new Color($this->bgcolor[0],$this->bgcolor[1],$this->bgcolor[2]);
  456. $bgcolorgrid=new Color($this->bgcolorgrid[0],$this->bgcolorgrid[1],$this->bgcolorgrid[2]);
  457. $colortrans=new Color(0,0,0,100);
  458. $colorsemitrans=new Color(255,255,255,60);
  459. $colorgradient= new LinearGradient(new Color(235, 235, 235),new Color(255, 255, 255),0);
  460. $colorwhite=new Color(255,255,255);
  461. // Graph
  462. $graph = new Graph($this->width, $this->height);
  463. $graph->border->hide();
  464. $graph->setAntiAliasing(true);
  465. if (isset($this->title))
  466. {
  467. $graph->title->set($this->title);
  468. //print $artichow_defaultfont;exit;
  469. $graph->title->setFont(new $artichow_defaultfont(10));
  470. }
  471. if (is_array($this->bgcolor)) $graph->setBackgroundColor($bgcolor);
  472. else $graph->setBackgroundGradient($colorgradient);
  473. $group = new PlotGroup;
  474. //$group->setSpace(5, 5, 0, 0);
  475. $paddleft=50;
  476. $paddright=10;
  477. $strl=dol_strlen(max(abs($this->MaxValue),abs($this->MinValue)));
  478. if ($strl > 6) $paddleft += ($strln * 4);
  479. $group->setPadding($paddleft, $paddright); // Width on left and right for Y axis values
  480. $group->legend->setSpace(0);
  481. $group->legend->setPadding(2,2,2,2);
  482. $group->legend->setPosition(NULL,0.1);
  483. $group->legend->setBackgroundColor($colorsemitrans);
  484. if (is_array($this->bgcolorgrid)) $group->grid->setBackgroundColor($bgcolorgrid);
  485. else $group->grid->setBackgroundColor($colortrans);
  486. if ($this->hideXGrid) $group->grid->hideVertical(true);
  487. if ($this->hideYGrid) $group->grid->hideHorizontal(true);
  488. // On boucle sur chaque lot de donnees
  489. $legends=array();
  490. $i=0;
  491. $nblot=count($this->data[0])-1;
  492. while ($i < $nblot)
  493. {
  494. $j=0;
  495. $values=array();
  496. foreach($this->data as $key => $valarray)
  497. {
  498. $legends[$j] = $valarray[0];
  499. $values[$j] = $valarray[$i+1];
  500. $j++;
  501. }
  502. // Artichow ne gere pas les valeurs inconnues
  503. // Donc si inconnu, on la fixe a null
  504. $newvalues=array();
  505. foreach($values as $val)
  506. {
  507. $newvalues[]=(is_numeric($val) ? $val : null);
  508. }
  509. if ($this->type == 'bars')
  510. {
  511. //print "Lot de donnees $i<br>";
  512. //print_r($values);
  513. //print '<br>';
  514. $color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
  515. $colorbis=new Color(min($this->datacolor[$i][0]+50,255),min($this->datacolor[$i][1]+50,255),min($this->datacolor[$i][2]+50,255),50);
  516. $colorgrey=new Color(100,100,100);
  517. $colorborder=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2]);
  518. if ($this->mode == 'side') $plot = new BarPlot($newvalues, $i+1, $nblot);
  519. if ($this->mode == 'depth') $plot = new BarPlot($newvalues, 1, 1, ($nblot-$i-1)*5);
  520. $plot->barBorder->setColor($colorgrey);
  521. //$plot->setBarColor($color);
  522. $plot->setBarGradient(new LinearGradient($colorbis, $color, 90));
  523. if ($this->mode == 'side') $plot->setBarPadding(0.1, 0.1);
  524. if ($this->mode == 'depth') $plot->setBarPadding(0.1, 0.4);
  525. if ($this->mode == 'side') $plot->setBarSpace(5);
  526. if ($this->mode == 'depth') $plot->setBarSpace(2);
  527. $plot->barShadow->setSize($this->SetShading);
  528. $plot->barShadow->setPosition(SHADOW_RIGHT_TOP);
  529. $plot->barShadow->setColor(new Color(160, 160, 160, 50));
  530. $plot->barShadow->smooth(TRUE);
  531. //$plot->setSize(1, 0.96);
  532. //$plot->setCenter(0.5, 0.52);
  533. // Le mode automatique est plus efficace
  534. $plot->SetYMax($this->MaxValue);
  535. $plot->SetYMin($this->MinValue);
  536. }
  537. if ($this->type == 'lines')
  538. {
  539. $color=new Color($this->datacolor[$i][0],$this->datacolor[$i][1],$this->datacolor[$i][2],20);
  540. $colorbis=new Color(min($this->datacolor[$i][0]+20,255),min($this->datacolor[$i][1]+20,255),min($this->datacolor[$i][2]+20,255),60);
  541. $colorter=new Color(min($this->datacolor[$i][0]+50,255),min($this->datacolor[$i][1]+50,255),min($this->datacolor[$i][2]+50,255),90);
  542. $plot = new LinePlot($newvalues);
  543. //$plot->setSize(1, 0.96);
  544. //$plot->setCenter(0.5, 0.52);
  545. $plot->setColor($color);
  546. $plot->setThickness(1);
  547. // Set line background gradient
  548. $plot->setFillGradient(new LinearGradient($colorter, $colorbis, 90));
  549. $plot->xAxis->setLabelText($legends);
  550. // Le mode automatique est plus efficace
  551. $plot->SetYMax($this->MaxValue);
  552. $plot->SetYMin($this->MinValue);
  553. //$plot->setYAxis(0);
  554. //$plot->hideLine(true);
  555. }
  556. //$plot->reduce(80); // Evite temps d'affichage trop long et nombre de ticks absisce satures
  557. $group->legend->setTextFont(new $artichow_defaultfont(10)); // This is to force Artichow to use awFileFontDriver to
  558. // solve a bug in Artichow with UTF8
  559. if (count($this->Legend))
  560. {
  561. if ($this->type == 'bars') $group->legend->add($plot, $this->Legend[$i], LEGEND_BACKGROUND);
  562. if ($this->type == 'lines') $group->legend->add($plot, $this->Legend[$i], LEGEND_LINE);
  563. }
  564. $group->add($plot);
  565. $i++;
  566. }
  567. $group->axis->bottom->setLabelText($legends);
  568. $group->axis->bottom->label->setFont(new $artichow_defaultfont(7));
  569. //print $group->axis->bottom->getLabelNumber();
  570. if ($this->labelInterval > 0) $group->axis->bottom->setLabelInterval($this->labelInterval);
  571. $graph->add($group);
  572. // Generate file
  573. $graph->draw($file);
  574. }
  575. }
  576. ?>