PageRenderTime 61ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/Image/Graph.php

https://bitbucket.org/yousef_fadila/vtiger
PHP | 851 lines | 376 code | 78 blank | 397 comment | 42 complexity | 8954593da08a0ef4638c36430141b744 MD5 | raw file
Possible License(s): LGPL-2.1, GPL-2.0
  1. <?php
  2. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  3. /**
  4. * Image_Graph - Main class for the graph creation.
  5. *
  6. * PHP versions 4 and 5
  7. *
  8. * LICENSE: This library is free software; you can redistribute it and/or modify
  9. * it under the terms of the GNU Lesser General Public License as published by
  10. * the Free Software Foundation; either version 2.1 of the License, or (at your
  11. * option) any later version. This library is distributed in the hope that it
  12. * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  13. * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
  14. * General Public License for more details. You should have received a copy of
  15. * the GNU Lesser General Public License along with this library; if not, write
  16. * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  17. * 02111-1307 USA
  18. *
  19. * @category Images
  20. * @package Image_Graph
  21. * @author Jesper Veggerby <pear.nosey@veggerby.dk>
  22. * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  23. * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  24. * @version CVS: $Id: Graph.php,v 1.58 2005/11/27 18:48:05 nosey Exp $
  25. * @link http://pear.php.net/package/Image_Graph
  26. */
  27. /**
  28. * Include PEAR.php
  29. */
  30. require_once 'PEAR.php';
  31. /**
  32. * Include file Image/Graph/Element.php
  33. */
  34. require_once 'Image/Graph/Element.php';
  35. /**
  36. * Include file Image/Graph/Constants.php
  37. */
  38. require_once 'Image/Graph/Constants.php';
  39. /**
  40. * Main class for the graph creation.
  41. *
  42. * This is the main class, it manages the canvas and performs the final output
  43. * by sequentialy making the elements output their results. The final output is
  44. * handled using the {@link Image_Canvas} classes which makes it possible
  45. * to use different engines (fx GD, PDFlib, libswf, etc) for output to several
  46. * formats with a non-intersecting API.
  47. *
  48. * This class also handles coordinates and the correct managment of setting the
  49. * correct coordinates on child elements.
  50. *
  51. * @category Images
  52. * @package Image_Graph
  53. * @author Jesper Veggerby <pear.nosey@veggerby.dk>
  54. * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  55. * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1
  56. * @version Release: 0.7.2
  57. * @link http://pear.php.net/package/Image_Graph
  58. */
  59. class Image_Graph extends Image_Graph_Element
  60. {
  61. /**
  62. * Show generation time on graph
  63. * @var bool
  64. * @access private
  65. */
  66. var $_showTime = false;
  67. /**
  68. * Display errors on the canvas
  69. * @var boolean
  70. * @access private
  71. */
  72. var $_displayErrors = false;
  73. /**
  74. * Image_Graph [Constructor].
  75. *
  76. * If passing the 3 parameters they are defined as follows:'
  77. *
  78. * Fx.:
  79. *
  80. * $Graph =& new Image_Graph(400, 300);
  81. *
  82. * or using the factory method:
  83. *
  84. * $Graph =& Image_Graph::factory('graph', array(400, 300));
  85. *
  86. * This causes a 'png' canvas to be created by default.
  87. *
  88. * Otherwise use a single parameter either as an associated array or passing
  89. * the canvas along to the constructor:
  90. *
  91. * 1) Create a new canvas with the following parameters:
  92. *
  93. * 'canvas' - The canvas type, can be any of 'gd', 'jpg', 'png' or 'svg'
  94. * (more to come) - if omitted the default is 'gd'
  95. *
  96. * 'width' - The width of the graph
  97. *
  98. * 'height' - The height of the graph
  99. *
  100. * An example of this usage:
  101. *
  102. * $Graph =& Image_Graph::factory('graph', array(array('width' => 400,
  103. * 'height' => 300, 'canvas' => 'jpg')));
  104. *
  105. * NB! In thïs case remember the "double" array (see {@link Image_Graph::
  106. * factory()})
  107. *
  108. * 2) Use the canvas specified, pass a valid Image_Canvas as
  109. * parameter. Remember to pass by reference, i. e. &amp;$canvas, fx.:
  110. *
  111. * $Graph =& new Image_Graph($Canvas);
  112. *
  113. * or using the factory method:
  114. *
  115. * $Graph =& Image_Graph::factory('graph', $Canvas));
  116. *
  117. * @param mixed $params The width of the graph, an indexed array
  118. * describing a new canvas or a valid {@link Image_Canvas} object
  119. * @param int $height The height of the graph in pixels
  120. * @param bool $createTransparent Specifies whether the graph should be
  121. * created with a transparent background (fx for PNG's - note: transparent
  122. * PNG's is not supported by Internet Explorer!)
  123. */
  124. function Image_Graph($params, $height = false, $createTransparent = false)
  125. {
  126. parent::Image_Graph_Element();
  127. $this->setFont(Image_Graph::factory('Image_Graph_Font'));
  128. if (defined('IMAGE_GRAPH_DEFAULT_CANVAS_TYPE')) {
  129. $canvasType = IMAGE_GRAPH_DEFAULT_CANVAS_TYPE;
  130. } else {
  131. $canvasType = 'png'; // use GD as default, if nothing else is specified
  132. }
  133. if (is_array($params)) {
  134. if (isset($params['canvas'])) {
  135. $canvasType = $params['canvas'];
  136. }
  137. $width = 0;
  138. $height = 0;
  139. if (isset($params['width'])) {
  140. $width = $params['width'];
  141. }
  142. if (isset($params['height'])) {
  143. $height = $params['height'];
  144. }
  145. } elseif (is_a($params, 'Image_Canvas')) {
  146. $this->_canvas =& $params;
  147. $width = $this->_canvas->getWidth();
  148. $height = $this->_canvas->getHeight();
  149. } elseif (is_numeric($params)) {
  150. $width = $params;
  151. }
  152. if ($this->_canvas == null) {
  153. include_once 'Image/Canvas.php';
  154. $this->_canvas =&
  155. Image_Canvas::factory(
  156. $canvasType,
  157. array('width' => $width, 'height' => $height)
  158. );
  159. }
  160. $this->_setCoords(0, 0, $width - 1, $height - 1);
  161. }
  162. /**
  163. * Gets the canvas for this graph.
  164. *
  165. * The canvas is set by either passing it to the constructor {@link
  166. * Image_Graph::ImageGraph()} or using the {@link Image_Graph::setCanvas()}
  167. * method.
  168. *
  169. * @return Image_Canvas The canvas used by this graph
  170. * @access private
  171. * @since 0.3.0dev2
  172. */
  173. function &_getCanvas()
  174. {
  175. return $this->_canvas;
  176. }
  177. /**
  178. * Sets the canvas for this graph.
  179. *
  180. * Calling this method makes this graph use the newly specified canvas for
  181. * handling output. This method should be called whenever multiple
  182. * 'outputs' are required. Invoke this method after calls to {@link
  183. * Image_Graph:: done()} has been performed, to switch canvass.
  184. *
  185. * @param Image_Canvas $canvas The new canvas
  186. * @return Image_Canvas The new canvas
  187. * @since 0.3.0dev2
  188. */
  189. function &setCanvas(&$canvas)
  190. {
  191. if (!is_a($this->_canvas, 'Image_Canvas')) {
  192. return $this->_error('The canvas introduced is not an Image_Canvas object');
  193. }
  194. $this->_canvas =& $canvas;
  195. $this->_setCoords(
  196. 0,
  197. 0,
  198. $this->_canvas->getWidth() - 1,
  199. $this->_canvas->getHeight() - 1
  200. );
  201. return $this->_canvas;
  202. }
  203. /**
  204. * Gets a very precise timestamp
  205. *
  206. * @return The number of seconds to a lot of decimals
  207. * @access private
  208. */
  209. function _getMicroTime()
  210. {
  211. list($usec, $sec) = explode(' ', microtime());
  212. return ((float)$usec + (float)$sec);
  213. }
  214. /**
  215. * Gets the width of this graph.
  216. *
  217. * The width is returned as 'defined' by the canvas.
  218. *
  219. * @return int the width of this graph
  220. */
  221. function width()
  222. {
  223. return $this->_canvas->getWidth();
  224. }
  225. /**
  226. * Gets the height of this graph.
  227. *
  228. * The height is returned as 'defined' by the canvas.
  229. *
  230. * @return int the height of this graph
  231. */
  232. function height()
  233. {
  234. return $this->_canvas->getHeight();
  235. }
  236. /**
  237. * Enables displaying of errors on the output.
  238. *
  239. * Use this method to enforce errors to be displayed on the output. Calling
  240. * this method makes PHP uses this graphs error handler as default {@link
  241. * Image_Graph::_default_error_handler()}.
  242. */
  243. function displayErrors()
  244. {
  245. $this->_displayErrors = true;
  246. set_error_handler(array(&$this, '_default_error_handler'));
  247. }
  248. /**
  249. * Sets the log method for this graph.
  250. *
  251. * Use this method to enable logging. This causes any errors caught
  252. * by either the error handler {@see Image_Graph::displayErrors()}
  253. * or explicitly by calling {@link Image_Graph_Common::_error()} be
  254. * logged using the specified logging method.
  255. *
  256. * If a filename is specified as log method, a Log object is created (using
  257. * the 'file' handler), with a handle of 'Image_Graph Error Log'.
  258. *
  259. * Logging requires {@link Log}.
  260. *
  261. * @param mixed $log The log method, either a Log object or filename to log
  262. * to
  263. * @since 0.3.0dev2
  264. */
  265. function setLog($log)
  266. {
  267. }
  268. /**
  269. * Factory method to create Image_Graph objects.
  270. *
  271. * Used for 'lazy including', i.e. loading only what is necessary, when it
  272. * is necessary. If only one parameter is required for the constructor of
  273. * the class simply pass this parameter as the $params parameter, unless the
  274. * parameter is an array or a reference to a value, in that case you must
  275. * 'enclose' the parameter in an array. Similar if the constructor takes
  276. * more than one parameter specify the parameters in an array, i.e
  277. *
  278. * Image_Graph::factory('MyClass', array($param1, $param2, &$param3));
  279. *
  280. * Variables that need to be passed by reference *must* have the &amp;
  281. * before the variable, i.e:
  282. *
  283. * Image_Graph::factory('line', &$Dataset);
  284. *
  285. * or
  286. *
  287. * Image_graph::factory('bar', array(array(&$Dataset1, &$Dataset2),
  288. * 'stacked'));
  289. *
  290. * Class name can be either of the following:
  291. *
  292. * 1 The 'real' Image_Graph class name, i.e. Image_Graph_Plotarea or
  293. * Image_Graph_Plot_Line
  294. *
  295. * 2 Short class name (leave out Image_Graph) and retain case, i.e.
  296. * Plotarea, Plot_Line *not* plot_line
  297. *
  298. * 3 Class name 'alias', the following are supported:
  299. *
  300. * 'graph' = Image_Graph
  301. *
  302. * 'plotarea' = Image_Graph_Plotarea
  303. *
  304. * 'line' = Image_Graph_Plot_Line
  305. *
  306. * 'area' = Image_Graph_Plot_Area
  307. *
  308. * 'bar' = Image_Graph_Plot_Bar
  309. *
  310. * 'pie' = Image_Graph_Plot_Pie
  311. *
  312. * 'radar' = Image_Graph_Plot_Radar
  313. *
  314. * 'step' = Image_Graph_Plot_Step
  315. *
  316. * 'impulse' = Image_Graph_Plot_Impulse
  317. *
  318. * 'dot' or 'scatter' = Image_Graph_Plot_Dot
  319. *
  320. * 'smooth_line' = Image_Graph_Plot_Smoothed_Line
  321. *
  322. * 'smooth_area' = Image_Graph_Plot_Smoothed_Area
  323. * 'dataset' = Image_Graph_Dataset_Trivial
  324. *
  325. * 'random' = Image_Graph_Dataset_Random
  326. *
  327. * 'function' = Image_Graph_Dataset_Function
  328. *
  329. * 'vector' = Image_Graph_Dataset_VectorFunction
  330. *
  331. * 'category' = Image_Graph_Axis_Category
  332. *
  333. * 'axis' = Image_Graph_Axis
  334. *
  335. * 'axis_log' = Image_Graph_Axis_Logarithmic
  336. *
  337. * 'title' = Image_Graph_Title
  338. *
  339. * 'line_grid' = Image_Graph_Grid_Lines
  340. *
  341. * 'bar_grid' = Image_Graph_Grid_Bars
  342. *
  343. * 'polar_grid' = Image_Graph_Grid_Polar
  344. *
  345. * 'legend' = Image_Graph_Legend
  346. *
  347. * 'font' = Image_Graph_Font
  348. *
  349. * 'ttf_font' = Image_Graph_Font
  350. *
  351. * 'Image_Graph_Font_TTF' = Image_Graph_Font (to maintain BC with Image_Graph_Font_TTF)
  352. *
  353. * 'gradient' = Image_Graph_Fill_Gradient
  354. *
  355. * 'icon_marker' = Image_Graph_Marker_Icon
  356. *
  357. * 'value_marker' = Image_Graph_Marker_Value
  358. *
  359. * @param string $class The class for the new object
  360. * @param mixed $params The paramaters to pass to the constructor
  361. * @return object A new object for the class
  362. * @static
  363. */
  364. function &factory($class, $params = null)
  365. {
  366. static $Image_Graph_classAliases = array(
  367. 'graph' => 'Image_Graph',
  368. 'plotarea' => 'Image_Graph_Plotarea',
  369. 'line' => 'Image_Graph_Plot_Line',
  370. 'area' => 'Image_Graph_Plot_Area',
  371. 'bar' => 'Image_Graph_Plot_Bar',
  372. 'smooth_line' => 'Image_Graph_Plot_Smoothed_Line',
  373. 'smooth_area' => 'Image_Graph_Plot_Smoothed_Area',
  374. 'pie' => 'Image_Graph_Plot_Pie',
  375. 'radar' => 'Image_Graph_Plot_Radar',
  376. 'step' => 'Image_Graph_Plot_Step',
  377. 'impulse' => 'Image_Graph_Plot_Impulse',
  378. 'dot' => 'Image_Graph_Plot_Dot',
  379. 'scatter' => 'Image_Graph_Plot_Dot',
  380. 'dataset' => 'Image_Graph_Dataset_Trivial',
  381. 'random' => 'Image_Graph_Dataset_Random',
  382. 'function' => 'Image_Graph_Dataset_Function',
  383. 'vector' => 'Image_Graph_Dataset_VectorFunction',
  384. 'category' => 'Image_Graph_Axis_Category',
  385. 'axis' => 'Image_Graph_Axis',
  386. 'axis_log' => 'Image_Graph_Axis_Logarithmic',
  387. 'title' => 'Image_Graph_Title',
  388. 'line_grid' => 'Image_Graph_Grid_Lines',
  389. 'bar_grid' => 'Image_Graph_Grid_Bars',
  390. 'polar_grid' => 'Image_Graph_Grid_Polar',
  391. 'legend' => 'Image_Graph_Legend',
  392. 'font' => 'Image_Graph_Font',
  393. 'ttf_font' => 'Image_Graph_Font',
  394. 'Image_Graph_Font_TTF' => 'Image_Graph_Font', // BC with Image_Graph_Font_TTF
  395. 'gradient' => 'Image_Graph_Fill_Gradient',
  396. 'icon_marker' => 'Image_Graph_Marker_Icon',
  397. 'value_marker' => 'Image_Graph_Marker_Value'
  398. );
  399. if (substr($class, 0, 11) != 'Image_Graph') {
  400. if (isset($Image_Graph_classAliases[$class])) {
  401. $class = $Image_Graph_classAliases[$class];
  402. } else {
  403. $class = 'Image_Graph_' . $class;
  404. }
  405. }
  406. include_once str_replace('_', '/', $class) . '.php';
  407. $obj = null;
  408. if (is_array($params)) {
  409. switch (count($params)) {
  410. case 1:
  411. $obj =& new $class(
  412. $params[0]
  413. );
  414. break;
  415. case 2:
  416. $obj =& new $class(
  417. $params[0],
  418. $params[1]
  419. );
  420. break;
  421. case 3:
  422. $obj =& new $class(
  423. $params[0],
  424. $params[1],
  425. $params[2]
  426. );
  427. break;
  428. case 4:
  429. $obj =& new $class(
  430. $params[0],
  431. $params[1],
  432. $params[2],
  433. $params[3]
  434. );
  435. break;
  436. case 5:
  437. $obj =& new $class(
  438. $params[0],
  439. $params[1],
  440. $params[2],
  441. $params[3],
  442. $params[4]
  443. );
  444. break;
  445. case 6:
  446. $obj =& new $class(
  447. $params[0],
  448. $params[1],
  449. $params[2],
  450. $params[3],
  451. $params[4],
  452. $params[5]
  453. );
  454. break;
  455. case 7:
  456. $obj =& new $class(
  457. $params[0],
  458. $params[1],
  459. $params[2],
  460. $params[3],
  461. $params[4],
  462. $params[5],
  463. $params[6]
  464. );
  465. break;
  466. case 8:
  467. $obj =& new $class(
  468. $params[0],
  469. $params[1],
  470. $params[2],
  471. $params[3],
  472. $params[4],
  473. $params[5],
  474. $params[6],
  475. $params[7]
  476. );
  477. break;
  478. case 9:
  479. $obj =& new $class(
  480. $params[0],
  481. $params[1],
  482. $params[2],
  483. $params[3],
  484. $params[4],
  485. $params[5],
  486. $params[6],
  487. $params[7],
  488. $params[8]
  489. );
  490. break;
  491. case 10:
  492. $obj =& new $class(
  493. $params[0],
  494. $params[1],
  495. $params[2],
  496. $params[3],
  497. $params[4],
  498. $params[5],
  499. $params[6],
  500. $params[7],
  501. $params[8],
  502. $params[9]
  503. );
  504. break;
  505. default:
  506. $obj =& new $class();
  507. break;
  508. }
  509. } else {
  510. if ($params == null) {
  511. $obj =& new $class();
  512. } else {
  513. $obj =& new $class($params);
  514. }
  515. }
  516. return $obj;
  517. }
  518. /**
  519. * Factory method to create layouts.
  520. *
  521. * This method is used for easy creation, since using {@link Image_Graph::
  522. * factory()} does not work with passing newly created objects from
  523. * Image_Graph::factory() as reference, this is something that is
  524. * fortunately fixed in PHP5. Also used for 'lazy including', i.e. loading
  525. * only what is necessary, when it is necessary.
  526. *
  527. * Use {@link Image_Graph::horizontal()} or {@link Image_Graph::vertical()}
  528. * instead for easier access.
  529. *
  530. * @param mixed $layout The type of layout, can be either 'Vertical'
  531. * or 'Horizontal' (case sensitive)
  532. * @param Image_Graph_Element $part1 The 1st part of the layout
  533. * @param Image_Graph_Element $part2 The 2nd part of the layout
  534. * @param int $percentage The percentage of the layout to split at
  535. * @return Image_Graph_Layout The newly created layout object
  536. * @static
  537. */
  538. function &layoutFactory($layout, &$part1, &$part2, $percentage = 50)
  539. {
  540. if (($layout != 'Vertical') && ($layout != 'Horizontal')) {
  541. return $this->_error('Layouts must be either \'Horizontal\' or \'Vertical\'');
  542. }
  543. if (!(is_a($part1, 'Image_Graph_Element'))) {
  544. return $this->_error('Part 1 is not a valid Image_Graph element');
  545. }
  546. if (!(is_a($part2, 'Image_Graph_Element'))) {
  547. return $this->_error('Part 2 is not a valid Image_Graph element');
  548. }
  549. if ((!is_numeric($percentage)) || ($percentage < 0) || ($percentage > 100)) {
  550. return $this->_error('Percentage has to be a number between 0 and 100');
  551. }
  552. include_once "Image/Graph/Layout/$layout.php";
  553. $class = "Image_Graph_Layout_$layout";
  554. $obj =& new $class($part1, $part2, $percentage);
  555. return $obj;
  556. }
  557. /**
  558. * Factory method to create horizontal layout.
  559. *
  560. * See {@link Image_Graph::layoutFactory()}
  561. *
  562. * @param Image_Graph_Element $part1 The 1st (left) part of the layout
  563. * @param Image_Graph_Element $part2 The 2nd (right) part of the layout
  564. * @param int $percentage The percentage of the layout to split at
  565. * (percentage of total height from the left side)
  566. * @return Image_Graph_Layout The newly created layout object
  567. * @static
  568. */
  569. function &horizontal(&$part1, &$part2, $percentage = 50)
  570. {
  571. $obj =& Image_Graph::layoutFactory('Horizontal', $part1, $part2, $percentage);
  572. return $obj;
  573. }
  574. /**
  575. * Factory method to create vertical layout.
  576. *
  577. * See {@link Image_Graph::layoutFactory()}
  578. *
  579. * @param Image_Graph_Element $part1 The 1st (top) part of the layout
  580. * @param Image_Graph_Element $part2 The 2nd (bottom) part of the layout
  581. * @param int $percentage The percentage of the layout to split at
  582. * (percentage of total width from the top edge)
  583. * @return Image_Graph_Layout The newly created layout object
  584. * @static
  585. */
  586. function &vertical(&$part1, &$part2, $percentage = 50)
  587. {
  588. $obj =& Image_Graph::layoutFactory('Vertical', $part1, $part2, $percentage);
  589. return $obj;
  590. }
  591. /**
  592. * The error handling routine set by set_error_handler().
  593. *
  594. * This method is used internaly by Image_Graph and PHP as a proxy for {@link
  595. * Image_Graph::_error()}.
  596. *
  597. * @param string $error_type The type of error being handled.
  598. * @param string $error_msg The error message being handled.
  599. * @param string $error_file The file in which the error occurred.
  600. * @param integer $error_line The line in which the error occurred.
  601. * @param string $error_context The context in which the error occurred.
  602. * @access private
  603. */
  604. function _default_error_handler($error_type, $error_msg, $error_file, $error_line, $error_context)
  605. {
  606. switch( $error_type ) {
  607. case E_ERROR:
  608. $level = 'error';
  609. break;
  610. case E_USER_ERROR:
  611. $level = 'user error';
  612. break;
  613. case E_WARNING:
  614. $level = 'warning';
  615. break;
  616. case E_USER_WARNING:
  617. $level = 'user warning';
  618. break;
  619. case E_NOTICE:
  620. $level = 'notice';
  621. break;
  622. case E_USER_NOTICE:
  623. $level = 'user notice';
  624. break;
  625. default:
  626. $level = '(unknown)';
  627. break;
  628. }
  629. $this->_error("PHP $level: $error_msg",
  630. array(
  631. 'type' => $error_type,
  632. 'file' => $error_file,
  633. 'line' => $error_line,
  634. 'context' => $error_context
  635. )
  636. );
  637. }
  638. /**
  639. * Displays the errors on the error stack.
  640. *
  641. * Invoking this method cause all errors on the error stack to be displayed
  642. * on the graph-output, by calling the {@link Image_Graph::_displayError()}
  643. * method.
  644. *
  645. * @access private
  646. */
  647. function _displayErrors()
  648. {
  649. return true;
  650. }
  651. /**
  652. * Display an error from the error stack.
  653. *
  654. * This method writes error messages caught from the {@link Image_Graph::
  655. * _default_error_handler()} if {@Image_Graph::displayErrors()} was invoked,
  656. * and the error explicitly set by the system using {@link
  657. * Image_Graph_Common::_error()}.
  658. *
  659. * @param int $x The horizontal position of the error message
  660. * @param int $y The vertical position of the error message
  661. * @param array $error The error context
  662. *
  663. * @access private
  664. */
  665. function _displayError($x, $y, $error)
  666. {
  667. }
  668. /**
  669. * Outputs this graph using the canvas.
  670. *
  671. * This causes the graph to make all elements perform their output. Their
  672. * result is 'written' to the output using the canvas, which also performs
  673. * the actual output, fx. it being to a file or directly to the browser
  674. * (in the latter case, the canvas will also make sure the correct HTTP
  675. * headers are sent, making the browser handle the output correctly, if
  676. * supported by it).
  677. *
  678. * Parameters are the ones supported by the canvas, common ones are:
  679. *
  680. * 'filename' To output to a file instead of browser
  681. *
  682. * 'tohtml' Return a HTML string that encompasses the current graph/canvas - this
  683. * implies an implicit save using the following parameters: 'filename' The "temporary"
  684. * filename of the graph, 'filepath' A path in the file system where Image_Graph can
  685. * store the output (this file must be in DOCUMENT_ROOT scope), 'urlpath' The URL that the
  686. * 'filepath' corresponds to (i.e. filepath + filename must be reachable from a browser using
  687. * urlpath + filename)
  688. *
  689. * @param mixed $param The output parameters to pass to the canvas
  690. * @return bool Was the output 'good' (true) or 'bad' (false).
  691. */
  692. function done($param = false)
  693. {
  694. $result = $this->_reset();
  695. if (PEAR::isError($result)) {
  696. return $result;
  697. }
  698. return $this->_done($param);
  699. }
  700. /**
  701. * Outputs this graph using the canvas.
  702. *
  703. * This causes the graph to make all elements perform their output. Their
  704. * result is 'written' to the output using the canvas, which also performs
  705. * the actual output, fx. it being to a file or directly to the browser
  706. * (in the latter case, the canvas will also make sure the correct HTTP
  707. * headers are sent, making the browser handle the output correctly, if
  708. * supported by it).
  709. *
  710. * @param mixed $param The output parameters to pass to the canvas
  711. * @return bool Was the output 'good' (true) or 'bad' (false).
  712. * @access private
  713. */
  714. function _done($param = false)
  715. {
  716. $timeStart = $this->_getMicroTime();
  717. if ($this->_shadow) {
  718. $this->setPadding(20);
  719. $this->_setCoords(
  720. $this->_left,
  721. $this->_top,
  722. $this->_right - 10,
  723. $this->_bottom - 10);
  724. }
  725. $result = $this->_updateCoords();
  726. if (PEAR::isError($result)) {
  727. return $result;
  728. }
  729. if ($this->_getBackground()) {
  730. $this->_canvas->rectangle(
  731. array(
  732. 'x0' => $this->_left,
  733. 'y0' => $this->_top,
  734. 'x1' => $this->_right,
  735. 'y1' => $this->_bottom
  736. )
  737. );
  738. }
  739. $result = parent::_done();
  740. if (PEAR::isError($result)) {
  741. return $result;
  742. }
  743. if ($this->_displayErrors) {
  744. $this->_displayErrors();
  745. }
  746. $timeEnd = $this->_getMicroTime();
  747. if (($this->_showTime) ||
  748. ((isset($param['showtime'])) && ($param['showtime'] === true))
  749. ) {
  750. $text = 'Generated in ' .
  751. sprintf('%0.3f', $timeEnd - $timeStart) . ' sec';
  752. $this->write(
  753. $this->_right,
  754. $this->_bottom,
  755. $text,
  756. IMAGE_GRAPH_ALIGN_RIGHT + IMAGE_GRAPH_ALIGN_BOTTOM,
  757. array('color' => 'red')
  758. );
  759. }
  760. if (isset($param['filename'])) {
  761. if ((isset($param['tohtml'])) && ($param['tohtml'])) {
  762. return $this->_canvas->toHtml($param);
  763. }
  764. else {
  765. return $this->_canvas->save($param);
  766. }
  767. } else {
  768. return $this->_canvas->show($param);
  769. }
  770. }
  771. }
  772. ?>