Version 1.12

This commit is contained in:
nemunaire 2009-11-01 12:00:00 +01:00
commit de31cd3e9a
1373 changed files with 156282 additions and 45238 deletions

View file

@ -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');
?>

View file

@ -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'
);
?>

View file

@ -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');
?>

View file

@ -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

View file

@ -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);
?>

View file

@ -1,3 +0,0 @@
Artichow 1.0.9
- Pie::setBorder(): replaced by Pie::setBorderColor()

View file

@ -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;
}
?>

View file

@ -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');
?>

View file

@ -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');
?>

View file

@ -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');
?>

View file

@ -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);
?>

View file

@ -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

View file

@ -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

View file

@ -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