Version 1.12
This commit is contained in:
parent
2a066a7498
commit
de31cd3e9a
1373 changed files with 156282 additions and 45238 deletions
|
|
@ -1,224 +0,0 @@
|
|||
<?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__)."/Image.class.php";
|
||||
|
||||
/**
|
||||
* AntiSpam
|
||||
* String printed on the images are case insensitive.
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awAntiSpam extends awImage {
|
||||
|
||||
/**
|
||||
* Anti-spam string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $string;
|
||||
|
||||
/**
|
||||
* Noise intensity
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $noise = 0;
|
||||
|
||||
/**
|
||||
* Construct a new awAntiSpam image
|
||||
*
|
||||
* @param string $string A string to display
|
||||
*/
|
||||
public function __construct($string = '') {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->string = (string)$string;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a random string
|
||||
*
|
||||
* @param int $length String length
|
||||
* @return string String created
|
||||
*/
|
||||
public function setRand($length) {
|
||||
|
||||
$length = (int)$length;
|
||||
|
||||
$this->string = '';
|
||||
|
||||
$letters = 'aAbBCDeEFgGhHJKLmMnNpPqQRsStTuVwWXYZz2345679';
|
||||
$number = strlen($letters);
|
||||
|
||||
for($i = 0; $i < $length; $i++) {
|
||||
$this->string .= $letters{mt_rand(0, $number - 1)};
|
||||
}
|
||||
|
||||
return $this->string;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set noise on image
|
||||
*
|
||||
* @param int $nois Noise intensity (from 0 to 10)
|
||||
*/
|
||||
public function setNoise($noise) {
|
||||
if($noise < 0) {
|
||||
$noise = 0;
|
||||
}
|
||||
if($noise > 10) {
|
||||
$noise = 10;
|
||||
}
|
||||
$this->noise = (int)$noise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Save string value in session
|
||||
* You can use check() to verify the value later
|
||||
*
|
||||
* @param string $qName A name that identify the anti-spam image
|
||||
*/
|
||||
public function save($qName) {
|
||||
$this->session();
|
||||
$session = 'artichow_'.(string)$qName;
|
||||
$_SESSION[$session] = $this->string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Verify user entry
|
||||
*
|
||||
* @param string $qName A name that identify the anti-spam image
|
||||
* @param string $value User-defined value
|
||||
* @param bool $case TRUE for case insensitive check, FALSE for case sensitive check ? (default to TRUE)
|
||||
* @return bool TRUE if the value is correct, FALSE otherwise
|
||||
*/
|
||||
public function check($qName, $value, $case = TRUE) {
|
||||
|
||||
$this->session();
|
||||
|
||||
$session = 'artichow_'.(string)$qName;
|
||||
|
||||
return (
|
||||
array_key_exists($session, $_SESSION) === TRUE and
|
||||
$case ?
|
||||
(strtolower($_SESSION[$session]) === strtolower((string)$value)) :
|
||||
($_SESSION[$session] === (string)$value)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw image
|
||||
*/
|
||||
public function draw() {
|
||||
|
||||
$fonts = array(
|
||||
'Tuffy',
|
||||
'TuffyBold',
|
||||
'TuffyItalic',
|
||||
'TuffyBoldItalic'
|
||||
);
|
||||
|
||||
$sizes = array(12, 12.5, 13, 13.5, 14, 15, 16, 17, 18, 19);
|
||||
|
||||
$widths = array();
|
||||
$heights = array();
|
||||
$texts = array();
|
||||
|
||||
// Set up a temporary driver to allow font size calculations...
|
||||
$this->setSize(10, 10);
|
||||
$driver = $this->getDriver();
|
||||
|
||||
for($i = 0; $i < strlen($this->string); $i++) {
|
||||
|
||||
$fontKey = array_rand($fonts);
|
||||
$sizeKey = array_rand($sizes);
|
||||
|
||||
$font = new awTTFFont(
|
||||
$fonts[$fontKey], $sizes[$sizeKey]
|
||||
);
|
||||
|
||||
$text = new awText(
|
||||
$this->string{$i},
|
||||
$font,
|
||||
NULL,
|
||||
mt_rand(-15, 15)
|
||||
);
|
||||
|
||||
$widths[] = $driver->getTextWidth($text);
|
||||
$heights[] = $driver->getTextHeight($text);
|
||||
$texts[] = $text;
|
||||
|
||||
}
|
||||
|
||||
// ... and get rid of it.
|
||||
$this->driver = NULL;
|
||||
|
||||
$width = array_sum($widths);
|
||||
$height = array_max($heights);
|
||||
|
||||
$totalWidth = $width + 10 + count($texts) * 10;
|
||||
$totalHeight = $height + 20;
|
||||
|
||||
$this->setSize($totalWidth, $totalHeight);
|
||||
|
||||
$this->create();
|
||||
|
||||
for($i = 0; $i < strlen($this->string); $i++) {
|
||||
|
||||
$this->driver->string(
|
||||
$texts[$i],
|
||||
new awPoint(
|
||||
5 + array_sum(array_slice($widths, 0, $i)) + $widths[$i] / 2 + $i * 10,
|
||||
10 + ($height - $heights[$i]) / 2
|
||||
)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
$this->drawNoise($totalWidth, $totalHeight);
|
||||
|
||||
$this->send();
|
||||
|
||||
}
|
||||
|
||||
protected function drawNoise($width, $height) {
|
||||
|
||||
$points = $this->noise * 30;
|
||||
$color = new awColor(0, 0, 0);
|
||||
|
||||
for($i = 0; $i < $points; $i++) {
|
||||
$this->driver->point(
|
||||
$color,
|
||||
new awPoint(
|
||||
mt_rand(0, $width),
|
||||
mt_rand(0, $height)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function session() {
|
||||
|
||||
// Start session if needed
|
||||
if(!session_id()) {
|
||||
session_start();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('AntiSpam');
|
||||
?>
|
||||
|
|
@ -1,85 +0,0 @@
|
|||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Path to Artichow
|
||||
*/
|
||||
|
||||
define('ARTICHOW', dirname(__FILE__));
|
||||
|
||||
|
||||
/*
|
||||
* Path to TrueType fonts
|
||||
* DO NOT USE FONT PATH WITH SPACE CHARACTER (" ") WITH GD <= 2.0.18
|
||||
*/
|
||||
if(!defined('ARTICHOW_FONT')) {
|
||||
|
||||
define('ARTICHOW_FONT', ARTICHOW.DIRECTORY_SEPARATOR.'font');
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Patterns directory
|
||||
*/
|
||||
if(!defined('ARTICHOW_PATTERN')) {
|
||||
|
||||
define('ARTICHOW_PATTERN', ARTICHOW.DIRECTORY_SEPARATOR.'patterns');
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Images directory
|
||||
*/
|
||||
if(!defined('ARTICHOW_IMAGE')) {
|
||||
|
||||
define('ARTICHOW_IMAGE', ARTICHOW.DIRECTORY_SEPARATOR.'images');
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Enable/disable cache support
|
||||
*/
|
||||
define('ARTICHOW_CACHE', TRUE);
|
||||
|
||||
/*
|
||||
* Cache directory
|
||||
*/
|
||||
if(!defined('ARTICHOW_CACHE_DIRECTORY')) {
|
||||
|
||||
define('ARTICHOW_CACHE_DIRECTORY', ARTICHOW.DIRECTORY_SEPARATOR.'cache');
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Prefix for class names
|
||||
* No prefix by default
|
||||
*/
|
||||
define('ARTICHOW_PREFIX', '');
|
||||
|
||||
/*
|
||||
* Trigger errors when use of a deprecated feature
|
||||
*/
|
||||
define('ARTICHOW_DEPRECATED', TRUE);
|
||||
|
||||
/*
|
||||
* Defines the default driver
|
||||
*/
|
||||
define('ARTICHOW_DRIVER', 'gd');
|
||||
|
||||
/*
|
||||
* Fonts to use
|
||||
*/
|
||||
$fonts = array(
|
||||
'Tuffy',
|
||||
'TuffyBold',
|
||||
'TuffyBoldItalic',
|
||||
'TuffyItalic'
|
||||
);
|
||||
|
||||
?>
|
||||
|
|
@ -1,364 +0,0 @@
|
|||
<?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__)."/Plot.class.php";
|
||||
|
||||
/**
|
||||
* BarPlot
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awBarPlot extends awPlot implements awLegendable {
|
||||
|
||||
/**
|
||||
* Labels on your bar plot
|
||||
*
|
||||
* @var Label
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* Bar plot identifier
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $identifier;
|
||||
|
||||
/**
|
||||
* Bar plot number
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $number;
|
||||
|
||||
/**
|
||||
* Bar plot depth
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $depth;
|
||||
|
||||
/**
|
||||
* For moving bars
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $move;
|
||||
|
||||
/**
|
||||
* Bars shadow
|
||||
*
|
||||
* @var Shadow
|
||||
*/
|
||||
public $barShadow;
|
||||
|
||||
/**
|
||||
* Bars border
|
||||
*
|
||||
* @var Border
|
||||
*/
|
||||
public $barBorder;
|
||||
|
||||
/**
|
||||
* Bars padding
|
||||
*
|
||||
* @var Side
|
||||
*/
|
||||
protected $barPadding;
|
||||
|
||||
/**
|
||||
* Bars space
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $barSpace = 0;
|
||||
|
||||
/**
|
||||
* Bars background
|
||||
*
|
||||
* @var Color, Gradient
|
||||
*/
|
||||
protected $barBackground;
|
||||
|
||||
/**
|
||||
* Construct a new awBarPlot
|
||||
*
|
||||
* @param array $values Some numeric values for Y axis
|
||||
* @param int $identifier Plot identifier
|
||||
* @param int $number Bar plot number
|
||||
* @param int $depth Bar plot depth in pixels
|
||||
*/
|
||||
public function __construct($values, $identifier = 1, $number = 1, $depth = 0) {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->label = new awLabel;
|
||||
|
||||
$this->barPadding = new awSide(0.08, 0.08, 0, 0);
|
||||
$this->barShadow = new awShadow(awShadow::RIGHT_TOP);
|
||||
$this->barBorder = new awBorder;
|
||||
|
||||
$this->setValues($values);
|
||||
|
||||
$this->identifier = (int)$identifier;
|
||||
$this->number = (int)$number;
|
||||
$this->depth = (int)$depth;
|
||||
|
||||
$this->move = new awSide;
|
||||
|
||||
// Hide vertical grid
|
||||
$this->grid->hideVertical(TRUE);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change bars padding
|
||||
* This method is not compatible with awBarPlot::setBarPadding()
|
||||
*
|
||||
* @param float $left Left padding (between 0 and 1)
|
||||
* @param float $right Right padding (between 0 and 1)
|
||||
*/
|
||||
public function setBarPadding($left = NULL, $right = NULL) {
|
||||
$this->barPadding->set($left, $right);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change bars size
|
||||
* This method is not compatible with awBarPlot::setBarPadding()
|
||||
*
|
||||
* @param int $width Bars size (between 0 and 1)
|
||||
*/
|
||||
public function setBarSize($size) {
|
||||
$padding = (1 - $size) / 2;
|
||||
$this->barPadding->set($padding, $padding);
|
||||
}
|
||||
|
||||
/**
|
||||
* Move bars
|
||||
*
|
||||
* @param int $x
|
||||
* @param int $y
|
||||
*/
|
||||
public function move($x, $y) {
|
||||
$this->move->set($x, NULL, $y, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change bars space
|
||||
*
|
||||
* @param int $space Space in pixels
|
||||
*/
|
||||
public function setBarSpace($space) {
|
||||
$this->barSpace = (int)$space;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line background color
|
||||
*
|
||||
* @param awColor $color
|
||||
*/
|
||||
public function setBarColor(awColor $color) {
|
||||
$this->barBackground = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line background gradient
|
||||
*
|
||||
* @param awGradient $gradient
|
||||
*/
|
||||
public function setBarGradient(awGradient $gradient) {
|
||||
$this->barBackground = $gradient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line thickness
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineThickness() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineStyle() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of line
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
public function getLegendLineColor() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background color or gradient of an element of the component
|
||||
*
|
||||
* @return Color, Gradient
|
||||
*/
|
||||
public function getLegendBackground() {
|
||||
return $this->barBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mark object
|
||||
*
|
||||
* @return Mark
|
||||
*/
|
||||
public function getLegendMark() {
|
||||
}
|
||||
|
||||
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
|
||||
|
||||
$count = count($this->datay);
|
||||
$max = $this->getRealYMax(NULL);
|
||||
$min = $this->getRealYMin(NULL);
|
||||
|
||||
// Find zero for bars
|
||||
if($this->xAxisZero and $min <= 0 and $max >= 0) {
|
||||
$zero = 0;
|
||||
} else if($max < 0) {
|
||||
$zero = $max;
|
||||
} else {
|
||||
$zero = $min;
|
||||
}
|
||||
|
||||
// Get base position
|
||||
$zero = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint(0, $zero));
|
||||
|
||||
// Distance between two values on the graph
|
||||
$distance = $this->xAxis->getDistance(0, 1);
|
||||
|
||||
// Compute paddings
|
||||
$leftPadding = $this->barPadding->left * $distance;
|
||||
$rightPadding = $this->barPadding->right * $distance;
|
||||
|
||||
$padding = $leftPadding + $rightPadding;
|
||||
$space = $this->barSpace * ($this->number - 1);
|
||||
|
||||
$barSize = ($distance - $padding - $space) / $this->number;
|
||||
$barPosition = $leftPadding + $barSize * ($this->identifier - 1);
|
||||
|
||||
for($key = 0; $key < $count; $key++) {
|
||||
|
||||
$value = $this->datay[$key];
|
||||
|
||||
if($value !== NULL) {
|
||||
|
||||
$position = awAxis::toPosition(
|
||||
$this->xAxis,
|
||||
$this->yAxis,
|
||||
new awPoint($key, $value)
|
||||
);
|
||||
|
||||
$barStart = $barPosition + ($this->identifier - 1) * $this->barSpace + $position->x;
|
||||
$barStop = $barStart + $barSize;
|
||||
|
||||
$t1 = min($zero->y, $position->y);
|
||||
$t2 = max($zero->y, $position->y);
|
||||
|
||||
if(round($t2 - $t1) == 0) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$p1 = new awPoint(
|
||||
round($barStart) + $this->depth + $this->move->left,
|
||||
round($t1) - $this->depth + $this->move->top
|
||||
);
|
||||
|
||||
$p2 = new awPoint(
|
||||
round($barStop) + $this->depth + $this->move->left,
|
||||
round($t2) - $this->depth + $this->move->top
|
||||
);
|
||||
|
||||
$this->drawBar($driver, $p1, $p2);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Draw labels
|
||||
foreach($this->datay as $key => $value) {
|
||||
|
||||
if($value !== NULL) {
|
||||
|
||||
$position = awAxis::toPosition(
|
||||
$this->xAxis,
|
||||
$this->yAxis,
|
||||
new awPoint($key, $value)
|
||||
);
|
||||
|
||||
$point = new awPoint(
|
||||
$barPosition + ($this->identifier - 1) * $this->barSpace + $position->x + $barSize / 2 + 1 + $this->depth,
|
||||
$position->y - $this->depth
|
||||
);
|
||||
|
||||
$this->label->draw($driver, $point, $key);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getXAxisNumber() {
|
||||
return count($this->datay) + 1;
|
||||
}
|
||||
// ça bidouille à fond ici !
|
||||
public function getXMax() {
|
||||
return array_max($this->datax) + 1;
|
||||
}
|
||||
|
||||
public function getXCenter() {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
protected function drawBar(awDriver $driver, awPoint $p1, awPoint $p2) {
|
||||
|
||||
// Draw shadow
|
||||
$this->barShadow->draw(
|
||||
$driver,
|
||||
$p1,
|
||||
$p2,
|
||||
awShadow::OUT
|
||||
);
|
||||
|
||||
if(abs($p2->y - $p1->y) > 1) {
|
||||
|
||||
$this->barBorder->rectangle(
|
||||
$driver,
|
||||
$p1,
|
||||
$p2
|
||||
);
|
||||
|
||||
if($this->barBackground !== NULL) {
|
||||
|
||||
$size = $this->barBorder->visible() ? 1 : 0;
|
||||
|
||||
$b1 = $p1->move($size, $size);
|
||||
$b2 = $p2->move(-1 * $size, -1 * $size);
|
||||
|
||||
// Draw background
|
||||
$driver->filledRectangle(
|
||||
$this->barBackground,
|
||||
new awLine($b1, $b2)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('BarPlot');
|
||||
?>
|
||||
|
|
@ -1,170 +0,0 @@
|
|||
Artichow 1.1
|
||||
|
||||
- All new driver-based architecture: Artichow now draws the graphs using drivers, located in 'inc/drivers/'. The move will ease development of new drawing formats (SVG, Flash, etc.) while keeping backward compatibility very high: you shouldn't have to change anything to your existing code and only two methods from the Font class have disappeared (see below) (Laurent)
|
||||
- Added Image::setDriver() to allow driver selection (Laurent)
|
||||
- Changed the Drawer class name to Driver. The class is now abstract, the implementation has to be made in the driver file itself. (Laurent)
|
||||
- Added the GDDriver class to draw with GD: the file is 'inc/drivers/gd.class.php' (Laurent)
|
||||
- Modified GDDriver::rectangle() so that it doesn't tamper with the Line object passed as an argument any more (Laurent)
|
||||
- Fixed a bug where calling GDDriver::polygon() wouldn't close the polygon being drawn when using a non-solid border (Laurent)
|
||||
- Added the constant ARTICHOW_DRIVER to define the default driver to use when none is selected (defaults to 'gd') (Laurent)
|
||||
- Changed and reorganised the Font related classes: added FileFont and PHPFont, reworked inheritance (Laurent)
|
||||
- Deleted Font::getTextWidth() and Font::getTextHeight(), replaced by Driver::getTextWidth() and Driver::getTextHeight() (Laurent)
|
||||
- Added two new helping classes for Font manipulation, PHPFontDriver and FileFontDriver (Laurent)
|
||||
- Fixed a bug that prevented values passed to Grid::setGrid() to have any effect (Laurent)
|
||||
- Added four new types of Mark (Mark::INVERTED_TRIANGLE, Mark::RHOMBUS, Mark::CROSS, Mark::PLUS) (Geoffrey)
|
||||
- Updated Image::drawError() so that it doesn't display HTML tags any more (Laurent)
|
||||
- Modified Lable::setCallbackFunction() so that it now accepts static method callbacks (i.e. setCallbackFunction(array($this, 'methodName'))) (Vincent)
|
||||
- Code cleanup and tweaking
|
||||
|
||||
Artichow 1.0.9
|
||||
|
||||
- Fixed a bug in Font class (second argument of wordwrap() can not be empty) (Vincent)
|
||||
- Fixed a bug in Drawer class (text size was not handled correctly) (Vincent)
|
||||
- Added support for using font paths containing space character when using GD <= 2.0.18 (bug#12) (Vincent)
|
||||
- Fixed a bug where the HTTP headers were sent even though the draw() method was called with Graph::DRAW_RETURN or a filename (Laurent)
|
||||
- Added support for antialiased pies on non-white background (only work with plain colors) (thanks to Eldwin) (Laurent)
|
||||
- Anti-aliasing is now handled by the Drawer class (Laurent)
|
||||
- Added method Drawer::setAntiAliasing() to turn anti-aliasing on or off (Laurent)
|
||||
- Fixed a bug where a LinePlot with multiple lines of different thickness wouldn't have its anti-aliasing setting correctly handled (Laurent)
|
||||
- Fixed a bug where the X axis wouldn't be labelled properly (bug#16) (Laurent)
|
||||
- Added a new type of Mark (Mark::TRIANGLE) (Laurent)
|
||||
- Fixed a bug where calling Axis::setYMax() wouldn't have any effect when drawing the axis (Vincent)
|
||||
- Fixed a bug where a dashed line wouldn't been drawn properly in certain circumstances (Laurent)
|
||||
- Fixed a bug where using Label::setFormat() or Label::setCallbackFunction() would be overriden by Axis::setLabelPrecision() (Laurent)
|
||||
- Fixed a "division by zero" error when using a gradient fill on a LinePlot with zeroed values (bug#19) (Laurent)
|
||||
- General code cleanup
|
||||
|
||||
Artichow 1.0.8
|
||||
|
||||
- Enhanced error support
|
||||
- Added multi-line text support
|
||||
- Updated and improved documentation
|
||||
- Changed Graph::draw() method to accept more options
|
||||
- Deleted first parameter of Image::send() method
|
||||
- Added a third parameter to Image::send() method to disable auto-sending of Content-Type header
|
||||
- Added a second parameter to Image::send() method to return an image instead of outputing it
|
||||
- Fixed a fatal error on direct access to files Image.class.php and inc/*
|
||||
- Fixed a bug in configuration file (bad constant definition check for ARTICHOW_CACHE_DIRECTORY)
|
||||
|
||||
Artichow 1.0.7
|
||||
|
||||
- Added constant ARTICHOW_CACHE_DIRECTORY to choose cache directory
|
||||
- Fixed a division by zero bug in Axis class
|
||||
- Improved cache handling
|
||||
- Fixed a bug with ob_* handlers
|
||||
- Fixed a bug for lines thickness
|
||||
- Shadow color now works fine
|
||||
|
||||
Artichow 1.0.6
|
||||
|
||||
- Added method Plot::setYAxisZero()
|
||||
- Added auto-scaling for plots
|
||||
- Added constant ARTICHOW_CACHE to enable/disable the cache
|
||||
- Improved prefix for classes
|
||||
|
||||
Artichow 1.0.5
|
||||
|
||||
- Added constant ARTICHOW_PREFIX to prefix Artichow's classes (bug #000002)
|
||||
- Added methods Shadow::hide() and Shadow::show()
|
||||
- Added method Plot::reduce()
|
||||
- It is now possible to save its charts in a file
|
||||
- Fixed a bug in PlotGroup (setYMin() / setYMax() did not work)
|
||||
- Fixed an incoherent behaviour if some values in $datay are not numeric (LinePlot, BarPlot, ScatterPlot)
|
||||
- Fixed an inclusion bug in Pattern
|
||||
- Fixed a bug for PHP 5.1.0
|
||||
|
||||
Artichow 1.0.4
|
||||
|
||||
- Added support for GIF images
|
||||
- Added patterns (Pattern.class.php)
|
||||
- Added titles on axis
|
||||
- Renamed Artichow.class.php to Graph.class.php (break backward compatibility)
|
||||
- Added a README file
|
||||
- Added support for ScatterPlot
|
||||
- Merged setBackgroundColor() and setBackgroundGradient() into setFill() in class Mark (break backward compatibility)
|
||||
- Added an optional argument $size to Mark::setType()
|
||||
- Grid background in now default to white in class Plot
|
||||
- Changed class Polygon to accept NULL values
|
||||
- Added a new legend type (Legend::MARKONLY)
|
||||
- Added method Legend::show()
|
||||
- Added methods Mark::move(), Mark::hide() and Mark::show()
|
||||
- Added new marks (star, book, ...)
|
||||
- Added methods Label::setBackground() and Legend::setBackground()
|
||||
- Added methods Plot::setXMax(), Plot::setXMin(), PlotGroup::setXMax() and PlotGroup::setXMin()
|
||||
- Added new colors to default theme in Pie
|
||||
- Removed methods Drawer::setBackground*()
|
||||
- Tests have been removed from the archive
|
||||
- Moved methods Component::addLabel() and Component::addAbsLabel() to class Graph
|
||||
- Modes LinePlot::MIDDLE and LinePlot::BAR have been merged into LinePlot::MIDDLE (break backward compatibility)
|
||||
- Fixed a bug in Artichow.cfg.php (unable to use some ttf fonts)
|
||||
- Fixed a bug in Legend (position of marks was sometimes broken)
|
||||
- Fixed a bug in Pie (pies can now take only a single value)
|
||||
- Fixed some bugs in Plot / LinePlot
|
||||
- Fixed a bug in Font::draw() (call to undefined function trigger__error)
|
||||
|
||||
Artichow 1.0.3 (beta)
|
||||
|
||||
- Added EXPERIMENTAL support for PHP 4
|
||||
- Changed class BarPlot so it now uses class Border instead of setBorderThickness() and setBorderColor()
|
||||
- Changed class Legend so it now uses class Border instead of setBorderSize() and setBorderColor()
|
||||
- Changed class Mark so it now uses class Border instead of setBorderSize() and setBorderColor()
|
||||
- Changed class Text so it now uses class Border instead of setBorderColor()
|
||||
- Changed class Label so it now uses class Border instead of setBorderColor()
|
||||
- Drawer::drawRectangle() and Drawer::drawFilledRectangle() now take a line as second argument
|
||||
- Added styles to rectangles and polygons
|
||||
- BarPlot::setBarPadding() takes now values in per-cent instead of pixels
|
||||
- Merged drawFilledRectangleColor() and drawFilledRectangleGradient() into drawFilledRectangle() in class Drawer
|
||||
- Merged drawFilledPolygonColor() and drawFilledPolygonGradient() into drawFilledPolygon() in class Drawer
|
||||
- Merged drawFilledEllipseColor() and drawFilledEllipseGradient() into drawFilledEllipse() in class Drawer
|
||||
- Added method BarPlot::setBarWidth()
|
||||
- Added an optional border to the class Image
|
||||
- Added a new class Border
|
||||
- Added support for MathPlot
|
||||
- LinePlot::STEP has been removed
|
||||
- Merged classes Paragraph and Label (no changes in the API)
|
||||
- Method Plot::setLabelCenter() is obsolete and has been removed
|
||||
- Rewrited Axis (add a new class Tick) (break backward compatibility)
|
||||
- Removed draw*Triangle* from class Drawer (use polygons instead)
|
||||
- Removed prefix draw in each method of class Drawer
|
||||
- Renamed LinePlot::setLineType() into LinePlot::setStyle()
|
||||
- Renamed LinePlot::setLineThickness() into LinePlot::setThickness()
|
||||
- Renamed LinePlot::setLineColor() into LinePlot::setColor()
|
||||
- Renamed LinePlot::setLineBackgroundColor() to LinePlot::setFillColor()
|
||||
- Renamed LinePlot::setLineBackgroundGradient() to LinePlot::setFillGradient()
|
||||
- Renamed Line::setType() to Line::setStyle()
|
||||
- Added methods Label::get(), Label::setFormat() and change method Label::setFont()
|
||||
- Added a parameter $smooth in Shadow::setSize();
|
||||
- Added filled areas in LinePlot
|
||||
- Added lots of new features in Math.class.php
|
||||
- Fixed a bug in Math::isVertical() and Math::isHorizontal()
|
||||
- Fixed a bug in Legend (shadow is now well-positioned is there is no border on the legend)
|
||||
- Lots of minor changes
|
||||
|
||||
Artichow 1.0.2 (beta)
|
||||
|
||||
- Added support for pies (2D & 3D)
|
||||
- Moved shadow from class Component to class Image
|
||||
- X Axis are now centered on 0 by default on bar and line plots
|
||||
- Added title to Graphs
|
||||
- Added 4 named fonts
|
||||
- Added 50 named colors
|
||||
- Added shadow to legends
|
||||
- Added method Image::setBackgroundGradient()
|
||||
- Added methods Label::setCallbackFunction() and Label::hide()
|
||||
- Added method Legend::hide()
|
||||
- Added methods Drawer::copyResizeImage(), Drawer::drawArc() and Drawer::drawFilledArcColor()
|
||||
- Renamed Positionable::setHorizontalAlign() and Positionable::setVerticalAlign() to Positionable::setAlign()
|
||||
- API for ellipses has changed
|
||||
- Title is now a property instead of a method in Component
|
||||
- Removed old code, that fixes a bug in the grid
|
||||
- Fixed a bug that affects position of bars in some cases
|
||||
- Fixed wrong size of shadow
|
||||
- Fixed a bug in Plot::setYMin() and Plot::setYMax()
|
||||
|
||||
Artichow 1.0.1 (alpha)
|
||||
|
||||
- Added anti-spam images
|
||||
|
||||
Artichow 1.0.0 (alpha)
|
||||
|
||||
- Initial release
|
||||
|
|
@ -1,415 +0,0 @@
|
|||
<?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__)."/Graph.class.php";
|
||||
|
||||
|
||||
/**
|
||||
* A graph can contain some groups of components
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
abstract class awComponentGroup extends awComponent {
|
||||
|
||||
/**
|
||||
* Components of this group
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $components;
|
||||
|
||||
/**
|
||||
* Build the component group
|
||||
*/
|
||||
public function __construct() {
|
||||
parent::__construct();
|
||||
$this->components = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a component to the group
|
||||
*
|
||||
* @param awComponent $component A component
|
||||
*/
|
||||
public function add(awComponent $component) {
|
||||
$this->components[] = $component;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('ComponentGroup', TRUE);
|
||||
|
||||
abstract class awComponent {
|
||||
|
||||
/**
|
||||
* Component driver
|
||||
*
|
||||
* @var Driver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* Component width
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $width = 1.0;
|
||||
|
||||
/**
|
||||
* Component height
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $height = 1.0;
|
||||
|
||||
/**
|
||||
* Position X of the center the graph (from 0 to 1)
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $x = 0.5;
|
||||
|
||||
/**
|
||||
* Position Y of the center the graph (from 0 to 1)
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $y = 0.5;
|
||||
|
||||
/**
|
||||
* Component absolute width (in pixels)
|
||||
*
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $w;
|
||||
|
||||
/**
|
||||
* Component absolute height (in pixels)
|
||||
*
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $h;
|
||||
|
||||
/**
|
||||
* Left-top corner Y position
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $top;
|
||||
|
||||
/**
|
||||
* Left-top corner X position
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $left;
|
||||
|
||||
/**
|
||||
* Component background color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $background;
|
||||
|
||||
/**
|
||||
* Component padding
|
||||
*
|
||||
* @var Side
|
||||
*/
|
||||
protected $padding;
|
||||
|
||||
/**
|
||||
* Component space
|
||||
*
|
||||
* @var Side
|
||||
*/
|
||||
protected $space;
|
||||
|
||||
/**
|
||||
* Component title
|
||||
*
|
||||
* @var Label
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* Adjust automatically the component ?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $auto = TRUE;
|
||||
|
||||
/**
|
||||
* Legend
|
||||
*
|
||||
* @var Legend
|
||||
*/
|
||||
public $legend;
|
||||
|
||||
/**
|
||||
* Build the component
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
// Component legend
|
||||
$this->legend = new awLegend();
|
||||
|
||||
$this->padding = new awSide(25, 25, 25, 25);
|
||||
$this->space = new awSide(0, 0, 0, 0);
|
||||
|
||||
// Component title
|
||||
$this->title = new awLabel(
|
||||
NULL,
|
||||
new awTuffy(10),
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
$this->title->setAlign(awLabel::CENTER, awLabel::TOP);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Adjust automatically the component ?
|
||||
*
|
||||
* @param bool $auto
|
||||
*/
|
||||
public function auto($auto) {
|
||||
$this->auto = (bool)$auto;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the size of the component
|
||||
*
|
||||
* @param int $width Component width (from 0 to 1)
|
||||
* @param int $height Component height (from 0 to 1)
|
||||
*/
|
||||
public function setSize($width, $height) {
|
||||
|
||||
$this->width = (float)$width;
|
||||
$this->height = (float)$height;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the absolute size of the component
|
||||
*
|
||||
* @param int $w Component width (in pixels)
|
||||
* @param int $h Component height (in pixels)
|
||||
*/
|
||||
public function setAbsSize($w, $h) {
|
||||
|
||||
$this->w = (int)$w;
|
||||
$this->h = (int)$h;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change component background color
|
||||
*
|
||||
* @param awColor $color (can be null)
|
||||
*/
|
||||
public function setBackgroundColor($color) {
|
||||
if($color === NULL or $color instanceof awColor) {
|
||||
$this->background = $color;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change component background gradient
|
||||
*
|
||||
* @param awGradient $gradient (can be null)
|
||||
*/
|
||||
public function setBackgroundGradient($gradient) {
|
||||
if($gradient === NULL or $gradient instanceof awGradient) {
|
||||
$this->background = $gradient;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change component background image
|
||||
*
|
||||
* @param awImage $image (can be null)
|
||||
*/
|
||||
public function setBackgroundImage($image) {
|
||||
if($image === NULL or $image instanceof awImage) {
|
||||
$this->background = $image;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the component background
|
||||
*
|
||||
* @return Color, Gradient
|
||||
*/
|
||||
public function getBackground() {
|
||||
return $this->background;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change component padding
|
||||
*
|
||||
* @param int $left Padding in pixels (NULL to keep old value)
|
||||
* @param int $right Padding in pixels (NULL to keep old value)
|
||||
* @param int $top Padding in pixels (NULL to keep old value)
|
||||
* @param int $bottom Padding in pixels (NULL to keep old value)
|
||||
*/
|
||||
public function setPadding($left = NULL, $right = NULL, $top = NULL, $bottom = NULL) {
|
||||
$this->padding->set($left, $right, $top, $bottom);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change component space
|
||||
*
|
||||
* @param float $left Space in % (NULL to keep old value)
|
||||
* @param float $right Space in % (NULL to keep old value)
|
||||
* @param float $bottom Space in % (NULL to keep old value)
|
||||
* @param float $top Space in % (NULL to keep old value)
|
||||
*/
|
||||
public function setSpace($left = NULL, $right = NULL, $bottom = NULL, $top = NULL) {
|
||||
$this->space->set($left, $right, $bottom, $top);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the absolute position of the component on the graph
|
||||
*
|
||||
* @var int $x Left-top corner X position
|
||||
* @var int $y Left-top corner Y position
|
||||
*/
|
||||
public function setAbsPosition($left, $top) {
|
||||
|
||||
$this->left = (int)$left;
|
||||
$this->top = (int)$top;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the center of the component
|
||||
*
|
||||
* @param int $x Position X of the center of the component
|
||||
* @param int $y Position Y of the center of the component
|
||||
*/
|
||||
public function setCenter($x, $y) {
|
||||
|
||||
$this->x = (float)$x;
|
||||
$this->y = (float)$y;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get component coords with its padding
|
||||
*
|
||||
* @return array Coords of the component
|
||||
*/
|
||||
public function getPosition() {
|
||||
|
||||
// Get component coords
|
||||
$x1 = $this->padding->left;
|
||||
$y1 = $this->padding->top;
|
||||
$x2 = $this->w - $this->padding->right;
|
||||
$y2 = $this->h - $this->padding->bottom;
|
||||
|
||||
return array($x1, $y1, $x2, $y2);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Init the drawing of the component
|
||||
*/
|
||||
public function init(awDriver $driver) {
|
||||
|
||||
// Set component background
|
||||
$background = $this->getBackground();
|
||||
|
||||
if($background !== NULL) {
|
||||
|
||||
$p1 = new awPoint(0, 0);
|
||||
$p2 = new awPoint($this->w - 1, $this->h - 1);
|
||||
|
||||
if($background instanceof awImage) {
|
||||
|
||||
$driver->copyImage(
|
||||
$background,
|
||||
$p1,
|
||||
$p2
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
$driver->filledRectangle(
|
||||
$background,
|
||||
new awLine($p1, $p2)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finalize the drawing of the component
|
||||
*/
|
||||
public function finalize(awDriver $driver) {
|
||||
|
||||
// Draw component title
|
||||
$point = new awPoint(
|
||||
$this->w / 2,
|
||||
$this->padding->top - 8
|
||||
);
|
||||
$this->title->draw($driver, $point);
|
||||
|
||||
// Draw legend
|
||||
$this->legend->draw($driver);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw the grid around your component
|
||||
*
|
||||
* @param Driver A driver
|
||||
* @return array Coords for the component
|
||||
*/
|
||||
abstract public function drawEnvelope(awDriver $driver);
|
||||
|
||||
/**
|
||||
* Draw the component on the graph
|
||||
* Component should be drawed into specified coords
|
||||
*
|
||||
* @param Driver A driver
|
||||
* @param int $x1
|
||||
* @param int $y1
|
||||
* @param int $x2
|
||||
* @param int $y2
|
||||
* @param bool $aliasing Use anti-aliasing to draw the component ?
|
||||
*/
|
||||
abstract public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing);
|
||||
|
||||
/**
|
||||
* Get space width in pixels
|
||||
*
|
||||
* @param int $width Component width
|
||||
* @param int $height Component height
|
||||
* @return array
|
||||
*/
|
||||
protected function getSpace($width, $height) {
|
||||
|
||||
$left = (int)($width * $this->space->left / 100);
|
||||
$right = (int)($width * $this->space->right / 100);
|
||||
$top = (int)($height * $this->space->top / 100);
|
||||
$bottom = (int)($height * $this->space->bottom / 100);
|
||||
|
||||
return array($left, $right, $top, $bottom);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('Component', TRUE);
|
||||
?>
|
||||
|
|
@ -1,3 +0,0 @@
|
|||
Artichow 1.0.9
|
||||
|
||||
- Pie::setBorder(): replaced by Pie::setBorderColor()
|
||||
|
|
@ -1,412 +0,0 @@
|
|||
<?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__)."/Image.class.php";
|
||||
|
||||
|
||||
/**
|
||||
* A graph
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awGraph extends awImage {
|
||||
|
||||
/**
|
||||
* Graph name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $name;
|
||||
|
||||
/**
|
||||
* Cache timeout
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $timeout = 0;
|
||||
|
||||
/**
|
||||
* Graph timing ?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $timing;
|
||||
|
||||
/**
|
||||
* Components
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $components = array();
|
||||
|
||||
/**
|
||||
* Some labels to add to the component
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $labels = array();
|
||||
|
||||
/**
|
||||
* Graph title
|
||||
*
|
||||
* @var Label
|
||||
*/
|
||||
public $title;
|
||||
|
||||
/**
|
||||
* File cache location
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $fileCache;
|
||||
|
||||
/**
|
||||
* Time file cache location
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $fileCacheTime;
|
||||
|
||||
/**
|
||||
* Drawing mode to return the graph
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const DRAW_RETURN = 1;
|
||||
|
||||
/**
|
||||
* Drawing mode to display the graph
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const DRAW_DISPLAY = 2;
|
||||
|
||||
/**
|
||||
* Construct a new graph
|
||||
*
|
||||
* @param int $width Graph width
|
||||
* @param int $height Graph height
|
||||
* @param string $name Graph name for the cache (must be unique). Let it null to not use the cache.
|
||||
* @param int $timeout Cache timeout (unix timestamp)
|
||||
*/
|
||||
public function __construct($width = NULL, $height = NULL, $name = NULL, $timeout = 0) {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->setSize($width, $height);
|
||||
|
||||
if(ARTICHOW_CACHE) {
|
||||
|
||||
$this->name = $name;
|
||||
$this->timeout = $timeout;
|
||||
|
||||
// Clean sometimes all the cache
|
||||
if(mt_rand(0, 5000) === 0) {
|
||||
awGraph::cleanCache();
|
||||
}
|
||||
|
||||
// Take the graph from the cache if possible
|
||||
if($this->name !== NULL) {
|
||||
|
||||
$this->fileCache = ARTICHOW_CACHE_DIRECTORY."/".$this->name;
|
||||
$this->fileCacheTime = $this->fileCache."-time";
|
||||
|
||||
if(is_file($this->fileCache)) {
|
||||
|
||||
$type = awGraph::cleanGraphCache($this->fileCacheTime);
|
||||
|
||||
if($type === NULL) {
|
||||
awGraph::deleteFromCache($this->name);
|
||||
} else {
|
||||
header("Content-Type: image/".$type);
|
||||
echo file_get_contents($this->fileCache);
|
||||
exit;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$this->title = new awLabel(
|
||||
NULL,
|
||||
new awTuffy(16),
|
||||
NULL,
|
||||
0
|
||||
);
|
||||
$this->title->setAlign(awLabel::CENTER, awLabel::BOTTOM);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a graph from the cache
|
||||
*
|
||||
* @param string $name Graph name
|
||||
* @return bool TRUE on success, FALSE on failure
|
||||
*/
|
||||
public static function deleteFromCache($name) {
|
||||
|
||||
if(ARTICHOW_CACHE) {
|
||||
|
||||
if(is_file(ARTICHOW_CACHE_DIRECTORY."/".$name."-time")) {
|
||||
unlink(ARTICHOW_CACHE_DIRECTORY."/".$name."");
|
||||
unlink(ARTICHOW_CACHE_DIRECTORY."/".$name."-time");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete all graphs from the cache
|
||||
*/
|
||||
public static function deleteAllCache() {
|
||||
|
||||
if(ARTICHOW_CACHE) {
|
||||
|
||||
$dp = opendir(ARTICHOW_CACHE_DIRECTORY);
|
||||
|
||||
while($file = readdir($dp)) {
|
||||
if($file !== '.' and $file != '..') {
|
||||
unlink(ARTICHOW_CACHE_DIRECTORY."/".$file);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Clean cache
|
||||
*/
|
||||
public static function cleanCache() {
|
||||
|
||||
if(ARTICHOW_CACHE) {
|
||||
|
||||
$glob = glob(ARTICHOW_CACHE_DIRECTORY."/*-time");
|
||||
|
||||
foreach($glob as $file) {
|
||||
|
||||
$type = awGraph::cleanGraphCache($file);
|
||||
|
||||
if($type === NULL) {
|
||||
$name = ereg_replace(".*/(.*)\-time", "\\1", $file);
|
||||
awGraph::deleteFromCache($name);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable/Disable Graph timing
|
||||
*
|
||||
* @param bool $timing
|
||||
*/
|
||||
public function setTiming($timing) {
|
||||
$this->timing = (bool)$timing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a component to the graph
|
||||
*
|
||||
* @param awComponent $component
|
||||
*/
|
||||
public function add(awComponent $component) {
|
||||
|
||||
$this->components[] = $component;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a label to the component
|
||||
*
|
||||
* @param awLabel $label
|
||||
* @param int $x Position on X axis of the center of the text
|
||||
* @param int $y Position on Y axis of the center of the text
|
||||
*/
|
||||
public function addLabel(awLabel $label, $x, $y) {
|
||||
|
||||
$this->labels[] = array(
|
||||
$label, $x, $y
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a label to the component with absolute position
|
||||
*
|
||||
* @param awLabel $label
|
||||
* @param awPoint $point Text position
|
||||
*/
|
||||
public function addAbsLabel(awLabel $label, awPoint $point) {
|
||||
|
||||
$this->labels[] = array(
|
||||
$label, $point
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Build the graph and draw component on it
|
||||
*
|
||||
* @param string $mode Display mode (can be a file name)
|
||||
*/
|
||||
public function draw($mode = Graph::DRAW_DISPLAY) {
|
||||
|
||||
if($this->timing) {
|
||||
$time = microtimeFloat();
|
||||
}
|
||||
|
||||
$this->create();
|
||||
|
||||
foreach($this->components as $component) {
|
||||
|
||||
$this->drawComponent($component);
|
||||
|
||||
}
|
||||
|
||||
$this->drawTitle();
|
||||
$this->drawShadow();
|
||||
$this->drawLabels();
|
||||
|
||||
if($this->timing) {
|
||||
$this->drawTiming(microtimeFloat() - $time);
|
||||
}
|
||||
|
||||
// Create graph
|
||||
$data = $this->get();
|
||||
|
||||
// Put the graph in the cache if needed
|
||||
$this->cache($data);
|
||||
|
||||
switch($mode) {
|
||||
|
||||
case Graph::DRAW_DISPLAY :
|
||||
$this->sendHeaders();
|
||||
echo $data;
|
||||
break;
|
||||
|
||||
case Graph::DRAW_RETURN :
|
||||
return $data;
|
||||
|
||||
default :
|
||||
if(is_string($mode)) {
|
||||
file_put_contents($mode, $data);
|
||||
} else {
|
||||
awImage::drawError("Class Graph: Unable to draw the graph.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function drawLabels() {
|
||||
|
||||
$driver = $this->getDriver();
|
||||
|
||||
foreach($this->labels as $array) {
|
||||
|
||||
if(count($array) === 3) {
|
||||
|
||||
// Text in relative position
|
||||
list($label, $x, $y) = $array;
|
||||
|
||||
$point = new awPoint(
|
||||
$x * $this->width,
|
||||
$y * $this->height
|
||||
);
|
||||
|
||||
} else {
|
||||
|
||||
// Text in absolute position
|
||||
list($label, $point) = $array;
|
||||
|
||||
}
|
||||
|
||||
$label->draw($driver, $point);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private function drawTitle() {
|
||||
|
||||
$driver = $this->getDriver();
|
||||
|
||||
$point = new awPoint(
|
||||
$this->width / 2,
|
||||
10
|
||||
);
|
||||
|
||||
$this->title->draw($driver, $point);
|
||||
|
||||
}
|
||||
|
||||
private function drawTiming($time) {
|
||||
|
||||
$driver = $this->getDriver();
|
||||
|
||||
$label = new awLabel;
|
||||
$label->set("(".sprintf("%.3f", $time)." s)");
|
||||
$label->setAlign(awLabel::LEFT, awLabel::TOP);
|
||||
$label->border->show();
|
||||
$label->setPadding(1, 0, 0, 0);
|
||||
$label->setBackgroundColor(new awColor(230, 230, 230, 25));
|
||||
|
||||
$label->draw($driver, new awPoint(5, $driver->imageHeight - 5));
|
||||
|
||||
}
|
||||
|
||||
private function cache($data) {
|
||||
if(ARTICHOW_CACHE and $this->name !== NULL) {
|
||||
|
||||
if(is_writable(ARTICHOW_CACHE_DIRECTORY) === FALSE) {
|
||||
awImage::drawError("Class Graph: Cache directory is not writable.");
|
||||
}
|
||||
|
||||
file_put_contents($this->fileCache, $data);
|
||||
file_put_contents($this->fileCacheTime, $this->timeout."\n".$this->getFormatString());
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static function cleanGraphCache($file) {
|
||||
|
||||
list(
|
||||
$time,
|
||||
$type
|
||||
) = explode("\n", file_get_contents($file));
|
||||
|
||||
$time = (int)$time;
|
||||
|
||||
if($time !== 0 and $time < time()) {
|
||||
return NULL;
|
||||
} else {
|
||||
return $type;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('Graph');
|
||||
|
||||
/*
|
||||
* To preserve PHP 4 compatibility
|
||||
*/
|
||||
function microtimeFloat() {
|
||||
list($usec, $sec) = explode(" ", microtime());
|
||||
return (float)$usec + (float)$sec;
|
||||
}
|
||||
?>
|
||||
|
|
@ -1,606 +0,0 @@
|
|||
<?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.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
if(is_file(dirname(__FILE__)."/Artichow.cfg.php")) { // For PHP 4+5 version
|
||||
require_once dirname(__FILE__)."/Artichow.cfg.php";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
* Register a class with the prefix in configuration file
|
||||
*/
|
||||
function registerClass($class, $abstract = FALSE) {
|
||||
|
||||
if(ARTICHOW_PREFIX === 'aw') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
if($abstract) {
|
||||
$abstract = 'abstract';
|
||||
} else {
|
||||
$abstract = '';
|
||||
}
|
||||
|
||||
|
||||
eval($abstract." class ".ARTICHOW_PREFIX.$class." extends aw".$class." { }");
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Register an interface with the prefix in configuration file
|
||||
*/
|
||||
function registerInterface($interface) {
|
||||
|
||||
if(ARTICHOW_PREFIX === 'aw') {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
eval("interface ".ARTICHOW_PREFIX.$interface." extends aw".$interface." { }");
|
||||
|
||||
|
||||
}
|
||||
|
||||
// Some useful files
|
||||
require_once ARTICHOW."/Component.class.php";
|
||||
|
||||
require_once ARTICHOW."/inc/Grid.class.php";
|
||||
require_once ARTICHOW."/inc/Tools.class.php";
|
||||
require_once ARTICHOW."/inc/Driver.class.php";
|
||||
require_once ARTICHOW."/inc/Math.class.php";
|
||||
require_once ARTICHOW."/inc/Tick.class.php";
|
||||
require_once ARTICHOW."/inc/Axis.class.php";
|
||||
require_once ARTICHOW."/inc/Legend.class.php";
|
||||
require_once ARTICHOW."/inc/Mark.class.php";
|
||||
require_once ARTICHOW."/inc/Label.class.php";
|
||||
require_once ARTICHOW."/inc/Text.class.php";
|
||||
require_once ARTICHOW."/inc/Color.class.php";
|
||||
require_once ARTICHOW."/inc/Font.class.php";
|
||||
require_once ARTICHOW."/inc/Gradient.class.php";
|
||||
require_once ARTICHOW."/inc/Shadow.class.php";
|
||||
require_once ARTICHOW."/inc/Border.class.php";
|
||||
|
||||
require_once ARTICHOW."/common.php";
|
||||
|
||||
/**
|
||||
* An image for a graph
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awImage {
|
||||
|
||||
/**
|
||||
* Graph width
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $width;
|
||||
|
||||
/**
|
||||
* Graph height
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
public $height;
|
||||
|
||||
/**
|
||||
* Use anti-aliasing ?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $antiAliasing = FALSE;
|
||||
|
||||
/**
|
||||
* Image format
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $format = awImage::PNG;
|
||||
|
||||
/**
|
||||
* Image background color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $background;
|
||||
|
||||
/**
|
||||
* GD resource
|
||||
*
|
||||
* @var resource
|
||||
*/
|
||||
protected $resource;
|
||||
|
||||
/**
|
||||
* A Driver object
|
||||
*
|
||||
* @var Driver
|
||||
*/
|
||||
protected $driver;
|
||||
|
||||
/**
|
||||
* Driver string
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $driverString;
|
||||
|
||||
/**
|
||||
* Shadow
|
||||
*
|
||||
* @var Shadow
|
||||
*/
|
||||
public $shadow;
|
||||
|
||||
/**
|
||||
* Image border
|
||||
*
|
||||
* @var Border
|
||||
*/
|
||||
public $border;
|
||||
|
||||
/**
|
||||
* Use JPEG for image
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const JPEG = IMG_JPG;
|
||||
|
||||
/**
|
||||
* Use PNG for image
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const PNG = IMG_PNG;
|
||||
|
||||
/**
|
||||
* Use GIF for image
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const GIF = IMG_GIF;
|
||||
|
||||
/**
|
||||
* Build the image
|
||||
*/
|
||||
public function __construct() {
|
||||
|
||||
$this->background = new awColor(255, 255, 255);
|
||||
$this->shadow = new awShadow(awShadow::RIGHT_BOTTOM);
|
||||
$this->border = new awBorder;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Get driver of the image
|
||||
*
|
||||
* @param int $w Driver width (from 0 to 1) (default to 1)
|
||||
* @param int $h Driver height (from 0 to 1) (default to 1)
|
||||
* @param float $x Position on X axis of the center of the driver (default to 0.5)
|
||||
* @param float $y Position on Y axis of the center of the driver (default to 0.5)
|
||||
* @return Driver
|
||||
*/
|
||||
public function getDriver($w = 1, $h = 1, $x = 0.5, $y = 0.5) {
|
||||
$this->create();
|
||||
$this->driver->setSize($w, $h);
|
||||
$this->driver->setPosition($x, $y);
|
||||
return $this->driver;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the driver that will be used to draw the graph
|
||||
*
|
||||
* @param string $driverString
|
||||
*/
|
||||
public function setDriver($driverString) {
|
||||
$this->driver = $this->selectDriver($driverString);
|
||||
|
||||
$this->driver->init($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the image size
|
||||
*
|
||||
* @var int $width Image width
|
||||
* @var int $height Image height
|
||||
*/
|
||||
public function setSize($width, $height) {
|
||||
|
||||
if($width !== NULL) {
|
||||
$this->width = (int)$width;
|
||||
}
|
||||
if($height !== NULL) {
|
||||
$this->height = (int)$height;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change image background
|
||||
*
|
||||
* @param mixed $background
|
||||
*/
|
||||
public function setBackground($background) {
|
||||
if($background instanceof awColor) {
|
||||
$this->setBackgroundColor($background);
|
||||
} elseif($background instanceof awGradient) {
|
||||
$this->setBackgroundGradient($background);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change image background color
|
||||
*
|
||||
* @param awColor $color
|
||||
*/
|
||||
public function setBackgroundColor(awColor $color) {
|
||||
$this->background = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change image background gradient
|
||||
*
|
||||
* @param awGradient $gradient
|
||||
*/
|
||||
public function setBackgroundGradient(awGradient $gradient) {
|
||||
$this->background = $gradient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return image background, whether a Color or a Gradient
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function getBackground() {
|
||||
return $this->background;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turn antialiasing on or off
|
||||
*
|
||||
* @var bool $bool
|
||||
*/
|
||||
public function setAntiAliasing($bool) {
|
||||
$this->antiAliasing = (bool)$bool;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the antialiasing setting
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getAntiAliasing() {
|
||||
return $this->antiAliasing;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change image format
|
||||
*
|
||||
* @var int $format New image format
|
||||
*/
|
||||
public function setFormat($format) {
|
||||
if($format === awImage::JPEG or $format === awImage::PNG or $format === awImage::GIF) {
|
||||
$this->format = $format;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image format as an integer
|
||||
*
|
||||
* @return unknown
|
||||
*/
|
||||
public function getFormat() {
|
||||
return $this->format;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the image format as a string
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getFormatString() {
|
||||
|
||||
switch($this->format) {
|
||||
case awImage::JPEG :
|
||||
return 'jpeg';
|
||||
case awImage::PNG :
|
||||
return 'png';
|
||||
case awImage::GIF :
|
||||
return 'gif';
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new awimage
|
||||
*/
|
||||
public function create() {
|
||||
|
||||
if($this->driver === NULL) {
|
||||
$driver = $this->selectDriver($this->driverString);
|
||||
|
||||
$driver->init($this);
|
||||
|
||||
$this->driver = $driver;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Select the correct driver
|
||||
*
|
||||
* @param string $driver The desired driver
|
||||
* @return mixed
|
||||
*/
|
||||
protected function selectDriver($driver) {
|
||||
$drivers = array('gd');
|
||||
$driver = strtolower((string)$driver);
|
||||
|
||||
if(in_array($driver, $drivers, TRUE)) {
|
||||
$string = $driver;
|
||||
} else {
|
||||
$string = ARTICHOW_DRIVER;
|
||||
}
|
||||
|
||||
switch ($string) {
|
||||
case 'gd':
|
||||
require_once ARTICHOW.'/inc/drivers/gd.class.php';
|
||||
$this->driverString = $string;
|
||||
return new awGDDriver();
|
||||
|
||||
default:
|
||||
// We should never get here, unless the wrong string is used AND the ARTICHOW_DRIVER
|
||||
// global has been messed with.
|
||||
awImage::drawError('Class Image: Unknown driver type (\''.$string.'\')');
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Draw a component on the image
|
||||
*
|
||||
* @var awComponent $component A component
|
||||
*/
|
||||
public function drawComponent(awComponent $component) {
|
||||
|
||||
$shadow = $this->shadow->getSpace(); // Image shadow
|
||||
$border = $this->border->visible() ? 1 : 0; // Image border size
|
||||
|
||||
$driver = clone $this->driver;
|
||||
$driver->setImageSize(
|
||||
$this->width - $shadow->left - $shadow->right - $border * 2,
|
||||
$this->height - $shadow->top - $shadow->bottom - $border * 2
|
||||
);
|
||||
|
||||
// No absolute size specified
|
||||
if($component->w === NULL and $component->h === NULL) {
|
||||
|
||||
list($width, $height) = $driver->setSize($component->width, $component->height);
|
||||
|
||||
// Set component size in pixels
|
||||
$component->setAbsSize($width, $height);
|
||||
|
||||
} else {
|
||||
|
||||
$driver->setAbsSize($component->w, $component->h);
|
||||
|
||||
}
|
||||
|
||||
if($component->top !== NULL and $component->left !== NULL) {
|
||||
$driver->setAbsPosition(
|
||||
$border + $shadow->left + $component->left,
|
||||
$border + $shadow->top + $component->top
|
||||
);
|
||||
} else {
|
||||
$driver->setPosition($component->x, $component->y);
|
||||
}
|
||||
|
||||
$driver->movePosition($border + $shadow->left, $border + $shadow->top);
|
||||
|
||||
list($x1, $y1, $x2, $y2) = $component->getPosition();
|
||||
|
||||
$component->init($driver);
|
||||
|
||||
$component->drawComponent($driver, $x1, $y1, $x2, $y2, $this->antiAliasing);
|
||||
$component->drawEnvelope($driver, $x1, $y1, $x2, $y2);
|
||||
|
||||
$component->finalize($driver);
|
||||
|
||||
}
|
||||
|
||||
protected function drawShadow() {
|
||||
|
||||
$driver = $this->getDriver();
|
||||
|
||||
$this->shadow->draw(
|
||||
$driver,
|
||||
new awPoint(0, 0),
|
||||
new awPoint($this->width, $this->height),
|
||||
awShadow::IN
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the image into a file or to the user browser
|
||||
*
|
||||
*/
|
||||
public function send() {
|
||||
$this->driver->send($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the image content as binary data
|
||||
*
|
||||
*/
|
||||
public function get() {
|
||||
return $this->driver->get($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Send the correct HTTP header according to the image type
|
||||
*
|
||||
*/
|
||||
public function sendHeaders() {
|
||||
|
||||
if(headers_sent() === FALSE) {
|
||||
|
||||
switch ($this->driverString) {
|
||||
case 'gd' :
|
||||
header('Content-type: image/'.$this->getFormatString());
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private static $errorWriting = FALSE;
|
||||
|
||||
|
||||
/*
|
||||
* Display an error image and exit
|
||||
*
|
||||
* @param string $message Error message
|
||||
*/
|
||||
public static function drawError($message) {
|
||||
|
||||
|
||||
if(self::$errorWriting) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::$errorWriting = TRUE;
|
||||
|
||||
$message = wordwrap($message, 40, "\n", TRUE);
|
||||
|
||||
$width = 400;
|
||||
$height = max(100, 40 + 22.5 * (substr_count($message, "\n") + 1));
|
||||
|
||||
$image = new awImage();
|
||||
$image->setSize($width, $height);
|
||||
$image->setDriver('gd');
|
||||
|
||||
$driver = $image->getDriver();
|
||||
$driver->init($image);
|
||||
|
||||
// Display title
|
||||
$driver->filledRectangle(
|
||||
new awWhite,
|
||||
new awLine(
|
||||
new awPoint(0, 0),
|
||||
new awPoint($width, $height)
|
||||
)
|
||||
);
|
||||
|
||||
$driver->filledRectangle(
|
||||
new awRed,
|
||||
new awLine(
|
||||
new awPoint(0, 0),
|
||||
new awPoint(110, 25)
|
||||
)
|
||||
);
|
||||
|
||||
$text = new awText(
|
||||
"Artichow error",
|
||||
new awFont3,
|
||||
new awWhite,
|
||||
0
|
||||
);
|
||||
|
||||
$driver->string($text, new awPoint(5, 6));
|
||||
|
||||
// Display red box
|
||||
$driver->rectangle(
|
||||
new awRed,
|
||||
new awLine(
|
||||
new awPoint(0, 25),
|
||||
new awPoint($width - 90, $height - 1)
|
||||
)
|
||||
);
|
||||
|
||||
// Display error image
|
||||
$file = ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.'error.png';
|
||||
|
||||
$imageError = new awFileImage($file);
|
||||
$driver->copyImage(
|
||||
$imageError,
|
||||
new awPoint($width - 81, $height - 81),
|
||||
new awPoint($width - 1, $height - 1)
|
||||
);
|
||||
|
||||
// Draw message
|
||||
$text = new awText(
|
||||
strip_tags($message),
|
||||
new awFont2,
|
||||
new awBlack,
|
||||
0
|
||||
);
|
||||
|
||||
$driver->string($text, new awPoint(10, 40));
|
||||
|
||||
$image->send();
|
||||
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Display an error image located in a file and exit
|
||||
*
|
||||
* @param string $error Error name
|
||||
*/
|
||||
public static function drawErrorFile($error) {
|
||||
|
||||
$file = ARTICHOW_IMAGE.DIRECTORY_SEPARATOR.'errors'.DIRECTORY_SEPARATOR.$error.'.png';
|
||||
|
||||
header("Content-Type: image/png");
|
||||
readfile($file);
|
||||
exit;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('Image');
|
||||
|
||||
|
||||
/**
|
||||
* Load an image from a file
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awFileImage extends awImage {
|
||||
|
||||
/**
|
||||
* Build a new awimage
|
||||
*
|
||||
* @param string $file Image file name
|
||||
*/
|
||||
public function __construct($file) {
|
||||
|
||||
$driver = $this->selectDriver($this->driverString);
|
||||
|
||||
$driver->initFromFile($this, $file);
|
||||
|
||||
$this->driver = $driver;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('FileImage');
|
||||
|
||||
?>
|
||||
|
|
@ -1,585 +0,0 @@
|
|||
<?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__)."/Plot.class.php";
|
||||
|
||||
|
||||
/**
|
||||
* LinePlot
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awLinePlot extends awPlot implements awLegendable {
|
||||
|
||||
/**
|
||||
* Add marks to your line plot
|
||||
*
|
||||
* @var Mark
|
||||
*/
|
||||
public $mark;
|
||||
|
||||
/**
|
||||
* Labels on your line plot
|
||||
*
|
||||
* @var Label
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* Filled areas
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $areas = array();
|
||||
|
||||
/**
|
||||
* Is the line hidden
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $lineHide = FALSE;
|
||||
|
||||
/**
|
||||
* Line color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $lineColor;
|
||||
|
||||
/**
|
||||
* Line mode
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineMode = awLinePlot::LINE;
|
||||
|
||||
/**
|
||||
* Line type
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineStyle = awLine::SOLID;
|
||||
|
||||
/**
|
||||
* Line thickness
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineThickness = 1;
|
||||
|
||||
/**
|
||||
* Line background
|
||||
*
|
||||
* @var Color, Gradient
|
||||
*/
|
||||
protected $lineBackground;
|
||||
|
||||
/**
|
||||
* Line mode
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const LINE = 0;
|
||||
|
||||
/**
|
||||
* Line in the middle
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MIDDLE = 1;
|
||||
|
||||
/**
|
||||
* Construct a new awLinePlot
|
||||
*
|
||||
* @param array $values Some numeric values for Y axis
|
||||
* @param int $mode
|
||||
*/
|
||||
public function __construct($values, $mode = awLinePlot::LINE) {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->mark = new awMark;
|
||||
$this->label = new awLabel;
|
||||
|
||||
$this->lineMode = (int)$mode;
|
||||
|
||||
$this->setValues($values);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide line
|
||||
*
|
||||
* @param bool $hide
|
||||
*/
|
||||
public function hideLine($hide) {
|
||||
$this->lineHide = (bool)$hide;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a filled area
|
||||
*
|
||||
* @param int $start Begining of the area
|
||||
* @param int $end End of the area
|
||||
* @param mixed $background Background color or gradient of the area
|
||||
*/
|
||||
public function setFilledArea($start, $stop, $background) {
|
||||
|
||||
if($stop <= $start) {
|
||||
awImage::drawError("Class LinePlot: End position can not be greater than begin position in setFilledArea().");
|
||||
}
|
||||
|
||||
$this->areas[] = array((int)$start, (int)$stop, $background);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line color
|
||||
*
|
||||
* @param awColor $color
|
||||
*/
|
||||
public function setColor(awColor $color) {
|
||||
$this->lineColor = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line style
|
||||
*
|
||||
* @param int $style
|
||||
*/
|
||||
public function setStyle($style) {
|
||||
$this->lineStyle = (int)$style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line tickness
|
||||
*
|
||||
* @param int $tickness
|
||||
*/
|
||||
public function setThickness($tickness) {
|
||||
$this->lineThickness = (int)$tickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line background color
|
||||
*
|
||||
* @param awColor $color
|
||||
*/
|
||||
public function setFillColor(awColor $color) {
|
||||
$this->lineBackground = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line background gradient
|
||||
*
|
||||
* @param awGradient $gradient
|
||||
*/
|
||||
public function setFillGradient(awGradient $gradient) {
|
||||
$this->lineBackground = $gradient;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line thickness
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineThickness() {
|
||||
return $this->lineThickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineStyle() {
|
||||
return $this->lineStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of line
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
public function getLegendLineColor() {
|
||||
return $this->lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background color or gradient of an element of the component
|
||||
*
|
||||
* @return Color, Gradient
|
||||
*/
|
||||
public function getLegendBackground() {
|
||||
return $this->lineBackground;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mark object
|
||||
*
|
||||
* @return Mark
|
||||
*/
|
||||
public function getLegendMark() {
|
||||
return $this->mark;
|
||||
}
|
||||
|
||||
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
|
||||
|
||||
$max = $this->getRealYMax();
|
||||
$min = $this->getRealYMin();
|
||||
|
||||
// Get start and stop values
|
||||
list($start, $stop) = $this->getLimit();
|
||||
|
||||
if($this->lineMode === awLinePlot::MIDDLE) {
|
||||
$inc = $this->xAxis->getDistance(0, 1) / 2;
|
||||
} else {
|
||||
$inc = 0;
|
||||
}
|
||||
|
||||
// Build the polygon
|
||||
$polygon = new awPolygon;
|
||||
|
||||
for($key = $start; $key <= $stop; $key++) {
|
||||
|
||||
$value = $this->datay[$key];
|
||||
|
||||
if($value !== NULL) {
|
||||
|
||||
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($key, $value));
|
||||
$p = $p->move($inc, 0);
|
||||
$polygon->set($key, $p);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Draw backgrounds
|
||||
if($this->lineBackground instanceof awColor or $this->lineBackground instanceof awGradient) {
|
||||
|
||||
$backgroundPolygon = new awPolygon;
|
||||
|
||||
$p = $this->xAxisPoint($start);
|
||||
$p = $p->move($inc, 0);
|
||||
$backgroundPolygon->append($p);
|
||||
|
||||
// Add others points
|
||||
foreach($polygon->all() as $point) {
|
||||
$backgroundPolygon->append(clone $point);
|
||||
}
|
||||
|
||||
$p = $this->xAxisPoint($stop);
|
||||
$p = $p->move($inc, 0);
|
||||
$backgroundPolygon->append($p);
|
||||
|
||||
// Draw polygon background
|
||||
$driver->filledPolygon($this->lineBackground, $backgroundPolygon);
|
||||
|
||||
}
|
||||
|
||||
$this->drawArea($driver, $polygon);
|
||||
|
||||
// Draw line
|
||||
$prev = NULL;
|
||||
|
||||
// Line color
|
||||
if($this->lineHide === FALSE) {
|
||||
|
||||
if($this->lineColor === NULL) {
|
||||
$this->lineColor = new awColor(0, 0, 0);
|
||||
}
|
||||
|
||||
foreach($polygon->all() as $point) {
|
||||
|
||||
if($prev !== NULL) {
|
||||
$driver->line(
|
||||
$this->lineColor,
|
||||
new awLine(
|
||||
$prev,
|
||||
$point,
|
||||
$this->lineStyle,
|
||||
$this->lineThickness
|
||||
)
|
||||
);
|
||||
}
|
||||
$prev = $point;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// Draw marks and labels
|
||||
foreach($polygon->all() as $key => $point) {
|
||||
|
||||
$this->mark->draw($driver, $point);
|
||||
$this->label->draw($driver, $point, $key);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function drawArea(awDriver $driver, awPolygon $polygon) {
|
||||
|
||||
$starts = array();
|
||||
foreach($this->areas as $area) {
|
||||
list($start) = $area;
|
||||
$starts[$start] = TRUE;
|
||||
}
|
||||
|
||||
// Draw filled areas
|
||||
foreach($this->areas as $area) {
|
||||
|
||||
list($start, $stop, $background) = $area;
|
||||
|
||||
$polygonArea = new awPolygon;
|
||||
|
||||
$p = $this->xAxisPoint($start);
|
||||
$polygonArea->append($p);
|
||||
|
||||
for($i = $start; $i <= $stop; $i++) {
|
||||
$p = clone $polygon->get($i);
|
||||
if($i === $stop and array_key_exists($stop, $starts)) {
|
||||
$p = $p->move(-1, 0);
|
||||
}
|
||||
$polygonArea->append($p);
|
||||
}
|
||||
|
||||
$p = $this->xAxisPoint($stop);
|
||||
if(array_key_exists($stop, $starts)) {
|
||||
$p = $p->move(-1, 0);
|
||||
}
|
||||
$polygonArea->append($p);
|
||||
|
||||
// Draw area
|
||||
$driver->filledPolygon($background, $polygonArea);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function getXAxisNumber() {
|
||||
if($this->lineMode === awLinePlot::MIDDLE) {
|
||||
return count($this->datay) + 1;
|
||||
} else {
|
||||
return count($this->datay);
|
||||
}
|
||||
}
|
||||
|
||||
protected function xAxisPoint($position) {
|
||||
$y = $this->xAxisZero ? 0 : $this->getRealYMin();
|
||||
return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y));
|
||||
}
|
||||
|
||||
public function getXCenter() {
|
||||
return ($this->lineMode === awLinePlot::MIDDLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('LinePlot');
|
||||
|
||||
|
||||
/**
|
||||
* Simple LinePlot
|
||||
* Useful to draw simple horizontal lines
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awSimpleLinePlot extends awPlot implements awLegendable {
|
||||
|
||||
/**
|
||||
* Line color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $lineColor;
|
||||
|
||||
/**
|
||||
* Line start
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineStart;
|
||||
|
||||
/**
|
||||
* Line stop
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineStop;
|
||||
|
||||
/**
|
||||
* Line value
|
||||
*
|
||||
* @var flaot
|
||||
*/
|
||||
protected $lineValue;
|
||||
|
||||
/**
|
||||
* Line mode
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineMode = awLinePlot::LINE;
|
||||
|
||||
/**
|
||||
* Line type
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineStyle = awLine::SOLID;
|
||||
|
||||
/**
|
||||
* Line thickness
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineThickness = 1;
|
||||
|
||||
/**
|
||||
* Line mode
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const LINE = 0;
|
||||
|
||||
/**
|
||||
* Line in the middle
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
const MIDDLE = 1;
|
||||
|
||||
/**
|
||||
* Construct a new awLinePlot
|
||||
*
|
||||
* @param float $value A Y value
|
||||
* @param int $start Line start index
|
||||
* @param int $stop Line stop index
|
||||
* @param int $mode Line mode
|
||||
*/
|
||||
public function __construct($value, $start, $stop, $mode = awLinePlot::LINE) {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->lineMode = (int)$mode;
|
||||
|
||||
$this->lineStart = (int)$start;
|
||||
$this->lineStop = (int)$stop;
|
||||
$this->lineValue = (float)$value;
|
||||
|
||||
$this->lineColor = new awColor(0, 0, 0);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line color
|
||||
*
|
||||
* @param awColor $color
|
||||
*/
|
||||
public function setColor(awColor $color) {
|
||||
$this->lineColor = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line style
|
||||
*
|
||||
* @param int $style
|
||||
*/
|
||||
public function setStyle($style) {
|
||||
$this->lineStyle = (int)$style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line tickness
|
||||
*
|
||||
* @param int $tickness
|
||||
*/
|
||||
public function setThickness($tickness) {
|
||||
$this->lineThickness = (int)$tickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line thickness
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineThickness() {
|
||||
return $this->lineThickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineStyle() {
|
||||
return $this->lineStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of line
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
public function getLegendLineColor() {
|
||||
return $this->lineColor;
|
||||
}
|
||||
|
||||
public function getLegendBackground() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function getLegendMark() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
|
||||
|
||||
if($this->lineMode === awLinePlot::MIDDLE) {
|
||||
$inc = $this->xAxis->getDistance(0, 1) / 2;
|
||||
} else {
|
||||
$inc = 0;
|
||||
}
|
||||
|
||||
$p1 = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($this->lineStart, $this->lineValue));
|
||||
$p2 = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($this->lineStop, $this->lineValue));
|
||||
|
||||
$driver->line(
|
||||
$this->lineColor,
|
||||
new awLine(
|
||||
$p1->move($inc, 0),
|
||||
$p2->move($inc, 0),
|
||||
$this->lineStyle,
|
||||
$this->lineThickness
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function getXAxisNumber() {
|
||||
if($this->lineMode === awLinePlot::MIDDLE) {
|
||||
return count($this->datay) + 1;
|
||||
} else {
|
||||
return count($this->datay);
|
||||
}
|
||||
}
|
||||
|
||||
protected function xAxisPoint($position) {
|
||||
$y = $this->xAxisZero ? 0 : $this->getRealYMin();
|
||||
return awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($position, $y));
|
||||
}
|
||||
|
||||
public function getXCenter() {
|
||||
return ($this->lineMode === awLinePlot::MIDDLE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('SimpleLinePlot');
|
||||
?>
|
||||
|
|
@ -1,439 +0,0 @@
|
|||
<?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";
|
||||
|
||||
/**
|
||||
* A mathematic function
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awMathFunction implements awLegendable {
|
||||
|
||||
/**
|
||||
* Function line
|
||||
*
|
||||
* @var Line
|
||||
*/
|
||||
public $line;
|
||||
|
||||
/**
|
||||
* Marks for your plot
|
||||
*
|
||||
* @var Mark
|
||||
*/
|
||||
public $mark;
|
||||
|
||||
/**
|
||||
* Callback function
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public $f;
|
||||
|
||||
/**
|
||||
* Start the drawing from this value
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $fromX;
|
||||
|
||||
/**
|
||||
* Stop the drawing at this value
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
public $toX;
|
||||
|
||||
/**
|
||||
* Line color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $color;
|
||||
|
||||
/**
|
||||
* Construct the function
|
||||
*
|
||||
* @param string $f Callback function
|
||||
* @param float $fromX
|
||||
* @param float $toX
|
||||
*/
|
||||
public function __construct($f, $fromX = NULL, $toX = NULL) {
|
||||
|
||||
$this->f = (string)$f;
|
||||
$this->fromX = is_null($fromX) ? NULL : (float)$fromX;
|
||||
$this->toX = is_null($toX) ? NULL : (float)$toX;
|
||||
|
||||
$this->line = new awLine;
|
||||
$this->mark = new awMark;
|
||||
$this->color = new awBlack;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line color
|
||||
*
|
||||
* @param awColor $color A new awcolor
|
||||
*/
|
||||
public function setColor(awColor $color) {
|
||||
$this->color = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get line color
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
public function getColor() {
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background color or gradient of an element of the component
|
||||
*
|
||||
* @return Color, Gradient
|
||||
*/
|
||||
public function getLegendBackground() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line thickness
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendLineThickness() {
|
||||
return $this->line->getThickness();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line type
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendLineStyle() {
|
||||
return $this->line->getStyle();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of line
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendLineColor() {
|
||||
return $this->color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mark object
|
||||
*
|
||||
* @return NULL
|
||||
*/
|
||||
public function getLegendMark() {
|
||||
return $this->mark;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('MathFunction');
|
||||
|
||||
/**
|
||||
* For mathematics functions
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awMathPlot extends awComponent {
|
||||
|
||||
/**
|
||||
* Functions
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $functions = array();
|
||||
|
||||
/**
|
||||
* Grid properties
|
||||
*
|
||||
* @var Grid
|
||||
*/
|
||||
public $grid;
|
||||
|
||||
/**
|
||||
* X axis
|
||||
*
|
||||
* @var Axis
|
||||
*/
|
||||
public $xAxis;
|
||||
|
||||
/**
|
||||
* Y axis
|
||||
*
|
||||
* @var Axis
|
||||
*/
|
||||
public $yAxis;
|
||||
|
||||
/**
|
||||
* Extremum
|
||||
*
|
||||
* @var Side
|
||||
*/
|
||||
private $extremum = NULL;
|
||||
|
||||
/**
|
||||
* Interval
|
||||
*
|
||||
* @var float
|
||||
*/
|
||||
private $interval = 1;
|
||||
|
||||
/**
|
||||
* Build the plot
|
||||
*
|
||||
* @param int $xMin Minimum X value
|
||||
* @param int $xMax Maximum X value
|
||||
* @param int $yMax Maximum Y value
|
||||
* @param int $yMin Minimum Y value
|
||||
*/
|
||||
public function __construct($xMin, $xMax, $yMax, $yMin) {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
$this->setPadding(8, 8, 8, 8);
|
||||
|
||||
$this->grid = new awGrid;
|
||||
|
||||
// Hide grid by default
|
||||
$this->grid->hide(TRUE);
|
||||
|
||||
// Set extremum
|
||||
$this->extremum = new awSide($xMin, $xMax, $yMax, $yMin);
|
||||
|
||||
// Create axis
|
||||
$this->xAxis = new awAxis;
|
||||
$this->xAxis->setTickStyle(awTick::IN);
|
||||
$this->xAxis->label->hideValue(0);
|
||||
$this->initAxis($this->xAxis);
|
||||
|
||||
$this->yAxis = new awAxis;
|
||||
$this->yAxis->setTickStyle(awTick::IN);
|
||||
$this->yAxis->label->hideValue(0);
|
||||
$this->initAxis($this->yAxis);
|
||||
|
||||
}
|
||||
|
||||
protected function initAxis(awAxis $axis) {
|
||||
|
||||
$axis->setLabelPrecision(1);
|
||||
$axis->addTick('major', new awTick(0, 5));
|
||||
$axis->addTick('minor', new awTick(0, 3));
|
||||
$axis->addTick('micro', new awTick(0, 1));
|
||||
$axis->setNumberByTick('minor', 'major', 1);
|
||||
$axis->setNumberByTick('micro', 'minor', 4);
|
||||
$axis->label->setFont(new awTuffy(7));
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Interval to calculate values
|
||||
*
|
||||
* @param float $interval
|
||||
*/
|
||||
public function setInterval($interval) {
|
||||
$this->interval = (float)$interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a formula f(x)
|
||||
*
|
||||
* @param awMathFunction $function
|
||||
* @param string $name Name for the legend (can be NULL if you don't want to set a legend)
|
||||
* @param int $type Type for the legend
|
||||
*/
|
||||
public function add(awMathFunction $function, $name = NULL, $type = awLegend::LINE) {
|
||||
|
||||
$this->functions[] = $function;
|
||||
|
||||
if($name !== NULL) {
|
||||
$this->legend->add($function, $name, $type);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public function init(awDriver $driver) {
|
||||
|
||||
list($x1, $y1, $x2, $y2) = $this->getPosition();
|
||||
|
||||
$this->xAxis->line->setX($x1, $x2);
|
||||
$this->xAxis->label->setAlign(NULL, awLabel::BOTTOM);
|
||||
$this->xAxis->label->move(0, 3);
|
||||
$this->xAxis->setRange($this->extremum->left, $this->extremum->right);
|
||||
|
||||
$this->yAxis->line->setY($y2, $y1);
|
||||
$this->yAxis->label->setAlign(awLabel::RIGHT);
|
||||
$this->yAxis->label->move(-6, 0);
|
||||
$this->yAxis->reverseTickStyle();
|
||||
$this->yAxis->setRange($this->extremum->bottom, $this->extremum->top);
|
||||
|
||||
|
||||
$this->xAxis->setYCenter($this->yAxis, 0);
|
||||
$this->yAxis->setXCenter($this->xAxis, 0);
|
||||
|
||||
if($this->yAxis->getLabelNumber() === NULL) {
|
||||
$number = $this->extremum->top - $this->extremum->bottom + 1;
|
||||
$this->yAxis->setLabelNumber($number);
|
||||
}
|
||||
|
||||
if($this->xAxis->getLabelNumber() === NULL) {
|
||||
$number = $this->extremum->right - $this->extremum->left + 1;
|
||||
$this->xAxis->setLabelNumber($number);
|
||||
}
|
||||
|
||||
// Set ticks
|
||||
|
||||
$this->xAxis->tick('major')->setNumber($this->xAxis->getLabelNumber());
|
||||
$this->yAxis->tick('major')->setNumber($this->yAxis->getLabelNumber());
|
||||
|
||||
|
||||
// Set axis labels
|
||||
$labels = array();
|
||||
for($i = 0, $count = $this->xAxis->getLabelNumber(); $i < $count; $i++) {
|
||||
$labels[] = $i;
|
||||
}
|
||||
$this->xAxis->label->set($labels);
|
||||
|
||||
$labels = array();
|
||||
for($i = 0, $count = $this->yAxis->getLabelNumber(); $i < $count; $i++) {
|
||||
$labels[] = $i;
|
||||
}
|
||||
$this->yAxis->label->set($labels);
|
||||
|
||||
parent::init($driver);
|
||||
|
||||
// Create the grid
|
||||
$this->createGrid();
|
||||
|
||||
// Draw the grid
|
||||
$this->grid->draw($driver, $x1, $y1, $x2, $y2);
|
||||
|
||||
}
|
||||
|
||||
public function drawEnvelope(awDriver $driver) {
|
||||
|
||||
// Draw axis
|
||||
$this->xAxis->draw($driver);
|
||||
$this->yAxis->draw($driver);
|
||||
|
||||
}
|
||||
|
||||
public function drawComponent(awDriver $driver, $x1, $y1, $x2, $y2, $aliasing) {
|
||||
|
||||
foreach($this->functions as $function) {
|
||||
|
||||
$f = $function->f;
|
||||
$fromX = is_null($function->fromX) ? $this->extremum->left : $function->fromX;
|
||||
$toX = is_null($function->toX) ? $this->extremum->right : $function->toX;
|
||||
|
||||
$old = NULL;
|
||||
|
||||
for($i = $fromX; $i <= $toX; $i += $this->interval) {
|
||||
|
||||
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($i, $f($i)));
|
||||
|
||||
if($p->y >= $y1 and $p->y <= $y2) {
|
||||
$function->mark->draw($driver, $p);
|
||||
}
|
||||
|
||||
if($old !== NULL) {
|
||||
|
||||
$line = $function->line;
|
||||
$line->setLocation($old, $p);
|
||||
|
||||
if(
|
||||
($line->p1->y >= $y1 and $line->p1->y <= $y2) or
|
||||
($line->p2->y >= $y1 and $line->p2->y <= $y2)
|
||||
) {
|
||||
$driver->line(
|
||||
$function->getColor(),
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$old = $p;
|
||||
|
||||
}
|
||||
|
||||
// Draw last point if needed
|
||||
if($old !== NULL and $i - $this->interval != $toX) {
|
||||
|
||||
$p = awAxis::toPosition($this->xAxis, $this->yAxis, new awPoint($toX, $f($toX)));
|
||||
|
||||
if($p->y >= $y1 and $p->y <= $y2) {
|
||||
$function->mark->draw($driver, $p);
|
||||
}
|
||||
|
||||
|
||||
$line = $function->line;
|
||||
$line->setLocation($old, $p);
|
||||
|
||||
if(
|
||||
($line->p1->y >= $y1 and $line->p1->y <= $y2) or
|
||||
($line->p2->y >= $y1 and $line->p2->y <= $y2)
|
||||
) {
|
||||
$driver->line(
|
||||
$function->getColor(),
|
||||
$line
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function createGrid() {
|
||||
|
||||
// Horizontal lines of the grid
|
||||
|
||||
$major = $this->yAxis->tick('major');
|
||||
$interval = $major->getInterval();
|
||||
$number = $this->yAxis->getLabelNumber() - 1;
|
||||
|
||||
$h = array();
|
||||
if($number > 0) {
|
||||
for($i = 0; $i <= $number; $i++) {
|
||||
$h[] = $i / $number;
|
||||
}
|
||||
}
|
||||
|
||||
// Vertical lines
|
||||
|
||||
$major = $this->xAxis->tick('major');
|
||||
$interval = $major->getInterval();
|
||||
$number = $this->xAxis->getLabelNumber() - 1;
|
||||
|
||||
$w = array();
|
||||
if($number > 0) {
|
||||
for($i = 0; $i <= $number; $i++) {
|
||||
if($i%$interval === 0) {
|
||||
$w[] = $i / $number;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$this->grid->setGrid($w, $h);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('MathPlot');
|
||||
?>
|
||||
|
|
@ -1,97 +0,0 @@
|
|||
<?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__)."/Graph.class.php";
|
||||
|
||||
/**
|
||||
* All patterns must derivate from this class
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
abstract class awPattern {
|
||||
|
||||
/**
|
||||
* Pattern arguments
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $args = array();
|
||||
|
||||
/**
|
||||
* Load a pattern
|
||||
*
|
||||
* @param string $pattern Pattern name
|
||||
* @return Component
|
||||
*/
|
||||
public static function get($pattern) {
|
||||
|
||||
$file = ARTICHOW_PATTERN.DIRECTORY_SEPARATOR.$pattern.'.php';
|
||||
|
||||
if(is_file($file)) {
|
||||
|
||||
require_once $file;
|
||||
|
||||
$class = $pattern.'Pattern';
|
||||
|
||||
if(class_exists($class)) {
|
||||
return new $class;
|
||||
} else {
|
||||
awImage::drawError("Class Pattern: Class '".$class."' does not exist.");
|
||||
}
|
||||
|
||||
} else {
|
||||
awImage::drawError("Class Pattern: Pattern '".$pattern."' does not exist.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Change pattern argument
|
||||
*
|
||||
* @param string $name Argument name
|
||||
* @param mixed $value Argument value
|
||||
*/
|
||||
public function setArg($name, $value) {
|
||||
if(is_string($name)) {
|
||||
$this->args[$name] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get an argument
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $default Default value if the argument does not exist (default to NULL)
|
||||
* @return mixed Argument value
|
||||
*/
|
||||
protected function getArg($name, $default = NULL) {
|
||||
if(array_key_exists($name, $this->args)) {
|
||||
return $this->args[$name];
|
||||
} else {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Change several arguments
|
||||
*
|
||||
* @param array $args New arguments
|
||||
*/
|
||||
public function setArgs($args) {
|
||||
if(is_array($args)) {
|
||||
foreach($args as $name => $value) {
|
||||
$this->setArg($name, $value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
registerClass('Pattern', TRUE);
|
||||
?>
|
||||
|
|
@ -1,695 +0,0 @@
|
|||
<?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(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::__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.'%';
|
||||
}
|
||||
?>
|
||||
File diff suppressed because it is too large
Load diff
120
artichow/README
120
artichow/README
|
|
@ -1,120 +0,0 @@
|
|||
I. Installation
|
||||
II. Configuration
|
||||
III. Utilisation
|
||||
IV. Divers
|
||||
|
||||
|
||||
I. Installation
|
||||
------------
|
||||
|
||||
*** Première installation ***
|
||||
|
||||
L'installation de Artichow se résume à décompresser l'archive dans le dossier
|
||||
de votre choix sur votre serveur. Veillez simplement à télécharger l'archive
|
||||
dont vous avez vraiment besoin (PHP 5 ou PHP 4 & 5).
|
||||
Notez que Artichow requiert GD 2 et PHP 4.3.0 au minimum pour fonctionner.
|
||||
|
||||
*** Mise à jour ***
|
||||
|
||||
Lorsque vous souhaitez mettre à jour Artichow avec la dernière version,
|
||||
essayez de suivre pas à pas ces étapes :
|
||||
1) Décompressez la dernière version de Artichow dans un dossier
|
||||
2) Ecrasez le fichier Artichow.cfg.php avec votre ancien fichier
|
||||
3) Copiez vos patterns dans le dossier patterns/ de la nouvelle version
|
||||
4) Supprimez l'ancienne version de Artichow de votre disque
|
||||
5) Copiez la nouvelle version là où était l'ancienne
|
||||
Une fois ces cinq étapes effectuées, vous n'aurez plus qu'à mettre
|
||||
éventuellement à jour vos graphiques, en fonction des dernières évolutions de
|
||||
l'API de Artichow. Pour cela, voyez le titre "Migrer d'une version à l'autre"
|
||||
sur la page :
|
||||
http://www.artichow.org/documentation
|
||||
|
||||
II. Configuration
|
||||
-------------
|
||||
|
||||
Même si une utilisation normale de Artichow ne nécessite pas de configuration
|
||||
particulière, il existe un fichier Artichow.cfg.php qui permet de modifier
|
||||
quelques paramètres de la librairie.
|
||||
Vous pouvez notamment configurer le répertoire vers les polices de caractère
|
||||
en modifiant la constante ARTICHOW_FONT (par exemple en choisissant
|
||||
'c:\Windows\font' si vous êtes sous Windows).
|
||||
Vous pouvez également redéfinir la variable $fonts. Cette variable contient une
|
||||
liste de polices TTF (sans l'extension) présentes dans votre répertoire
|
||||
ARTICHOW_FONT. Pour toutes les polices de cette liste, une classe du même nom
|
||||
est créée. Les polices ainsi définies peuvent ensuite être utilisées de cette
|
||||
manière :
|
||||
<?php
|
||||
$font = new Verdana(12); // 12 représente la taille en points
|
||||
?>
|
||||
Il existe également une constante ARTICHOW_DEPRECATED. Si cette constante vaut
|
||||
TRUE, alors un message d'erreur sera affiché lorsque vous utiliserez une
|
||||
fonctionnalité dépréciée de Artichow. A l'inverse, avec la valeur FALSE,
|
||||
vous pourrez continuer à utiliser les fonctions dépréciées sans soucis.
|
||||
Cependant, dans un souci de compatibilité, il est préférable de mettre à
|
||||
jour vos graphiques dès lors qu'un message de ce type apparaît (et donc de
|
||||
laisser la constante à TRUE). Les fonctionnalités dépréciées sont toujours
|
||||
potentiellement susceptibles de disparaître d'une version à l'autre de la
|
||||
librairie.
|
||||
La constante ARTICHOW_PREFIX est vide par défaut et correspond à un préfixe qui
|
||||
est ajouté au nom de chaque classe utilisée sur Artichow. Certains noms de
|
||||
classe (Graph, Image, Text, Font, etc.) sont utilisés par d'autres librairies
|
||||
et cela peut aboutir à des conflits. Pour résoudre ce problème, choisissez par
|
||||
exemple 'xyz' comme préfixe et toutes les classes de Artichow s'appèleront
|
||||
désormais xyz[Nom normal]. Exemple d'utilisation de Artichow avec
|
||||
ARTICHOW_PREFIX à 'xyz' :
|
||||
<?php
|
||||
require_once "Artichow/LinePlot.class.php";
|
||||
|
||||
$plot = new xyzLinePlot(array(1, 2, 3));
|
||||
$plot->title->set('Mon graphique');
|
||||
$plot->title->setFont(new xyzFont4);
|
||||
|
||||
$graph = new xyzGraph(400, 300);
|
||||
$graph->add($plot);
|
||||
$graph->draw();
|
||||
?>
|
||||
|
||||
|
||||
III. Utilisation
|
||||
-----------
|
||||
|
||||
Si vous utilisez la version conçue exclusivement pour PHP 5, vous pouvez vous
|
||||
référer aux exemples et aux tutoriels afin de bien prendre en main la
|
||||
librairie.
|
||||
Si vous utilisez la version pour PHP 4 & 5, référez vous également aux exemples
|
||||
et tutoriels mais faîtes attention lors de l'inclusion des fichiers de
|
||||
Artichow. N'incluez pas les fichiers de cette manière :
|
||||
<?php
|
||||
// Ceci ne fonctionnera pas
|
||||
require_once "Artichow/php5/LinePlot.class.php";
|
||||
// Cela non plus
|
||||
require_once "Artichow/php4/LinePlot.class.php";
|
||||
?>
|
||||
Préférez plutôt :
|
||||
<?php
|
||||
// Fonctionnera correctement
|
||||
require_once "Artichow/LinePlot.class.php";
|
||||
?>
|
||||
C'est la librairie qui se charge de sélectionner les bons fichiers en fonction
|
||||
de la version de PHP dont vous disposez.
|
||||
|
||||
IV. Divers
|
||||
------
|
||||
|
||||
La documentation de Artichow est disponible sur :
|
||||
http://www.artichow.org/documentation
|
||||
|
||||
Des tutoriels sont accessibles sur :
|
||||
http://www.artichow.org/tutorial
|
||||
|
||||
Un forum de support peut être trouvé sur :
|
||||
http://www.artichow.org/forum/
|
||||
|
||||
N'oubliez pas que Artichow est dans le domaine public. Vous pouvez donc faire
|
||||
CE QUE VOUS SOUHAITEZ avec cette librairie, y compris ajouter votre nom dans
|
||||
chaque fichier, et la redistribuer ainsi.
|
||||
|
||||
Si vous souhaitez aider et participer au développement de Artichow, n'hésitez
|
||||
pas à consulter cette page :
|
||||
http://www.artichow.org/help
|
||||
|
||||
|
|
@ -1,300 +0,0 @@
|
|||
<?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__)."/Plot.class.php";
|
||||
|
||||
/**
|
||||
* ScatterPlot
|
||||
*
|
||||
* @package Artichow
|
||||
*/
|
||||
class awScatterPlot extends awPlot implements awLegendable {
|
||||
|
||||
/**
|
||||
* Add marks to the scatter plot
|
||||
*
|
||||
* @var Mark
|
||||
*/
|
||||
public $mark;
|
||||
|
||||
/**
|
||||
* Labels on the plot
|
||||
*
|
||||
* @var Label
|
||||
*/
|
||||
public $label;
|
||||
|
||||
/**
|
||||
* Link points ?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $link = FALSE;
|
||||
|
||||
/**
|
||||
* Display impulses
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $impulse = NULL;
|
||||
|
||||
/**
|
||||
* Link NULL points ?
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $linkNull = FALSE;
|
||||
|
||||
/**
|
||||
* Line color
|
||||
*
|
||||
* @var Color
|
||||
*/
|
||||
protected $lineColor;
|
||||
|
||||
/**
|
||||
* Line type
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineStyle = awLine::SOLID;
|
||||
|
||||
/**
|
||||
* Line thickness
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $lineThickness = 1;
|
||||
|
||||
/**
|
||||
* Construct a new awScatterPlot
|
||||
*
|
||||
* @param array $datay Numeric values for Y axis
|
||||
* @param array $datax Numeric values for X axis
|
||||
* @param int $mode
|
||||
*/
|
||||
public function __construct($datay, $datax = NULL) {
|
||||
|
||||
parent::__construct();
|
||||
|
||||
// Defaults marks
|
||||
$this->mark = new awMark;
|
||||
$this->mark->setType(awMark::CIRCLE);
|
||||
$this->mark->setSize(7);
|
||||
$this->mark->border->show();
|
||||
|
||||
$this->label = new awLabel;
|
||||
|
||||
$this->setValues($datay, $datax);
|
||||
$this->setColor(new awBlack);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Display plot as impulses
|
||||
*
|
||||
* @param awColor $impulse Impulses color (or NULL to disable impulses)
|
||||
*/
|
||||
public function setImpulse($color) {
|
||||
$this->impulse = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Link scatter plot points
|
||||
*
|
||||
* @param bool $link
|
||||
* @param awColor $color Line color (default to black)
|
||||
*/
|
||||
public function link($link, $color = NULL) {
|
||||
$this->link = (bool)$link;
|
||||
if($color instanceof awColor) {
|
||||
$this->setColor($color);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ignore null values for Y data and continue linking
|
||||
*
|
||||
* @param bool $link
|
||||
*/
|
||||
public function linkNull($link) {
|
||||
$this->linkNull = (bool)$link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line color
|
||||
*
|
||||
* @param awColor $color
|
||||
*/
|
||||
public function setColor(awColor $color) {
|
||||
$this->lineColor = $color;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line style
|
||||
*
|
||||
* @param int $style
|
||||
*/
|
||||
public function setStyle($style) {
|
||||
$this->lineStyle = (int)$style;
|
||||
}
|
||||
|
||||
/**
|
||||
* Change line tickness
|
||||
*
|
||||
* @param int $tickness
|
||||
*/
|
||||
public function setThickness($tickness) {
|
||||
$this->lineThickness = (int)$tickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line thickness
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineThickness() {
|
||||
return $this->lineThickness;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the line type
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function getLegendLineStyle() {
|
||||
return $this->lineStyle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the color of line
|
||||
*
|
||||
* @return Color
|
||||
*/
|
||||
public function getLegendLineColor() {
|
||||
return $this->lineColor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the background color or gradient of an element of the component
|
||||
*
|
||||
* @return Color, Gradient
|
||||
*/
|
||||
public function getLegendBackground() {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a mark object
|
||||