home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / Image / Graph / Plot.php < prev    next >
Encoding:
PHP Script  |  2008-07-02  |  27.8 KB  |  824 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
  4.  
  5. /**
  6.  * Image_Graph - PEAR PHP OO Graph Rendering Utility.
  7.  *
  8.  * PHP versions 4 and 5
  9.  *
  10.  * LICENSE: This library is free software; you can redistribute it and/or modify
  11.  * it under the terms of the GNU Lesser General Public License as published by
  12.  * the Free Software Foundation; either version 2.1 of the License, or (at your
  13.  * option) any later version. This library is distributed in the hope that it
  14.  * will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  15.  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
  16.  * General Public License for more details. You should have received a copy of
  17.  * the GNU Lesser General Public License along with this library; if not, write
  18.  * to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
  19.  * 02111-1307 USA
  20.  *
  21.  * @category   Images
  22.  * @package    Image_Graph
  23.  * @subpackage Plot
  24.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  25.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  26.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  27.  * @version    CVS: $Id: Plot.php,v 1.20 2006/02/28 22:33:00 nosey Exp $
  28.  * @link       http://pear.php.net/package/Image_Graph
  29.  */
  30.  
  31. /**
  32.  * Include file Image/Graph/Plotarea/Element.php
  33.  */
  34. require_once 'Image/Graph/Plotarea/Element.php';
  35.  
  36. /**
  37.  * Framework for a chart
  38.  *
  39.  * @category   Images
  40.  * @package    Image_Graph
  41.  * @subpackage Plot
  42.  * @author     Jesper Veggerby <pear.nosey@veggerby.dk>
  43.  * @copyright  Copyright (C) 2003, 2004 Jesper Veggerby Hansen
  44.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  45.  * @version    Release: 0.7.2
  46.  * @link       http://pear.php.net/package/Image_Graph
  47.  * @abstract
  48.  */
  49. class Image_Graph_Plot extends Image_Graph_Plotarea_Element
  50. {
  51.  
  52.     /**
  53.      * The dataset to plot
  54.      * @var Dataset
  55.      * @access private
  56.      */
  57.     var $_dataset;
  58.  
  59.     /**
  60.      * The marker to plot the data set as
  61.      * @var Marker
  62.      * @access private
  63.      */
  64.     var $_marker = null;
  65.  
  66.     /**
  67.      * The dataselector to use for data marking
  68.      * @var DataSelector
  69.      * @access private
  70.      */
  71.     var $_dataSelector = null;
  72.  
  73.     /**
  74.      * The Y axis to associate the plot with
  75.      * @var int
  76.      * @access private
  77.      */
  78.     var $_axisY = IMAGE_GRAPH_AXIS_Y;
  79.  
  80.     /**
  81.      * The type of the plot if multiple datasets are used
  82.      * @var string
  83.      * @access private
  84.      */
  85.     var $_multiType = 'normal';
  86.  
  87.     /**
  88.      * The title of the plot, used for legending in case of simple plots
  89.      * @var string
  90.      * @access private
  91.      */
  92.     var $_title = 'plot';
  93.  
  94.     /**
  95.      * PlotType [Constructor]
  96.      *
  97.      * Valid values for multiType are:
  98.      *
  99.      * 'normal' Plot is normal, multiple datasets are displayes next to one
  100.      * another
  101.      *
  102.      * 'stacked' Datasets are stacked on top of each other
  103.      *
  104.      * 'stacked100pct' Datasets are stacked and displayed as percentages of the
  105.      * total sum
  106.      *
  107.      * I no title is specified a default is used, which is basically the plot
  108.      * type (fx. for a 'Image_Graph_Plot_Smoothed_Area' default title is
  109.      * 'Smoothed Area')
  110.      *
  111.      * @param Image_Graph_Dataset $dataset The data set (value containter) to
  112.      *   plot or an array of datasets
  113.      * @param string $multiType The type of the plot
  114.      * @param string $title The title of the plot (used for legends,
  115.      *   {@link Image_Graph_Legend})
  116.      */
  117.     function Image_Graph_Plot(& $dataset, $multiType = 'normal', $title = '')
  118.     {
  119.         if (!is_a($dataset, 'Image_Graph_Dataset')) {
  120.             if (is_array($dataset)) {
  121.                 $keys = array_keys($dataset);
  122.                 foreach ($keys as $key) {
  123.                     if (!is_a($dataset[$key], 'Image_Graph_Dataset')) {
  124.                         $this->_error('Invalid dataset passed to ' . get_class($this));
  125.                     }
  126.                 }
  127.                 unset($keys);
  128.             } else {
  129.                 $this->_error('Invalid dataset passed to ' . get_class($this));
  130.             }
  131.         }
  132.  
  133.         parent::Image_Graph_Common();
  134.         if ($dataset) {
  135.             if (is_array($dataset)) {
  136.                 $this->_dataset =& $dataset;
  137.             } else {
  138.                 $this->_dataset = array(&$dataset);
  139.             }
  140.         }
  141.         if ($title) {
  142.             $this->_title = $title;
  143.         } else {
  144.             $this->_title = str_replace('_', ' ', substr(get_class($this), 17));
  145.         }
  146.  
  147.         $multiType = strtolower($multiType);
  148.         if (($multiType == 'normal') ||
  149.             ($multiType == 'stacked') ||
  150.             ($multiType == 'stacked100pct'))
  151.         {
  152.             $this->_multiType = $multiType;
  153.         } else {
  154.             $this->_error(
  155.                 'Invalid multitype: ' . $multiType .
  156.                 ' expected (normal|stacked|stacked100pct)'
  157.             );
  158.             $this->_multiType = 'normal';
  159.         }
  160.     }
  161.  
  162.     /**
  163.      * Sets the title of the plot, used for legend
  164.      *
  165.      * @param string $title The title of the plot
  166.      */
  167.     function setTitle($title)
  168.     {
  169.         $this->_title = $title;
  170.     }
  171.     
  172.     /**
  173.      * Parses the URL mapping data in the point and adds it to the parameter array used by
  174.      * Image_Canvas
  175.      * 
  176.      * @param array $point The data point (from the dataset)
  177.      * @param array $canvasData The The for the canvas method
  178.      * @return array The union of the canvas data points and the appropriate points for the dataset
  179.      * @access private 
  180.      */
  181.     function _mergeData($point, $canvasData)
  182.     {       
  183.         if (isset($point['data'])) {
  184.             if (isset($point['data']['url'])) {
  185.                 $canvasData['url'] = $point['data']['url'];
  186.             }
  187.             if (isset($point['data']['target'])) {
  188.                 $canvasData['target'] = $point['data']['target']; 
  189.             }
  190.             if (isset($point['data']['alt'])) {
  191.                 $canvasData['alt'] = $point['data']['alt']; 
  192.             }
  193.             if (isset($point['data']['htmltags'])) {
  194.                 $canvasData['htmltags'] = $point['data']['htmltags']; 
  195.             }
  196.         }
  197.         
  198.         return $canvasData;        
  199.     }
  200.  
  201.     /**
  202.      * Sets the Y axis to plot the data
  203.      *
  204.      * @param int $axisY The Y axis (either IMAGE_GRAPH_AXIS_Y / 'y' or
  205.      * IMAGE_GRAPH_AXIS_Y_SECONDARY / 'ysec' (defaults to IMAGE_GRAPH_AXIS_Y))
  206.      * @access private
  207.      */
  208.     function _setAxisY($axisY)
  209.     {
  210.         if ($axisY == 'y') {
  211.            $this->_axisY = IMAGE_GRAPH_AXIS_Y;
  212.         } elseif ($axisY == 'ysec') {
  213.            $this->_axisY = IMAGE_GRAPH_AXIS_Y_SECONDARY;
  214.         } else {
  215.             $this->_axisY = $axisY;
  216.         }
  217.     }
  218.  
  219.     /**
  220.      * Sets the marker to 'display' data points on the graph
  221.      *
  222.      * @param Marker $marker The marker
  223.      */
  224.     function &setMarker(& $marker)
  225.     {
  226.         $this->add($marker);
  227.         $this->_marker =& $marker;
  228.         return $marker;
  229.     }
  230.  
  231.     /**
  232.      * Sets the dataselector to specify which data should be displayed on the
  233.      * plot as markers and which are not
  234.      *
  235.      * @param DataSelector $dataSelector The dataselector
  236.      */
  237.     function setDataSelector(& $dataSelector)
  238.     {
  239.         $this->_dataSelector =& $dataSelector;
  240.     }
  241.  
  242.     /**
  243.      * Calculate marker point data
  244.      *
  245.      * @param array Point The point to calculate data for
  246.      * @param array NextPoint The next point
  247.      * @param array PrevPoint The previous point
  248.      * @param array Totals The pre-calculated totals, if needed
  249.      * @return array An array containing marker point data
  250.      * @access private
  251.      */
  252.     function _getMarkerData($point, $nextPoint, $prevPoint, & $totals)
  253.     {
  254.         if (is_array($this->_dataset)) {
  255.             if ($this->_multiType == 'stacked') {
  256.                 if (!isset($totals['SUM_Y'])) {
  257.                     $totals['SUM_Y'] = array();
  258.                 }
  259.                 $x = $point['X'];
  260.                 if (!isset($totals['SUM_Y'][$x])) {
  261.                     $totals['SUM_Y'][$x] = 0;
  262.                 }
  263.             } elseif ($this->_multiType == 'stacked100pct') {
  264.                 $x = $point['X'];
  265.                 if ($totals['TOTAL_Y'][$x] != 0) {
  266.                     if (!isset($totals['SUM_Y'])) {
  267.                         $totals['SUM_Y'] = array();
  268.                     }
  269.                     if (!isset($totals['SUM_Y'][$x])) {
  270.                         $totals['SUM_Y'][$x] = 0;
  271.                     }
  272.                 }
  273.             }
  274.  
  275.             if (isset($totals['ALL_SUM_Y'])) {
  276.                 $point['SUM_Y'] = $totals['ALL_SUM_Y'];
  277.             }
  278.  
  279.             if (!$prevPoint) {
  280.                 $point['AX'] = -5;
  281.                 $point['AY'] = 5;
  282.                 $point['PPX'] = 0;
  283.                 $point['PPY'] = 0;
  284.                 $point['NPX'] = $nextPoint['X'];
  285.                 $point['NPY'] = $nextPoint['Y'];
  286.             } elseif (!$nextPoint) {
  287.                 $point['AX'] = 5;
  288.                 $point['AY'] = 5;
  289.                 $point['PPX'] = $prevPoint['X'];
  290.                 $point['PPY'] = $prevPoint['Y'];
  291.                 $point['NPX'] = 0;
  292.                 $point['NPY'] = 0;
  293.             } else {
  294.                 $point['AX'] = $this->_pointY($prevPoint) - $this->_pointY($nextPoint);
  295.                 $point['AY'] = $this->_pointX($nextPoint) - $this->_pointX($prevPoint);
  296.                 $point['PPX'] = $prevPoint['X'];
  297.                 $point['PPY'] = $prevPoint['Y'];
  298.                 $point['NPX'] = $nextPoint['X'];
  299.                 $point['NPY'] = $nextPoint['Y'];
  300.             }
  301.  
  302.             $point['APX'] = $point['X'];
  303.             $point['APY'] = $point['Y'];
  304.  
  305.             if ((isset($totals['MINIMUM_X'])) && ($totals['MINIMUM_X'] != 0)) {
  306.                 $point['PCT_MIN_X'] = 100 * $point['X'] / $totals['MINIMUM_X'];
  307.             }
  308.             if ((isset($totals['MAXIMUM_X'])) && ($totals['MAXIMUM_X'] != 0)) {
  309.                 $point['PCT_MAX_X'] = 100 * $point['X'] / $totals['MAXIMUM_X'];
  310.             }
  311.  
  312.             if ((isset($totals['MINIMUM_Y'])) && ($totals['MINIMUM_Y'] != 0)) {
  313.                 $point['PCT_MIN_Y'] = 100 * $point['Y'] / $totals['MINIMUM_Y'];
  314.             }
  315.             if ((isset($totals['MAXIMUM_Y'])) && ($totals['MAXIMUM_Y'] != 0)) {
  316.                 $point['PCT_MAX_Y'] = 100 * $point['Y'] / $totals['MAXIMUM_Y'];
  317.             }
  318.  
  319.             $point['LENGTH'] = sqrt($point['AX'] * $point['AX'] +
  320.                 $point['AY'] * $point['AY']);
  321.  
  322.             if ((isset($point['LENGTH'])) && ($point['LENGTH'] != 0)) {
  323.                 $point['ANGLE'] = asin($point['AY'] / $point['LENGTH']);
  324.             }
  325.  
  326.             if ((isset($point['AX'])) && ($point['AX'] > 0)) {
  327.                 $point['ANGLE'] = pi() - $point['ANGLE'];
  328.             }
  329.             
  330.             if ($this->_parent->_horizontal) {                
  331.                 $point['MARKER_Y1'] = $this->_pointY($point) -
  332.                     (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0);
  333.     
  334.                 $point['MARKER_Y2'] = $this->_pointY($point) +
  335.                     (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0);
  336.     
  337.                 $point['COLUMN_WIDTH'] = abs($point['MARKER_Y2'] -
  338.                     $point['MARKER_Y1']) / count($this->_dataset);
  339.     
  340.                 $point['MARKER_Y'] = $point['MARKER_Y1'] +
  341.                     ((isset($totals['NUMBER']) ? $totals['NUMBER'] : 0) + 0.5) *
  342.                     $point['COLUMN_WIDTH'];
  343.     
  344.                 $point['MARKER_X'] = $this->_pointX($point);
  345.     
  346.                 if ($this->_multiType == 'stacked') {
  347.                     $point['MARKER_Y'] =
  348.                         ($point['MARKER_Y1'] + $point['MARKER_Y2']) / 2;
  349.     
  350.                     $P1 = array('Y' => $totals['SUM_Y'][$x]);
  351.                     $P2 = array('Y' => $totals['SUM_Y'][$x] + $point['Y']);
  352.     
  353.                     $point['MARKER_X'] =
  354.                         ($this->_pointX($P1) + $this->_pointX($P2)) / 2;
  355.                 } elseif ($this->_multiType == 'stacked100pct') {
  356.                     $x = $point['X'];
  357.                     if ($totals['TOTAL_Y'][$x] != 0) {
  358.                         $point['MARKER_Y'] =
  359.                             ($point['MARKER_Y1'] + $point['MARKER_Y2']) / 2;
  360.     
  361.                         $P1 = array(
  362.                             'Y' => 100 * $totals['SUM_Y'][$x] / $totals['TOTAL_Y'][$x]
  363.                         );
  364.     
  365.                         $P2 = array(
  366.                             'Y' => 100 * ($totals['SUM_Y'][$x] + $point['Y']) / $totals['TOTAL_Y'][$x]
  367.                         );
  368.     
  369.                         $point['MARKER_X'] =
  370.                             ($this->_pointX($P1) + $this->_pointX($P2)) / 2;
  371.                     } else {
  372.                         $point = false;
  373.                     }
  374.                 }
  375.             }
  376.             else {
  377.                 $point['MARKER_X1'] = $this->_pointX($point) -
  378.                     (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0);
  379.     
  380.                 $point['MARKER_X2'] = $this->_pointX($point) +
  381.                     (isset($totals['WIDTH']) ? $totals['WIDTH'] : 0);
  382.     
  383.                 $point['COLUMN_WIDTH'] = abs($point['MARKER_X2'] -
  384.                     $point['MARKER_X1']) / count($this->_dataset);
  385.     
  386.                 $point['MARKER_X'] = $point['MARKER_X1'] +
  387.                     ((isset($totals['NUMBER']) ? $totals['NUMBER'] : 0) + 0.5) *
  388.                     $point['COLUMN_WIDTH'];
  389.     
  390.                 $point['MARKER_Y'] = $this->_pointY($point);
  391.     
  392.                 if ($this->_multiType == 'stacked') {
  393.                     $point['MARKER_X'] =
  394.                         ($point['MARKER_X1'] + $point['MARKER_X2']) / 2;
  395.     
  396.                     $P1 = array('Y' => $totals['SUM_Y'][$x]);
  397.                     $P2 = array('Y' => $totals['SUM_Y'][$x] + $point['Y']);
  398.     
  399.                     $point['MARKER_Y'] =
  400.                         ($this->_pointY($P1) + $this->_pointY($P2)) / 2;
  401.                 } elseif ($this->_multiType == 'stacked100pct') {
  402.                     $x = $point['X'];
  403.                     if ($totals['TOTAL_Y'][$x] != 0) {
  404.                         $point['MARKER_X'] =
  405.                             ($point['MARKER_X1'] + $point['MARKER_X2']) / 2;
  406.     
  407.                         $P1 = array(
  408.                             'Y' => 100 * $totals['SUM_Y'][$x] / $totals['TOTAL_Y'][$x]
  409.                         );
  410.     
  411.                         $P2 = array(
  412.                             'Y' => 100 * ($totals['SUM_Y'][$x] + $point['Y']) / $totals['TOTAL_Y'][$x]
  413.                         );
  414.     
  415.                         $point['MARKER_Y'] =
  416.                             ($this->_pointY($P1) + $this->_pointY($P2)) / 2;
  417.                     } else {
  418.                         $point = false;
  419.                     }
  420.                 }
  421.             }
  422.             return $point;
  423.         }
  424.     }
  425.  
  426.     /**
  427.      * Draws markers on the canvas
  428.      *
  429.      * @access private
  430.      */
  431.     function _drawMarker()
  432.     {        
  433.         if (($this->_marker) && (is_array($this->_dataset))) {
  434.             $this->_canvas->startGroup(get_class($this) . '_marker');
  435.             
  436.             $totals = $this->_getTotals();
  437.             $totals['WIDTH'] = $this->width() / ($this->_maximumX() + 2) / 2;
  438.  
  439.             $number = 0;
  440.             $keys = array_keys($this->_dataset);
  441.             foreach ($keys as $key) {
  442.                 $dataset =& $this->_dataset[$key];
  443.                 $totals['MINIMUM_X'] = $dataset->minimumX();
  444.                 $totals['MAXIMUM_X'] = $dataset->maximumX();
  445.                 $totals['MINIMUM_Y'] = $dataset->minimumY();
  446.                 $totals['MAXIMUM_Y'] = $dataset->maximumY();
  447.                 $totals['NUMBER'] = $number ++;
  448.                 $dataset->_reset();
  449.                 while ($point = $dataset->_next()) {
  450.                     $prevPoint = $dataset->_nearby(-2);
  451.                     $nextPoint = $dataset->_nearby();
  452.  
  453.                     $x = $point['X'];
  454.                     $y = $point['Y'];
  455.                     if (((!is_object($this->_dataSelector)) ||
  456.                         ($this->_dataSelector->_select($point))) && ($point['Y'] !== null))
  457.                     {
  458.  
  459.                         $point = $this->_getMarkerData(
  460.                             $point,
  461.                             $nextPoint,
  462.                             $prevPoint,
  463.                             $totals
  464.                         );
  465.  
  466.                         if (is_array($point)) {
  467.                             $this->_marker->_drawMarker(
  468.                                 $point['MARKER_X'],
  469.                                 $point['MARKER_Y'],
  470.                                 $point
  471.                             );
  472.                         }
  473.                     }
  474.                     if (!isset($totals['SUM_Y'])) {
  475.                         $totals['SUM_Y'] = array();
  476.                     }
  477.                     if (isset($totals['SUM_Y'][$x])) {
  478.                         $totals['SUM_Y'][$x] += $y;
  479.                     } else {
  480.                         $totals['SUM_Y'][$x] = $y;
  481.                     }
  482.                 }
  483.             }
  484.             unset($keys);
  485.             $this->_canvas->endGroup();
  486.         }              
  487.     }
  488.  
  489.     /**
  490.      * Get the minimum X value from the dataset
  491.      *
  492.      * @return double The minimum X value
  493.      * @access private
  494.      */
  495.     function _minimumX()
  496.     {
  497.         if (!is_array($this->_dataset)) {
  498.             return 0;
  499.         }
  500.  
  501.         $min = false;
  502.         if (is_array($this->_dataset)) {
  503.             $keys = array_keys($this->_dataset);
  504.             foreach ($keys as $key) {
  505.                 if ($min === false) {
  506.                     $min = $this->_dataset[$key]->minimumX();
  507.                 } else {
  508.                     $min = min($min, $this->_dataset[$key]->minimumX());
  509.                 }
  510.             }
  511.             unset($keys);
  512.         }
  513.         return $min;
  514.     }
  515.  
  516.     /**
  517.      * Get the maximum X value from the dataset
  518.      *
  519.      * @return double The maximum X value
  520.      * @access private
  521.      */
  522.     function _maximumX()
  523.     {
  524.         if (!is_array($this->_dataset)) {
  525.             return 0;
  526.         }
  527.  
  528.         $max = 0;
  529.         if (is_array($this->_dataset)) {
  530.             $keys = array_keys($this->_dataset);
  531.             foreach ($keys as $key) {
  532.                 $max = max($max, $this->_dataset[$key]->maximumX());
  533.             }
  534.             unset($keys);
  535.         }
  536.         return $max;
  537.     }
  538.  
  539.     /**
  540.      * Get the minimum Y value from the dataset
  541.      *
  542.      * @return double The minimum Y value
  543.      * @access private
  544.      */
  545.     function _minimumY()
  546.     {
  547.         if (!is_array($this->_dataset)) {
  548.             return 0;
  549.         }
  550.  
  551.         $min = false;
  552.         if (is_array($this->_dataset)) {
  553.             $keys = array_keys($this->_dataset);
  554.             foreach ($keys as $key) {
  555.                 if ($this->_multiType == 'normal') {
  556.                     if ($min === false) {
  557.                         $min = $this->_dataset[$key]->minimumY();
  558.                     } else {
  559.                         $min = min($min, $this->_dataset[$key]->minimumY());
  560.                     }
  561.                 } else {
  562.                     if ($min === false) {
  563.                         $min = 0;
  564.                     }
  565.                     $dataset =& $this->_dataset[$key];
  566.                     $dataset->_reset();
  567.                     while ($point = $dataset->_next()) {
  568.                         if ($point['Y'] < 0) {
  569.                             $x = $point['X'];
  570.                             if ((!isset($total)) || (!isset($total[$x]))) {
  571.                                 $total[$x] = $point['Y'];
  572.                             } else {
  573.                                 $total[$x] += $point['Y'];
  574.                             }
  575.                             if (isset($min)) {
  576.                                 $min = min($min, $total[$x]);
  577.                             } else {
  578.                                 $min = $total[$x];
  579.                             }
  580.                         }
  581.                     }
  582.                 }
  583.             }
  584.             unset($keys);
  585.         }
  586.         return $min;
  587.     }
  588.  
  589.     /**
  590.      * Get the maximum Y value from the dataset
  591.      *
  592.      * @return double The maximum Y value
  593.      * @access private
  594.      */
  595.     function _maximumY()
  596.     {
  597.         if ($this->_multiType == 'stacked100pct') {
  598.             return 100;
  599.         }
  600.  
  601.         $maxY = 0;
  602.         if (is_array($this->_dataset)) {
  603.             $keys = array_keys($this->_dataset);
  604.             foreach ($keys as $key) {
  605.                 $dataset =& $this->_dataset[$key];
  606.  
  607.                 if ($this->_multiType == 'normal') {
  608.                     if (isset($maxY)) {
  609.                         $maxY = max($maxY, $dataset->maximumY());
  610.                     } else {
  611.                         $maxY = $dataset->maximumY();
  612.                     }
  613.                 } else {
  614.                     $dataset->_reset();
  615.                     while ($point = $dataset->_next()) {
  616.                         if ($point['Y'] > 0) {
  617.                             $x = $point['X'];
  618.                             if ((!isset($total)) || (!isset($total[$x]))) {
  619.                                 $total[$x] = $point['Y'];
  620.                             } else {
  621.                                 $total[$x] += $point['Y'];
  622.                             }
  623.                             if (isset($maxY)) {
  624.                                 $maxY = max($maxY, $total[$x]);
  625.                             } else {
  626.                                 $maxY = $total[$x];
  627.                             }
  628.                         }
  629.                     }
  630.                 }
  631.             }
  632.             unset($keys);
  633.         }
  634.         return $maxY;
  635.     }
  636.  
  637.     /**
  638.      * Get the X pixel position represented by a value
  639.      *
  640.      * @param double $point The value to get the pixel-point for
  641.      * @return double The pixel position along the axis
  642.      * @access private
  643.      */
  644.     function _pointX($point)
  645.     {
  646.         $point['AXIS_Y'] = $this->_axisY;
  647.         return parent::_pointX($point);
  648.     }
  649.  
  650.     /**
  651.      * Get the Y pixel position represented by a value
  652.      *
  653.      * @param double $point the value to get the pixel-point for
  654.      * @return double The pixel position along the axis
  655.      * @access private
  656.      */
  657.     function _pointY($point)
  658.     {
  659.         $point['AXIS_Y'] = $this->_axisY;
  660.         return parent::_pointY($point);
  661.     }
  662.  
  663.     /**
  664.      * Update coordinates
  665.      *
  666.      * @access private
  667.      */
  668.     function _updateCoords()
  669.     {
  670.         $this->_setCoords($this->_parent->_plotLeft, $this->_parent->_plotTop, $this->_parent->_plotRight, $this->_parent->_plotBottom);
  671.         parent::_updateCoords();
  672.     }
  673.  
  674.     /**
  675.      * Get the dataset
  676.      *
  677.      * @return Image_Graph_Dataset The dataset(s)
  678.      */
  679.     function &dataset()
  680.     {
  681.         return $this->_dataset;
  682.     }
  683.  
  684.     /**
  685.      * Calulate totals
  686.      *
  687.      * @return array An associated array with the totals
  688.      * @access private
  689.      */
  690.     function _getTotals()
  691.     {
  692.         $total = array(
  693.             'MINIMUM_X' => $this->_minimumX(),
  694.             'MAXIMUM_X' => $this->_maximumX(),
  695.             'MINIMUM_Y' => $this->_minimumY(),
  696.             'MAXIMUM_Y' => $this->_maximumY()
  697.         );
  698.         $total['ALL_SUM_Y'] = 0;
  699.  
  700.         $keys = array_keys($this->_dataset);
  701.         foreach ($keys as $key) {
  702.             $dataset =& $this->_dataset[$key];
  703.  
  704.             $dataset->_reset();
  705.             while ($point = $dataset->_next()) {
  706.                 $x = $point['X'];
  707.                 
  708.                 if (is_numeric($point['Y'])) {
  709.                     $total['ALL_SUM_Y'] += $point['Y'];
  710.                     if (isset($total['TOTAL_Y'][$x])) {
  711.                         $total['TOTAL_Y'][$x] += $point['Y'];
  712.                     } else {
  713.                         $total['TOTAL_Y'][$x] = $point['Y'];
  714.                     }
  715.                 }
  716.                 
  717.                 if (is_numeric($point['X'])) {
  718.                     if (isset($total['TOTAL_X'][$x])) {
  719.                         $total['TOTAL_X'][$x] += $point['X'];
  720.                     } else {
  721.                         $total['TOTAL_X'][$x] = $point['X'];
  722.                     }
  723.                 }
  724.             }
  725.         }
  726.         unset($keys);
  727.         return $total;
  728.     }
  729.  
  730.     /**
  731.      * Perform the actual drawing on the legend.
  732.      *
  733.      * @param int $x0 The top-left x-coordinate
  734.      * @param int $y0 The top-left y-coordinate
  735.      * @param int $x1 The bottom-right x-coordinate
  736.      * @param int $y1 The bottom-right y-coordinate
  737.      * @access private
  738.      */
  739.     function _drawLegendSample($x0, $y0, $x1, $y1)
  740.     {
  741.         $this->_canvas->rectangle(array('x0' => $x0, 'y0' => $y0, 'x1' => $x1, 'y1' => $y1));
  742.     }
  743.  
  744.     /**
  745.      * Draw a sample for use with legend
  746.      *
  747.      * @param array $param The parameters for the legend
  748.      * @access private
  749.      */
  750.     function _legendSample(&$param)
  751.     {
  752.         if (!is_array($this->_dataset)) {
  753.             return false;
  754.         }
  755.  
  756.         if (is_a($this->_fillStyle, 'Image_Graph_Fill')) {
  757.             $this->_fillStyle->_reset();
  758.         }
  759.  
  760.         $count = 0;
  761.         $keys = array_keys($this->_dataset);
  762.         foreach ($keys as $key) {
  763.             $dataset =& $this->_dataset[$key];
  764.             $count++;
  765.  
  766.             $caption = ($dataset->_name ? $dataset->_name : $this->_title);
  767.  
  768.             $this->_canvas->setFont($param['font']);
  769.             $width = 20 + $param['width'] + $this->_canvas->textWidth($caption);
  770.             $param['maxwidth'] = max($param['maxwidth'], $width);
  771.             $x2 = $param['x'] + $width;
  772.             $y2 = $param['y'] + $param['height'] + 5;
  773.  
  774.             if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) {
  775.                 $param['y'] = $param['top'];
  776.                 $param['x'] = $x2;
  777.                 $y2 = $param['y'] + $param['height'];
  778.             } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) {
  779.                 $param['x'] = $param['left'];
  780.                 $param['y'] = $y2;
  781.                 $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption);
  782.             }
  783.  
  784.             $x = $x0 = $param['x'];
  785.             $y = $param['y'];
  786.             $y0 = $param['y'];
  787.             $x1 = $param['x'] + $param['width'];
  788.             $y1 = $param['y'] + $param['height'];
  789.  
  790.             if (!isset($param['simulate'])) {
  791.                 $this->_getFillStyle($key);
  792.                 $this->_getLineStyle();
  793.                 $this->_drawLegendSample($x0, $y0, $x1, $y1);
  794.  
  795.                 if (($this->_marker) && ($dataset) && ($param['show_marker'])) {
  796.                     $dataset->_reset();
  797.                     $point = $dataset->_next();
  798.                     $prevPoint = $dataset->_nearby(-2);
  799.                     $nextPoint = $dataset->_nearby();
  800.  
  801.                     $tmp = array();
  802.                     $point = $this->_getMarkerData($point, $nextPoint, $prevPoint, $tmp);
  803.                     if (is_array($point)) {
  804.                         $point['MARKER_X'] = $x+$param['width']/2;
  805.                         $point['MARKER_Y'] = $y;
  806.                         unset ($point['AVERAGE_Y']);
  807.                         $this->_marker->_drawMarker($point['MARKER_X'], $point['MARKER_Y'], $point);
  808.                     }
  809.                 }
  810.                 $this->write($x + $param['width'] + 10, $y + $param['height'] / 2, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']);
  811.             }
  812.  
  813.             if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) {
  814.                 $param['y'] = $y2;
  815.             } else {
  816.                 $param['x'] = $x2;
  817.             }
  818.         }
  819.         unset($keys);
  820.     }
  821.     
  822. }
  823.  
  824. ?>