mirror of
https://github.com/alchemy-fr/Phraseanet.git
synced 2025-10-17 23:13:15 +00:00
initial import
This commit is contained in:
696
lib/classes/graphik/Pie.class.php
Normal file
696
lib/classes/graphik/Pie.class.php
Normal file
@@ -0,0 +1,696 @@
|
||||
<?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";
|
||||
|
||||
|
||||
/**
|
||||
* Pie
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awPie extends awComponent {
|
||||
|
||||
/**
|
||||
* A dark theme for pies
|
||||
*
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const DARK = 1;
|
||||
|
||||
/**
|
||||
* A colored theme for pies
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const COLORED = 2;
|
||||
|
||||
/**
|
||||
* A water theme for pies
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const AQUA = 3;
|
||||
|
||||
/**
|
||||
* A earth theme for pies
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const EARTH = 4;
|
||||
|
||||
/**
|
||||
* Pie values
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $values;
|
||||
|
||||
/**
|
||||
* Pie colors
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $colors;
|
||||
|
||||
/**
|
||||
* Pie legend
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $legendValues = array();
|
||||
|
||||
/**
|
||||
* Intensity of the 3D effect
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $size;
|
||||
|
||||
/**
|
||||
* Border color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $border;
|
||||
|
||||
/**
|
||||
* Pie explode
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $explode = array();
|
||||
|
||||
/**
|
||||
* Initial angle
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $angle = 0;
|
||||
|
||||
/**
|
||||
* Labels precision
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $precision;
|
||||
|
||||
/**
|
||||
* Labels number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $number;
|
||||
|
||||
/**
|
||||
* Labels minimum
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $minimum;
|
||||
|
||||
/**
|
||||
* Labels position
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $position = 15;
|
||||
|
||||
/**
|
||||
* Labels of your pie
|
||||
*
|
||||
* @var Label
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* Build the plot
|
||||
*
|
||||
* @param array $values Pie values
|
||||
*/
|
||||
public function __construct($values, $colors = awPie::COLORED) {
|
||||
|
||||
$this->setValues($values);
|
||||
|
||||
if(is_array($colors)) {
|
||||
$this->colors = $colors;
|
||||
} else {
|
||||
|
||||
switch($colors) {
|
||||
|
||||
case awPie::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 awPie::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 awPie::DARK :
|
||||
$this->colors = array(
|
||||
new awColor(76, 71, 81),
|
||||
new awColor(70, 55, 90),
|
||||
new awColor(50, 1, 115),
|
||||
new awColor(87, 33, 157),
|
||||
new awColor(150, 85, 236),
|
||||
new awColor(155, 129, 289),
|
||||
new awColor(232, 225, 242)
|
||||
);
|
||||
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::__construct();
|
||||
|
||||
$this->label = new awLabel;
|
||||
$this->label->setCallbackFunction('callbackPerCent');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change legend values
|
||||
*
|
||||
* @param array $legend An array of values for each part of the pie
|
||||
*/
|
||||
public function setLegend($legend) {
|
||||
|
||||
$this->legendValues = (array)$legend;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a border all around the pie
|
||||
*
|
||||
* @param awColor $color A color for the border
|
||||
*/
|
||||
public function setBorderColor(awColor $color) {
|
||||
$this->border = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a border all around the pie
|
||||
*
|
||||
* @param awColor $color A color for the border
|
||||
*/
|
||||
public function setBorder(awColor $color) {
|
||||
if(ARTICHOW_DEPRECATED === TRUE) {
|
||||
awImage::drawError('Class Pie: Method setBorder() has been deprecated since Artichow 1.0.9. Please use setBorderColor() instead.');
|
||||
} else {
|
||||
$this->setBorderColor($color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change 3D effect intensity
|
||||
*
|
||||
* @param int $size Effect size
|
||||
*/
|
||||
public function set3D($size) {
|
||||
$this->size = (int)$size;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change initial angle
|
||||
*
|
||||
* @param int $angle New angle in degrees
|
||||
*/
|
||||
public function setStartAngle($angle) {
|
||||
$this->angle = (int)$angle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change label precision
|
||||
*
|
||||
* @param int $precision New precision
|
||||
*/
|
||||
public function setLabelPrecision($precision) {
|
||||
$this->precision = (int)$precision;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change label position
|
||||
*
|
||||
* @param int $position New position in pixels
|
||||
*/
|
||||
public function setLabelPosition($position) {
|
||||
$this->position = (int)$position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change label number
|
||||
*
|
||||
* @param int $number New number
|
||||
*/
|
||||
public function setLabelNumber($number) {
|
||||
$this->number = is_null($number) ? $number : (int)$number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change label minimum
|
||||
*
|
||||
* @param int $minimum New minimum
|
||||
*/
|
||||
public function setLabelMinimum($minimum) {
|
||||
$this->minimum = is_null($minimum) ? $minimum : (int)$minimum;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change Pie explode
|
||||
*
|
||||
* @param array $explode
|
||||
*/
|
||||
public function explode($explode) {
|
||||
$this->explode = (array)$explode;
|
||||
}
|
||||
|
||||
public function drawEnvelope(awDriver $driver) {
|
||||
|
||||
}
|
||||
|
||||
public function drawComponent(awDriver $driver, $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, awLegend::BACKGROUND);
|
||||
|
||||
$position += $angle;
|
||||
|
||||
}
|
||||
|
||||
if($aliasing) {
|
||||
|
||||
$mainDriver = $driver;
|
||||
|
||||
$x *= 2;
|
||||
$y *= 2;
|
||||
$width *= 2;
|
||||
$height *= 2;
|
||||
$this->size *= 2;
|
||||
|
||||
$image = new awImage;
|
||||
$image->border->hide();
|
||||
|
||||
// Adds support for antialiased pies on non-white background
|
||||
$background = $this->getBackground();
|
||||
|
||||
if($background instanceof awColor) {
|
||||
$image->setBackgroundColor($background);
|
||||
}
|
||||
// elseif($background instanceof awGradient) {
|
||||
// $image->setBackgroundColor(new White(100));
|
||||
// }
|
||||
|
||||
$image->setSize(
|
||||
$width + $side->left + $side->right,
|
||||
$height + $side->top + $side->bottom + $this->size + 1 /* bugs.php.net ! */
|
||||
);
|
||||
|
||||
$driver = $image->getDriver(
|
||||
$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 = clone $this->colors[$key % count($this->colors)];
|
||||
$color->brightness(-50);
|
||||
|
||||
list($from, $to, $explode) = $value;
|
||||
|
||||
$driver->filledArc($color, $explode->move($x, $y + $i), $width, $height, $from, $to);
|
||||
|
||||
unset($color);
|
||||
|
||||
if($this->border instanceof awColor) {
|
||||
|
||||
$point = $explode->move($x, $y);
|
||||
|
||||
if($i === $this->size) {
|
||||
|
||||
$driver->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;
|
||||
|
||||
$driver->filledArc($color, $explode->move($x, $y), $width, $height, $from, $to);
|
||||
|
||||
if($this->border instanceof awColor) {
|
||||
|
||||
$point = $explode->move($x, $y);
|
||||
$driver->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
|
||||
);
|
||||
}
|
||||
|
||||
$mainDriver->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
|
||||
);
|
||||
|
||||
$driver = $mainDriver;
|
||||
|
||||
}
|
||||
|
||||
// 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(awLabel::CENTER, awLabel::BOTTOM);
|
||||
} else if($angle >= 135 and $angle < 225) {
|
||||
$this->label->setAlign(awLabel::RIGHT, awLabel::MIDDLE);
|
||||
} else if($angle >= 225 and $angle < 315) {
|
||||
$this->label->setAlign(awLabel::CENTER, awLabel::TOP);
|
||||
} else {
|
||||
$this->label->setAlign(awLabel::LEFT, awLabel::MIDDLE);
|
||||
}
|
||||
|
||||
$this->label->draw(
|
||||
$driver,
|
||||
$point,
|
||||
$key
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return margins around the component
|
||||
*
|
||||
* @return array Left, right, top and bottom margins
|
||||
*/
|
||||
public 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
|
||||
*/
|
||||
public function setValues($values) {
|
||||
|
||||
$this->checkArray($values);
|
||||
$this->values = $values;
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return values of Y axis
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getValues() {
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
private function checkArray(&$array) {
|
||||
|
||||
if(is_array($array) === FALSE) {
|
||||
awImage::drawError("Class Pie: 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) {
|
||||
awImage::drawError("Class Pie: Your graph must have at least 1 value.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('Pie');
|
||||
|
||||
/**
|
||||
* Pie
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awPiePart implements awLegendable {
|
||||
|
||||
/**
|
||||
* Pie part color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $color;
|
||||
|
||||
/**
|
||||
* Build a new awPiePart
|
||||
*
|
||||
* @param awColor $color Pie part color
|
||||
*/
|
||||
public function __construct(awColor $color) {
|
||||
|
||||
$this->color = $color;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background color or gradient of an element of the component
|
||||
*
|
||||
* @return Color, Gradient
|
||||
*/
|
||||
public function getLegendBackground() {
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line thickness
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendLineThickness() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line type
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendLineStyle() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of line
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendLineColor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mark object
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendMark() {
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('PiePart');
|
||||
|
||||
function callbackPerCent($value) {
|
||||
return $value.'%';
|
||||
}
|
||||
?>
|
Reference in New Issue
Block a user