/tags/phpmyvisites_1_9/libs/artichow/php4/Pie.class.php
PHP | 680 lines | 325 code | 148 blank | 207 comment | 29 complexity | abe1635b27bd654a1d5222945f479801 MD5 | raw file
- <?php
- /*
- * This work is hereby released into the Public Domain.
- * To view a copy of the public domain dedication,
- * visit http://creativecommons.org/licenses/publicdomain/ or send a letter to
- * Creative Commons, 559 Nathan Abbott Way, Stanford, California 94305, USA.
- *
- */
- require_once dirname(__FILE__)."/Component.class.php";
-
- /* <php4> */
- define("PIE_DARK", 1);
- define("PIE_COLORED", 2);
- define("PIE_AQUA", 3);
- define("PIE_EARTH", 4);
- /* </php4> */
-
- /**
- * Pie
- *
- * @package Artichow
- */
- class awPie extends awComponent {
- /**
- * A dark theme for pies
- *
- *
- * @var int
- */
-
- /**
- * A colored theme for pies
- *
- * @var int
- */
-
- /**
- * A water theme for pies
- *
- * @var int
- */
-
- /**
- * A earth theme for pies
- *
- * @var int
- */
-
-
- /**
- * Pie values
- *
- * @var array
- */
- var $values;
-
- /**
- * Pie colors
- *
- * @var array
- */
- var $colors;
-
- /**
- * Pie legend
- *
- * @var array
- */
- var $legendValues = array();
-
- /**
- * Intensity of the 3D effect
- *
- * @var int
- */
- var $size;
-
- /**
- * Border color
- *
- * @var Color
- */
- var $border;
-
- /**
- * Pie explode
- *
- * @var array
- */
- var $explode = array();
-
- /**
- * Initial angle
- *
- * @var int
- */
- var $angle = 0;
-
- /**
- * Labels precision
- *
- * @var int
- */
- var $precision;
-
- /**
- * Labels number
- *
- * @var int
- */
- var $number;
-
- /**
- * Labels minimum
- *
- * @var int
- */
- var $minimum;
-
- /**
- * Labels position
- *
- * @var int
- */
- var $position = 15;
-
- /**
- * Labels of your pie
- *
- * @var Label
- */
- var $label;
-
- /**
- * Build the plot
- *
- * @param array $values Pie values
- */
- function awPie($values, $colors = PIE_COLORED) {
-
- $this->setValues($values);
-
- if(is_array($colors)) {
- $this->colors = $colors;
- } else {
-
- switch($colors) {
-
- case PIE_AQUA :
- $this->colors = array(
- new awColor(131, 220, 215),
- new awColor(131, 190, 215),
- new awColor(131, 160, 215),
- new awColor(160, 140, 215),
- new awColor(190, 131, 215),
- new awColor(220, 131, 215)
- );
- break;
-
- case PIE_EARTH :
- $this->colors = array(
- new awColor(97, 179, 110),
- new awColor(130, 179, 97),
- new awColor(168, 179, 97),
- new awColor(179, 147, 97),
- new awColor(179, 108, 97),
- new awColor(99, 107, 189),
- new awColor(99, 165, 189)
- );
- break;
-
- case PIE_DARK :
- $this->colors = array(
- new awColor(140, 100, 170),
- new awColor(130, 170, 100),
- new awColor(160, 160, 120),
- new awColor(150, 110, 140),
- new awColor(130, 150, 160),
- new awColor(90, 170, 140)
- );
- break;
-
- default :
- $this->colors = array(
- new awColor(187, 213, 151),
- new awColor(223, 177, 151),
- new awColor(111, 186, 132),
- new awColor(197, 160, 230),
- new awColor(165, 169, 63),
- new awColor(218, 177, 89),
- new awColor(116, 205, 121),
- new awColor(200, 201, 78),
- new awColor(127, 205, 177),
- new awColor(205, 160, 160),
- new awColor(190, 190, 190)
- );
- break;
-
- }
-
- }
-
- parent::awComponent();
-
- $this->label = new awLabel;
- $this->label->setCallbackFunction('callbackPerCent');
-
- }
-
- /**
- * Change legend values
- *
- * @param array $legend An array of values for each part of the pie
- */
- function setLegend($legend) {
-
- $this->legendValues = (array)$legend;
-
- }
-
- /**
- * Set a border all around the pie
- *
- * @param $color A color for the border
- */
- function setBorder($color) {
- $this->border = $color;
- }
-
- /**
- * Change 3D effect intensity
- *
- * @param int $size Effect size
- */
- function set3D($size) {
- $this->size = (int)$size;
- }
-
- /**
- * Change initial angle
- *
- * @param int $angle New angle in degrees
- */
- function setStartAngle($angle) {
- $this->angle = (int)$angle;
- }
-
- /**
- * Change label precision
- *
- * @param int $precision New precision
- */
- function setLabelPrecision($precision) {
- $this->precision = (int)$precision;
- }
-
- /**
- * Change label position
- *
- * @param int $position New position in pixels
- */
- function setLabelPosition($position) {
- $this->position = (int)$position;
- }
-
- /**
- * Change label number
- *
- * @param int $number New number
- */
- function setLabelNumber($number) {
- $this->number = is_null($number) ? $number : (int)$number;
- }
-
- /**
- * Change label minimum
- *
- * @param int $minimum New minimum
- */
- function setLabelMinimum($minimum) {
- $this->minimum = is_null($minimum) ? $minimum : (int)$minimum;
- }
-
- /**
- * Change Pie explode
- *
- * @param array $explode
- */
- function explode($explode) {
- $this->explode = (array)$explode;
- }
-
- function drawEnvelope($drawer) {
-
- }
-
- function drawComponent($drawer, $x1, $y1, $x2, $y2, $aliasing) {
-
- $count = count($this->values);
- $sum = array_sum($this->values);
-
- $width = $x2 - $x1;
- $height = $y2 - $y1;
-
- if($aliasing) {
- $x = $width / 2;
- $y = $height / 2;
- } else {
- $x = $width / 2 + $x1;
- $y = $height / 2 + $y1;
- }
-
- $position = $this->angle;
- $values = array();
- $parts = array();
- $angles = 0;
-
- if($aliasing) {
- $side = new awSide(0, 0, 0, 0);
- }
-
- foreach($this->values as $key => $value) {
-
- $angle = ($value / $sum * 360);
-
- if($key === $count - 1) {
- $angle = 360 - $angles;
- }
-
- $angles += $angle;
-
- if(array_key_exists($key, $this->explode)) {
- $middle = 360 - ($position + $angle / 2);
- $posX = $this->explode[$key] * cos($middle * M_PI / 180);
- $posY = $this->explode[$key] * sin($middle * M_PI / 180) * -1;
-
- if($aliasing) {
- $explode = new awPoint(
- $posX * 2,
- $posY * 2
- );
- $side->set(
- max($side->left, $posX * -2),
- max($side->right, $posX * 2),
- max($side->top, $posY * -2),
- max($side->bottom, $posY * 2)
- );
- } else {
- $explode = new awPoint(
- $posX,
- $posY
- );
- }
-
- } else {
- $explode = new awPoint(0, 0);
- }
-
- $values[$key] = array(
- $position, ($position + $angle), $explode
- );
-
- $color = $this->colors[$key % count($this->colors)];
- $parts[$key] = new awPiePart($color);
-
- // Add part to the legend
- $legend = array_key_exists($key, $this->legendValues) ? $this->legendValues[$key] : $key;
- $this->legend->add($parts[$key], $legend, LEGEND_BACKGROUND);
-
- $position += $angle;
-
- }
-
- if($aliasing) {
-
- $mainDrawer = $drawer;
-
- $x *= 2;
- $y *= 2;
- $width *= 2;
- $height *= 2;
- $this->size *= 2;
-
- $image = new awImage;
- $image->border->hide();
- $image->setSize(
- $width + $side->left + $side->right,
- $height + $side->top + $side->bottom + $this->size + 1 /* bugs.php.net ! */
- );
-
- $drawer = $image->getDrawer(
- $width / $image->width,
- $height / $image->height,
- ($width / 2 + $side->left) / $image->width,
- ($height / 2 + $side->top) / $image->height
- );
-
- }
-
- // Draw 3D effect
- for($i = $this->size; $i > 0; $i--) {
-
- foreach($values as $key => $value) {
-
- $color = $this->colors[$key % count($this->colors)];
- $color->brightness(-50);
-
- list($from, $to, $explode) = $value;
-
- $drawer->filledArc($color, $explode->move($x, $y + $i), $width, $height, $from, $to);
-
- $color->free();
- unset($color);
-
- if(is_a($this->border, 'awColor')) {
-
- $point = $explode->move($x, $y);
-
- if($i === $this->size) {
-
- $drawer->arc($this->border, $point->move(0, $this->size), $width, $height, $from, $to);
-
- }
-
- }
-
- }
-
- }
-
- foreach($values as $key => $value) {
-
- $color = $this->colors[$key % count($this->colors)];
-
- list($from, $to, $explode) = $value;
-
- $drawer->filledArc($color, $explode->move($x, $y), $width, $height, $from, $to);
-
- if(is_a($this->border, 'awColor')) {
-
- $point = $explode->move($x, $y);
- $drawer->arc($this->border, $point, $width, $height, $from, $to);
- }
-
- }
-
- if($aliasing) {
-
- $x = $x / 2 + $x1;
- $y = $y / 2 + $y1;
- $width /= 2;
- $height /= 2;
- $this->size /= 2;
-
- foreach($values as $key => $value) {
- $old = $values[$key][2];
- $values[$key][2] = new awPoint(
- $old->x / 2, $old->y / 2
- );
- }
-
- $mainDrawer->copyResizeImage(
- $image,
- new awPoint($x1 - $side->left / 2, $y1 - $side->top / 2),
- new awPoint($x1 - $side->left / 2 + $image->width / 2, $y1 - $side->top / 2 + $image->height/ 2),
- new awPoint(0, 0),
- new awPoint($image->width, $image->height),
- TRUE
- );
-
- $drawer = $mainDrawer;
-
- }
-
- // Get labels values
- $pc = array();
- foreach($this->values as $key => $value) {
- $pc[$key] = round($value / $sum * 100, $this->precision);
- }
- if($this->label->count() === 0) { // Check that there is no user defined values
- $this->label->set($pc);
- }
-
- $position = 0;
-
- foreach($pc as $key => $value) {
-
- // Limit number of labels to display
- if($position === $this->number) {
- break;
- }
-
- if(is_null($this->minimum) === FALSE and $value < $this->minimum) {
- continue;
- }
-
- $position++;
-
- list($from, $to, $explode) = $values[$key];
-
- $angle = $from + ($to - $from) / 2;
- $angleRad = (360 - $angle) * M_PI / 180;
-
- $point = new awPoint(
- $x + $explode->x + cos($angleRad) * ($width / 2 + $this->position),
- $y + $explode->y - sin($angleRad) * ($height / 2 + $this->position)
- );
-
- $angle %= 360;
-
- // We don't display labels on the 3D effect
- if($angle > 0 and $angle < 180) {
- $point = $point->move(0, -1 * sin($angleRad) * $this->size);
- }
-
- if($angle >= 45 and $angle < 135) {
- $this->label->setAlign(LABEL_CENTER, LABEL_BOTTOM);
- } else if($angle >= 135 and $angle < 225) {
- $this->label->setAlign(LABEL_RIGHT, LABEL_MIDDLE);
- } else if($angle >= 225 and $angle < 315) {
- $this->label->setAlign(LABEL_CENTER, LABEL_TOP);
- } else {
- $this->label->setAlign(LABEL_LEFT, LABEL_MIDDLE);
- }
-
- $this->label->draw(
- $drawer,
- $point,
- $key
- );
-
- }
-
- }
-
- /**
- * Return margins around the component
- *
- * @return array Left, right, top and bottom margins
- */
- function getMargin() {
-
- // Get axis informations
-
- $leftAxis = $this->padding->left;
- $rightAxis = $this->padding->right;
- $topAxis = $this->padding->top;
- $bottomAxis = $this->padding->bottom;
-
- return array($leftAxis, $rightAxis, $topAxis, $bottomAxis);
-
- }
-
-
- /**
- * Change values of Y axis
- * This method ignores not numeric values
- *
- * @param array $values
- */
- function setValues($values) {
-
- $this->checkArray($values);
- $this->values = $values;
-
- }
-
-
- /**
- * Return values of Y axis
- *
- * @return array
- */
- function getValues() {
- return $this->values;
- }
-
- function checkArray(&$array) {
-
- if(is_array($array) === FALSE) {
- trigger_error("You tried to set values that are not an array");
- }
-
- foreach($array as $key => $value) {
- if(is_numeric($value) === FALSE) {
- unset($array[$key]);
- }
- }
-
- if(count($array) < 1) {
- trigger_error("Your graph must have at least 1 value");
- }
-
- }
- }
- registerClass('Pie');
- /**
- * Pie
- *
- * @package Artichow
- */
- class awPiePart {
- /**
- * Pie part color
- *
- * @var Color
- */
- var $color;
- /**
- * Build a new awPiePart
- *
- * @param $color Pie part color
- */
- function awPiePart($color) {
-
- $this->color = $color;
-
- }
- /**
- * Get the background color or gradient of an element of the component
- *
- * @return Color, Gradient
- */
- function getLegendBackground() {
- return $this->color;
- }
- /**
- * Get the line thickness
- *
- * @return NULL
- */
- function getLegendLineThickness() {
- }
- /**
- * Get the line type
- *
- * @return NULL
- */
- function getLegendLineStyle() {
- }
- /**
- * Get the color of line
- *
- * @return NULL
- */
- function getLegendLineColor() {
- }
- /**
- * Get a mark object
- *
- * @return NULL
- */
- function getLegendMark() {
- }
- }
- registerClass('PiePart');
- function callbackPerCent($value) {
- return $value.'%';
- }
- ?>