From 4427f59c63f88971deeaaa9809374df18d1eb288 Mon Sep 17 00:00:00 2001 From: Daniel Stefan Haischt Date: Thu, 27 Jul 2006 01:32:35 +0000 Subject: - added missing PEAR Image dependency --- packages/dspam/pear/Image/Graph/Plot/Area.php | 194 ++++++ packages/dspam/pear/Image/Graph/Plot/Band.php | 205 ++++++ packages/dspam/pear/Image/Graph/Plot/Bar.php | 307 +++++++++ .../dspam/pear/Image/Graph/Plot/BoxWhisker.php | 298 +++++++++ .../dspam/pear/Image/Graph/Plot/CandleStick.php | 251 +++++++ packages/dspam/pear/Image/Graph/Plot/Dot.php | 99 +++ packages/dspam/pear/Image/Graph/Plot/Fit/Line.php | 118 ++++ packages/dspam/pear/Image/Graph/Plot/Impulse.php | 204 ++++++ packages/dspam/pear/Image/Graph/Plot/Line.php | 171 +++++ packages/dspam/pear/Image/Graph/Plot/Odo.php | 719 +++++++++++++++++++++ packages/dspam/pear/Image/Graph/Plot/Pie.php | 623 ++++++++++++++++++ packages/dspam/pear/Image/Graph/Plot/Radar.php | 118 ++++ .../dspam/pear/Image/Graph/Plot/Smoothed/Area.php | 145 +++++ .../pear/Image/Graph/Plot/Smoothed/Bezier.php | 173 +++++ .../dspam/pear/Image/Graph/Plot/Smoothed/Line.php | 172 +++++ .../dspam/pear/Image/Graph/Plot/Smoothed/Radar.php | 142 ++++ packages/dspam/pear/Image/Graph/Plot/Step.php | 200 ++++++ 17 files changed, 4139 insertions(+) create mode 100644 packages/dspam/pear/Image/Graph/Plot/Area.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Band.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Bar.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/BoxWhisker.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/CandleStick.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Dot.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Fit/Line.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Impulse.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Line.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Odo.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Pie.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Radar.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Smoothed/Area.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Smoothed/Line.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php create mode 100644 packages/dspam/pear/Image/Graph/Plot/Step.php (limited to 'packages/dspam/pear/Image/Graph/Plot') diff --git a/packages/dspam/pear/Image/Graph/Plot/Area.php b/packages/dspam/pear/Image/Graph/Plot/Area.php new file mode 100644 index 00000000..a5288e1a --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Area.php @@ -0,0 +1,194 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Area Chart plot. + * + * An area chart plots all data points similar to a {@link + * Image_Graph_Plot_Line}, but the area beneath the line is filled and the whole + * area 'the-line', 'the right edge', 'the x-axis' and 'the left edge' is + * bounded. Smoothed charts are only supported with non-stacked types + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Area extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 3; + $dy = abs($y1 - $y0) / 3; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y1)); + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y0 + $dy)); + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y0)); + $this->_canvas->addVertex(array('x' => $x0 + 2*$dx, 'y' => $y0 + 2*$dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y0 + $dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + $base = array(); + if ($this->_multiType == 'stacked') { + reset($this->_dataset); + $key = key($this->_dataset); + $dataset =& $this->_dataset[$key]; + + $first = $dataset->first(); + $point = array ('X' => $first['X'], 'Y' => '#min_pos#'); + $base[] = array(); + $base[] = $this->_pointY($point); + $first = $this->_pointX($point); + $base[] = $first; + + $last = $dataset->last(); + $point = array ('X' => $last['X'], 'Y' => '#min_pos#'); + $base[] = array(); + $base[] = $this->_pointY($point); + $base[] = $this->_pointX($point); + + $current = array(); + } + + $minYaxis = $this->_parent->_getMinimum($this->_axisY); + $maxYaxis = $this->_parent->_getMaximum($this->_axisY); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + if ($this->_multiType == 'stacked') { + $plotarea = array_reverse($base); + $base = array(); + while ($point = $dataset->_next()) { + $x = $point['X']; + $p = $point; + if (isset($current[$x])) { + $p['Y'] += $current[$x]; + } else { + $current[$x] = 0; + } + $x1 = $this->_pointX($p); + $y1 = $this->_pointY($p); + $plotarea[] = $x1; + $plotarea[] = $y1; + $plotarea[] = $point; + $base[] = array(); + $base[] = $y1; + $base[] = $x1; + $current[$x] += $point['Y']; + } + } else { + $first = true; + $plotarea = array(); + while ($point = $dataset->_next()) { + if ($first) { + $firstPoint = array ('X' => $point['X'], 'Y' => '#min_pos#'); + $plotarea[] = $this->_pointX($firstPoint); + $plotarea[] = $this->_pointY($firstPoint); + $plotarea[] = array(); + } + $plotarea[] = $this->_pointX($point); + $plotarea[] = $this->_pointY($point); + $plotarea[] = $point; + $lastPoint = $point; + $first = false; + } + $endPoint['X'] = $lastPoint['X']; + $endPoint['Y'] = '#min_pos#'; + $plotarea[] = $this->_pointX($endPoint); + $plotarea[] = $this->_pointY($endPoint); + $plotarea[] = array(); + } + + reset($plotarea); + while (list(, $x) = each($plotarea)) { + list(, $y) = each($plotarea); + list(, $data) = each($plotarea); + $this->_canvas->addVertex( + $this->_mergeData( + $data, + array('x' => $x, 'y' => $y) + ) + ); + } + + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true, 'map_vertices' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Band.php b/packages/dspam/pear/Image/Graph/Plot/Band.php new file mode 100644 index 00000000..3d5b629a --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Band.php @@ -0,0 +1,205 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * "Band" (area chart with min AND max) chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_Band extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $h = abs($y1 - $y0) / 6; + $w = round(abs($x1 - $x0) / 5); + $y = ($y0 + $y1) / 2; + + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y - $h * 3)); + $this->_canvas->addVertex(array('x' => $x0 + $w, 'y' => $y - 4 * $h)); + $this->_canvas->addVertex(array('x' => $x0 + 2 * $w, 'y' => $y - $h * 2)); + $this->_canvas->addVertex(array('x' => $x0 + 3 * $w, 'y' => $y - $h * 4)); + $this->_canvas->addVertex(array('x' => $x0 + 4 * $w, 'y' => $y - $h * 3)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y - $h * 2)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y + $h * 3)); + $this->_canvas->addVertex(array('x' => $x0 + 4 * $w, 'y' => $y + $h)); + $this->_canvas->addVertex(array('x' => $x0 + 3 * $w, 'y' => $y + 2 * $h)); + $this->_canvas->addVertex(array('x' => $x0 + 2 * $w, 'y' => $y + 1 * $h)); + $this->_canvas->addVertex(array('x' => $x0 + 1 * $w, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y + $h)); + + $this->_getLineStyle(); + $this->_getFillStyle(); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $current = array(); + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $upperBand = array(); + $lowerBand = array(); + while ($data = $dataset->_next()) { + if ($this->_parent->_horizontal) { + $point['X'] = $data['X']; + + $point['Y'] = $data['Y']['high']; + $y = $this->_pointY($point); + $x_high = $this->_pointX($point); + + $point['Y'] = $data['Y']['low']; + $x_low = $this->_pointX($point); + + $data = array('X' => $x_high, 'Y' => $y); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $upperBand[] = $data; + + $data = array('X' => $x_low, 'Y' => $y); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $lowerBand[] = $data; + } + else { + $point['X'] = $data['X']; + $y = $data['Y']; + + $point['Y'] = $data['Y']['high']; + $x = $this->_pointX($point); + $y_high = $this->_pointY($point); + + $point['Y'] = $data['Y']['low']; + $y_low = $this->_pointY($point); + + $data = array('X' => $x, 'Y' => $y_high); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $upperBand[] = $data; + + $data = array('X' => $x, 'Y' => $y_low); + if (isset($point['data'])) { + $data['data'] = $point['data']; + } else { + $data['data'] = array(); + } + $lowerBand[] = $data; + } + } + $lowerBand = array_reverse($lowerBand); + foreach ($lowerBand as $point) { + $this->_canvas->addVertex( + $this->_mergeData( + $point['data'], + array('x' => $point['X'], 'y' => $point['Y']) + ) + ); + } + foreach ($upperBand as $point) { + $this->_canvas->addVertex( + $this->_mergeData( + $point['data'], + array('x' => $point['X'], 'y' => $point['Y']) + ) + ); + } + unset($upperBand); + unset($lowerBand); + + $this->_getLineStyle($key); + $this->_getFillStyle($key); + $this->_canvas->polygon(array('connect' => true, 'map_vertices' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Bar.php b/packages/dspam/pear/Image/Graph/Plot/Bar.php new file mode 100644 index 00000000..3e35f92c --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Bar.php @@ -0,0 +1,307 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * A bar chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Bar extends Image_Graph_Plot +{ + + /** + * The space between 2 bars (should be a multipla of 2) + * @var int + * @access private + */ + var $_space = 4; + + /** + * The width of the bars + * @var array + * @access private + */ + var $_width = 'auto'; + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 7; + $this->_canvas->rectangle(array('x0' => $x0 + $dx, 'y0' => $y0, 'x1' => $x1 - $dx, 'y1' => $y1)); + } + + /** + * Set the spacing between 2 neighbouring bars + * + * @param int $space The number of pixels between 2 bars, should be a + * multipla of 2 (ie an even number) + */ + function setSpacing($space) + { + $this->_space = (int) ($space / 2); + } + + /** + * Set the width of a bars. + * + * Specify 'auto' to auto calculate the width based on the positions on the + * x-axis. + * + * Supported units are: + * + * '%' The width is specified in percentage of the total plot width + * + * 'px' The width specified in pixels + * + * @param string $width The width of any bar + * @param string $unit The unit of the width + */ + function setBarWidth($width, $unit = false) + { + if ($width == 'auto') { + $this->_width = $width; + } else { + $this->_width = array( + 'width' => $width, + 'unit' => $unit + ); + } + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + if ($this->_width == 'auto') { + $width = $this->_parent->_labelDistance(IMAGE_GRAPH_AXIS_X) / 2; + } elseif ($this->_width['unit'] == '%') { + $width = $this->_width['width'] * $this->width() / 200; + } elseif ($this->_width['unit'] == 'px') { + $width = $this->_width['width'] / 2; + } + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + + $minYaxis = $this->_parent->_getMinimum($this->_axisY); + $maxYaxis = $this->_parent->_getMaximum($this->_axisY); + + $number = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($point = $dataset->_next()) { + + if ($this->_parent->_horizontal) { + $y1 = $this->_pointY($point) - $width; + $y2 = $this->_pointY($point) + $width; + + if ($y2 - $this->_space > $y1 + $this->_space) { + /* + * Take bar spacing into account _only_ if the space doesn't + * turn the bar "inside-out", i.e. if the actual bar width + * is smaller than the space between the bars + */ + $y2 -= $this->_space; + $y1 += $this->_space; + } + } + else { + $x1 = $this->_pointX($point) - $width; + $x2 = $this->_pointX($point) + $width; + + if ($x2 - $this->_space > $x1 + $this->_space) { + /* + * Take bar spacing into account _only_ if the space doesn't + * turn the bar "inside-out", i.e. if the actual bar width + * is smaller than the space between the bars + */ + $x2 -= $this->_space; + $x1 += $this->_space; + } + } + + + if (($this->_multiType == 'stacked') || + ($this->_multiType == 'stacked100pct')) + { + $x = $point['X']; + + if ($point['Y'] >= 0) { + if (!isset($current[$x])) { + $current[$x] = 0; + } + + if ($this->_multiType == 'stacked') { + $p0 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + $point['Y'] + ); + } else { + $p0 = array( + 'X' => $point['X'], + 'Y' => 100 * $current[$x] / $total['TOTAL_Y'][$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x] + ); + } + $current[$x] += $point['Y']; + } else { + if (!isset($currentNegative[$x])) { + $currentNegative[$x] = 0; + } + + $p0 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + $point['Y'] + ); + $currentNegative[$x] += $point['Y']; + } + } else { + if (count($this->_dataset) > 1) { + $w = 2 * ($width - $this->_space) / count($this->_dataset); + if ($this->_parent->_horizontal) { + $y2 = ($y1 = ($y1 + $y2) / 2 - ($width - $this->_space) + $number * $w) + $w; + } + else { + $x2 = ($x1 = ($x1 + $x2) / 2 - ($width - $this->_space) + $number * $w) + $w; + } + } + $p0 = array('X' => $point['X'], 'Y' => 0); + $p1 = $point; + } + + if ((($minY = min($p0['Y'], $p1['Y'])) < $maxYaxis) && + (($maxY = max($p0['Y'], $p1['Y'])) > $minYaxis) + ) { + $p0['Y'] = $minY; + $p1['Y'] = $maxY; + + if ($p0['Y'] < $minYaxis) { + $p0['Y'] = '#min_pos#'; + } + if ($p1['Y'] > $maxYaxis) { + $p1['Y'] = '#max_neg#'; + } + + if ($this->_parent->_horizontal) { + $x1 = $this->_pointX($p0); + $x2 = $this->_pointX($p1); + } + else { + $y1 = $this->_pointY($p0); + $y2 = $this->_pointY($p1); + } + + $ID = $point['ID']; + if (($ID === false) && (count($this->_dataset) > 1)) { + $ID = $key; + } + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + + if (($y1 != $y2) && ($x1 != $x2)) { + $this->_canvas->rectangle( + $this->_mergeData( + $point, + array( + 'x0' => min($x1, $x2), + 'y0' => min($y1, $y2), + 'x1' => max($x1, $x2), + 'y1' => max($y1, $y2) + ) + ) + ); + } + } + } + $number ++; + } + unset($keys); + + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/BoxWhisker.php b/packages/dspam/pear/Image/Graph/Plot/BoxWhisker.php new file mode 100644 index 00000000..59c1ee44 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/BoxWhisker.php @@ -0,0 +1,298 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Box & Whisker chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_BoxWhisker extends Image_Graph_Plot +{ + /** + * Whisker circle size + * @var int + * @access private + */ + var $_whiskerSize = false; + + /** + * Draws a box & whisker + * + * @param int $x The x position + * @param int $w The width of the box + * @param int $r The radius of the circle markers + * @param int $y_min The Y position of the minimum value + * @param int $y_q1 The Y position of the median of the first quartile + * @param int $y_med The Y position of the median + * @param int $y_q3 The Y position of the median of the third quartile + * @param int $y_max The Y position of the maximum value + * @param int $key The ID tag + * @access private + */ + function _drawBoxWhiskerV($x, $w, $r, $y_min, $y_q1, $y_med, $y_q3, $y_max, $key = false) + { + // draw circles + $this->_getLineStyle(); + $this->_getFillStyle('min'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_min, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile1'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_q1, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('median'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_med, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile3'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_q3, $r, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('max'); + $this->_canvas->ellipse(array('x' => $x, 'y' => $y_max, $r, 'rx' => $r, 'ry' => $r)); + + // draw box and lines + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y_min, 'x1' => $x, 'y1' => $y_q1)); + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x, 'y0' => $y_q3, 'x1' => $x, 'y1' => $y_max)); + + $this->_getLineStyle(); + $this->_getFillStyle('box'); + $this->_canvas->rectangle(array('x0' => $x - $w, 'y0' => $y_q1, 'x1' => $x + $w, 'y1' => $y_q3)); + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x - $w, 'y0' => $y_med, 'x1' => $x + $w, 'y1' => $y_med)); + } + + /** + * Draws a box & whisker + * + * @param int $y The x position + * @param int $h The width of the box + * @param int $r The radius of the circle markers + * @param int $x_min The Y position of the minimum value + * @param int $x_q1 The Y position of the median of the first quartile + * @param int $x_med The Y position of the median + * @param int $x_q3 The Y position of the median of the third quartile + * @param int $x_max The Y position of the maximum value + * @param int $key The ID tag + * @access private + */ + function _drawBoxWhiskerH($y, $h, $r, $x_min, $x_q1, $x_med, $x_q3, $x_max, $key = false) + { + // draw circles + $this->_getLineStyle(); + $this->_getFillStyle('min'); + $this->_canvas->ellipse(array('x' => $x_min, 'y' => $y, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile1'); + $this->_canvas->ellipse(array('x' => $x_q1, 'y' => $y, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('median'); + $this->_canvas->ellipse(array('x' => $x_med, 'y' => $y, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('quartile3'); + $this->_canvas->ellipse(array('x' => $x_q3, 'y' => $y, $r, 'rx' => $r, 'ry' => $r)); + + $this->_getLineStyle(); + $this->_getFillStyle('max'); + $this->_canvas->ellipse(array('x' => $x_max, 'y' => $y, $r, 'rx' => $r, 'ry' => $r)); + + // draw box and lines + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x_min, 'y0' => $y, 'x1' => $x_q1, 'y1' => $y)); + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x_q3, 'y0' => $y, 'x1' => $x_max, 'y1' => $y)); + + $this->_getLineStyle(); + $this->_getFillStyle('box'); + $this->_canvas->rectangle(array('x0' => $x_q1, 'y0' => $y - $h, 'x1' => $x_q3, 'y1' => $y + $h)); + + $this->_getLineStyle(); + $this->_canvas->line(array('x0' => $x_med, 'y0' => $y - $h, 'x1' => $x_med, 'y1' => $y + $h)); + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $x = round(($x0 + $x1) / 2); + $h = abs($y1 - $y0) / 9; + $w = round(abs($x1 - $x0) / 5); + $r = 2;//round(abs($x1 - $x0) / 13); + $this->_drawBoxWhiskerV($x, $w, $r, $y1, $y1 - 2 * $h, $y1 - 4 * $h, $y0 + 3 * $h, $y0); + } + + /** + * Sets the whisker circle size + * + * @param int $size Size (radius) of the whisker circle/dot + */ + function setWhiskerSize($size = false) + { + $this->_whiskerSize = $size; + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + $current = array(); + $number = 0; + $width = floor(0.5 * $this->_parent->_labelDistance(IMAGE_GRAPH_AXIS_X) / 2); + + if ($this->_whiskerSize !== false) { + $r = $this->_whiskerSize; + } else { + $r = min(5, $width / 10); + } + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($data = $dataset->_next()) { + if ($this->_parent->_horizontal) { + $point['X'] = $data['X']; + $y = $data['Y']; + + $min = min($y); + $max = max($y); + $q1 = $dataset->_median($y, 'first'); + $med = $dataset->_median($y, 'second'); + $q3 = $dataset->_median($y, 'third'); + + $point['Y'] = $min; + $y = $this->_pointY($point); + $x_min = $this->_pointX($point); + + $point['Y'] = $max; + $x_max = $this->_pointX($point); + + $point['Y'] = $q1; + $x_q1 = $this->_pointX($point); + + $point['Y'] = $med; + $x_med = $this->_pointX($point); + + $point['Y'] = $q3; + $x_q3 = $this->_pointX($point); + + $this->_drawBoxWhiskerH($y, $width, $r, $x_min, $x_q1, $x_med, $x_q3, $x_max, $key); + } + else { + $point['X'] = $data['X']; + $y = $data['Y']; + + $min = min($y); + $max = max($y); + $q1 = $dataset->_median($y, 'first'); + $med = $dataset->_median($y, 'second'); + $q3 = $dataset->_median($y, 'third'); + + $point['Y'] = $min; + $x = $this->_pointX($point); + $y_min = $this->_pointY($point); + + $point['Y'] = $max; + $y_max = $this->_pointY($point); + + $point['Y'] = $q1; + $y_q1 = $this->_pointY($point); + + $point['Y'] = $med; + $y_med = $this->_pointY($point); + + $point['Y'] = $q3; + $y_q3 = $this->_pointY($point); + + $this->_drawBoxWhiskerV($x, $width, $r, $y_min, $y_q1, $y_med, $y_q3, $y_max, $key); + } + } + } + unset($keys); + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/CandleStick.php b/packages/dspam/pear/Image/Graph/Plot/CandleStick.php new file mode 100644 index 00000000..b050aea1 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/CandleStick.php @@ -0,0 +1,251 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Candlestick chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_CandleStick extends Image_Graph_Plot +{ + + /** + * (Add basic description here) + * + * @access private + */ + function _drawCandleStickH($y, $h, $x_min, $x_open, $x_close, $x_max, $ID) + { + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => min($x_open, $x_close), + 'y0' => $y, + 'x1' => $x_min, + 'y1' => $y + ) + ); + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => max($x_open, $x_close), + 'y0' => $y, + 'x1' => $x_max, + 'y1' => $y + ) + ); + + $this->_getLineStyle($ID); + $this->_getFillStyle($ID); + $this->_canvas->rectangle( + array( + 'x0' => min($x_open, $x_close), + 'y0' => $y - $h, + 'x1' => max($x_open, $x_close), + 'y1' => $y + $h + ) + ); + } + + /** + * (Add basic description here) + * + * @access private + */ + function _drawCandleStickV($x, $w, $y_min, $y_open, $y_close, $y_max, $ID) + { + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => $x, + 'y0' => min($y_open, $y_close), + 'x1' => $x, + 'y1' => $y_max + ) + ); + $this->_getLineStyle($ID); + $this->_canvas->line( + array( + 'x0' => $x, + 'y0' => max($y_open, $y_close), + 'x1' => $x, + 'y1' => $y_min + ) + ); + + $this->_getLineStyle($ID); + $this->_getFillStyle($ID); + $this->_canvas->rectangle( + array( + 'x0' => $x - $w, + 'y0' => min($y_open, $y_close), + 'x1' => $x + $w, + 'y1' => max($y_open, $y_close) + ) + ); + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $x = round(($x0 + $x1) / 2); + $h = abs($y1 - $y0) / 4; + $w = round(abs($x1 - $x0) / 5); + $this->_drawCandleStickV($x, $w, $y1, $y1 - $h, $y0 + $h, $y0, 'green'); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + $current = array(); + $number = 0; + $width = floor(0.8 * $this->_parent->_labelDistance(IMAGE_GRAPH_AXIS_X) / 2); + + $lastClosed = false; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($data = $dataset->_next()) { + if ($this->_parent->_horizontal) { + $point['X'] = $data['X']; + //$y = $data['Y']; + + if (isset($data['Y']['open'])) { + $point['Y'] = $data['Y']['open']; + } else { + $point['Y'] = $lastClosed; + } + $y = $this->_pointY($point); + $x_open = $this->_pointX($point); + + $lastClosed = $point['Y'] = $data['Y']['close']; + $x_close = $this->_pointX($point); + + $point['Y'] = $data['Y']['min']; + $x_min = $this->_pointX($point); + + $point['Y'] = $data['Y']['max']; + $x_max = $this->_pointX($point); + + if ($data['Y']['close'] < $data['Y']['open']) { + $ID = 'red'; + } else { + $ID = 'green'; + } + + $this->_drawCandleStickH($y, $width, $x_min, $x_open, $x_close, $x_max, $ID); + } + else { + $point['X'] = $data['X']; + //$y = $data['Y']; + + if (isset($data['Y']['open'])) { + $point['Y'] = $data['Y']['open']; + } else { + $point['Y'] = $lastClosed; + } + $x = $this->_pointX($point); + $y_open = $this->_pointY($point); + + $lastClosed = $point['Y'] = $data['Y']['close']; + $y_close = $this->_pointY($point); + + $point['Y'] = $data['Y']['min']; + $y_min = $this->_pointY($point); + + $point['Y'] = $data['Y']['max']; + $y_max = $this->_pointY($point); + + if ($data['Y']['close'] < $data['Y']['open']) { + $ID = 'red'; + } else { + $ID = 'green'; + } + + $this->_drawCandleStickV($x, $width, $y_min, $y_open, $y_close, $y_max, $ID); + } + } + } + unset($keys); + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup($this->_title); + + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Dot.php b/packages/dspam/pear/Image/Graph/Plot/Dot.php new file mode 100644 index 00000000..19352567 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Dot.php @@ -0,0 +1,99 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Dot / scatter chart (only marker). + * + * This plot type only displays a {@link Image_Graph_Marker} for the datapoints. + * The marker must explicitly be defined using {@link Image_Graph_Plot:: + * setMarker()}. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Dot extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + if (isset($this->_marker)) { + $key = key($this->_dataset); + $samplePoint = $this->_dataset[$key]->_nearby(); + $this->_marker->_drawMarker(($x0 + $x1) / 2, ($y0 + $y1) / 2, $samplePoint); + } + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (Image_Graph_Plot::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + + $this->_clip(true); + + $this->_drawMarker(); + + $this->_clip(false); + + $this->_canvas->endGroup(); + + return true; + } +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Fit/Line.php b/packages/dspam/pear/Image/Graph/Plot/Fit/Line.php new file mode 100644 index 00000000..07f3b9cc --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Fit/Line.php @@ -0,0 +1,118 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Include file Image/Graph/Tool.php + */ +require_once 'Image/Graph/Tool.php'; + +/** + * Fit the graph (to a line using linear regression). + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Fit_Line extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $y = ($y0 + $y1) / 2; + $dy = abs($y1 - $y0) / 6; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y + $dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y - $dy)); + $this->_canvas->polygon(array('connect' => false)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (Image_Graph_Plot::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $data = array(); + while ($point = $dataset->_next()) { + $data[] = array( + 'X' => $this->_pointX($point), + 'Y' => $this->_pointY($point) + ); + } + + $regression = Image_Graph_Tool::calculateLinearRegression($data); + $this->_getLineStyle($key); + $this->_canvas->line( + array( + 'x0' => $this->_left, + 'y0' => $this->_left * $regression['slope'] + $regression['intersection'], + 'x1' => $this->_right, + 'y1' => $this->_right * $regression['slope'] + $regression['intersection'] + ) + ); + } + $this->_clip(false); + $this->_canvas->endGroup(); + + return true; + } +} + +?> diff --git a/packages/dspam/pear/Image/Graph/Plot/Impulse.php b/packages/dspam/pear/Image/Graph/Plot/Impulse.php new file mode 100644 index 00000000..91372cd1 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Impulse.php @@ -0,0 +1,204 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Impulse chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Impulse extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $x = ($x0 + $x1) / 2; + $this->_canvas->line(array('x0' => $x, 'y0' => $y0, 'x1' => $x, 'y1' => $y1)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + $current = array(); + $number = 0; + + $minYaxis = $this->_parent->_getMinimum($this->_axisY); + $maxYaxis = $this->_parent->_getMaximum($this->_axisY); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $x0 = $this->_pointX($point); + if (($this->_multiType == 'stacked') || + ($this->_multiType == 'stacked100pct')) + { + $x = $point['X']; + + if ($point['Y'] >= 0) { + if (!isset($current[$x])) { + $current[$x] = 0; + } + + if ($this->_multiType == 'stacked') { + $p0 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $current[$x] + $point['Y'] + ); + } else { + $p0 = array( + 'X' => $point['X'], + 'Y' => 100 * $current[$x] / $total['TOTAL_Y'][$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x] + ); + } + $current[$x] += $point['Y']; + } else { + if (!isset($currentNegative[$x])) { + $currentNegative[$x] = 0; + } + + $p0 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + ); + $p1 = array( + 'X' => $point['X'], + 'Y' => $currentNegative[$x] + $point['Y'] + ); + $currentNegative[$x] += $point['Y']; + } + } else { + $p0 = array('X' => $point['X'], 'Y' => 0); + $p1 = $point; + } + + if ((($minY = min($p0['Y'], $p1['Y'])) < $maxYaxis) && + (($maxY = max($p0['Y'], $p1['Y'])) > $minYaxis) + ) { + $p0['Y'] = $minY; + $p1['Y'] = $maxY; + + if ($p0['Y'] < $minYaxis) { + $p0['Y'] = '#min_pos#'; + } + if ($p1['Y'] > $maxYaxis) { + $p1['Y'] = '#max_neg#'; + } + + $x1 = $this->_pointX($p0); + $y1 = $this->_pointY($p0); + + $x2 = $this->_pointX($p1); + $y2 = $this->_pointY($p1); + + if ($this->_multiType == 'normal') { + $offset = 5*$number; + $x1 += $offset; + $x2 += $offset; + } + + $ID = $point['ID']; + if (($ID === false) && (count($this->_dataset) > 1)) { + $ID = $key; + } + $this->_getLineStyle($key); + $this->_canvas->line( + $this->_mergeData( + $point, + array( + 'x0' => $x1, + 'y0' => $y1, + 'x1' => $x2, + 'y1' => $y2 + ) + ) + ); + } + } + $number++; + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Line.php b/packages/dspam/pear/Image/Graph/Plot/Line.php new file mode 100644 index 00000000..009b4e1f --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Line.php @@ -0,0 +1,171 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Linechart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Line extends Image_Graph_Plot +{ + + /** + * Gets the fill style of the element + * + * @return int A GD filestyle representing the fill style + * @see Image_Graph_Fill + * @access private + */ + function _getFillStyle($ID = false) + { + return IMG_COLOR_TRANSPARENT; + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $y = ($y0 + $y1) / 2; + $dx = abs($x1 - $x0) / 3; + $dy = abs($y1 - $y0) / 5; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y)); + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y - $dy * 2)); + $this->_canvas->addVertex(array('x' => $x1 - $dx, 'y' => $y + $dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y - $dy)); + $this->_canvas->polygon(array('connect' => false)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + if (!is_array($this->_dataset)) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + reset($this->_dataset); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + + $p1 = false; + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $numPoints = 0; + while ($point = $dataset->_next()) { + if (($this->_multiType == 'stacked') || + ($this->_multiType == 'stacked100pct')) + { + $x = $point['X']; + if (!isset($current[$x])) { + $current[$x] = 0; + } + if ($this->_multiType == 'stacked') { + $py = $current[$x] + $point['Y']; + } else { + $py = 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x]; + } + $current[$x] += $point['Y']; + $point['Y'] = $py; + } + + if ($point['Y'] === null) { + if ($numPoints > 1) { + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + $numPoints = 0; + } else { + $p2['X'] = $this->_pointX($point); + $p2['Y'] = $this->_pointY($point); + + $this->_canvas->addVertex( + $this->_mergeData( + $point, + array('x' => $p2['X'], 'y' => $p2['Y']) + ) + ); + $numPoints++; + } + } + if ($numPoints > 1) { + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Odo.php b/packages/dspam/pear/Image/Graph/Plot/Odo.php new file mode 100644 index 00000000..d6bf7969 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Odo.php @@ -0,0 +1,719 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Include file Image/Graph/Tool.php + */ +require_once 'Image/Graph/Tool.php'; + +/** + * 2D Odochart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Maxime Delorme + * @copyright Copyright (C) 2005 Maxime Delorme + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Odo extends Image_Graph_Plot +{ + /** + * the percent of the radius of the chart that will be use as the width of the range + * @access private + * @var int + */ + var $_radiusPercent = 50; + + /** + * the minimun value of the chart or the start value + * @access private + * @var int + */ + var $_value_min = 0; + + /** + * the maximum value of the chart or the end value + * @access private + * @var int + */ + var $_value_max = 100; + + /** + * the start angle + * @access private + * @var int + */ + var $_deg_offset = 135; + + /** + * the angle of the chart , the length of the chart + * 180 min a half circle + * @access private + * @var int + */ + var $_deg_width = 270; + + /** + * the length of the big ticks + * the small ones will be half ot it, the values 160% of it + * 180 min a half circle + * @access private + * @var int + */ + var $_tickLength = 14; + + /** + * how many small ticks a big tick appears + * the small ticks appear every 6° + * so with the default value of 5, every 30° there is a value and a big tick + * 180 min a half circle + * @access private + * @var int + */ + var $_axisTicks = 5; + + /** + * Arrow marker + * @access private + * @var Image_Graph_Marker + */ + var $_arrowMarker; + + /** + * Range marker fill style + * @access private + * @var Image_Graph_Fill + */ + var $_rangeFillStyle = null; + + /** + * The width of the arrow + * @access private + * @var int + */ + var $_arrowWidth = 5; + + /** + * The length of the arrow + * @access private + * @var int + */ + var $_arrowLength = 80; + + /** + * The radius of the plot + * @access private + * @var int + */ + var $_radius = false; + + /** + * The total Y + * @access private + * @var int + */ + var $_totalY = false; + + /** + * Center X of odometer "circle" + * @access private + * @var int + */ + var $_centerX = false; + + /** + * Center y of odometer "circle" + * @access private + * @var int + */ + var $_centerY = false; + + /** + * Plot_Odo [Constructor] + * + * dataset with one data per arrow + * @param Image_Graph_Dataset $dataset The data set (value containter) to + * plot or an array of datasets + * {@link Image_Graph_Legend} + */ + function Image_Graph_Plot_Odo(&$dataset) + { + parent::Image_Graph_Plot($dataset); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + if (isset($min)) { + $min = min($dataset->minimumY(), $min); + } + else { + $min = $dataset->minimumY(); + } + if (isset($max)) { + $max = max($dataset->maximumY(), $max); + } + else { + $max = $dataset->maximumY(); + } + } + $this->_value_min = $min; + $this->_value_max = $max; + } + + /** + * Set the center of the odometer + * + * @param int $centerX The center x point + * @param int $centerY The center y point + */ + function setCenter($centerX, $centerY) + { + $this->_centerX = $centerX; + $this->_centerY = $centerY; + } + + /** + * Convert a value to the angle position onto the odometer + * + * @access private + * @param int $value the value to convert + * @return int the angle'position onto the odometer + */ + function _value2angle($value) + { + return $this->_deg_width * (($value - $this->_value_min) / $this->_totalY) + $this->_deg_offset; + } + + /** + * set some internal var + * + * @access private + */ + function _initialize() + { + $v1 = $this->_deg_offset; + $v2 = $this->_deg_offset + $this->_deg_width; + + $dimensions = Image_Graph_Tool::calculateArcDimensionAndCenter($v1, $v2); + + $radiusX = ($this->width() / 2) / $dimensions['rx']; + $radiusY = ($this->height() / 2) / $dimensions['ry']; + + $this->_radius = min($radiusX, $radiusY); + + if ($this->_marker) { + $this->_radius = $this->_radius * 0.85; + } + + //the center of the plot + if ($this->_centerX === false) { + $this->_centerX = (int) (($this->_left + $this->_right) / 2) + + $this->_radius * ($dimensions['cx'] - 0.5); + } + + if ($this->_centerY === false) { + $this->_centerY = (int) (($this->_top + $this->_bottom) / 2) + + $this->_radius * ($dimensions['cy'] - 0.5); + } + + //the max range + $this->_totalY = abs($this->_value_max - $this->_value_min); + } + + /** + * set min and max value of the range + * + * @access public + * @param integer $value_min the minimun value of the chart or the start value + * @param integer $value_max the maximum value of the chart or the end value + */ + function setRange($value_min, $value_max) + { + $this->_value_min = $value_min; + $this->_value_max = $value_max; + } + + /** + * Set start's angle and amplitude of the chart + * + * @access public + * @param integer $deg_offset the start angle + * @param integer $deg_width the angle of the chart (the length) + */ + function setAngles($deg_offset, $deg_width) + { + $this->_deg_offset = min(360, abs($deg_offset)); + $this->_deg_width = min(360, abs($deg_width)); + } + + /** + * set the width of the chart + * + * @access public + * @param string $radius_percent a value between 0 and 100 + */ + function setRadiusWidth($radius_percent) + { + $this->_radiusPercent = $radius_percent; + } + + /** + * set the width and length of the arrow (in percent of the total plot "radius") + * + * @param int length The length in percent + * @param int width The width in percent + */ + function setArrowSize($length, $width) + { + $this->_arrowWidth = max(0, min(100, $width)); + $this->_arrowLength = max(0, min(100, $length)); + } + + /** + * Set the arrow marker + * @param Image_Graph_Marker $marker The marker to set for arrow marker + */ + function setArrowMarker(&$marker) + { + $this->_arrowMarker =& $marker; + } + + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + $this->_initialize(); + $this->_drawRange(); + $this->_drawAxis(); + $this->_drawArrow(); + $this->_drawMarker(); + return true; + } + + /** + * set the length of the ticks + * + * @access public + * @param string $radius_percent a value between 0 and 100 + */ + function setTickLength($radius) + { + $this->_tickLength = $radius; + } + + /** + * set the length of the ticks + * + * @access public + * @param string $radius_percent a value between 0 and 100 + */ + function setAxisTicks($int) + { + $this->_axisTicks = $int; + } + + /** + * Draw the outline and the axis + * + * @access private + */ + function _drawAxis() + { + //draw outline + $this->_getLineStyle(); + $this->_canvas->pieslice( + array( + 'x' => $this->_centerX, + 'y' => $this->_centerY, + 'rx' => $this->_radius, + 'ry' => $this->_radius, + 'v1' => $this->_deg_offset, + 'v2' => $this->_deg_offset+$this->_deg_width, + 'srx' => $this->_radius * (1 - $this->_radiusPercent / 100), + 'sry' => $this->_radius * (1 - $this->_radiusPercent / 100) + ) + ); + + //step for every 6° + $step = (int) ($this->_totalY / $this->_deg_width * 6); + $value = $this->_value_min; + $i = 0; + while ($value <= $this->_value_max) { + $angle = $this->_value2angle($value); + + $cos = cos(deg2rad($angle)); + $sin = sin(deg2rad($angle)); + $point = array('Y' => $value); + $point['AX'] = $cos; + $point['AY'] = $sin; + $point['LENGTH'] = 1; + $x = $this->_centerX + $this->_radius * $cos; + $y = $this->_centerY + $this->_radius * $sin; + $deltaX = - $cos * $this->_tickLength ; + $deltaY = - $sin * $this->_tickLength ; + $this->_getLineStyle(); + if(($i % $this->_axisTicks) == 0){ + $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $deltaX, 'y1' => $y + $deltaY)); + if ($this->_arrowMarker) { + $this->_arrowMarker->_drawMarker($x + $deltaX * 1.6, $y + $deltaY *1.6, $point); + } + } else { + $this->_canvas->line(array('x0' => $x, 'y0' => $y, 'x1' => $x + $deltaX * 0.5, 'y1' => $y + $deltaY * 0.5)); + } + $i++; + $value += $step; + } + + } + + /** + * Set the line style of the arrows + * + * @param Image_Graph_Line $lineStyle The line style of the Arrow + * @see Image_Graph_Line + * @access public + */ + function setArrowLineStyle($lineStyle) + { + $this->_arrowLineStyle = &$lineStyle; + } + + /** + * Set the fillstyle of the arrows + * + * @param Image_Graph_Fill $fillStyle The fill style of the arrows + * @see Image_Graph_Fill + * @access public + */ + function setArrowFillStyle($fillStyle) + { + $this->_arrowFillStyle = &$fillStyle; + } + + /** + * Draw the arrows + * + * @access private + */ + function _drawArrow() + { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $this->setLineStyle($this->_arrowLineStyle); + $this->setFillStyle($this->_arrowFillStyle); + while ($point = $dataset->_next()) { + $ID = $point['ID']; + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + $deg = $this->_value2angle($point['Y']); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX + $this->_arrowLength * $this->_radius / 100, $this->_centerY, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX, $this->_centerY - $this->_arrowWidth * $this->_radius/100, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX - $this->_arrowWidth * $this->_radius / 100, $this->_centerY, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + list($xr,$yr) = Image_Graph_Tool::rotate($this->_centerX,$this->_centerY + $this->_arrowWidth * $this->_radius / 100, $this->_centerX, $this->_centerY, $deg); + $this->_canvas->addVertex(array('x' => $xr, 'y' => $yr)); + $this->_canvas->polygon(array('connect' => true)); + } + } + } + + /** + * Calculate marker point data + * + * @param array $point The point to calculate data for + * @param array $nextPoint The next point + * @param array $prevPoint The previous point + * @param array $totals The pre-calculated totals, if needed + * @return array An array containing marker point data + * @access private + */ + function _getMarkerData($point, $nextPoint, $prevPoint, &$totals) + { + $point = parent::_getMarkerData($point, $nextPoint, $prevPoint, $totals); + + $point['ANGLE'] = $this->_value2angle($point['Y']); + + $point['ANG_X'] = cos(deg2rad($point['ANGLE'])); + $point['ANG_Y'] = sin(deg2rad($point['ANGLE'])); + + $point['AX'] = -$point['ANG_X']; + $point['AY'] = -$point['ANG_Y']; + + $point['LENGTH'] = 2.5; //$radius; + + $point['MARKER_X'] = $totals['CENTER_X'] + + $totals['ODO_RADIUS'] * $point['ANG_X']; + $point['MARKER_Y'] = $totals['CENTER_Y'] + + $totals['ODO_RADIUS'] * $point['ANG_Y']; + + return $point; + } + + /** + * Draws markers of the arrows on the canvas + * + * @access private + */ + function _drawMarker() + { + + if ($this->_marker) { + $this->_marker->_radius += $this->_radius / 2; + $totals = $this->_getTotals(); + + $totals['CENTER_X'] = $this->_centerX; + $totals['CENTER_Y'] = $this->_centerY; + + + /* $keys = array_keys($this->_dataset); + foreach ($keys as $key) { */ + $dataset =& $this->_dataset[0]; + + $totals['RADIUS0'] = false; + $totals['ODO_RADIUS'] = 1.1 * $this->_radius * $this->_arrowLength / 100; + $totals['ALL_SUM_Y'] = $this->_totalY; + + $dataset->_reset(); + while ($point = $dataset->_next()) { + if ((!is_object($this->_dataSelector)) || + ($this->_dataSelector->select($point)) + ) { + $point = $this->_getMarkerData( + $point, + false, + false, + $totals + ); + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + } + /* } + unset($keys); */ + } + } + + /** + * Set range + * + * dataset with two data start and end value of the range + * @param Image_Graph_Dataset $dataset The data set (value containter) to + * plot or an array of datasets + * + */ + function addRangeMarker($min, $max, $id = false) + { + $this->_range[] = + array( + 'min' => max($this->_value_min, min($min, $max)), + 'max' => min($this->_value_max, max($min, $max)), + 'id' => $id + ); + } + + /** + * Set the fillstyle of the ranges + * + * @param Image_Graph_Fill $fillStyle The fill style of the range + * @see Image_Graph_Fill + * @access public + */ + function &setRangeMarkerFillStyle(&$rangeMarkerFillStyle) + { + $this->_rangeFillStyle = $rangeMarkerFillStyle; + } + + /** + * Draw the ranges + * + * @access private + */ + function _drawRange() + { + if($this->_range){ + $radius0 = $this->_radius * (1 - $this->_radiusPercent/100); + foreach ($this->_range as $range) { + $angle1 = $this->_value2angle($range['min']); + $angle2 = $this->_value2angle($range['max']); + + if (is_object($this->_rangeFillStyle)) { + $this->_canvas->setFill($this->_rangeFillStyle->_getFillStyle($range['id'])); + } elseif ($this->_rangeFillStyle != null) { + $this->_canvas->setFill($this->_rangeFillStyle); + } + $this->_getLineStyle(); + $this->_canvas->Pieslice( + array( + 'x' => $this->_centerX, + 'y' => $this->_centerY, + 'rx' => $this->_radius, + 'ry' => $this->_radius, + 'v1' => $angle1, + 'v2' => $angle2, + 'srx' => $radius0, + 'sry' => $radius0 + ) + ); + } + } + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 4; + $this->_canvas->addVertex(array('x' => $x0 + $dx , 'y' => $y1)); + $this->_canvas->addVertex(array('x' => ($x0 + $x1) / 2, 'y' => $y0 )); + $this->_canvas->addVertex(array('x' => $x1 - $dx , 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Draw a sample for use with legend + * + * @param array $param The parameters for the legend + * @access private + */ + function _legendSample(&$param) + { + if (is_array($this->_dataset)) { + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + $totals = $this->_getTotals(); + $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); + $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); + $totals['RADIUS'] = min($this->height(), $this->width()) * 0.75 * 0.5; + $totals['CURRENT_Y'] = 0; + + if (is_a($this->_fillStyle, "Image_Graph_Fill")) { + $this->_fillStyle->_reset(); + } + + $count = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $count++; + + $dataset->_reset(); + while ($point = $dataset->_next()) { + $caption = $point['X']; + + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($caption); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height'] + 5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y'] - $param['height'] / 2; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height'] / 2; + + if (!isset($param['simulate'])) { + $this->_getFillStyle($point['ID']); + $this->_getLineStyle($point['ID']); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + if (($this->_marker) && ($dataset) && ($param['show_marker'])) { + $prevPoint = $dataset->_nearby(-2); + $nextPoint = $dataset->_nearby(); + + $p = $this->_getMarkerData($point, $nextPoint, $prevPoint, $totals); + if (is_array($point)) { + $p['MARKER_X'] = $x+$param['width'] / 2; + $p['MARKER_Y'] = $y; + unset ($p['AVERAGE_Y']); + $this->_marker->_drawMarker($p['MARKER_X'], $p['MARKER_Y'], $p); + } + } + $this->write($x + $param['width'] + 10, $y, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + } + unset($keys); + $this->_clip(false); + $this->_canvas->endGroup(); + } + } +} +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Pie.php b/packages/dspam/pear/Image/Graph/Plot/Pie.php new file mode 100644 index 00000000..f0e872c3 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Pie.php @@ -0,0 +1,623 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * 2D Piechart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Pie extends Image_Graph_Plot +{ + + /** + * The radius of the 'pie' spacing + * @access private + * @var int + */ + var $_radius = 3; + + /** + * Explode pie slices. + * @access private + * @var mixed + */ + var $_explode = false; + + /** + * The starting angle of the plot + * @access private + * @var int + */ + var $_startingAngle = 0; + + /** + * The angle direction (1 = CCW, -1 = CW) + * @access private + * @var int + */ + var $_angleDirection = 1; + + /** + * The diameter of the pie plot + * @access private + * @var int + */ + var $_diameter = false; + + /** + * Group items below this limit together as "the rest" + * @access private + * @var double + */ + var $_restGroupLimit = false; + + /** + * Rest group title + * @access private + * @var string + */ + var $_restGroupTitle = 'The rest'; + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $y = ($y0 + $y1) / 2; + $this->_canvas->pieslice( + array( + 'x' => $x1, + 'y' => $y, + 'rx' => abs($x1 - $x0) / 2, + 'ry' => abs($y1 - $y0) / 2, + 'v1' => 45, + 'v2' => 315 + ) + ); + } + + /** + * Calculate marker point data + * + * @param array $point The point to calculate data for + * @param array $nextPoint The next point + * @param array $prevPoint The previous point + * @param array $totals The pre-calculated totals, if needed + * @return array An array containing marker point data + * @access private + */ + function _getMarkerData($point, $nextPoint, $prevPoint, &$totals) + { + $point = parent::_getMarkerData($point, $nextPoint, $prevPoint, $totals); + + $y = $totals['CURRENT_Y']; + + if ($this->_angleDirection < 0) { + $y = $totals['ALL_SUM_Y'] - $y; + } + + $point['ANGLE'] = 360 * (($y + ($point['Y'] / 2)) / $totals['ALL_SUM_Y']) + $this->_startingAngle; + $totals['CURRENT_Y'] += $point['Y']; + + $point['ANG_X'] = cos(deg2rad($point['ANGLE'])); + $point['ANG_Y'] = sin(deg2rad($point['ANGLE'])); + + $point['AX'] = -10 * $point['ANG_X']; + $point['AY'] = -10 * $point['ANG_Y']; + + if ((isset($totals['ALL_SUM_Y'])) && ($totals['ALL_SUM_Y'] != 0)) { + $point['PCT_MIN_Y'] = $point['PCT_MAX_Y'] = (100 * $point['Y'] / $totals['ALL_SUM_Y']); + } + + $point['LENGTH'] = 10; //$radius; + + $x = $point['X']; + $explodeRadius = 0; + if ((is_array($this->_explode)) && (isset($this->_explode[$x]))) { + $explodeRadius = $this->_explode[$x]; + } elseif (is_numeric($this->_explode)) { + $explodeRadius = $this->_explode; + } + + $point['MARKER_X'] = $totals['CENTER_X'] + + ($totals['RADIUS'] + $explodeRadius) * $point['ANG_X']; + $point['MARKER_Y'] = $totals['CENTER_Y'] + + ($totals['RADIUS'] + $explodeRadius) * $point['ANG_Y']; + + return $point; + } + + /** + * Draws markers on the canvas + * + * @access private + */ + function _drawMarker() + { + + if ($this->_marker) { + $totals = $this->_getTotals(); + + $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); + $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); + + $totals['CURRENT_Y'] = 0; + $number = 0; + + $diameter = $this->_getDiameter(); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + + if (count($this->_dataset) == 1) { + $totals['RADIUS0'] = false; + $totals['RADIUS'] = $diameter / 2; + } else { + $dr = $diameter / (2 * count($this->_dataset)); + + $totals['RADIUS0'] = $number * $dr + ($number > 0 ? $this->_radius : 0); + $totals['RADIUS'] = ($number + 1) * $dr; + } + + $totals['ALL_SUM_Y'] = 0; + $totals['CURRENT_Y'] = 0; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $totals['ALL_SUM_Y'] += $point['Y']; + } + + $dataset->_reset(); + $currentY = 0; + $the_rest = 0; + while ($point = $dataset->_next()) { + if (($this->_restGroupLimit !== false) && ($point['Y'] <= $this->_restGroupLimit)) { + $the_rest += $point['Y']; + } + else { + if ((!is_object($this->_dataSelector)) || + ($this->_dataSelector->select($point)) + ) { + $point = $this->_getMarkerData( + $point, + false, + false, + $totals + ); + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + } + } + if ($the_rest > 0) { + $point = array('X' => $this->_restGroupTitle, 'Y' => $the_rest); + $point = $this->_getMarkerData( + $point, + false, + false, + $totals + ); + if (is_array($point)) { + $this->_marker->_drawMarker( + $point['MARKER_X'], + $point['MARKER_Y'], + $point + ); + } + } + $number++; + } + unset($keys); + } + } + + /** + * Explodes a piece of this pie chart + * + * @param int $explode Radius to explode with (or an array) + * @param string $x The 'x' value to explode or omitted + */ + function explode($explode, $x = false) + { + if ($x === false) { + $this->_explode = $explode; + } else { + $this->_explode[$x] = $explode; + } + } + + /** + * Set the starting angle of the plot + * + * East is 0 degrees + * South is 90 degrees + * West is 180 degrees + * North is 270 degrees + * + * It is also possible to specify the direction of the plot angles (i.e. clockwise 'cw' or + * counterclockwise 'ccw') + */ + function setStartingAngle($angle = 0, $direction = 'ccw') + { + $this->_startingAngle = ($angle % 360); + $this->_angleDirection = ($direction == 'ccw' ? 1 : -1); + } + + /** + * Set the diameter of the pie plot (i.e. the number of pixels the + * pie plot should be across) + * + * Use 'max' for the maximum possible diameter + * + * Use negative values for the maximum possible - minus this value (fx -2 + * to leave 1 pixel at each side) + * + * @param mixed @diameter The number of pixels + */ + function setDiameter($diameter) + { + $this->_diameter = $diameter; + } + + /** + * Set the limit for the y-value, where values below are grouped together + * as "the rest" + * + * @param double $limit The limit + * @param string $title The title to display in the legends (default 'The + * rest') + */ + function setRestGroup($limit, $title = 'The rest') + { + $this->_restGroupLimit = $limit; + $this->_restGroupTitle = $title; + } + + /** + * Get the diameter of the plot + * @return int The number of pixels the diameter is + * @access private + */ + function _getDiameter() + { + $diameter = 0; + if ($this->_diameter === false) { + $diameter = min($this->height(), $this->width()) * 0.75; + } + else { + if ($this->_diameter === 'max') { + $diameter = min($this->height(), $this->width()); + } + elseif ($this->_diameter < 0) { + $diameter = min($this->height(), $this->width()) + $this->_diameter; + } else { + $diameter = $this->_diameter; + } + } + return $diameter; + } + + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $number = 0; + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + + $totalY = 0; + $dataset->_reset(); + while ($point = $dataset->_next()) { + $totalY += $point['Y']; + } + + $centerX = (int) (($this->_left + $this->_right) / 2); + $centerY = (int) (($this->_top + $this->_bottom) / 2); + $diameter = $this->_getDiameter(); + if ($this->_angleDirection < 0) { + $currentY = $totalY; + } else { + $currentY = 0; //rand(0, 100)*$totalY/100; + } + $dataset->_reset(); + + if (count($this->_dataset) == 1) { + $radius0 = false; + $radius1 = $diameter / 2; + } else { + $dr = $diameter / (2 * count($this->_dataset)); + + $radius0 = $number * $dr + ($number > 0 ? $this->_radius : 0); + $radius1 = ($number + 1) * $dr; + } + + $the_rest = 0; + while ($point = $dataset->_next()) { + if (($this->_restGroupLimit !== false) && ($point['Y'] <= $this->_restGroupLimit)) { + $the_rest += $point['Y']; + } + else { + $angle1 = 360 * ($currentY / $totalY) + $this->_startingAngle; + $currentY += $this->_angleDirection * $point['Y']; + $angle2 = 360 * ($currentY / $totalY) + $this->_startingAngle; + + $x = $point['X']; + $id = $point['ID']; + + $dX = 0; + $dY = 0; + $explodeRadius = 0; + if ((is_array($this->_explode)) && (isset($this->_explode[$x]))) { + $explodeRadius = $this->_explode[$x]; + } elseif (is_numeric($this->_explode)) { + $explodeRadius = $this->_explode; + } + + if ($explodeRadius > 0) { + $dX = $explodeRadius * cos(deg2rad(($angle1 + $angle2) / 2)); + $dY = $explodeRadius * sin(deg2rad(($angle1 + $angle2) / 2)); + } + + $ID = $point['ID']; + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + $this->_canvas->pieslice( + $this->_mergeData( + $point, + array( + 'x' => $centerX + $dX, + 'y' => $centerY + $dY, + 'rx' => $radius1, + 'ry' => $radius1, + 'v1' => $angle1, + 'v2' => $angle2, + 'srx' => $radius0, + 'sry' => $radius0 + ) + ) + ); + } + } + + if ($the_rest > 0) { + $angle1 = 360 * ($currentY / $totalY) + $this->_startingAngle; + $currentY += $this->_angleDirection * $the_rest; + $angle2 = 360 * ($currentY / $totalY) + $this->_startingAngle; + + $x = 'rest'; + $id = 'rest'; + + $dX = 0; + $dY = 0; + $explodeRadius = 0; + if ((is_array($this->_explode)) && (isset($this->_explode[$x]))) { + $explodeRadius = $this->_explode[$x]; + } elseif (is_numeric($this->_explode)) { + $explodeRadius = $this->_explode; + } + + if ($explodeRadius > 0) { + $dX = $explodeRadius * cos(deg2rad(($angle1 + $angle2) / 2)); + $dY = $explodeRadius * sin(deg2rad(($angle1 + $angle2) / 2)); + } + + $ID = $id; + $this->_getFillStyle($ID); + $this->_getLineStyle($ID); + $this->_canvas->pieslice( + $this->_mergeData( + $point, + array( + 'x' => $centerX + $dX, + 'y' => $centerY + $dY, + 'rx' => $radius1, + 'ry' => $radius1, + 'v1' => $angle1, + 'v2' => $angle2, + 'srx' => $radius0, + 'sry' => $radius0 + ) + ) + ); + } + $number++; + } + unset($keys); + $this->_drawMarker(); + return true; + } + + /** + * Draw a sample for use with legend + * + * @param array $param The parameters for the legend + * @access private + */ + function _legendSample(&$param) + { + if (is_array($this->_dataset)) { + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + $totals = $this->_getTotals(); + $totals['CENTER_X'] = (int) (($this->_left + $this->_right) / 2); + $totals['CENTER_Y'] = (int) (($this->_top + $this->_bottom) / 2); + $totals['RADIUS'] = min($this->height(), $this->width()) * 0.75 * 0.5; + $totals['CURRENT_Y'] = 0; + + if (is_a($this->_fillStyle, "Image_Graph_Fill")) { + $this->_fillStyle->_reset(); + } + + $count = 0; + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $count++; + + $dataset->_reset(); + $the_rest = 0; + while ($point = $dataset->_next()) { + $caption = $point['X']; + if (($this->_restGroupLimit !== false) && ($point['Y'] <= $this->_restGroupLimit)) { + $the_rest += $point['Y']; + } + else { + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($caption); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height']+5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($caption); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y'] - $param['height']/2; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height']/2; + + if (!isset($param['simulate'])) { + $this->_getFillStyle($point['ID']); + $this->_getLineStyle($point['ID']); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + if (($this->_marker) && ($dataset) && ($param['show_marker'])) { + $prevPoint = $dataset->_nearby(-2); + $nextPoint = $dataset->_nearby(); + + $p = $this->_getMarkerData($point, $nextPoint, $prevPoint, $totals); + if (is_array($point)) { + $p['MARKER_X'] = $x+$param['width']/2; + $p['MARKER_Y'] = $y; + unset ($p['AVERAGE_Y']); + $this->_marker->_drawMarker($p['MARKER_X'], $p['MARKER_Y'], $p); + } + } + $this->write($x + $param['width'] +10, $y, $caption, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + } + if ($the_rest > 0) { + $this->_canvas->setFont($param['font']); + $width = 20 + $param['width'] + $this->_canvas->textWidth($this->_restGroupTitle); + $param['maxwidth'] = max($param['maxwidth'], $width); + $x2 = $param['x'] + $width; + $y2 = $param['y'] + $param['height']+5; + + if ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) && ($y2 > $param['bottom'])) { + $param['y'] = $param['top']; + $param['x'] = $x2; + $y2 = $param['y'] + $param['height']; + } elseif ((($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) == 0) && ($x2 > $param['right'])) { + $param['x'] = $param['left']; + $param['y'] = $y2; + $x2 = $param['x'] + 20 + $param['width'] + $this->_canvas->textWidth($this->_restGroupTitle); + } + + $x = $x0 = $param['x']; + $y = $param['y']; + $y0 = $param['y'] - $param['height']/2; + $x1 = $param['x'] + $param['width']; + $y1 = $param['y'] + $param['height']/2; + + if (!isset($param['simulate'])) { + $this->_getFillStyle('rest'); + $this->_getLineStyle('rest'); + $this->_drawLegendSample($x0, $y0, $x1, $y1); + + $this->write($x + $param['width'] + 10, $y, $this->_restGroupTitle, IMAGE_GRAPH_ALIGN_CENTER_Y | IMAGE_GRAPH_ALIGN_LEFT, $param['font']); + } + + if (($param['align'] & IMAGE_GRAPH_ALIGN_VERTICAL) != 0) { + $param['y'] = $y2; + } else { + $param['x'] = $x2; + } + } + } + unset($keys); + $this->_clip(false); + $this->_canvas->endGroup(); + } + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Radar.php b/packages/dspam/pear/Image/Graph/Plot/Radar.php new file mode 100644 index 00000000..1bfd9da7 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Radar.php @@ -0,0 +1,118 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Radar chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Radar extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $p = 10; + $rx = abs($x1 - $x0) / 2; + $ry = abs($x1 - $x0) / 2; + $r = min($rx, $ry); + $cx = ($x0 + $x1) / 2; + $cy = ($y0 + $y1) / 2; + $max = 5; + for ($i = 0; $i < $p; $i++) { + $v = 2 * pi() * $i / $p; + $t = $r * rand(3, $max) / $max; + $x = $cx + $t * cos($v); + $y = $cy + $t * sin($v); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + if (is_a($this->_parent, 'Image_Graph_Plotarea_Radar')) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $maxY = $dataset->maximumY(); + $count = $dataset->count(); + + $dataset->_reset(); + while ($point = $dataset->_next()) { + $this->_canvas->addVertex(array('x' => + $this->_pointX($point), 'y' => + $this->_pointY($point) + )); + } + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + unset($keys); + } + $this->_drawMarker(); + + $this->_clip(false); + $this->_canvas->endGroup(); + return parent::_done(); + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Smoothed/Area.php b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Area.php new file mode 100644 index 00000000..8ea469dd --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Area.php @@ -0,0 +1,145 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot/Smoothed/Bezier.php + */ +require_once 'Image/Graph/Plot/Smoothed/Bezier.php'; + +/** + * Bezier smoothed area chart + * + * Similar to an {@link Image_Graph_Plot_Area}, but the interconnecting lines + * between two datapoints are smoothed using a Bezier curve, which enables the + * chart to appear as a nice curved plot instead of the sharp edges of a + * conventional {@link Image_Graph_Plot_Area}. Smoothed charts are only supported + * with non-stacked types + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Smoothed_Area extends Image_Graph_Plot_Smoothed_Bezier +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y1)); + $this->_addSamplePoints($x0, $y0, $x1, $y1); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * Output the Bezier smoothed plot as an Area Chart + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $first = true; + while ($p1 = $dataset->_next()) { + $p0 = $dataset->_nearby(-2); + $p2 = $dataset->_nearby(0); + $p3 = $dataset->_nearby(1); + if ($first) { + $p = $p1; + $p['Y'] = '#min_pos#'; + $x = $this->_pointX($p); + $y = $this->_pointY($p); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + + if ($p2) { + $cp = $this->_getControlPoints($p1, $p0, $p2, $p3); + $this->_canvas->addSpline( + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ); + } else { + $x = $this->_pointX($p1); + $y = $this->_pointY($p1); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + $lastPoint = $p1; + $first = false; + } + $lastPoint['Y'] = '#min_pos#'; + $x = $this->_pointX($lastPoint); + $y = $this->_pointY($lastPoint); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php new file mode 100644 index 00000000..bc21b4c8 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Bezier.php @@ -0,0 +1,173 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot.php + */ +require_once 'Image/Graph/Plot.php'; + +/** + * Include file Image/Graph/Tool.php + */ +require_once 'Image/Graph/Tool.php'; + +/** + * Bezier smoothed plottype. + * + * The framework for calculating the Bezier smoothed curve from the dataset. + * Used in {@link Image_Graph_Plot_Smoothed_Line} and {@link + * Image_Graph_Plot_Smoothed_Area}. Smoothed charts are only supported with non- + * stacked types + * @link http://homepages.borland.com/efg2lab/Graphics/Jean- + * YvesQueinecBezierCurves.htm efg computer lab - description of bezier curves + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @abstract + */ +class Image_Graph_Plot_Smoothed_Bezier extends Image_Graph_Plot +{ + + /** + * Image_Graph_Plot_Smoothed_Bezier [Constructor] + * + * Only 'normal' multitype supported + * + * @param Dataset $dataset The data set (value containter) to plot + * @param string $title The title of the plot (used for legends, {@link + * Image_Graph_Legend}) + */ + function Image_Graph_Plot_Smoothed_Bezier(& $dataset, $title = '') + { + parent::Image_Graph_Plot($dataset, 'normal', $title); + } + + /** + * Return the minimum Y point + * + * @return double The minumum Y point + * @access private + */ + function _minimumY() + { + return 1.05 * parent::_minimumY(); + } + + /** + * Return the maximum Y point + * + * @return double The maximum Y point + * @access private + */ + function _maximumY() + { + return 1.05 * parent::_maximumY(); + } + + /** + * Calculates all Bezier points, for the curve + * + * @param array $p1 The actual point to calculate control points for + * @param array $p0 The point "just before" $p1 + * @param array $p2 The point "just after" $p1 + * @param array $p3 The point "just after" $p2 + * @return array Array of Bezier points + * @access private + */ + function _getControlPoints($p1, $p0, $p2, $p3) + { + $p1 = $this->_pointXY($p1); + if ($p2) { + $p2 = $this->_pointXY($p2); + } + if (!$p0) { + $p0['X'] = $p1['X'] - abs($p2['X'] - $p1['X']); + $p0['Y'] = $p1['Y']; //-($p2['Y']-$p1['Y']); + } else { + $p0 = $this->_pointXY($p0); + } + if (!$p3) { + $p3['X'] = $p1['X'] + 2*abs($p1['X'] - $p0['X']); + $p3['Y'] = $p1['Y']; + } else { + $p3 = $this->_pointXY($p3); + } + + if (!$p2) { + $p2['X'] = $p1['X'] + abs($p1['X'] - $p0['X']); + $p2['Y'] = $p1['Y']; + } + + $pC1['X'] = Image_Graph_Tool::controlPoint($p0['X'], $p1['X'], $p2['X']); + $pC1['Y'] = Image_Graph_Tool::controlPoint($p0['Y'], $p1['Y'], $p2['Y']); + $pC2['X'] = Image_Graph_Tool::controlPoint($p3['X'], $p2['X'], $p1['X']); + $pC2['Y'] = Image_Graph_Tool::controlPoint($p3['Y'], $p2['Y'], $p1['Y']); + + return array( + 'X' => $p1['X'], + 'Y' => $p1['Y'], + 'P1X' => $pC1['X'], + 'P1Y' => $pC1['Y'], + 'P2X' => $pC2['X'], + 'P2Y' => $pC2['Y'] + ); + } + + /** + * Create legend sample data for the canvas. + * + * Common for all smoothed plots + * + * @access private + */ + function _addSamplePoints($x0, $y0, $x1, $y1) + { + $p = abs($x1 - $x0); + $cy = ($y0 + $y1) / 2; + $h = abs($y1 - $y0); + $dy = $h / 4; + $dw = abs($x1 - $x0) / $p; + for ($i = 0; $i < $p; $i++) { + $v = 2 * pi() * $i / $p; + $x = $x0 + $i * $dw; + $y = $cy + 2 * $v * sin($v); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Smoothed/Line.php b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Line.php new file mode 100644 index 00000000..00692839 --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Line.php @@ -0,0 +1,172 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot/Smoothed/Bezier.php + */ +require_once 'Image/Graph/Plot/Smoothed/Bezier.php'; + +/** + * Bezier smoothed line chart. + * + * Similar to a {@link Image_Graph_Plot_Line}, but the interconnecting lines + * between two datapoints are smoothed using a Bezier curve, which enables the + * chart to appear as a nice curved plot instead of the sharp edges of a + * conventional {@link Image_Graph_Plot_Line}. Smoothed charts are only supported + * with non-stacked types + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Smoothed_Line extends Image_Graph_Plot_Smoothed_Bezier +{ + + /** + * Gets the fill style of the element + * + * @return int A GD filestyle representing the fill style + * @see Image_Graph_Fill + * @access private + */ + function _getFillStyle($ID = false) + { + return IMG_COLOR_TRANSPARENT; + } + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $this->_addSamplePoints($x0, $y0, $x1, $y1); + $this->_canvas->polygon(array('connect' => false)); + } + + /** + * Output the Bezier smoothed plot as an Line Chart + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (parent::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $numPoints = 0; + while ($p1 = $dataset->_next()) { + if ($p1['Y'] === null) { + if ($numPoints > 1) { + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + $numPoints = 0; + } else { + $p0 = $dataset->_nearby(-2); + $p2 = $dataset->_nearby(0); + $p3 = $dataset->_nearby(1); + + if (($p0) && ($p0['Y'] === null)) { + $p0 = false; + } + if (($p2) && ($p2['Y'] === null)) { + $p2 = false; + } + if (($p3) && ($p3['Y'] === null)) { + $p3 = false; + } + + if ($p2) { + $cp = $this->_getControlPoints($p1, $p0, $p2, $p3); + $this->_canvas->addSpline( + $this->_mergeData( + $p1, + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ) + ); + } else { + $x = $this->_pointX($p1); + $y = $this->_pointY($p1); + $this->_canvas->addVertex( + $this->_mergeData( + $p1, + array('x' => $x, 'y' => $y) + ) + ); + } + $numPoints++; + } + } + if ($numPoints > 1) { + $this->_getLineStyle(); + $this->_canvas->polygon(array('connect' => false, 'map_vertices' => true)); + } + else { + $this->_canvas->reset(); + } + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } + +} +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php new file mode 100644 index 00000000..d505a11f --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Smoothed/Radar.php @@ -0,0 +1,142 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + * @since File available since Release 0.3.0dev2 + */ + +/** + * Include file Image/Graph/Plot/Smoothed/Bezier.php + */ +require_once 'Image/Graph/Plot/Smoothed/Bezier.php'; + +/** + * Smoothed radar chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + * @since Class available since Release 0.3.0dev2 + */ +class Image_Graph_Plot_Smoothed_Radar extends Image_Graph_Plot_Smoothed_Bezier +{ + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + if (is_a($this->_parent, 'Image_Graph_Plotarea_Radar')) { + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + if ($dataset->count() >= 3) { + $dataset->_reset(); + $p1_ = $dataset->_next(); + $p2_ = $dataset->_next(); + $p3_ = $dataset->_next(); + $plast_ = false; + if ($p3_) { + while ($p = $dataset->_next()) { + $plast_ = $p; + } + } + + if ($plast_ === false) { + $plast_ = $p3_; + } + $dataset->_reset(); + while ($p1 = $dataset->_next()) { + $p0 = $dataset->_nearby(-2); + $p2 = $dataset->_nearby(0); + $p3 = $dataset->_nearby(1); + + if ($p0 === false) { + $p0 = $plast_; + } + + if ($p2 === false) { + $p2 = $p1_; + $p3 = $p2_; + } elseif ($p3 === false) { + $p3 = $p1_; + } + + + $cp = $this->_getControlPoints($p1, $p0, $p2, $p3); + $this->_canvas->addSpline( + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ); + + $next2last = $p0; + $last = $p1; + } + + $cp = $this->_getControlPoints($p1_, $plast_, $p2_, $p3_); + $this->_canvas->addSpline( + array( + 'x' => $cp['X'], + 'y' => $cp['Y'], + 'p1x' => $cp['P1X'], + 'p1y' => $cp['P1Y'], + 'p2x' => $cp['P2X'], + 'p2y' => $cp['P2Y'] + ) + ); + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + } + unset($keys); + } + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup($this->_title); + return parent::_done(); + } + +} + +?> \ No newline at end of file diff --git a/packages/dspam/pear/Image/Graph/Plot/Step.php b/packages/dspam/pear/Image/Graph/Plot/Step.php new file mode 100644 index 00000000..bc9267fe --- /dev/null +++ b/packages/dspam/pear/Image/Graph/Plot/Step.php @@ -0,0 +1,200 @@ + + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version CVS: $Id$ + * @link http://pear.php.net/package/Image_Graph + */ + +/** + * Include file Image/Graph/Plot/Bar.php + */ +require_once 'Image/Graph/Plot/Bar.php'; + +/** + * Step chart. + * + * @category Images + * @package Image_Graph + * @subpackage Plot + * @author Jesper Veggerby + * @copyright Copyright (C) 2003, 2004 Jesper Veggerby Hansen + * @license http://www.gnu.org/copyleft/lesser.html LGPL License 2.1 + * @version Release: @package_version@ + * @link http://pear.php.net/package/Image_Graph + */ +class Image_Graph_Plot_Step extends Image_Graph_Plot +{ + + /** + * Perform the actual drawing on the legend. + * + * @param int $x0 The top-left x-coordinate + * @param int $y0 The top-left y-coordinate + * @param int $x1 The bottom-right x-coordinate + * @param int $y1 The bottom-right y-coordinate + * @access private + */ + function _drawLegendSample($x0, $y0, $x1, $y1) + { + $dx = abs($x1 - $x0) / 3; + $dy = abs($y1 - $y0) / 3; + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y1)); + $this->_canvas->addVertex(array('x' => $x0, 'y' => $y0 + $dy)); + + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y0 + $dy)); + $this->_canvas->addVertex(array('x' => $x0 + $dx, 'y' => $y0)); + + $this->_canvas->addVertex(array('x' => $x0 + 2*$dx, 'y' => $y0)); + $this->_canvas->addVertex(array('x' => $x0 + 2*$dx, 'y' => $y0 + 2*$dy)); + + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y0 + 2*$dy)); + $this->_canvas->addVertex(array('x' => $x1, 'y' => $y1)); + $this->_canvas->polygon(array('connect' => true)); + } + + /** + * PlotType [Constructor] + * + * A 'normal' step chart is 'stacked' + * + * @param Dataset $dataset The data set (value containter) to plot + * @param string $multiType The type of the plot + * @param string $title The title of the plot (used for legends, + * {@link Image_Graph_Legend}) + */ + function Image_Graph_Plot_Step(& $dataset, $multiType = 'stacked', $title = '') + { + $multiType = strtolower($multiType); + if (($multiType != 'stacked') && ($multiType != 'stacked100pct')) { + $multiType = 'stacked'; + } + parent::Image_Graph_Plot($dataset, $multiType, $title); + } + + /** + * Output the plot + * + * @return bool Was the output 'good' (true) or 'bad' (false). + * @access private + */ + function _done() + { + if (Image_Graph_Plot::_done() === false) { + return false; + } + + $this->_canvas->startGroup(get_class($this) . '_' . $this->_title); + $this->_clip(true); + + if ($this->_multiType == 'stacked100pct') { + $total = $this->_getTotals(); + } + + if ($this->_parent->_horizontal) { + $width = $this->height() / ($this->_maximumX() + 2) / 2; + } + else { + $width = $this->width() / ($this->_maximumX() + 2) / 2; + } + + reset($this->_dataset); + $key = key($this->_dataset); + $dataset =& $this->_dataset[$key]; + + $first = $dataset->first(); + $last = $dataset->last(); + + $point = array ('X' => $first['X'], 'Y' => '#min_pos#'); + $firstY = $this->_pointY($point) + ($this->_parent->_horizontal ? $width : 0); + $base[] = $firstY; + $firstX = $this->_pointX($point) - ($this->_parent->_horizontal ? 0 : $width); + $base[] = $firstX; + + $point = array ('X' => $last['X'], 'Y' => '#min_pos#'); + $base[] = $this->_pointY($point) - ($this->_parent->_horizontal ? $width : 0); + $base[] = $this->_pointX($point) + ($this->_parent->_horizontal ? 0 : $width); + + $first = ($this->_parent->_horizontal ? $firstY : $firstX); + + $keys = array_keys($this->_dataset); + foreach ($keys as $key) { + $dataset =& $this->_dataset[$key]; + $dataset->_reset(); + $polygon = array_reverse($base); + unset ($base); + $last = $first; + while ($point = $dataset->_next()) { + $x = $point['X']; + $p = $point; + + if (!isset($current[$x])) { + $current[$x] = 0; + } + + if ($this->_multiType == 'stacked100pct') { + $p['Y'] = 100 * ($current[$x] + $point['Y']) / $total['TOTAL_Y'][$x]; + } else { + $p['Y'] += $current[$x]; + } + $current[$x] += $point['Y']; + $point = $p; + + if ($this->_parent->_horizontal) { + $x0 = $this->_pointX($point); + $y0 = $last; + $x1 = $this->_pointX($point); + $last = $y1 = $this->_pointY($point) - $width; + } + else { + $x0 = $last; + $y0 = $this->_pointY($point); + $last = $x1 = $this->_pointX($point) + $width; + $y1 = $this->_pointY($point); + } + $polygon[] = $x0; $base[] = $y0; + $polygon[] = $y0; $base[] = $x0; + $polygon[] = $x1; $base[] = $y1; + $polygon[] = $y1; $base[] = $x1; + } + + while (list(, $x) = each($polygon)) { + list(, $y) = each($polygon); + $this->_canvas->addVertex(array('x' => $x, 'y' => $y)); + } + + $this->_getFillStyle($key); + $this->_getLineStyle($key); + $this->_canvas->polygon(array('connect' => true)); + } + unset($keys); + $this->_drawMarker(); + $this->_clip(false); + $this->_canvas->endGroup(); + return true; + } +} + +?> \ No newline at end of file -- cgit v1.2.3